Tìm ra điểm rơi giữa hai đường thẳng song song


8

Tôi đang đối mặt với một vấn đề trong ArcGIS. Tôi làm việc trên một cơ sở dữ liệu điều hướng. Trong cơ sở dữ liệu của chúng tôi, các đường một làn được thể hiện bằng một Đường duy nhất, trong khi đường nhiều làn (đường có dải phân cách ở giữa) được thể hiện bằng hai đường song song (đường màu đỏ trong hình).

Tôi có một shapefile điểm với một số điểm rơi trong đường nhiều ngõ và một số bên ngoài.

Tôi muốn tạo một tập lệnh ArcPy để tìm các điểm nằm trong Đường nhiều làn. tức là giữa các đường thẳng song song này (được đánh dấu trong hình).

Tôi không biết làm thế nào để đạt được điều này, Ai đó có thể giúp tôi không?

Một vấn đề đường nhiều làn

Tôi đã thực hiện một số bài tập về nó và tôi thấy rằng việc tạo bộ đệm ở một bên của dòng có thể tạo bên trong đa giác Multi-Lane (Hiển thị trong ảnh).

nhập mô tả hình ảnh ở đây

nhưng bây giờ vấn đề là, đa giác thực sự đang băng qua đường (tức là chồng lấp ranh giới nhiều làn). vì vậy nó sẽ bắt được những điểm không cần thiết Có cách nào để căn chỉnh đa giác này với đường phố không?

Lưu ý: tích hợp sẽ không hoạt động ở đây, vì nó cũng di chuyển đường phố. tôi chỉ cần căn chỉnh đa giác dọc theo đường phố.


Một cái gì đó giống như Đo góc phương vị của đường phố - Tạo các đường nối từ mỗi điểm theo góc Azimuth + 90 độ - Đếm số lượng đường thẳng song song của bạn mà đường này giao nhau. Nếu không hoặc hai -> bên ngoài, nếu một -> Bạn đã tìm thấy nó. Chỉ cần suy nghĩ, có thể làm việc hoặc không. Một ý tưởng khác là chuyển đổi đường hai chiều thành đa giác và chọn các điểm giao nhau. Điều thứ hai có thể là khó khăn để làm với python. Vâng, đầu tiên là tốt nếu đường phố cong. Nhưng với bộ đệm một mặt, bạn có thể xây dựng các đa giác đường phố khá đẹp.
dùng49584

1
bạn có giấy phép nâng cao không? Nó sẽ khá đơn giản với công cụ gần.
radouxju

vâng tôi có giấy phép nâng cao.
Akhil Kumar

Lúc đầu, tôi nghĩ đến việc lấy đa giác đệm và hơn là cắt các đa giác đó. và tìm ra những điểm rơi trong đa giác giao nhau đó. nhưng vấn đề lớn nhất là ở giữa khoảng cách không nhất quán ở mọi nơi trên đường phố. ở đâu đó chỉ 10 mét ở đâu đó khoảng 20 mét, trong trường hợp đó logic đa giác giao nhau sẽ không thành công
Akhil Kumar

1
Tạo bộ đệm bên phải 10 m từ bên trái và bộ đệm bên trái từ bên phải một. Bằng cách đó, bạn bao gồm phạm vi 10-20 m. Sự chồng chéo không gây hại gì và bạn cũng có thể hợp nhất các đa giác trước. Hoặc làm cho đa giác bộ đệm một bên rộng hơn và cắt nó bằng cách giao với cách bên kia. Sử dụng trí tưởng tượng và chơi.
dùng49584

Câu trả lời:


4

Tôi sẽ thử dưới thuật toán arcpy (thậm chí thủ công!)

  1. Tìm chiều rộng phù hợp của hai làn đường - ở đây bạn có thể cần phải phân cụm các đường có cùng chiều rộng và làm theo quy trình dưới đây cho mỗi cụm.
  2. Tạo bộ đệm cả hai hướng về cả hai hướng (phải và trái) với chiều rộng đó (hoặc nhỏ hơn một chút - để đảm bảo diện tích đường).
  3. Chạy công cụ Giao lộ để có được Vùng chồng lấp.
  4. Chạy Chọn theo vị trí để chọn các điểm nằm trong đa giác này.

Tôi nghĩ rằng đây là con đường để đi. Tìm một cách dễ dàng để nối các đường thẳng với nhau, bằng cách đệm hoặc bằng cách nào đó đóng các đường thẳng để tạo một đa giác duy nhất và sau đó chọn bên trong.
Barrett

2

Tôi muốn nói đây là bài tập hình học.

MÃ PSEUDO:

  • Đối với mọi điểm (điểm đen), tìm đường gần nhất và tìm điểm chiếu trên đường này (điểm đỏ).
  • Vẽ đường ngắn (nét đứt) theo hướng ngược lại bắt đầu từ điểm đen
  • Tìm nếu có giao điểm giữa đường ngắn và đường cùng tên, ngôi sao màu xanh. Nếu có một, điểm đen là điểm chúng ta theo sau.

nhập mô tả hình ảnh ở đây

Như người ta có thể thấy có những trường hợp đặc biệt - những điểm đen được khoanh tròn:

  1. Rất ngoằn ngoèo 1 đường. Điều này có thể được loại bỏ bằng cách a) chỉ làm việc với 2 đường hoặc b) đảm bảo FID của các đường giao nhau giữa chấm đỏ và sao khác nhau. Tuy nhiên, nếu đường uốn cong có giao lộ với đường 1 khác, điều này có thể không hoạt động.
  2. Điểm đen đang ngồi trên phần mở rộng của đường 1 vuông góc chính xác. Trong trường hợp này, có khả năng 1 làn đường có thể được chọn làm hàng xóm gần nhất.
  3. Điểm đen nằm trên đường.

Tất cả các trường hợp trên đều rất khó xảy ra, tuy nhiên có vẻ như tùy chọn an toàn nhất là chỉ hoạt động với 2 đường, tức là xuất chúng sang một lớp tính năng riêng biệt. Trường hợp 3 là một trường hợp buồn cười, chúng ta sẽ để nó có cơ hội, bởi vì khoảng cách ngắn nhất đến đường thẳng không bao giờ đúng bằng 0, do đó có thể tìm thấy hướng ngược lại của tia nối 2 điểm.

Triển khai Python:

import arcpy, traceback, os, sys
from arcpy import env
env.overwriteoutput=True

# things to change ---------
maxD=30
mxd = arcpy.mapping.MapDocument("CURRENT")
pointLR = arcpy.mapping.ListLayers(mxd,"NODES")[0]
lineLR = arcpy.mapping.ListLayers(mxd,"LINKS")[0]
sjOneToMany=r'D:\scratch\sj2.shp'
RDNAME='street'
# -------------------------
dDest=arcpy.Describe(lineLR)
SR=dDest.spatialReference

try:
    def showPyMessage():
        arcpy.AddMessage(str(time.ctime()) + " - " + message)
    g = arcpy.Geometry()
    geometryList=arcpy.CopyFeatures_management(pointLR,g)
    n=len(geometryList)
    endPoint=arcpy.Point()

    arcpy.SpatialJoin_analysis(pointLR, lineLR,sjOneToMany,"JOIN_ONE_TO_MANY","KEEP_COMMON","","WITHIN_A_DISTANCE",maxD)
    initFidList=(-1,)
    for fid in range(n):
        query='"TARGET_FID" = %s' %str(fid)
        nearTable=arcpy.da.TableToNumPyArray(sjOneToMany,("TARGET_FID","JOIN_FID"),query)
        if len(nearTable)<2:continue
        fidLines=[int(row[1]) for row in nearTable]
        query='"FID" in %s' %str(tuple(fidLines))
        listOfLines={}
        blackPoint=geometryList[fid]
        with arcpy.da.SearchCursor(lineLR,("FID", "Shape@","STREET"),query) as rows:
            dMin=100000
            for row in rows:
                shp=row[1];dCur=blackPoint.distanceTo(shp)
                listOfLines[row[0]]=row[-2:]
                if dCur<dMin:
                    fidNear,lineNear, roadNear=row
                    dMin=dCur
            chainage=lineNear.measureOnLine(blackPoint)
            redPoint=lineNear.positionAlongLine (chainage).firstPoint
            smallD=blackPoint.distanceTo(redPoint)
            fp=blackPoint.firstPoint
            dX=(redPoint.X-fp.X)*(maxD-smallD)/smallD
            dY=(redPoint.Y-fp.Y)*(maxD-smallD)/smallD
            endPoint.X=fp.X-dX;endPoint.Y=fp.Y-dY
            dashLine=arcpy.Polyline(arcpy.Array([fp,endPoint]),SR)

            for n in listOfLines:
                if n==fidNear:continue
                line, road=listOfLines[n]
                if road!=roadNear:continue
                blueStars=dashLine.intersect(line,1)
                if blueStars.partCount==0:continue
                initFidList+=(fid,); break
    query='"FID" in %s' %str(initFidList)
    arcpy.SelectLayerByAttribute_management(pointLR, "NEW_SELECTION", query)
    arcpy.AddMessage ('\n %i point(s) found' %(len(initFidList)-1))
except:
    message = "\n*** PYTHON ERRORS *** "; showPyMessage()
    message = "Python Traceback Info: " + traceback.format_tb(sys.exc_info()[2])[0]; showPyMessage()
    message = "Python Error Info: " +  str(sys.exc_type)+ ": " + str(sys.exc_value) + "\n"; showPyMessage()            

Có một giải pháp khả thi khác có lẽ thanh lịch hơn. Nó liên quan đến tam giác. Hãy cho tôi biết nếu đó là mối quan tâm và tôi sẽ cập nhật câu trả lời của mình


Điều này khá phức tạp, wow. Có vẻ như sẽ đơn giản hơn rất nhiều khi tạo một đa giác từ các đường và sau đó sử dụng phương pháp đúc tia . Việc xác định nếu một điểm nằm trên một đường thẳng cũng nên đơn giản.
Paul

1
Nếu bạn có thể tạo đa giác từ các dòng chính xác, không cần đúc. Chọn theo vị trí sẽ làm. Tạo đa giác là một thách thức mặc dù
FelixIP

Nó có hoạt động tốt ở các khúc cua không - chỉ để làm rõ :)
SIslam

1
@SIslam nó sẽ hoạt động ngay cả với các uốn cong lớn tương tự như trường hợp 1 (xem nếu n == fidNear: continue). Chà, nếu không có 1 làn đường nào đi vào. Tôi cứ nghĩ rằng việc giải thể có thể giúp ích, nhưng không phải lúc nào cũng vậy
FelixIP

@Islam Rất tiếc! Nó sẽ không, bởi vì điều kiện (nếu n == fidNear: tiếp tục) sẽ loại bỏ các điểm ngồi ngoài uốn cong, nhưng đánh dấu điểm bên trong là một người ngồi bên ngoài. Mặc dù cần sắc nét, bán kính nhỏ hơn chiều rộng?
FelixIP

0

Vì các đường là song song, tôi đã giả định rằng chúng được tạo bằng Copy Parallelcông cụ trong thanh công cụ Chỉnh sửa, do đó làm cho các cặp đường có cùng hướng. Sau đó chúng ta có thể lặp lại tọa độ của dòng đầu tiên và thêm chúng vào một đa giác và sau đó lặp lại theo chiều ngược lại của dòng thứ hai. Chắc chắn có một cách tốt hơn để tiếp cận các cặp đường; phương pháp OID hoạt động, nhưng nó không đẹp lắm.

import collections
import arcpy

FC = "fc"
points = "points"
pgons = "pgons"
arcpy.env.overwriteOutput = True

def buildpoly(oid_coords):
    #create ddict of the form OID:<x1y1, x2y2, ..., xn-1yn-1, xnyn>
    ddict = collections.defaultdict(list)    
    for k,v in oid_coords:
        ddict[k].append(v)

    line1,line2 = ddict.keys()    

    #Assume that the parallel lines have same direction, so reverse the second
    arr = arcpy.Array()
    arr.extend(arcpy.Point(*pt) for pt in ddict[line1])    
    arr.extend(arcpy.Point(*pt) for pt in ddict[line2][::-1])

    return arcpy.Polygon(arr)

#id is an integer field that pairs parallel lines together
unique = list(set(t[0] for t in arcpy.da.SearchCursor(FC, "id")))
polygons = []
for uni in unique:
    polygons.append(buildpoly([r for r in row] for row in arcpy.da.SearchCursor(FC,
                                                                                ["OID@", "SHAPE@XY"],
                                                                                "id={}".format(uni),
                                                                                explode_to_points=True)))


arcpy.CopyFeatures_management(polygons, pgons)

Từ đó, đó là một cuộc gọi đến Giao lộ / Chọn Lớp theo vị trí / những gì có bạn. Lưu ý rằng Sđa giác hình không hoàn hảo vì tôi đã vẽ nó tự do và có một số cung explode_to_pointskhông xử lý đúng. Chỉ cần chạy Densifyhoặc tương đương.

nhập mô tả hình ảnh ở đây


Đây là bộ dữ liệu mạng đường, do đó, 1 làn đường được kết nối với 2 làn qua nút, tức là không có những thứ như cặp tính năng song song
FelixIP

Trước tiên, bạn có thể muốn mở rộng giải pháp của mình bằng cách hòa tan bằng tên đường riêng lẻ (không có phần m) và xem xét các trường hợp 1 hoặc 2 dòng
FelixIP

@FelixIP, tôi không rành lắm về bộ dữ liệu mạng. Giải pháp của tôi chủ yếu là một bằng chứng về khái niệm về cách nó có thể được thực hiện với các dòng đơn giản (OP có thể mở rộng nó để bao gồm mđộ phân giải, nhiều phần, v.v.). Tôi không biết làm thế nào các tính năng như thế này thực sự được thể hiện trong một mạng.
Paul

@ Paul Đường cùng tên có thể được biểu thị bằng 100 phân đoạn ngồi ở các hàng khác nhau trong bảng. Hơn nữa, làn đường đôi có thể trở thành làn đường duy nhất ở đâu đó. Hòa tan sẽ thất bại nặng nề nếu không có phần nào trong (1,2), đây là lý do tại sao tôi không đi với giải pháp tam giác
FelixIP

1
@AkhilKumar, không quan trọng nếu chúng gần như song song. Đây là truy tìm các dòng hiện có.
Paul
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.