An app I'm working on has a regions
table containing a geometry column called polygon
. The app is using PostGIS via the activerecord-postgis-adapter
gem. Active Record migrations involving geometry columns result in a schema that shows:
t.geometry "polygon", limit: {:srid=>0, :type=>"geometry"}
Users can store circles, rectangles, and polygons via a Leaflet.js map in the front end. When a circle is created, the browser request includes the center and radius (in meters).
To create a circle, the app stores the center and radius along with a polygon. To save the polygon, the Region
model uses the following method:
def uncached_circle(coordinates, radius)
ActiveRecord::Base.connection.execute("
SELECT ST_Buffer(ST_GeomFromText('#{uncached_point(coordinates.first)}')::geography, #{radius}, 'quad_segs=8')::geometry AS circle;
")[0]["circle"]
end
I'm having a few problems, the most pressing of which is that certain circles fail with a LinearRing failed ring test
error. For example, these request parameters:
{"name"=>"New Orleans, LA", "coordinates"=>[{"lat"=>29.9510658, "lng"=>-90.0715323}], "radius"=>25000, "shape"=>"circle", "format"=>:json, "region"=>{"name"=>"New Orleans, LA", "shape"=>"circle"}}
...produce this query from the aforementioned method:
SELECT ST_Buffer(ST_GeomFromText('POINT(29.9510658 -90.0715323)')::geography, 25000, 'quad_segs=8')::geometry AS circle;
...which fails with the LinearRing error. Another circle centered in Boston (for example) passes.
I rely on the polygon representation of the circle to conduct intersection tests with other circles.
I'm not experienced with PostGIS and am unable to get around this issue after a lot of research and a variety of attempts. The closest I can get is to wrap the circle creation queries in ST_MakeValid
, which I view as a code smell.
Can anyone diagnose what I've done wrong? Happy to provide more detail as needed. Thank you.
I believe you're switching the order of the coordinate pairs. It should be lon,lat
instead of lat,lon
.
So, try your query using POINT(-90.0715323 29.9510658)
and not POINT(29.9510658 -90.0715323)
:
SELECT
ST_Buffer('POINT(-90.0715323 29.9510658)'::geography,
25000,
'quad_segs=8')::geometry AS circle;
Further reading: WGS84
(EPSG:4326)