Make sure a LineString has at least two points

According to the GeoJSON specification [1]:

> For type "LineString", the "coordinates" member is an array of two or
> more positions.

Note that the same doesn't seem to apply to a MultiPoint [2]:

> For type "MultiPoint", the "coordinates" member is an array of
> positions.

[1] https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.4
[2] https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.3
This commit is contained in:
Javi Martín
2024-11-29 17:06:35 +01:00
parent 624e60eab9
commit 9ef68f863a
2 changed files with 26 additions and 14 deletions

View File

@@ -79,8 +79,10 @@ class GeojsonFormatValidator < ActiveModel::EachValidator
case geometry["type"] case geometry["type"]
when "Point" when "Point"
valid_wgs84_coordinates?(coordinates) valid_wgs84_coordinates?(coordinates)
when "LineString", "MultiPoint" when "LineString"
coordinates.all? { |coordinates| valid_wgs84_coordinates?(coordinates) } coordinates.many? && valid_coordinates_array?(coordinates)
when "MultiPoint"
valid_coordinates_array?(coordinates)
when "Polygon", "MultiLineString" when "Polygon", "MultiLineString"
valid_polygon_coordinates?(coordinates) valid_polygon_coordinates?(coordinates)
when "MultiPolygon" when "MultiPolygon"
@@ -99,9 +101,13 @@ class GeojsonFormatValidator < ActiveModel::EachValidator
(-180.0..180.0).include?(longitude) && (-90.0..90.0).include?(latitude) (-180.0..180.0).include?(longitude) && (-90.0..90.0).include?(latitude)
end end
def valid_coordinates_array?(coordinates_array)
coordinates_array.all? { |coordinates| valid_wgs84_coordinates?(coordinates) }
end
def valid_polygon_coordinates?(polygon_coordinates) def valid_polygon_coordinates?(polygon_coordinates)
polygon_coordinates.all? do |ring| polygon_coordinates.all? do |ring_coordinates|
ring.all? { |coordinates| valid_wgs84_coordinates?(coordinates) } valid_coordinates_array?(ring_coordinates)
end end
end end
end end

View File

@@ -122,16 +122,6 @@ describe GeojsonFormatValidator do
expect(record).not_to be_valid expect(record).not_to be_valid
end end
it "is valid with a two-dimensional array including only one point" do
record.geojson = '{ "type": "LineString", "coordinates": [[1.23, 4.56]] }'
expect(record).to be_valid
record.geojson = '{ "type": "MultiPoint", "coordinates": [[1.23, 4.56]] }'
expect(record).to be_valid
end
it "is not valid when some coordinates are invalid" do it "is not valid when some coordinates are invalid" do
record.geojson = '{ "type": "LineString", "coordinates": [[1.23, 4.56], [180.01, 4.56]] }' record.geojson = '{ "type": "LineString", "coordinates": [[1.23, 4.56], [180.01, 4.56]] }'
@@ -153,6 +143,22 @@ describe GeojsonFormatValidator do
end end
end end
context "LineString geometry" do
it "is not valid with only one point" do
record.geojson = '{ "type": "LineString", "coordinates": [[1.23, 4.56]] }'
expect(record).not_to be_valid
end
end
context "MultiPoint geometry" do
it "is valid with only one point" do
record.geojson = '{ "type": "MultiPoint", "coordinates": [[1.23, 4.56]] }'
expect(record).to be_valid
end
end
context "GeometryCollection" do context "GeometryCollection" do
it "is not valid if it doesn't contain geometries" do it "is not valid if it doesn't contain geometries" do
record.geojson = '{ "type": "GeometryCollection" }' record.geojson = '{ "type": "GeometryCollection" }'