Помощь с геометрией полигона PostGIS - незамкнутые кольца

10

Я взял копию супер злой книги Эрика Вестры «Python Geospatial Development» ( ссылка на Amazon ) и прорабатываю ее. В настоящее время он учит меня загружать данные береговой линии GSHHS из шейп-файла в базу данных PostGIS при подготовке к созданию геопространственного веб-приложения.

Моя проблема заключается в следующем: когда я пытаюсь импортировать данные GSHHS в PostGIS, они отклоняются из-за того, что полигоны береговой линии не считаются «действительными». В частности, мне выдается сообщение об ошибке, описывающее некоторые (но не все) полигоны береговой линии как «незамкнутые кольца».

Я понимаю, что эта ошибка пытается сказать мне, что первая и последняя точки многоугольника не совпадают. Однако это просто неправда. Я изучил WKT-представление многих полигонов, и они верны. Они определенно начинаются и заканчиваются одной и той же координатой.

Полигоны извлекаются из шейп-файлов с использованием библиотеки OGR и экспортируют каждый объект полигона в WKT. Я пытался воссоздать полигон через Shapely и экспериментировал с WKB, но безрезультатно. Я уже был в состоянии загрузить одни и те же данные в PostGIS в виде таблицы MultiPolygon, используя shp2pgsql погрузчик.

Мне было интересно, если кто-то там:
(а) возможно, использовал ту же книгу, застрял в той же проблеме, и есть ли ответ для меня?
(б) столкнулся с подобной проблемой, и нашел решение?
(c) если это не удастся, есть ли рекомендации «передового опыта» для обеспечения правильной геометрии перед загрузкой в ​​PostGIS?

ОБНОВЛЕНИЕ: коллега предположил, что проблема «незамкнутых колец» может быть просто симптомом другой проблемы. Возможно, что моя конфигурация PostGIS / PostgreSQL имеет ограничения по размеру (для транзакций вставки, полученных пакетов, текстовых строк и т. Д.).

Поскольку я использую очень длинные WKT-полигоны в качестве входных данных, PostGIS может обрезать их слишком рано, чтобы позволить завершить каждый полигон. Я проверю это завтра, но это звучит правдоподобно. Моя вставка границ страны принимала только некоторые записи, а не другие. По памяти принятые геометрии были для малых островных стран, таких как Антигуа (и поэтому, вероятно, имели короткие представления WKT).

Таким образом, это может оказаться скорее потоком администратора базы данных PostGIS, чем недопустимым потоком геометрии.

Тимми
источник
Можете ли вы предоставить образец файла shp?
Марио Милер
не беспокойтесь. Данные GSHHS о береговой линии, которые я использую, загружаются отсюда 96 Мб . Данные о границах мира, которые я использую, - это набор данных о границах мира с thematicmapping.org
Тимми

Ответы:

6

Я посмотрел на ваши данные и пример книги, проблема в том, что в книге обрабатываются три недопустимых полигона:

GSHHS_l_L1.shp

ID = 92-W

POLYGON ((-180.0 71.514793999999995,-179.69008299999999 71.577888999999999,-178.648889 71.577416999999997,-178.40644399999999 71.549916999999994,-177.406306 71.244167000000004,-177.877444 71.022889000000006,-179.500111 70.863749999999996,-179.93011100000001 70.979583000000005,-180.0 70.962072000000006))

ID = 486-W

POLYGON ((-180.0 -16.799126,-179.84419399999999 -16.691278,-179.80041700000001 -16.789193999999998,-179.850472 -16.878361000000002,-180.0 -16.959561))

GSHHS_l_L2.shp

ID = 7333-W

POLYGON ((-180.0 65.393473,-179.76583299999999 65.428332999999995,-179.95416700000001 65.385555999999994,-179.90972199999999 65.316389,-180.0 65.321635))

Поскольку это пример, было бы проще удалить эти полигоны из набора данных или просто добавить оператор if в ваш код.

if geometry.IsValid():
       cursor.execute("INSERT INTO gshhs (level, geom) VALUES (%s, ST_GeomFromText(%s, 4326))", (level, wkt))
Марио Милер
источник
Благодаря Марио, похоже, я забегал далеко вперед, вместо того, чтобы правильно проверять ВСЕ мои входные полигоны. Ваш ответ был правильным - эти полигоны оказались недействительными при тестировании с OGR. Интересно, что в QGis все выглядело отлично, но ArcMap показал, что им не хватает полного кольца. Все эти три многоугольника упали на линию даты, и я думаю, что геометрия шейп-файла не учитывала ребро многоугольника вдоль линии даты. Ваше решение - это удобный и простой способ обнаружить недопустимые полигоны. Я отмечу пост как ответивший.
Тимми
Если вы чувствуете себя благотворительным, есть ли у вас какие-либо хорошие решения для следующего шага в процессе, который исправляет недействительные полигоны? Я пытался использовать функцию OGR .CloseRing (), но безрезультатно. Я думаю, он просто проигнорировал вызов функции.
Тимми
Я пытался использовать «буфер трюк» ( workshops.opengeo.org/postgis-intro/validity.html ) с стройными и OGR , но без успеха. Shapely не будет читать недопустимый полигон и ogr не будет выполнять буферную операцию, в настоящее время я не знаю почему. Если я наткнусь на ответ, я дам вам знать. Может быть, у кого-то еще больше успеха с этой проблемой. Сожалею.
Марио Милер
Я думаю, что моя проверка полигонов работает сейчас. Я думаю, что использовал функцию OGR .CloseRings () неправильно. Меня назвали как метод многоугольника (то есть poly.CloseRings ()). Вместо этого мне пришлось извлечь линейное кольцо из многоугольника, а затем запустить его на нем (т. Е. Lr = poly.GetGeometryRef (0); lr.CloseRings ()). Результаты успешно вставляются в PostGIS, и я могу использовать 3 проблемных полигона в QGis, не беспокоясь. Проверка правильности КАЖДОГО полигона требует лишь небольшого количества вычислительных затрат.
Тимми