ГИС-анализ для поиска дублирующих геометрий

9

У меня есть большой шейп-файл, который содержит все здания и дома города, в котором я работаю (около 90 000 объектов). Данные о зданиях / домах сохраняются инженерами-геодезистами города, и из-за плохой практики и доступа различных геодезистов к этим данным многие здания / дома были сохранены дважды и отображаются на карте в виде дубликатов.

Некоторые из них точно дублируются (они появляются один над другим), в то время как другие дублируются с пробелом между двумя объектами (как один объект находится внутри другого - см. Прикрепленный снимок экрана).

введите описание изображения здесь

Я хочу очистить эти данные, чтобы у меня были только правильные здания / дома в городе, поэтому мой вопрос:

Есть ли какой-нибудь ГИС-анализ или выражение SQL, которое я могу запустить, чтобы найти все дублированные функции (как точные, так и те, которые находятся внутри других)? У меня есть и ArcGIS, и QGIS, поэтому я открыт для всех ваших предложений.

GIS_DBA
источник
Вы можете попробовать изучить инструмент удаления идентичных . Однако это требует уровня лицензии предприятия. Вы можете просмотреть некоторые другие опции, доступные в технической статье 36031. Предоставляет ли ArcGIS способ идентификации или удаления объектов с дублирующейся геометрией, лучше всего использовать расширение Data Reviewer . ни один из этих инструментов не будет работать с вашими раздельными геометриями
MDHald
Кроме того, вы должны учитывать, что табличные компоненты не будут сравниваться в инструменте удаления идентичных. Я знаю, что это не ответ, но, надеюсь, это поможет в решении проблем.
MDHald
Данные в базе данных? Какого вида?
Рассел на ISC
Одним из вариантов может быть использование инструмента пересечения (как описано в этом ответе ) в ArcMap, который будет выводить любые места наложения. Для этого потребуется вручную проверить и решить, какой полигон удалять, но в случае неточных дубликатов, я думаю, вам все равно придется это делать.
Эрика
4
Использование термина «дубликат» немного вводит в заблуждение в этом вопросе. В случае точных, идентичных, составленных копий, тогда да, они (или могут быть - атрибуты могут отличаться) дубликаты, и, как другие предположили, инструмент Удалить или Найти идентичный может быть полезен, если у вас есть этот уровень лицензии. Но если они вообще смещены или имеют другую форму, они не являются дубликатами сами по себе. Если у вас есть лицензия Advanced, я бы посмотрел топологию базы геоданных, запустив проверку Must Not Overlap. Без Advanced, возможно, то же самое можно сделать с QGIS и плагином, как предполагает ответ Луиджи.
Крис W

Ответы:

4

в QGIS плагин Topology Checker может решить вашу проблему

Луиджи Пирелли
источник
3
Я согласен, что топология - это, вероятно, лучшее решение проблемы очистки данных. Однако вы можете немного расширить свой ответ, предоставив ссылку на плагин и краткое описание того, что топология или что делает, и какую проверку вы будете выполнять. Боюсь, ваш набранный ответ, скорее всего, будет помечен как некачественный.
Крис W
хорошо: описание плагина здесь: docs.qgis.org/2.2/en/docs/user_manual/plugins/… и «не должно перекрываться» может решить проблему. Видеогид по плагину находится здесь: youtube.com/watch?v=huhkTZkoKC8 .
Луиджи Пирелли
6

Я бы использовал itertools Python и SearchCursor для очень эффективного способа поиска пространственных связей, которые вам нужны. Вы можете включать методы геометрии overlaps , containsи equalполучить на свойства геометрии.

  1. Начните с создания функции для лучшей организации рабочего процесса и для повторяемости

    def findOverlaps(x):

  2. Откройте поисковый курсор, чтобы перейти к геометрии отдельных объектов

    with arcpy.da.SearchCursor(x, ['OID@', 'SHAPE@']) as cur:

  3. использовать itertools.combinations()для возврата подпоследовательностей элементов из итеративного вводаcur

    for feature1,feature2 in itertools.combinations(cur, 2):

  4. Доступ к свойствам геометрии со следующими методами: equals(), overlaps()и contains(). Они настроены в логической последовательности - вы можете настроить это для достижения ваших конкретных целей, если это необходимо.

        if feature1[1].equals(feature2[1]):
            print "{} equals {}".format(feature1[0],feature2[0])
        if feature1[1].overlaps(feature2[1]):
            print "{} overlaps {}".format(feature1[0],feature2[0])
        if feature1[1].contains(feature2[1]):
            print "{} contains {}".format(feature1[0],feature2[0])
    
  5. Запустить его...

enter code herefindOverlaps (к)


import itertools, arcpy

fc = r'C:\path\to\your\fc'

def findOverlaps(x):
    with arcpy.da.SearchCursor(x, ['OID@', 'SHAPE@']) as cur:
        for feature1,feature2 in itertools.combinations(cur, 2):
            if feature1[1].equals(feature2[1]):
                print "{} equals {}".format(feature1[0],feature2[0])
            if feature1[1].overlaps(feature2[1]):
                print "{} overlaps {}".format(feature1[0],feature2[0])
            if feature1[1].contains(feature2[1]):
                print "{} contains {}".format(feature1[0],feature2[0])

findOverlaps(fc)

введите описание изображения здесь

На снимке экрана показаны различные функции, которые перекрываются, перекрываются и идентичны, а также уникальны.

введите описание изображения здесь

Аарон
источник
2

У меня есть идея, что может сработать для вас. Он будет основан на некоторых предположениях, но это поможет сузить список возможных идентичных функций. Это не был бы автоматизированный процесс, но это потребовало бы ручного просмотра дубликатов. Исходя из комментариев, кажется, что автоматизированные инструменты не сравнивают атрибуты, так что это поможет вам не случайно удалить объекты.

Использование 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')). Для каждой записи проверьте свой список, чтобы увидеть, содержит ли он этот идентификатор, и отметьте свой столбец для дубликатов, если он там есть.

myList = []
rows = arcpy.UpdateCursor("layername")
for row in rows:
  if str(row.UniqueIdentifier) in myList:
    #value duplicated
    row.DuplicateColumnName = "y"
  else:
    #not there, add it
    myList.append(row.UniqueIdentifier)
  rows.updateRow(row)

(5) Затем вы можете сравнить или сделать все, что вы хотите с этими отмеченными столбцами.

Вероятно, есть более эффективные способы проведения этих сравнений, но я считаю, что это два, которые должны сработать или, по крайней мере, помочь вам начать.

редактировать

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

Используя ArcMap, вы можете запустить инструмент Minimum Bounding Geometry в Data Management. После проверки параметров, я думаю, что использование параметра CONVEX_HULL , вероятно, было бы лучше.

Если вы сравните поля MBG_APodX / Y1 , MBG_APod_X / Y2 и MBG_Orientation для дубликатов, вы сможете получить представление о дублированных функциях. Я бы предложил использовать метод Summarize, который я описал выше, для сравнения. Выберите одну из вершин (координат) из ограничивающего прямоугольника, чтобы найти дубликаты. Вы можете получить несколько случайных «совпадений», но как только вы добавите в другие вершины плюс ориентацию, было бы вполне уверенным, что функции результатов будут дубликатами.

Хотя я не использовал его и не совсем уверен в результатах этого инструмента, вам может показаться, что изучить полученный шейп-файл проще, если вы используете инструмент Сводная статистика в ArcMap. Похоже, что вы можете суммировать несколько столбцов таким образом, вместо моего варианта одного столбца.

Я не думаю, что был бы полностью автоматизированный способ сделать это, не беспокоясь о возможности удаления не дублирующейся функции. Эти методы должны помочь ограничить количество функций, которые вам необходимо будет просмотреть вручную.

Бранко
источник
Я предполагаю, что это были полигоны. Если это линии, вы можете использовать длину. Точки легче всего с координатами X / Y.
Бранко
2
Я тоже подумал об «равных элементах области», но мне кажется вероятным, что у следов здания может быть достаточно однотипных фигур для создания непреднамеренных совпадений. Я думаю, что это улучшило бы шансы на дальнейшее уточнение вещей с пересечением функций MBR. То есть, если они имеют одинаковую область (и могут иметь одну и ту же функцию) И их MBR пересекаются, то, вероятно, они, вероятно, являются двумя поколениями одной и той же функции. Имеет ли это смысл?
elrobis
2

Вы можете сделать это в SQL, используя пространственное самостоятельное соединение. Вы не указываете, какой диалект SQL вы используете, поэтому в этом примере используется Postgres / Postgis, но его можно легко адаптировать к Oracle или SQL Server. Предположим, что таблица называется зданиями, а геометрия хранится в столбце с именем geom:

SELECT a.id, b.id from buildings a, buildings b WHERE 
  ST_INTERSECTS(a.geom, b.geom) AND a.id < b.id;

Это найдет пересечения. Если вы хотите полного равенства, замените ST_Intersects на ST_Equals. Или просто объедините два:

SELECT a.id, b.id from buildings a, buildings b WHERE 
   (ST_INTERSECTS(a.geom, b.geom) OR ST_EQUALS(a.geom, b.geom)) 
   AND a.id < b.id;

Обратите внимание, что a.id <b.id означает, что при самостоятельном объединении вы рассматриваете только половину случаев, что делает его a) более быстрым и b) дает вам список, который можно использовать для удаления половины перекрывающихся полигонов, не удаляя их все , Понятно, что это все еще алгоритм O (n²), но на практике он будет намного быстрее, если у вас есть пространственный индекс, что на самом деле является общим требованием для любого нетривиального набора данных.

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

Джон Пауэлл
источник
Если вам не хватает уникального атрибута в шейп-файле, вы можете использовать a.rowidвместо a.id. rowidэто ключевое слово в SQLite, которое даст вам внутренний идентификатор набора данных.
LuWi
1

Плагин Topology Checker - хороший инструмент, если его использовать правильно. Вы все еще должны иметь фундаментальное понимание ваших данных И вы должны внести «исправления» вручную. Плагин будет подсвечивать ошибки. Затем вы должны изучить каждый из них и принять соответствующее решение для вас и ваших данных. С 90 000 предметов в вашем слое, вы можете быть дома к Рождеству!

Johanna
источник