У меня есть довольно подробный шейп-файл с функциями многоугольника / многоугольника (размер файла около 500 МБ). На самом деле это шейп-файл всего мира с элементами, представляющими береговые линии. Мне нужно разделить эти данные с помощью сетки. Чтобы было ясно, я не хочу «сортировать» данные, но на самом деле разрезать полигоны на плитки. Я понимаю, что этот вопрос уже задавался, но найденные мной решения не сработали.
Я пробовал:
Использование QGIS и пересечение содержимого шейп-файла с векторной сеткой - результаты ужасны. Большая часть суши волшебным образом исчезает, хотя иногда кажется, что небольшие куски земли делают это. Я должен отметить, что этот метод действительно хорошо работает с гораздо более простыми данными (т. Е. Меньше точек)
Использование инструментов пересечения OGR. Я попробовал это как через ogr2ogr, так и через собственный инструмент C ++. У них обоих такая же проблема, как у QGIS. Они также не демонстрируют эту проблему для простых файлов, но дают сбой более сложным. Для справки я использую шейп-файл из Австралии и Новой Зеландии размером менее 20 МБ, и QGIS и OGR не могут его «преобразовать в сетку».
Кто-то предложил использовать PostGIS в какой-то момент, так как он имеет функцию пересечения, но ST_Intersect в PostGIS использует тот же сервер GEOS, что и OGR. На самом деле, они оба вызывают одну и ту же функцию, насколько я могу судить, поэтому я не думаю, что PostGIS даст разные результаты.
Я искал предложения относительно того, что еще я мог попробовать. Мне нужно надежное приложение или инструментарий, который может разделить высокодетализированные шейп-файлы на плитки.
РЕДАКТИРОВАТЬ: Добавление дополнительной информации
В ответ Симбамангу:
Шейп-файл - это в основном данные береговой линии из OpenStreetMap. Это объединенная версия файла «process_p» (поэтому он не разделен на плитки), которую я получил, отправив по электронной почте их список разработчиков. Обратите внимание, что их разбиение тайлов (на куски размером 100 х 100 км с перекрытием) не обязательно то, что я хочу - я не хочу перекрытия, и мне нужна свобода выбора размера сетки, или я бы просто использовал по умолчанию.
По умолчанию данные береговой линии содержат ошибки геометрии, сообщаемые QGIS. Я исправляю эти ошибки с помощью небольшого инструмента, который я собрал с помощью некоторого кода, который я нашел специально для решения этой проблемы (исправление ошибок геометрии в данных береговой линии: https://github.com/tudelft-gist/prepair ). Работа с файлами с помощью этого инструмента исправляет практически все ошибки, которые обнаруживает QGIS. Я пытаюсь сделать пересечение только после очистки файлов.
Именно то, что я сделал, используя QGIS: откройте данные, чтобы убедиться, что они хорошо выглядят в QGIS. Попробуйте разделить его на плитки, создав слой плиток, используя Vector Grid с указанным интервалом, а затем пересекая два слоя - не ходи. Попробуйте использовать меньший набор данных - выберите объекты в Океании (Aus, NZ), чтобы попробовать меньший набор данных - этот файл формы имеет размер <20 МБ. Снова попробуйте разделить его, не работает.
Что я сделал с OGR: ogr2ogr напрямую, используя опции '-spat' и '-clipsrc' с spat_extent. Также написал небольшой инструмент C ++, который работает на WKT, поэтому я преобразую шейп-файл в WKT с помощью ogr2ogr, а затем передаю текстовый файл в свое приложение. Он запускает файл и вызывает метод Intersection (), описанный здесь: http://www.gdal.org/ogr/classOGRGeometry.html . Я думаю, что это в конечном итоге делает то же самое, что и использование ogr2ogr напрямую.
В ответ на Brent:
- Оно делает. Все в WGS84 Lat / Lon
- Я бы подумал, что верно обратное - для данного набора плиток сетки, чтобы пересечь один гигантский мультиполигон, потребовалось бы намного больше времени, нежели множество фрагментированных элементов, которые могли бы быть более пространственно локализованы для каждой плитки, но это интересное предложение - попробую и доложу.
- Во время процесса поля атрибутов не сохраняются, меня интересует только геометрия.
- Я не уверен, но я думаю, что вы говорите, что я должен выбрать полигоны, которые перекрывают данный фрагмент сетки, а затем выполнить пересечение. Это слишком громоздко с QGIS вручную. Мой инструмент уже делает это в определенной степени с помощью флажка с ограничением. Есть немного ускорения, но конечный результат все еще плох и ничем не отличается.
- Это не вариант. Прямо сейчас я пытаюсь разделить данные так, чтобы они составляли 1 градус широта х 1 градус долготы, и я ищу общую / надежную методологию, которая работает во всех случаях. Я попытался увеличить размер сетки (то есть 10x10), чтобы увидеть, получу ли я лучшие результаты, и я не вижу никакой корреляции между размером сетки и качеством вывода.
Редактировать № 2:
Я попытался поиграть с этим больше, и в целом просто кажется, что результаты ненадежны как при использовании GEOS, так и с QGIS (который использует fTools, я не знаю, использует ли он, в свою очередь, GEOS снова). Я ошибся, заявив, что размер сетки не имеет никакого отношения к результатам - чем больше сетка, тем лучше результаты (это полезно знать, но все же не решение). Вот скриншот действительно разнесенной сетки, которая в основном работала, но частично не работала в одной плитке:
Геометрия чистая - QGIS показывает 0 ошибок с помощью инструмента «Проверить правильность». Я не собираюсь подходить к этой проблеме шаг за шагом; проверить, не удалось ли определенным объектам пересечение в наборе данных такого большого размера, когда оно не является визуально видимым (и не будет с меньшими фрагментами), нецелесообразно.
Ответы:
Я только что закончил создавать свои собственные инструменты для этого.
Я использовал библиотеку Clipper ( http://www.angusj.com/delphi/clipper.php ) вместе с OGR, чтобы разделить мои настройки данных. Стоит отметить, что наивное выполнение пересечений с этой библиотекой занимает очень много времени, поэтому я вместо этого использовал подход с четырьмя деревьями ... то есть разделил на четыре ячейки сетки, разделил каждую из них на еще четыре и т. Д., Пока вы не получите желаемое разрешение. Хотя библиотека работает отлично, я приложил скриншот, показывающий результаты в восточном полушарии:
Приведенный выше результат занял около 4,5 часов на процессоре с частотой 1,33 ГГц.
Вот инструменты на случай, если кто-то столкнется с подобной проблемой в будущем. Обратите внимание, что они взломаны вместе для проверки концепций, и вам, вероятно, не следует использовать их напрямую (хотя это может послужить хорошей отправной точкой для чего-либо):
https://github.com/preet/scratch/tree/master/gis/polytoolkit
https://github.com/preet/scratch/tree/master/gis/shapefiles/shptk
источник
Похоже, у вас есть проблемы с геометрией. Маловероятно, что вы сможете получить чистые результаты из грязного входного файла независимо от используемого программного обеспечения, если только вы сначала не решите свои проблемы с геометрией. Как только вы разберетесь с проблемами геометрии, вы можете попробовать следующее, если у вас все еще есть проблемы:
1) Убедитесь, что ваш набор данных сетки имеет ту же проекцию, что и ваш набор многоугольников мира. Если нет, воссоздайте его в правильной проекции.
2) Конвертировать все функции в одну часть - гораздо проще обрабатывать
3) Удалите все посторонние поля, оставив только поле идентификатора, которое позволит вам присоединить ваши атрибуты обратно после того, как пересечение было выполнено - опять же, намного проще в обработке
4) Вместо того, чтобы пересекать весь набор данных сетки со всем набором данных многоугольников мира, попробуйте зациклить свои полигоны сетки, выбрав пересекающиеся многоугольники в своем наборе данных мира и выполнив клип на основе своего многоугольника сетки. Это позволит вам изолировать любые проблемы и, в конце концов, вы сможете объединить результаты для достижения вашей первоначальной цели.
5) Попробуйте использовать большие полигоны сетки.
источник
Другой подход мог бы заключаться в том, чтобы попробовать преобразование вектора в растр для создания набора точечных данных, а затем использовать набор точечных данных в качестве основы для написания некоторого кода для создания ваших плиток.
источник