У меня есть большой шейп-файл, который содержит все здания и дома города, в котором я работаю (около 90 000 объектов). Данные о зданиях / домах сохраняются инженерами-геодезистами города, и из-за плохой практики и доступа различных геодезистов к этим данным многие здания / дома были сохранены дважды и отображаются на карте в виде дубликатов.
Некоторые из них точно дублируются (они появляются один над другим), в то время как другие дублируются с пробелом между двумя объектами (как один объект находится внутри другого - см. Прикрепленный снимок экрана).
Я хочу очистить эти данные, чтобы у меня были только правильные здания / дома в городе, поэтому мой вопрос:
Есть ли какой-нибудь ГИС-анализ или выражение SQL, которое я могу запустить, чтобы найти все дублированные функции (как точные, так и те, которые находятся внутри других)? У меня есть и ArcGIS, и QGIS, поэтому я открыт для всех ваших предложений.
Ответы:
в QGIS плагин Topology Checker может решить вашу проблему
источник
Я бы использовал itertools Python и SearchCursor для очень эффективного способа поиска пространственных связей, которые вам нужны. Вы можете включать методы геометрии
overlaps
,contains
иequal
получить на свойства геометрии.Начните с создания функции для лучшей организации рабочего процесса и для повторяемости
def findOverlaps(x):
Откройте поисковый курсор, чтобы перейти к геометрии отдельных объектов
with arcpy.da.SearchCursor(x, ['OID@', 'SHAPE@']) as cur:
использовать
itertools.combinations()
для возврата подпоследовательностей элементов из итеративного вводаcur
for feature1,feature2 in itertools.combinations(cur, 2):
Доступ к свойствам геометрии со следующими методами:
equals()
,overlaps()
иcontains()
. Они настроены в логической последовательности - вы можете настроить это для достижения ваших конкретных целей, если это необходимо.Запустить его...
enter code here
findOverlaps (к)На снимке экрана показаны различные функции, которые перекрываются, перекрываются и идентичны, а также уникальны.
источник
У меня есть идея, что может сработать для вас. Он будет основан на некоторых предположениях, но это поможет сузить список возможных идентичных функций. Это не был бы автоматизированный процесс, но это потребовало бы ручного просмотра дубликатов. Исходя из комментариев, кажется, что автоматизированные инструменты не сравнивают атрибуты, так что это поможет вам не случайно удалить объекты.
Использование ArcMap
(1) Сделайте копию своего шейп-файла на случай, если что-то пойдет не так.
(2) Добавьте столбец в свой шейп-файл как двойной.
(3) Рассчитайте площадь для каждого объекта, используя наиболее описательный (самый точный) формат, который вы можете. Что-то, где округление не может быть проблемой.
(4) Запустите сводку (итоги) по этому столбцу. Убедитесь, что вы выбрали уникальный идентификатор в сводке и отметили как первый, так и последний.
(5) В вашей выходной таблице найдите те записи, в которых поле счетчика больше 1.
(6a) Вручную проверьте функции и повторяйте процесс, пока больше не будет дубликатов.
(6b) Вы можете просто создать список этих уникальных идентификаторов и удалить объекты с помощью arcpy, но у вас есть шанс получить два неидентичных объекта с одной и той же областью.
Другая техника с использованием ArcPy
Когда я строил приведенный выше ответ, я думал о возможности того, что несколько авторов этих данных могли использовать одни и те же уникальные идентификаторы для дублированных функций. Если это так, вы можете найти дубликаты в цикле arcpy.
То, как я думаю об этом с помощью ArcPy, может обойтись без вашей системы.
(1) Сделайте копию своего шейп-файла (на всякий случай снова)
(2) Добавьте новый столбец для обозначения дубликатов. Что-то, что принимает как 'y' или 'n' или 0 или 1 или что-то еще, будет работать.
(3) Создайте список в Python для хранения уникального идентификатора.
(4) Запустите курсор обновления (
arcpy.UpdateCursor('LAYERNAME')
). Для каждой записи проверьте свой список, чтобы увидеть, содержит ли он этот идентификатор, и отметьте свой столбец для дубликатов, если он там есть.(5) Затем вы можете сравнить или сделать все, что вы хотите с этими отмеченными столбцами.
Вероятно, есть более эффективные способы проведения этих сравнений, но я считаю, что это два, которые должны сработать или, по крайней мере, помочь вам начать.
редактировать
Основываясь на комментарии elrobis , вы можете использовать минимальный ограничивающий прямоугольник, чтобы еще больше снизить вероятность удаления неправильных объектов.
Используя ArcMap, вы можете запустить инструмент Minimum Bounding Geometry в Data Management. После проверки параметров, я думаю, что использование параметра CONVEX_HULL , вероятно, было бы лучше.
Если вы сравните поля MBG_APodX / Y1 , MBG_APod_X / Y2 и MBG_Orientation для дубликатов, вы сможете получить представление о дублированных функциях. Я бы предложил использовать метод Summarize, который я описал выше, для сравнения. Выберите одну из вершин (координат) из ограничивающего прямоугольника, чтобы найти дубликаты. Вы можете получить несколько случайных «совпадений», но как только вы добавите в другие вершины плюс ориентацию, было бы вполне уверенным, что функции результатов будут дубликатами.
Хотя я не использовал его и не совсем уверен в результатах этого инструмента, вам может показаться, что изучить полученный шейп-файл проще, если вы используете инструмент Сводная статистика в ArcMap. Похоже, что вы можете суммировать несколько столбцов таким образом, вместо моего варианта одного столбца.
Я не думаю, что был бы полностью автоматизированный способ сделать это, не беспокоясь о возможности удаления не дублирующейся функции. Эти методы должны помочь ограничить количество функций, которые вам необходимо будет просмотреть вручную.
источник
Вы можете сделать это в SQL, используя пространственное самостоятельное соединение. Вы не указываете, какой диалект SQL вы используете, поэтому в этом примере используется Postgres / Postgis, но его можно легко адаптировать к Oracle или SQL Server. Предположим, что таблица называется зданиями, а геометрия хранится в столбце с именем geom:
Это найдет пересечения. Если вы хотите полного равенства, замените ST_Intersects на ST_Equals. Или просто объедините два:
Обратите внимание, что a.id <b.id означает, что при самостоятельном объединении вы рассматриваете только половину случаев, что делает его a) более быстрым и b) дает вам список, который можно использовать для удаления половины перекрывающихся полигонов, не удаляя их все , Понятно, что это все еще алгоритм O (n²), но на практике он будет намного быстрее, если у вас есть пространственный индекс, что на самом деле является общим требованием для любого нетривиального набора данных.
Возможно, вам придется немного помассировать это, чтобы соответствовать определению перекрытия - вы не хотите удалять соседние дома, которые были плохо обследованы.
источник
a.rowid
вместоa.id
.rowid
это ключевое слово в SQLite, которое даст вам внутренний идентификатор набора данных.Плагин Topology Checker - хороший инструмент, если его использовать правильно. Вы все еще должны иметь фундаментальное понимание ваших данных И вы должны внести «исправления» вручную. Плагин будет подсвечивать ошибки. Затем вы должны изучить каждый из них и принять соответствующее решение для вас и ваших данных. С 90 000 предметов в вашем слое, вы можете быть дома к Рождеству!
источник