Python: Przerwanie oznaczania linii na podstawie warunku

11

Mam ramkę danych geopandas wiązki linii, które mają pewne dane związane z każdym wierzchołkiem / punktem:

Point_x = (Lat, Lon, Time, ID, Data1, Data2, Data3)

Punkty są konwertowane na linie na podstawie identyfikatora i uporządkowane według czasu.

Chcę przełamać pasy w miejscu, w którym spełniony jest jakiś warunek. W tej chwili odległość między punktami jest większa niż pewna wartość. W przyszłości może się zdarzyć, że funkcja pól danych ma pewną wartość. Na przykład podziel linię, gdy prędkość przekroczy 5 km / h.

Obecny problem polega na tym, że niektóre ścieżki są tworzone z punktów, które mają zduplikowane identyfikatory, więc linia liniowa skacze tam iz powrotem na duże odległości i chcę, aby próg przekroczył te linie.

Jakieś pomysły na właściwy sposób ustrukturyzowania tego lub bibliotek / metod, które mogą być przydatne?

Rama danych ma ponad 150 000 ścieżek z wieloma punktami na ścieżkę, więc wydajność byłaby niezła.

Oto przykład utworów DF:

ID         geometry                                                  
204235000  LINESTRING (37.62001 -28.99535, 37.62015 -28.9...   
205400000  LINESTRING (3.807816666666666 -18.083181666666...   
207138000  LINESTRING (22.73206 -34.97915833333333, 22.73...   
209016000  LINESTRING (8.447673333333331 -23.522783333333...     

Oto próbka z punktów DF. Istnieje 18 kolumn, w tym Datetime, Point (Lon, Lat), Speed, Size itp. Itd .:

Index           Heading   Latitude  Longitude       ID  
20              92.8 -35.946802  13.089695  210725000               
21              93.5 -35.946912  13.091808  210725000               
22              95.4 -35.965520  13.497698  210725000               
23              94.7 -35.965803  13.501898  210725000               
24              94.9 -35.965987  13.504573  210725000               

EDYCJA: Próbowałem być trochę jaśniejszy.

RedM
źródło
Jaka jest struktura twojego GeoDataFrame? Kopia gd.head()byłaby mile widziana.
gen
Edytowano, aby pokazać głowę
RedM
W przeszłości korzystałem z GeoPy (geopy.distance.vincenty) do czegoś podobnego. Musiałem połączyć punkty, ale nie chciałem, aby były połączone, jeśli były dłuższe niż mój określony próg. Wysłałem każdą parę współrzędnych przez funkcję i podłączyłem je tylko wtedy, gdy były mniejsze niż mój próg. geopy.readthedocs.io/en/1.10.0/#geopy.distance.vincenty
JohnR
Jaki jest podstawowy klucz / warunek sortowania dla funkcji duplikatu identyfikatora: czas vs. identyfikator lub identyfikator vs. czas?
huckfinn
Nie jestem pewien, co masz na myśli. Punkty są grupowane według identyfikatora, a następnie sortowane według czasu, a następnie uporządkowane pozycje użyte do utworzenia ciągu linii. Identyfikator jest czasem duplikowany między obiektami. Przykład: w mieście A jest samochód o numerze ID = „123”. Przesyła swoją pozycję i czas. W mieście B jest także samochód o numerze ID = „123”, który przesyła także swoje pozycje i czasy są przeplatane. Linia zbudowana z tych punktów przeskakuje między A i B
RedM

Odpowiedzi:

1

Nie używałem jeszcze shapely / geopandas, więc mogę podać tylko pseudokod:

distance_threshold = 50 # Value at which distance to cut off
new_lines = [] # Array to hold the newly created, split lines
new_line_marker = 0 # Let's remember where our new line starts
for linestring in linestrings: # Iterate over all linestrings
  for i, coord in enumerate(linestring.coords[:-1]): # Iterate over all coords of the linestring
    if distance(coord, coords[i+1]) >= distance_threshold: # Check if threshold is met
      # If condition is met, we generate a new linestring,
      # starting from the last split to the current one
      new_lines[] = new LineString(coords[new_line_marker:i])
      new_line_marker = i+1 # remember to reset the marker

Funkcja odległości powinna być czymś, co już oferują twoje biblioteki, albo będziesz musiał ją zaimplementować (stary przyjacielu Pitagoras ci pomoże).

Stamtąd można poprawić efektywność, ale powinien to być dobry punkt wyjścia.

Senshi
źródło