Активная запись и PostGIS ST_BUFFER: LinearRing не прошел проверку звонка - PullRequest
2 голосов
/ 25 февраля 2020

В приложении, над которым я работаю, есть таблица 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, который я рассматриваю как запах кода.

Может кто-нибудь диагностировать, что я сделал неправильно? Рад предоставить более подробную информацию по мере необходимости. Спасибо.

1 Ответ

2 голосов
/ 26 февраля 2020

Я полагаю, вы меняете порядок пар координат. Это должно быть lon,lat вместо lat,lon.

Итак, попробуйте запрос, используя POINT(-90.0715323 29.9510658) и , а не POINT(29.9510658 -90.0715323):

SELECT 
  ST_Buffer('POINT(-90.0715323 29.9510658)'::geography, 
            25000, 
            'quad_segs=8')::geometry AS circle;

enter image description here

Дополнительное чтение: WGS84 (EPSG: 4326)

...