Distinguer les lignes qui se croisent des lignes qui se touchent?

9

Comment distinguer ces cas dans ArcGIS 10?

  • Cas 1 : les deux extrémités d'une ligne touchent une autre ligne
  • Cas 2 : les deux extrémités se balancent sur les lignes qu'elles croisent

Je regarde la fonction Trim Line mais ce n'est pas ce que je veux (destructif).

Le cas d'utilisation dans le monde réel est de faire la distinction entre les routes de service reliant les deux routes d'une autoroute et les autres cas de routes se croisant avec des autoroutes.

entrez la description de l'image ici entrez la description de l'image ici

mvexel
la source

Réponses:

13

Pour une seule entité à la fois, vous pouvez le faire assez facilement de manière interactive en utilisant la boîte de dialogue normale Sélectionner par emplacement , en utilisant la touche suivante comme guide pour les types de relations spatiales pour les superpositions ligne par ligne (à partir de Sélectionner par emplacement: exemples graphiques ):

image
(source: arcgis.com )

Sélectionnez la ligne en utilisant la ligne

INTERSECTER A, C, D, E, F, G, H, I, J

CONTIENT G, H

COMPLETELY_CONTAINS G

CONTIENT_CLEMENTINI G, H

DANS F, H

COMPLETELY_WITHIN F

WITHIN_CLEMENTINI F, H

ARE_IDENTICAL_TO H

BOUNDARY_TOUCHES C, E

Les types de relations pertinents dans ce cas sont INTERSECTet BOUNDARY_TOUCHES. Comme vous pouvez le voir sur le diagramme ci-dessus, vous pouvez utiliser BOUNDARY_TOUCHESpour sélectionner les fonctions qui touchent un point final de la ligne. Si exactement deux entités sont sélectionnées, vous avez votre cas 1. Si une entité n'est touchée par aucune autre entité mais seulement coupée par celles-ci, alors BOUNDARY_TOUCHESrien ne sera sélectionné. INTERSECTsélectionnera toutes les entités qui se croisent, qu'elles touchent ou non un point final. Donc, si vous savez qu'il n'y a pas d'entités touchant les points d'extrémité, mais que vous trouvez qu'il y a des entités qui se croisent, alors vous avez votre cas 2.

Pour automatiser le processus, vous pouvez utiliser le script Python suivant (implémenter comme outil de script si vous le souhaitez) pour calculer le nombre de touches et d'intersections pour chaque entité dans une classe d'entités ou une couche:

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)

Une fois que cela s'est exécuté, vous pouvez facilement rechercher les entités qui se touchent exactement deux fois et se croisent exactement deux fois (cas 1), et celles qui touchent 0 fois et se croisent exactement deux fois (cas 2).

Exemples de requêtes de définition:

  • Cas 1 (touche deux fois, croise deux fois):"NUM_TOUCHES" = 2 AND "NUM_INTERSECTIONS" = 2
  • Cas 2 (ne touche aucun, se croise deux fois):"NUM_TOUCHES" = 0 AND "NUM_INTERSECTIONS" = 2

Voir la capture d'écran ci-dessous pour une illustration des instances des deux cas trouvés: Capture d'écran d'ArcMap montrant diverses relations d'intersection de lignes / tactiles

Notez qu'avec les données du monde réel, normalement les segments de rue sont décomposés aux intersections, et les pendules ne se produisent que lorsque les routes se croisent comme à un échangeur ou un pont. Donc, normalement, vous avez le même nombre de fonctions qui se croisent que le toucher.

Pour le cas plus général, vous pouvez rechercher des pendules en vérifiant si "NUM_INTERSECTIONS" > "NUM_TOUCHES".

blah238
la source
Merci pour la réponse élaborée. J'ai un peu de mal à le transformer en outil de script (il se fige lorsque j'essaie de sélectionner une couche) mais je suis convaincu que l'approche est valide.
mvexel du
Un autre commentaire: j'ai dû réduire la longueur du nom de champ à moins de 10 caractères (probablement parce que la source de la couche est un fichier de formes).
mvexel
Il semble y avoir une URL vers une image de documentation ArcGIS qui s'est égarée au début de cette réponse.
PolyGeo
@PolyGeo lequel? Ça me semble bien.
blah238
C'est bizarre, la première image (sur ce qui serait environ la quatrième ligne) montrait hier comme une petite croix. Aujourd'hui ça a l'air bien. Je pense que je l'ai vu dans le navigateur (que j'utilise maintenant) plutôt que dans le client iOS que j'utilise souvent.
PolyGeo
2

Split Line At Vertices (Gestion des données)

"Crée une classe d'entités contenant des lignes qui sont générées en divisant des lignes d'entrée ou des limites de polygone à leurs sommets"

Gardez l'attribution.

entrez la description de l'image ici

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//00170000003z000000

Mapperz
la source
Je ne sais pas comment cela va m'aider, mais je me rends compte que j'aurais pu clarifier ce dont j'avais besoin pour obtenir un peu mieux. Modifié la question.
mvexel
-1

Que diriez-vous de copier la couche d'entités, de rogner les lignes, puis de comparer le jeu d'entités rogné à l'original pour trouver les entités qui ont changé? Pas joli, nécessite presque certainement l'utilisation de Python, mais il semble que cela devrait fonctionner.

Llaves
la source
-1

Vous pouvez également extraire les nœuds du réseau. Dans le cas 1, vous obtiendrez 2 nœuds chacun avec une valence de 4. Dans le cas 2, il n'y a pas de nœuds.

Hornbydd
la source
Pouvez-vous suggérer comment procéder dans ArcGIS?
blah238
Vous pouvez utiliser le script ou l'outil de quelqu'un pour ajouter des identifiants uniques à la polyligne qui sont les nœuds de départ et d'arrivée. Je sais que archydro le fait, mais je suis sûr qu'il existe des scripts sur le site Web arcscripts qui font cela. Ensuite, de manière non programmée, vous pouvez exécuter l'outil de fréquence sur le champ from puis sur le champ to node et les additionner, cela vous donne une valence de nœud que vous pouvez joindre à une couche de points représentant les nœuds.
Hornbydd