Для одного объекта за раз вы можете сделать это довольно легко в интерактивном режиме с помощью обычного диалогового окна « Выбор по местоположению », используя следующую клавишу в качестве руководства по типам пространственных отношений для наложений «линия по линии» (из « Выбор по расположению: графические примеры» ):
(источник: arcgis.com )
Выберите строку, используя линию
ИНТЕРСЕКТ A, C, D, E, F, G, H, I, J
СОДЕРЖИТ G, H
COMPLETELY_CONTAINS G
CONTAINS_CLEMENTINI G, H
В Ф, Н
COMPLETELY_WITHIN F
WITHIN_CLEMENTINI F, H
ARE_IDENTICAL_TO H
BOUNDARY_TOUCHES C, E
Соответствующими типами отношений в этом случае являются INTERSECT
и BOUNDARY_TOUCHES
. Как видно из диаграммы выше, вы можете использовать BOUNDARY_TOUCHES
для выбора функции, которые касаются конечной точки линии. Если выбрано ровно две функции, то у вас есть ваш Случай 1. Если функция не затрагивается какими-либо другими функциями, а только пересекается с ними, то BOUNDARY_TOUCHES
ничего не выберет. INTERSECT
выберет все объекты, которые пересекаются, независимо от того, касаются они конечной точки или нет. Поэтому, если вы знаете, что нет никаких объектов, которые касаются конечных точек, но вы обнаружите, что они пересекаются, то у вас есть Случай 2.
Чтобы автоматизировать процесс, вы можете использовать следующий скрипт Python ( при желании реализовать в качестве инструмента-скрипта ), чтобы рассчитать количество касаний и пересечений для каждого объекта в классе пространственных объектов или слое:
import arcpy
################################ Configuration #################################
numTouchesField = "NUM_TOUCHES"
numIntersectionsField = "NUM_INTERSECTIONS"
################################################################################
def countTouches(layer, feature):
"""Returns the number of times the boundary of a feature touches other
features in the same feature layer."""
return countSpatialRelation(layer, feature, "BOUNDARY_TOUCHES")
def countIntersections(layer, feature):
"""Returns the number of times a feature intersects other features in the
same feature layer."""
return countSpatialRelation(layer, feature, "INTERSECT") - 1 # Subtract 1 because the feature will always intersect its clone in the feature layer
def countSpatialRelation(layer, feature, relation):
"""Returns the number of times a feature meets the specified spatial
relationship with other features in the same feature layer."""
arcpy.SelectLayerByLocation_management(layer, relation, feature)
count = int(arcpy.GetCount_management(layer).getOutput(0))
return count
def addField(table, fieldName, fieldType):
"""Adds a fields of the given name and type to a table, unless a field with
the same name already exists."""
desc = arcpy.Describe(table)
fieldInfo = desc.fieldInfo
fieldIndex = fieldInfo.findFieldByName(fieldName)
if fieldIndex == -1:
# Field does not exist, add it
arcpy.AddField_management(table, fieldName, fieldType)
def countTouchesAndIntersections(layer):
"""Adds and populates fields describing the number of times each feature
touches and intersects other features in the feature layer."""
addField(layer, numTouchesField, "LONG")
addField(layer, numIntersectionsField, "LONG")
desc = arcpy.Describe(layer)
shapeField = desc.shapeFieldName
rows = arcpy.UpdateCursor(layer)
for row in rows:
feature = row.getValue(shapeField)
row.setValue(numTouchesField, countTouches(layer, feature))
row.setValue(numIntersectionsField, countIntersections(layer, feature))
rows.updateRow(row)
del row, rows
if __name__ == "__main__":
layer = arcpy.MakeFeatureLayer_management(arcpy.GetParameterAsText(0))
countTouchesAndIntersections(layer)
После этого вы можете легко запросить объекты, которые касаются ровно дважды и пересекаются ровно дважды (Случай 1), и те, которые касаются 0 раз и пересекаются ровно дважды (Случай 2).
Пример определения запросов:
- Случай 1 (Касается дважды, дважды пересекается):
"NUM_TOUCHES" = 2 AND "NUM_INTERSECTIONS" = 2
- Случай 2 (не касается, пересекается дважды):
"NUM_TOUCHES" = 0 AND "NUM_INTERSECTIONS" = 2
Смотрите скриншот ниже для иллюстрации экземпляров двух найденных случаев:
Обратите внимание, что с данными реального мира, как правило, сегменты улиц разбиваются на перекрестках, и повисание происходит только тогда, когда дороги пересекают друг друга, как на развязке или мосту. Так что обычно у вас есть то же количество пересекающихся функций, что и касание.
В более общем случае вы можете поискать какие-либо зависания, проверив, есть ли "NUM_INTERSECTIONS" > "NUM_TOUCHES"
.