Отримайте точку на полілінії від кінцевих точок, заданих відстані вздовж полі лінії


10

У мене є початкова і кінцева точка полілінії. Як я можу отримати точку на цій полілінії від кінцевих точок, визначених заданою відстані.

введіть тут опис зображення

Як я можу це отримати за допомогою arcpy за умови, що цей скрипт повинен працювати в ArcView без імпорту модулів ( як ця відповідь ). Я намагаюся не жорсткі значення коду.

Питання, пов'язані з цим:


Ви не отримуєте жодних результатів, використовуючи object.interpolate (відстань [, нормалізований = Невірно])?
vinayan

1
Де ти взяв object.interpolate(distance[, normalized=False]). Це метод архпії? Якщо це так, можете, будь ласка, опублікувати посилання. Я погуглив його, але не знайшов.
користувач

це стройний метод .. toblerity.github.com/shapely/… думаю, що ви спробували це в іншому питанні .. не впевнений, чи отримали ви результати ..
vinayan

2
Ще одне пов'язане питання - gis.stackexchange.com/questions/6476/… , яке стосується зворотної цієї проблеми (знайдіть відстань, задану крапкою). Два рішення тісно пов’язані між собою: як тільки поліліній стане вимірюваним, усі точки вздовж нього можуть бути вирішені з точки зору їх відстані (а довільні сегменти вздовж нього можуть бути вирішені діапазонами відстаней).
whuber

Відповіді:


7

Це схоже на "Лінійна довідка", і цей набір інструментів буде доступний в ArcView. Крім того, ви можете легко скриптувати цей інструмент.

Посилання на довідку ESRI для лінійних довідок


1
+1 Це "правильний" підхід у сенсі використання зрілих можливостей, створених для цієї проблеми.
whuber

6

Виходячи з ваших потреб, як згадував @LouisH, використання лінійної довідки - це безумовно шлях. Я з'єднав разом якийсь код, який повинен відповідати вашим потребам не жорстких елементів кодування, але натомість запитав їх як параметри.

Як пояснення, інструмент Лінійне посилання, що використовується нижче, приймає "Маршрути", у вашому випадку функції лінії та розміщує "Події", у вашому випадку точки, вздовж них на основі поля відстані. Це призводить до появи FeatureLayer, який зберігається в пам'яті, що є причиною останньої функції, яка копіює функції у вихідний клас функцій.

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)

Редагувати - одне, про що потрібно задуматися з цим інструментом, і, ймовірно, будь-яка операція з пошуку точок на основі відстані від кінця рядка - це з якого кінця рядка ви почнете. Наприклад, інструмент лінійного посилання працює на основі оцифрованого напрямку лінії. Важливо переконатися, що у вас є певний спосіб визначити, на якій кінцевій точці ґрунтуються ваші вимірювання.


5

Вирішення подібної лінійної задачі without importing any modulesвиходить за межі мого діапазону.

Я використовував Shapely(пакет python для маніпуляцій та аналізу 2D геопросторових геометрій. І це ліцензія BSD :-))

скачати його тут . Версія 2.6, яка є єдиною, яка підтримує arcgis 10 arcpy. Це проста установка (розмір 1,5 Мб)

і ось ось аркпійський скрипт для досягнення мети .. пробачте мій пітон..тільки сьогодні я дізнався про петлі, кортежі тощо :)

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)

Примітка : це не буде працювати, якщо функція має криві сегменти


2

Я знайшов це питання, намагаючись зробити те, що, на мою думку, те саме. Я хотів, щоб це все було зроблено за допомогою arcpy. Використання лінійних довідок для мене не мало сенсу, оскільки я вже не маю точкових подій (і я не міг зрозуміти, як використовувати LR, щоб отримати їх). Суть у тому, що я в кінцевому підсумку використав, було

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

Для цього потрібна дуга 10.1 або вище; Я не зміг розібратися, чи доступна вона нижче рівня ліцензування ArcInfo, який у мене є (ArcView вказано в ОР).

У своєму прикладі вище я хотів крапку не на певній відстані, а на відсоток від загальної довжини лінії. Для цього я подав другий факультативний аргумент positionAlongLine. Ви пропускаєте другий аргумент, якщо просто хочете вказати абсолютну відстань. Ось док .

Більш повний зразок коду

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'є моєю особливістю Шар рядків, на яких я хочу знайти точки. Бігає досить швидко. NumPyArrayToFeatureClassЦе був дуже приємний спосіб скинути всі мої точки назад у функціональний клас (дякую моєму колезі Кертісу за цю частину!). Експериментував з / Append_managementале це було досить повільно.


+1 Дякуємо, що поділилися цим. Це виглядає як хороше одноразове рішення, коли ви не хочете вкладати зусилля, створюючи розмірену полілінію. Зауважимо, що це рішення використовує неявну орієнтацію полілінії, визначену порядком, в якому зберігаються його координати. Якщо з цим не дотримуватися обережності, ви можете закінчити обчислення точок, починаючи з неправильного кінця. Таким чином, було б непогано вдосконалити це рішення, щоб користувач міг (якось) застерегти - можливо, шляхом введення точки біля одного кінця - що є початком полілінії.
whuber

1
Це, безумовно, правда. Я використовую лінії з дренажної мережі, які всі (нібито) орієнтовані вниз за течією, тому мені не довелося з цим боротися. Якщо орієнтація лінії не є навмисною, вона може бути організована як попередній процес до того, що я запропонував вище. Якщо орієнтація навмисна, то можна зробити копію, переорієнтувати та використати мій рецепт. Бали все ще будуть належним чином розташовуватися на початковій лінійці класного класу належним чином, навіть якщо його орієнтація не сприяє поточному аналізу.
Роланд

1

Це може бути зайвим, але якщо у вас є доступ до розширення мережевого аналізу, ви можете створити мережу з своїх поліліній, а потім створити зони обслуговування навколо вхідних точок, вказавши розмір SA як відстань, що цікавить. Ось короткий приклад із 111 метрів SA від точки:

введіть тут опис зображення

Тоді вам доведеться знайти точки, де SA перетинає лінію.


-1

Я думаю, ви можете отримати це за допомогою методу Feature Vertices To Points (управління даними). ви можете отримати більше інформації тут .

або ви можете перевірити розділену лінію в точці (управління даними) тут .

їх недостатньо цілком, але ви можете написати власний код ...

я сподіваюся, що це допоможе тобі ...


2
Схоже, що проблема з цими параметрами полягає в тому, що вони потребують попереднього знання місця точки, щоб розділити лінію або додати вершину до рядка до її розбиття. Це місце розташування - це те, що невідомо у вищезазначеному питанні, тому важко застосувати будь-яке з цих рішень.
Отримайте просторовий
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.