Khớp các đoạn có độ dài khác nhau


13

Tôi đang cố gắng khớp các phân đoạn nhỏ với một phân khúc lớn hơn mà chúng có lẽ liên quan nhiều nhất đến: tương đối gần, chịu lực tương tự và đối diện nhau.

Dưới đây là một ví dụ điển hình về dữ liệu tôi có:

phân khúc

Ở đây tôi cần khớp đoạn 652 đến 198969, trong khi có 711 và 707 không khớp với bất cứ thứ gì.

Tôi đã tìm kiếm các phương pháp khác nhau, đặc biệt là khoảng cách Hausdorff (dựa trên các câu trả lời ở đây ). Tôi đã tính toán nó bằng PostGIS nhưng tôi nhận được kết quả kỳ lạ: khoảng cách ngắn nhất tôi nhận được là từ 707 đến 198985 và 652 có khoảng cách lớn hơn đến 198969 so với 198985 chẳng hạn (tôi có thể thêm truy vấn và kết quả nếu cần).

Có thực sự là phương pháp chính xác để giải quyết vấn đề này? Có cách tiếp cận nào khác không? Tôi đã nghĩ đơn giản là tạo ra một bộ kiểm tra về các tham số tôi đã đề cập (khoảng cách, phương hướng, v.v.) nhưng tôi sợ phải thêm cả đống điều kiện để xử lý các trường hợp cạnh hoặc những thứ như đập vào mức độ chúng đôi mặt vơi nhau.

Cập nhật: Tôi đã tìm thấy một phương pháp có vẻ như là một sự thỏa hiệp có thể chấp nhận:

  • Trước tiên tôi tìm thấy 10 đoạn màu đen gần nhất từ ​​đoạn màu xanh mà tôi đang cố khớp (sử dụng <->toán tử PostGIS ) cách đó chưa đến 10m.
  • Sau đó, tôi tạo một phân đoạn mới bằng cách tìm các điểm gần nhất đến cuối của phân đoạn màu xanh trên mỗi phân đoạn màu đen (sử dụng ST_ClosestPoint) và lọc ra các kết quả có độ dài nhỏ hơn 90% so với phân đoạn màu xanh (có nghĩa là các phân đoạn không phải đối mặt hoặc chênh lệch ổ trục lớn hơn ~ 20 °)
  • Sau đó, tôi nhận được kết quả đầu tiên được sắp xếp theo khoảng cách và khoảng cách Hausdorff, nếu có.

Có thể có một số điều chỉnh tốt để làm nhưng nó dường như làm một công việc chấp nhận được cho đến bây giờ. Vẫn đang tìm kiếm bất kỳ phương pháp nào khác hoặc kiểm tra bổ sung để chạy nếu tôi bỏ lỡ một số trường hợp cạnh.


1
Tại sao không chỉ sử dụng các điểm cuối của các phân đoạn (màu xanh) để xác định các kết quả khớp tiềm năng giữa các phân đoạn mục tiêu (màu đen)? Phân đoạn khớp với bạn đang tìm kiếm xảy ra khi cả hai điểm cuối gần với một mục tiêu chung, đây là một truy vấn đơn giản để thực hiện. Phương pháp này xử lý các khác biệt do lỗi ở vị trí của các điểm cuối của phân khúc, điều mà có thể khó đối phó: lưu ý rằng một đoạn rất ngắn (màu xanh) có độ chính xác thấp hơn nhiều so với đoạn dài hơn.
whuber

1
Đúng, tôi thực sự đang thử một cái gì đó dọc theo những dòng này, tôi sẽ cập nhật câu hỏi với các chi tiết.
Jukurrpa

1
Không chắc chắn nếu tôi hiểu bạn chính xác, nhưng bạn đã cố gắng tạo trọng tâm cho các đường màu xanh và sau đó kiểm tra khoảng cách từ chúng đến các đường gần nhất, kết quả là khoảng cách ngắn nhất?
Cyril

1
Xin chào Cyril, tôi không làm việc với vấn đề này nữa, nhưng vấn đề cũng là để phù hợp với các phân đoạn màu xanh dựa trên định hướng của chúng và mức độ chúng "đối mặt" với các phân đoạn màu đen. Điều đó có nghĩa là trong trường hợp này, 711 không nên phù hợp với bất cứ điều gì mặc dù anh ta khá gần với các phân đoạn màu đen
Jukurrpa

Câu trả lời:


1

Dưới đây là một vài chức năng tôi đã viết sẽ cho phép bạn làm những gì bạn cần làm. Kiểm tra và xem nếu dòng là polyline hoặc phân đoạn nếu polyline làm nổ dòng, sau đó so sánh góc phương vị và nghịch đảo của điểm đầu tiên và điểm cuối trên dòng, đặt cho bạn tiêu chí chấp nhận được để đưa ra quyết định cho bạn. Đây là những phương pháp arcpy nhưng có thể được sửa đổi.

trả về góc phương vị từ phân đoạn dòng ESRI @shape

def returnAzimuth(shape):
    point1 = shape.firstPoint
    point2 = shape.lastPoint
    dX = point2.X-point1.X
    dY = point2.Y-point1.Y
    az = math.atan2(dX,dY)*180/math.pi
    if az<0:
        az = az+360
        return az
    return az

trả về nghịch đảo từ các điểm ESRI

def returnInverse(point1,point2):
    dX = point2.X-point1.X
    dY = point2.Y-point1.Y
    dis = sqrt(dX**2+dY**2)
    az = math.atan2(dX,dY)*180/math.pi
    if az<0:
        az = az+360
        return az,dis
    return az,dis

nổ polyline vào đoạn đường

def explodePolyline(shape):
    sr = "insert your spatial reference"
    lines=[]
    pnts = shape.getPart(0)
    for x in range(len(pnts)-1):
        array = arcpy.Array()
        point1 = arcpy.Point(pnts.getObject(x).X,pnts.getObject(x).Y,pnts.getObject(x).Z)
        point2 = arcpy.Point(pnts.getObject(x+1).X,pnts.getObject(x+1).Y,pnts.getObject(x+1).Z)
        array.add(point1)
        array.add(point2)
        line = arcpy.Polyline(array,sr,True,True)
        print(line)
        lines.append(line)
    return lines

chạy qua bàn của bạn như thế này

for shape in Table:
    for shape2 in Table:
         check if shape is polyline:
            if yes, explode and compare returned line segments with shape2
                for seg in returnedlinesegments
                    if seg.firstpoint=shape2.lastpoint and shape.az=shape2.az
                        do stuff.....
            if no, compare shape and shape2
                if shape.firstpoint=shape2.lastpoint and shape.az=shape2.az
                   do stuff.....

các thuộc tính này nên có sẵn trong postgis - Firstpoint, Lastpoint, pointarray Tôi giả sử các thuộc tính esri ở trên vì đó là những gì tôi biết rõ nhất nhưng ở trên có thể dễ dàng thay đổi để hoạt động với postgis.

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.