Python: interrompe il linestring in base alla condizione


11

Ho un frame di dati geopandas di un gruppo di linestring che hanno alcuni dati associati a ciascun vertice / punto:

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

I punti vengono convertiti in linestring in base all'ID e ordinati in base al tempo.

Voglio interrompere le stringhe di linea dove nel punto in cui si verificano alcune condizioni. In questo momento è quando la distanza tra i punti è maggiore di un valore. In futuro potrebbe essere dove una funzione dei campi Dati ha un certo valore. Ad esempio, dividere una stringa lineare quando la velocità supera 5 km / h.

Il problema attuale è che alcune tracce sono formate da punti che hanno ID duplicati, quindi il linestring salta avanti e indietro su enormi distanze e voglio che una soglia interrompa queste linee.

Qualche idea sul modo corretto di strutturare questo o librerie / metodi che potrebbero essere utili?

Il dataframe ha oltre 150k tracce con molti punti per traccia, quindi l'efficienza sarebbe buona.

Ecco un esempio delle tracce 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...     

Ecco un esempio dai punti DF. Ci sono 18 colonne tra cui Datetime, Point (Lon, Lat), Speed, Size etc etc:

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               

EDIT: Ho cercato di essere un po 'più chiaro.


Qual è la struttura del tuo GeoDataFrame? Una copia di gd.head()sarebbe benvenuta.
gene

A cura di mostrare la testa
RedM

Ho usato GeoPy (geopy.distance.vincenty) in passato per qualcosa di simile. Avevo bisogno di collegare i punti, ma non li volevo collegati se fossero più lunghi della mia soglia determinata. Ho inviato ciascuna coppia di coordinate attraverso la funzione e le ho collegate solo se erano inferiori alla mia soglia. geopy.readthedocs.io/it/1.10.0/#geopy.distance.vincenty
JohnR

Qual è la chiave primaria / condizione di ordinamento per la funzione ID duplicato: time vs. ID o ID vs. time?
huckfinn,

Non so davvero cosa intendi. I punti sono raggruppati per ID, quindi ordinati per ora e quindi quelle posizioni ordinate utilizzate per creare una stringa di linea. L'ID è talvolta duplicato tra gli oggetti. Esempio: c'è un'auto nella città A con ID = '123'. Sta trasmettendo la sua posizione e il suo tempo. C'è anche un'auto nella città B con ID = '123' e sta anche trasmettendo le sue posizioni e i tempi sono intercalati. Una linea costruita da questi punti salta tra A e B
RedM

Risposte:


1

Non ho ancora usato shapely / geopandas, quindi posso fornire solo pseudocodice:

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

La funzione di distanza dovrebbe essere qualcosa che le tue librerie offrono già, o dovrai implementarla tu stesso (il vecchio amico Pitagora ti aiuterà).

L'efficienza può essere migliorata secondo necessità da lì, ma dovrebbe essere un buon punto di partenza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.