Obtenir un point sur une polyligne à partir de points d'extrémité étant donné la distance le long de la polyligne

10

J'ai le point de départ et le point final d'une polyligne. Comment puis-je obtenir un point sur cette polyligne à partir de points d'extrémité spécifiés par la distance donnée.

entrez la description de l'image ici

Comment puis-je obtenir cela en utilisant arcpy à condition que ce script fonctionne sur ArcView sans importer de modules ( comme cette réponse ). J'essaie de ne pas coder en dur les valeurs.

Question connexe:

utilisateur
la source
n'obtenez-vous aucun résultat en utilisant object.interpolate (distance [, normalized = False])?
vinayan
1
Où es-tu arrivé object.interpolate(distance[, normalized=False]). Est-ce une méthode d'arcpy? Si tel est le cas, pouvez-vous s'il vous plaît poster le lien. Je l'ai googlé, mais je ne l'ai pas trouvé.
utilisateur
c'est la méthode galbée .. toblerity.github.com/shapely/… pensez que vous l'avez essayé dans l'autre question .. je ne sais pas si vous avez obtenu des résultats ..
vinayan
2
Une autre question connexe est gis.stackexchange.com/questions/6476/… , qui concerne l'inverse de ce problème (trouver la distance étant donné le point). Les deux solutions sont étroitement liées: une fois la polyligne rendue mesurable, tous les points le long de celle-ci peuvent être adressés en fonction de leurs distances (et les segments arbitraires le long de celle-ci peuvent être adressés par des plages de distance).
whuber

Réponses:

7

Cela ressemble au "référencement linéaire" et cet ensemble d'outils serait disponible dans ArcView. De plus, vous pouvez créer un script pour cet outil très facilement.

Lien vers l'aide ESRI pour le référencement linéaire

Louis H
la source
1
+1 Il s'agit de la "bonne" approche dans le sens d'utiliser une capacité mature créée expressément pour ce problème.
whuber
6

En fonction de vos besoins, comme l'a mentionné @LouisH, l'utilisation du référencement linéaire est certainement la voie à suivre. J'ai bricolé du code qui devrait répondre à votre besoin de ne pas coder en dur, mais plutôt de les demander comme paramètres.

Comme explication, l'outil de référencement linéaire utilisé ci-dessous prend "Routes", dans votre cas les traits de la ligne, et place "Events", dans votre cas les points, le long d'eux en fonction d'un champ de distance. Il en résulte un FeatureLayer, qui est stocké en mémoire, ce qui est la raison de la dernière fonction qui copie les fonctionnalités dans une classe de sortie.

import arcpy
import os
from arcpy import env

#Working directory
wkspace        = arcpy.GetParameterAsText(0)
#Line feature class
rtecls         = arcpy.GetParameterAsText(1)
#Line Unique ID
rtecls_ID      = arcpy.GetParameterAsText(2)
#Table of points to be located
pnttbl         = arcpy.GetParameterAsText(3)
#Field in point table that references line point will be located along
pttbl_rteid    = arcpy.GetParameterAsText(4)
#Distance field in point table
pttbl_dst      = arcpy.GetParameterAsText(5)
#Output Layer, layer is stored in memory.  Features still need to be copied to feature class saved to disk
outlayer       = arcpy.GetParameterAsText(6)
#Output Feature Class - If shapefile, make sure to include ".shp" at the end.
outclass       = arcpy.GetParameterAsText(7)

#Type of feature being located
fttype = "POINT"

#Set Workspace
env.workspace = wkspace

#Build String for input parameters in Linear Referencing tool
pt_props = pttbl_rteid + " " + fttype + " " + pttbl_dst

#Output featureclass path
outfclass = wkspace + os.sep + outclass

# Execute MakeRouteEventLayer
arcpy.MakeRouteEventLayer_lr (rtecls, rtecls_ID, pnttbl, pt_props, outlayer)

#Save feature layer to feature class on disk
arcpy.CopyFeatures_management(outlayer, outfclass)

Modifier - Une chose à laquelle vous devez penser avec cet outil, et probablement toute opération pour localiser des points en fonction de la distance de la fin d'une ligne, est de quelle extrémité de la ligne vous commencerez. L'outil de référencement linéaire, par exemple, fonctionne en fonction de la direction numérisée d'une ligne. Il sera important de vous assurer que vous disposez d'un moyen d'identifier le point final sur lequel vos mesures sont basées.

Obtenez spatial
la source
5

Résoudre un problème de référence linéaire comme celui-ci without importing any modulesest hors de ma portée.

J'ai utilisé Shapely(package python pour la manipulation et l'analyse des géométries géospatiales 2D. Et il est sous licence BSD :-))

téléchargez-le d' ici . La version 2.6 qui est la seule à prendre en charge arcgis 10 arcpy..Il s'agit d'une installation simple (taille de 1,5 Mo)

et maintenant voici le script arcpy pour atteindre le but .. pardonnez mon python..seulement aujourd'hui j'ai appris les boucles, les tuples etc :)

import arcpy
import math
from arcpy import env

env.workspace = r"C:\testshape"

desc = arcpy.Describe("Rivers.shp")
shapefieldname = desc.ShapeFieldName

rows = arcpy.SearchCursor("Rivers.shp")

temptup = ()

# get ESRI geometries out of their cage..
for row in rows:

    feat = row.getValue(shapefieldname)
    partnum = 0
    for part in feat:
        for pnt in feat.getPart(partnum):
            if pnt:
                temptup += ((pnt.X, pnt.Y),)
            else:
                print "Interior Ring:"
        partnum += 1    

# and now the shapely magic :)

import shapely
from shapely.geometry import LineString
lnstr = LineString(temptup)
rsltPoint = lnstr.interpolate(0.5)
print(rsltPoint.x,rsltPoint.y)

remarque : cela ne fonctionnera pas si l'entité a des segments de courbe

vinayan
la source
2

J'ai trouvé cette question en essayant de faire ce que je pense est la même chose. Je voulais que tout se fasse via arcpy. L'utilisation du référencement linéaire n'avait pas de sens pour moi car je n'ai pas déjà les événements ponctuels (et je ne pouvais pas comprendre comment utiliser LR pour les obtenir). Le nœud de ce que j'ai fini par utiliser était

    line = arcpy.Polyline(arrayPts)
    pt = line.positionAlongLine (0.99, 'True')

Cela nécessite Arc 10.1 ou supérieur; Je n'ai pas pu déterminer si cela était disponible en dessous du niveau de licence ArcInfo que j'ai (ArcView spécifié par OP).

Dans mon exemple ci-dessus, je voulais un point non pas à une distance fixe, mais par un pourcentage de la longueur totale de la ligne. Pour ce faire, j'ai fourni le deuxième argument facultatif à positionAlongLine. Vous sautez le deuxième argument si vous voulez simplement spécifier une distance absolue. Voici le doc .

L'exemple de code plus complet est

import numpy
ptsList = list()
id = 0

with arcpy.da.SearchCursor('flFL', ["SHAPE@"]) as cursor:
    for row in cursor: 
        arrayPts = row[0].getPart()
        line = arcpy.Polyline(arrayPts)
        pt = line.positionAlongLine (0.99, 'True')
        ptsList.append((id, (pt.getPart().X, pt.getPart().Y)))
        id += 1

array = numpy.array([ptsList], \
numpy.dtype([('idfield',numpy.int32),('XY', '<f8', 2)]))

SR = arcpy.Describe("flFL").spatialReference
arcpy.da.NumPyArrayToFeatureClass(array, 'nsegSamplePts', ['XY'], SR)

'flFL'est ma fonctionCouche de lignes sur laquelle je veux localiser les points. Fonctionne assez rapidement. NumPyArrayToFeatureClassétait un très bon moyen de sauvegarder tous mes points dans une fonctionClasse (merci à mon collègue Curtis pour cette partie!). Avait expérimenté avec Append_managementmais c'était un peu plus lent.

Roland
la source
+1 Merci d'avoir partagé cela. Cela ressemble à une bonne solution ponctuelle lorsque vous ne voulez pas investir l'effort de configuration d'une polyligne mesurée. Notez que cette solution utilise l'orientation implicite de la polyligne déterminée par l'ordre dans lequel ses coordonnées sont stockées. Si vous n'y prenez pas garde, vous pourriez vous retrouver avec des points calculés à partir de la mauvaise extrémité. Il serait donc intéressant d'améliorer cette solution pour permettre à l'utilisateur (en quelque sorte) de stipuler - peut-être au moyen de la saisie d'un point près d'une extrémité - qui est le début de la polyligne.
whuber
1
C'est vraiment vrai. J'utilise des lignes d'un réseau de drainage qui sont toutes (soi-disant) orientées en aval, donc je n'ai pas eu à faire face à cela. Si l'orientation de la ligne n'est pas délibérée, elle pourrait être organisée comme un pré-processus à ce que j'ai suggéré ci-dessus. Si l'orientation est délibérée, alors on pourrait faire une copie, réorienter et utiliser ma recette. Les points s'aligneront toujours correctement sur la ligne de traits d'origine, même si son orientation n'est pas propice à l'analyse en cours.
Roland
1

Cela peut être exagéré, mais si vous avez accès à l'extension Network Analysis, vous pouvez créer un réseau à partir de vos polylignes, puis créer des zones de service autour de vos points d'entrée, en spécifiant la taille SA comme distance d'intérêt. Voici un exemple superficiel à 111 mètres SA du point:

entrez la description de l'image ici

Il faudrait ensuite trouver des points où SA franchit la ligne.

radek
la source
-1

Je pense que vous pouvez l'obtenir avec la méthode Feature Vertices To Points (Data Management). vous pouvez obtenir plus d'informations ici .

ou vous pouvez consulter Split Line At Point (Gestion des données) ici .

ils ne suffisent pas entièrement mais vous pouvez écrire votre propre code ...

J'espère que ça t'aide...

Aragon
la source
2
Il semble que le problème avec ces options est qu'elles nécessitent une connaissance préalable de l'emplacement du point afin de diviser la ligne, ou d'ajouter un sommet sur la ligne avant de la diviser. Cet emplacement de point est ce qui n'est pas connu dans la question ci-dessus, il est donc difficile d'appliquer l'une ou l'autre de ces solutions.
Obtenez Spatial