Make sure polygons contain valid rings

According to the GeoJSON specification [1]:

> * A linear ring is a closed LineString with four or more positions.
> * The first and last positions are equivalent, and they MUST contain
>   identical values; their representation SHOULD also be identical.
> (...)
> * For type "Polygon", the "coordinates" member MUST be an array of
>   linear ring coordinate arrays.

Note that, for simplicity, right now we aren't checking whether the
coordinates are defined counterclockwise for exterior rings and
clockwise for interior rings, which is what the specification expects.

[1] https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.6
This commit is contained in:
Javi Martín
2024-12-02 13:21:49 +01:00
parent c3bda443a6
commit 1f627d34f1
5 changed files with 228 additions and 8 deletions

View File

@@ -115,8 +115,13 @@ class GeojsonFormatValidator < ActiveModel::EachValidator
end
def valid_polygon_coordinates?(polygon_coordinates)
polygon_coordinates.all? do |ring_coordinates|
valid_coordinates_array?(ring_coordinates)
end
polygon_coordinates.is_a?(Array) &&
polygon_coordinates.all? { |ring_coordinates| valid_ring_coordinates?(ring_coordinates) }
end
def valid_ring_coordinates?(ring_coordinates)
valid_coordinates_array?(ring_coordinates) &&
ring_coordinates.size >= 4 &&
ring_coordinates.first == ring_coordinates.last
end
end