GPS 궤도에서 특이점 탐지 및 수정


9

latitude longitude 포스트 프로세싱 중에 궤적에서 특이점을 감지 할 수있는 알고리즘이나 방법을 찾아야합니다. 그런 다음 고칠 수 있습니다 (이웃에 따라 궤적의 경로로 다시 가져옵니다).

감지하고 수정하려는 특이점의 예로써 다음과 같은 이미지를 첨부했습니다.

파란색의 원시 데이터.

무향 칼만 필터를 사용하여 가능한 한 데이터를 최대한 부드럽게하려고 시도했지만 더 극단적 인 이상치 (원시 데이터는 파란색, 평활화 된 데이터는 빨간색)에 대해 효과적으로 작동하지 않는 것 같습니다.

파란색의 원시 데이터, UKF는 빨간색의 데이터를 부드럽게했습니다.

UKF가 제대로 보정되지 않았을 수도 있습니다 (그러나 확실하다고 확신합니다).

궤적은 워커, 러너, 자전거 타는 사람의 시작이며 멈출 수는 있지만 인간의 힘으로 움직일 수 있지만 속도 나 위치가 급격히 또는 갑자기 급격히 변하지는 않습니다.

처리중인 데이터에 항상 타이밍 데이터가 포함되어 있지 않을 수 있으므로 타이밍 데이터에 의존하지 않고 위치 데이터에만 의존하는 솔루션이 매우 유용합니다. 그러나 이런 종류의 솔루션이 존재하지 않을 가능성이 높다는 것을 알고 있습니다.

이상적으로 솔루션은 이상 값을 감지하여 수정 될 수 있도록 궤적을 수정합니다.

원시 데이터가 녹색으로 수정되었습니다.


내가 조사한 자료 :

답변:


1

하천 네트워크 처리 도구의 일환으로 네트워크에서 "스파이크"를 검색하는 품질 관리 도구를 만들었습니다. 하천 네트워크를 처리하는 것처럼 내 도구를 사용하라고 제안하지는 않지만 내가 한 일의 이미지를 보여주는 도움말 파일 을 가리 킵니다 .

폴리 라인의 각 선분 사이의 연속 각도를 식별하기 위해 코사인 법칙을 사용하여 코드를 개발했습니다 . 이 아이디어를 중심으로 고유 한 코드를 개발하여 폴리 라인을 따라 이동 하고 극단적 인 각도를 식별 할 수 있습니다.


설명 된 것과 같은 방법을 사용하고 (코사인 법칙을 사용하여) 특이점을 더 잘 결정하기 위해 점 사이의 거리를 포함시키는 것이 좋았습니다. 감사합니다!
JP

8

내가 사용하는 알고리즘.

  1. 유클리드 최소 스패닝 포인트 트리를 계산합니다.

여기에 이미지 설명을 입력하십시오

  1. 이 네트워크에서 서로 가장 멀리있는 2 개의 포인트를 찾습니다.

여기에 이미지 설명을 입력하십시오

  1. 그들 사이에서 가장 짧은 경로를 찾으십시오.

여기에 이미지 설명을 입력하십시오

보시다시피 날카로운 회전으로 코너를자를 수 있습니다.

위 알고리즘의 ArcGIS python 구현이 있으며 networkx 모듈을 사용합니다. 이것이 관심 있는지 알려 주시면 스크립트로 답변을 업데이트하겠습니다.

최신 정보:

# Connects points to make polyline. Makes 1 line at a time
# Tool assumes that 1st layer in Table of Conternt is TARGET polyline feature class,
# second layer in TOC is SOURCE point fc.
# If no selection found in SOURCE layer, works on entire dataset

import arcpy, traceback, os, sys
import itertools as itt
from math import sqrt
sys.path.append(r'C:\Users\felix_pertziger\AppData\Roaming\Python\Python27\site-packages')
import networkx as nx
from networkx import dijkstra_path_length

try:
    def showPyMessage():
        arcpy.AddMessage(str(time.ctime()) + " - " + message)
    def CheckLayerLine(infc):
        d=arcpy.Describe(infc)
        theType=d.shapeType
        if theType!="Polyline":
            arcpy.AddWarning("\nTool designed to work with polylines as TARGET!")
            raise NameError, "Wrong input\n"
        return d
    def CheckLayerPoint(infc):
        d=arcpy.Describe(infc)
        theType=d.shapeType
        if theType!="Point":
            arcpy.AddWarning("\nTool designed to work with points as SOURCE!")
            raise NameError, "Wrong input\n"
        return d
    mxd = arcpy.mapping.MapDocument("CURRENT")
    layers = arcpy.mapping.ListLayers(mxd)
    if len(layers)<=1:
        arcpy.AddWarning("\nNot enough layers in the view!")
        raise NameError, "Wrong input\n"
    destLR, sourceLR=layers[0],layers[1]
    a = CheckLayerPoint(sourceLR);d = CheckLayerLine(destLR)

#  copy all points to manageable list
    g=arcpy.Geometry()
    geometryList=arcpy.CopyFeatures_management(sourceLR,g)
    nPoints=len(geometryList)
    arcpy.AddMessage('Computing minimum spanning tree')
    list2connect=[p.firstPoint for p in geometryList]
#  create network    
    p=list(itt.combinations(range(nPoints), 2))
    arcpy.SetProgressor("step", "", 0, len(p),1)
    G=nx.Graph()
    for f,t in p:
        p1=list2connect[f]
        p2=list2connect[t]
        dX=p2.X-p1.X;dY=p2.Y-p1.Y
        lenV=sqrt(dX*dX+dY*dY)
        G.add_edge(f,t,weight=lenV)
        arcpy.SetProgressorPosition()
    arcpy.AddMessage(len(G.edges()))
    mst=nx.minimum_spanning_tree(G)
    del G

#  find remotest pair
    arcpy.AddMessage(len(mst.edges()))
    length0=nx.all_pairs_dijkstra_path_length(mst)
    lMax=0
    for f,t in p:
        lCur=length0[f][t]
        if lCur>lMax:
            lMax=lCur
            best=(f,t)
    gL=nx.dijkstra_path(mst,best[0],best[1])
    del mst
    nPoints=len(gL)
    ordArray=arcpy.Array()
    for i in gL: ordArray.add(list2connect[i])

#  append line to TARGET
    curT = arcpy.da.InsertCursor(destLR,"SHAPE@")
    curT.insertRow((arcpy.Polyline(ordArray),))
    arcpy.RefreshActiveView()
    del curT

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

흠 재미있는 접근법 .. 공유해 주셔서 감사합니다! 실제 사례는 가치가 있다고 확신합니다!
nickves

1
이 방법의 결과와 입력 데이터를 따름으로써 얻을 수있는 결과를 일종의 부분적으로 비교하면 "스파이크"를 제거하지만 여전히 모서리를 유지하는 임계 값을 설정할 수 있습니다. 이는 일부 로그에서 자연스럽게 발생하는 각 지점과 관련된 시간 정보도있는 경우 특히 유용 할 수 있습니다.
더그 맥클린

1
그럴 수 있지. n 시간 간격을두고 노드 사이에 링크를 만들지 않으면 서 스크립트를 쉽게 수정할 수 있습니다. GPS 경로가 아닌 다른 용도로 스크립트를 사용하고 있습니다. 그래프의 링크 수를 크게 줄이는 삼각 측량과 같은 다른 개선 방법도 있습니다.
FelixIP

2
이 방법은 경우에 따라 작동하지만 일부 궤적의 모양은이 방법을 사용하는 것이 내 유스 케이스에서 불가능하다는 것을 의미합니다. (예를 들어, 많은 노드가 무시되고 지그재그로 인해 궤도가 자체적으로 배가되는 문제가 발생합니다. 마찬가지로, 해당 구간의 출입구가 충분히 가깝다면 궤도의 전체 구간이 무시 될 수 있습니다).
JP

1
그것은 원시 라인 1의 밀도를 높이기 위해 도움이 될 경로 거꾸로가는 대한 @JP
FelixIP

4

한 가지 아이디어는 경로의 모든 세그먼트의 각도 (및 길이)를 나열하는 스크립트를 작성하는 것입니다. 이제 모든 세그먼트의 값을 직접 이웃과 비교하고 (두 번째 이웃도 정확도를 높이기 위해) 주어진 임계 값을 초과하는 모든 지점을 선택할 수 있습니다. 마지막으로 단순히 경로에서 점을 삭제하십시오.


@Hornbydd가 기술 한 유사한 방법을 사용하여 코사인 법칙을 사용하여 각도를 결정하고 점 사이의 거리를 통합했습니다. 제안 해 주셔서 감사합니다.
JP

2

또한 Median-5 방법도 살펴볼 가치가 있습니다.

각 x (또는 y) 좌표는 주변의 5 x (또는 y) 값의 중앙값으로 순서대로 설정됩니다 (즉, 두 개의 이전 값과 두 개의 후속 값).

예를 들어 x3 = median (x1, x2, x3, x4, x5) y3 = median (y1, y2, y3, y4, y5) 등

방법은 빠르고 스트리밍 데이터에서도 사용하기 쉽습니다.



0

데이터를 Excel로 가져 오거나 팬더 및 플래그를 사용하거나 비현실적인 거리 임계 값을 초과하는 이전 지점에서 모든 거리를 삭제할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.