Python: Unterbrechen Sie den Linestring basierend auf der Bedingung


11

Ich habe einen Geopandas-Datenrahmen aus einer Reihe von Linestrings, denen einige Daten mit jedem Scheitelpunkt / Punkt zugeordnet sind:

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

Die Punkte werden basierend auf der ID in Linestrings konvertiert und nach Zeit sortiert.

Ich möchte die Linestrings an dem Punkt brechen, an dem eine Bedingung erfüllt ist. Im Moment ist der Abstand zwischen den Punkten größer als ein Wert. In Zukunft könnte es sein, dass eine Funktion der Datenfelder einen Wert hat. Teilen Sie zum Beispiel einen Linestring, wenn die Geschwindigkeit 5 km / h überschreitet.

Das aktuelle Problem ist, dass einige der Spuren aus Punkten mit doppelten IDs gebildet werden, sodass der Linestring über große Entfernungen hin und her springt und ich möchte, dass ein Schwellenwert diese Linien durchbricht.

Irgendwelche Ideen zur richtigen Strukturierung dieser oder Bibliotheken / Methoden, die von Nutzen sein könnten?

Der Datenrahmen enthält über 150.000 Spuren mit vielen Punkten pro Spur, sodass die Effizienz gut wäre.

Hier ist ein Beispiel für die Tracks 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...     

Hier ist ein Beispiel aus den Punkten DF. Es gibt 18 Spalten, einschließlich Datetime, Punkt (Lon, Lat), Geschwindigkeit, Größe usw. usw.:

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: Versucht, ein wenig klarer zu sein.


Wie ist Ihr GeoDataFrame aufgebaut? Eine Kopie von gd.head()wäre willkommen.
Gen

Bearbeitet, um Kopf zu zeigen
RedM

Ich habe in der Vergangenheit GeoPy (geopy.distance.vincenty) für etwas Ähnliches verwendet. Ich musste Punkte verbinden, wollte aber nicht, dass sie verbunden wurden, wenn sie länger als mein festgelegter Schwellenwert waren. Ich habe jedes Koordinatenpaar durch die Funktion gesendet und sie nur verbunden, wenn sie unter meinem Schwellenwert lagen. geopy.readthedocs.io/en/1.10.0/#geopy.distance.vincenty
JohnR

Was ist die Primärschlüssel- / Sortierbedingung für die Funktion "Doppelte ID": Zeit vs. ID oder ID vs. Zeit?
Huckfinn

Ich bin mir nicht sicher, was du meinst. Die Punkte werden nach ID gruppiert, dann nach Zeit sortiert und dann nach den geordneten Positionen, die zum Erstellen einer Linienzeichenfolge verwendet werden. Die ID wird manchmal zwischen Objekten dupliziert. Beispiel: In Stadt A steht ein Auto mit der ID = '123'. Es überträgt seine Position und Zeit. Es gibt auch ein Auto in Stadt B mit der ID = '123' und es überträgt auch seine Positionen und die Zeiten sind verschachtelt. Eine Linie, die aus diesen Punkten aufgebaut wurde, würde zwischen A und B springen
RedM

Antworten:


1

Ich habe Shapely / Geopandas noch nicht verwendet, daher kann ich nur Pseudocode bereitstellen:

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

Die Distanzfunktion sollte etwas sein, das Ihre Bibliotheken bereits anbieten, oder Sie müssen sie selbst implementieren (der alte Kumpel Pythagoras wird Ihnen helfen).

Von dort aus kann die Effizienz nach Bedarf verbessert werden, dies sollte jedoch ein guter Ausgangspunkt sein.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.