Per una singola funzione alla volta, puoi farlo in modo abbastanza interattivo usando la normale finestra di dialogo Seleziona per posizione , usando il seguente tasto come guida ai tipi di relazione spaziale per sovrapposizioni linea su linea (da Seleziona per posizione: esempi grafici ):
(fonte: arcgis.com )
Seleziona la linea usando la linea
INTERSETTO A, C, D, E, F, G, H, I, J
CONTIENE G, H
COMPLETELY_CONTAINS G
CONTAINS_CLEMENTINI G, H
ENTRO F, H
COMPLETAMENTE_WITHIN F
WITHIN_CLEMENTINI F, H
ARE_IDENTICAL_TO H
BOUNDARY_TOUCHES C, E
I tipi di relazione rilevanti in questo caso sono INTERSECT
e BOUNDARY_TOUCHES
. Come puoi vedere dal diagramma sopra, puoi usare BOUNDARY_TOUCHES
per selezionare le caratteristiche che toccano un punto finale della linea. Se sono selezionate esattamente due funzioni, allora hai il tuo Caso 1. Se una funzione non viene toccata da altre funzioni ma intersecata solo da esse, BOUNDARY_TOUCHES
non selezionerà nulla. INTERSECT
selezionerà tutte le funzioni che si intersecano indipendentemente dal fatto che tocchino o meno un endpoint. Quindi, se sai che non ci sono funzionalità che toccano gli endpoint, ma scopri che ci sono funzioni che si intersecano, allora hai il tuo caso 2.
Per automatizzare il processo è possibile utilizzare il seguente script Python (implementare come strumento di script se lo si desidera) per calcolare il numero di tocchi e intersezioni per ogni funzione in una classe di funzionalità o in un livello:
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)
Una volta eseguito, puoi facilmente cercare le funzioni che toccano esattamente due volte e si intersecano esattamente due volte (Caso 1) e quelle che toccano 0 volte e si intersecano esattamente due volte (Caso 2).
Query di definizione di esempio:
- Caso 1 (tocca due volte, si interseca due volte):
"NUM_TOUCHES" = 2 AND "NUM_INTERSECTIONS" = 2
- Caso 2 (non tocca nessuno, si interseca due volte):
"NUM_TOUCHES" = 0 AND "NUM_INTERSECTIONS" = 2
Vedi lo screenshot seguente per un'illustrazione delle istanze dei due casi trovati:
Si noti che con i dati del mondo reale, normalmente i segmenti di strada vengono suddivisi agli incroci e i penzoloni si verificano solo quando le strade si incrociano come in uno scambio o in un ponte. Quindi normalmente hai lo stesso numero di funzioni che si intersecano toccando.
Per il caso più generale, potresti voler cercare eventuali pericoli controllando se "NUM_INTERSECTIONS" > "NUM_TOUCHES"
.