Получить точку на полилинии из конечных точек на заданном расстоянии вдоль линии полилинии

10

У меня есть начальная точка и конечная точка полилинии. Как я могу получить точку на этой полилинии из конечных точек, указанных на данном расстоянии.

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

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

Связанный вопрос:

пользователь
источник
вы не получаете никаких результатов, используя object.interpolate (distance [, normalized = False])?
Винаян
1
Откуда вы взяли object.interpolate(distance[, normalized=False]). Это метод arcpy? Если это так, вы можете опубликовать ссылку. Я гуглил это, но не нашел это.
пользователь
это метод shapely .. toblerity.github.com/shapely/… думаю, что вы попробовали это в другом вопросе .. не уверены, что получили результаты ..
vinayan
2
Другой связанный вопрос - gis.stackexchange.com/questions/6476/… , который касается обратной задачи (найдите расстояние с учетом точки). Два решения тесно связаны: после того, как полилиния сделана измеримой, все точки вдоль нее могут быть рассмотрены с точки зрения их расстояний (а произвольные отрезки вдоль нее могут быть рассмотрены с помощью диапазонов расстояний).
whuber

Ответы:

7

Это похоже на «Линейные ссылки», и этот набор инструментов будет доступен в ArcView. Кроме того, вы можете написать этот инструмент очень легко.

Ссылка на справку ESRI для линейных ссылок

Луи Н
источник
1
+1 Это «правильный» подход в смысле использования зрелой способности, созданной специально для этой проблемы.
whuber
6

Исходя из ваших потребностей, как упоминал @LouisH, использование Linear Referencing - определенно лучший способ. Я собрал воедино некоторый код, который должен отвечать вашим потребностям не в жестком кодировании элементов, а в запросе их в качестве параметров.

В качестве объяснения, инструмент «Линейные ссылки», используемый ниже, берет «Маршруты», в вашем случае линейные объекты, и размещает «События», в вашем случае - точки вдоль них на основе поля расстояния. Это приводит к 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 МБ)

и теперь вот Arcpy скрипт для достижения цели .. прости мой питон .. только сегодня я узнал о циклах, кортежах и т.д. :)

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

Для этого требуется Arc 10.1 или выше; Я не смог выяснить, было ли это доступно ниже уровня лицензирования ArcInfo, который у меня есть (OP указал 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'это мой FeatureLayer линий, на которых я хочу, чтобы найти точки. Работает довольно быстро. NumPyArrayToFeatureClassбыл очень хороший способ сбросить все мои очки обратно в FeatureClass (спасибо моей коллеге Кертис за эту часть!). Экспериментировал, Append_managementно это было немного медленнее.

Roland
источник
+1 Спасибо, что поделился этим. Это выглядит как хорошее одноразовое решение, когда вы не хотите вкладывать усилия в настройку измеряемой полилинии. Обратите внимание, что в этом решении используется неявная ориентация ломаной, определяемая порядком, в котором хранятся ее координаты. Если с этим не позаботиться, вы можете получить очки, рассчитанные не с того конца. Таким образом, было бы неплохо усовершенствовать это решение, чтобы позволить пользователю (каким-то образом) определить - возможно, путем ввода точки рядом с одним концом - который является началом полилинии.
whuber
1
Это определенно правда. Я использую линии из дренажной сети, которые (предположительно) ориентированы вниз по течению, поэтому мне не пришлось иметь дело с этим. Если ориентация линии не является преднамеренной, она может быть организована как предварительный процесс к тому, что я предложил выше. Если ориентация преднамеренная, то можно сделать копию, переориентировать и использовать мой рецепт. Точки по-прежнему будут правильно выстраиваться в исходном линейном классе объектов, даже если его ориентация не способствует текущему анализу.
Роланд
1

Это может быть излишним, но если у вас есть доступ к расширению Network Analysis, вы можете создать сеть из ваших полилиний, а затем создать зоны обслуживания вокруг ваших точек ввода, указав размер SA в качестве расстояния интереса. Вот краткий пример с 111-метровой СА от точки:

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

Тогда вам нужно будет найти точки, где SA пересекает линию.

Радек
источник
-1

Я думаю, что вы можете получить его с помощью метода Feature Vertices To Points (Управление данными). Вы можете получить больше информации здесь .

или вы можете проверить Split Line At Point (Управление данными) здесь .

их недостаточно, но вы можете написать свой собственный код ...

я надеюсь, что это поможет вам ...

Арагон
источник
2
Кажется, что проблема с этими опциями заключается в том, что они требуют предварительного знания местоположения точки, чтобы разбить линию или добавить вершину в линию до ее разделения. Эта точечная локация - это то, что не известно в приведенном выше вопросе, поэтому трудно применить одно из этих решений.
Получить Spatial