В приложении, над которым я работаю, есть таблица regions
, содержащая столбец геометрии с именем polygon
. Приложение использует PostGIS через гем activerecord-postgis-adapter
. Миграции Active Record, включающие столбцы геометрии, приводят к схеме, которая показывает:
t.geometry "polygon", limit: {:srid=>0, :type=>"geometry"}
Пользователи могут хранить круги, прямоугольники и многоугольники с помощью карты Leaflet. js во внешнем интерфейсе. Когда создается круг, запрос браузера включает в себя центр и радиус (в метрах).
Чтобы создать круг, приложение сохраняет центр и радиус вместе с многоугольником. Чтобы сохранить многоугольник, модель Region
использует следующий метод:
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
У меня возникло несколько проблем, наиболее острой из которых является то, что определенные круги не работают с ошибкой LinearRing failed ring test
. Например, эти параметры запроса:
{"name"=>"New Orleans, LA", "coordinates"=>[{"lat"=>29.9510658, "lng"=>-90.0715323}], "radius"=>25000, "shape"=>"circle", "format"=>:json, "region"=>{"name"=>"New Orleans, LA", "shape"=>"circle"}}
... создают этот запрос из вышеупомянутого метода:
SELECT ST_Buffer(ST_GeomFromText('POINT(29.9510658 -90.0715323)')::geography, 25000, 'quad_segs=8')::geometry AS circle;
..., который завершается ошибкой с LinearRing ошибка. Проходит другой круг с центром в Бостоне (например).
Я полагаюсь на полигональное представление круга для проведения испытаний на пересечение с другими кругами.
Я не знаком с PostGIS и не могу чтобы обойти эту проблему после долгих исследований и различных попыток. Самое близкое, что я могу получить - это обернуть запросы на создание круга в ST_MakeValid
, который я рассматриваю как запах кода.
Может кто-нибудь диагностировать, что я сделал неправильно? Рад предоставить более подробную информацию по мере необходимости. Спасибо.