Distinguere le linee che si intersecano dalle linee che toccano?


9

Come faccio a distinguere tra questi casi in ArcGIS 10?

  • Caso 1 : entrambi i punti finali di una linea toccano un'altra linea
  • Caso 2 : entrambi gli endpoint pendono dalle linee che interseca

Sto guardando la funzione Trim Line ma non è quello che voglio (distruttivo).

Il caso d'uso reale consiste nel distinguere tra strade di servizio che collegano entrambe le strade di un'autostrada senza pedaggio e altri casi di strade che si intersecano con autostrade.

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Risposte:


13

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 ):

Immagine
(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 INTERSECTe BOUNDARY_TOUCHES. Come puoi vedere dal diagramma sopra, puoi usare BOUNDARY_TOUCHESper 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_TOUCHESnon selezionerà nulla. INTERSECTselezionerà 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: Schermata di ArcMap che mostra varie intersezioni di linee / relazioni tattili

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".


Grazie per la risposta elaborata. Ho un piccolo problema a trasformarlo in uno strumento di script (si blocca quando provo a selezionare un livello) ma sono sicuro che l'approccio sia valido.
mvexel,

Un altro commento: ho dovuto ridurre la lunghezza del nome del campo a meno di 10 caratteri (probabilmente perché l'origine del livello è un file di forma).
mvexel,

Sembra che ci sia un URL per un'immagine della documentazione ArcGIS che si è smarrita all'inizio di questa risposta.
PolyGeo

@PolyGeo quale? Sembra che vada bene.
blah238,

È strano, la prima foto (su quello che sarebbe circa la quarta riga) è stata mostrata ieri come una piccola croce. Oggi sembra a posto. Penso di averlo visto nel browser (che sto usando ora) anziché nel client iOS che utilizzo spesso.
PolyGeo


-1

Che ne dici di copiare il feature layer, tagliare le linee, quindi confrontare il set di funzionalità ritagliate con l'originale per trovare le funzionalità che sono cambiate? Non abbastanza, quasi certamente richiede l'uso di Python, ma sembra che dovrebbe funzionare.


-1

È inoltre possibile estrarre i nodi della rete. Nel caso 1 otterrai 2 nodi ciascuno con una valenza di 4. Nel caso 2 non ci sono nodi.


Puoi suggerire come farlo in ArcGIS?
blah238,

È possibile utilizzare lo script o lo strumento di qualcuno per aggiungere ID univoci alla polilinea che sono i nodi da e a. So che archydro lo fa, ma sono sicuro che ci sono script sul sito web di arcscripts che lo fanno. Quindi, in modo non programmabile, è possibile eseguire lo strumento di frequenza sul campo da e quindi sul campo nodo e sommarli, questo ti dà valenza nodo che puoi ricollegare a un livello punto che rappresenta i nodi.
Hornbydd,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.