Matching with an AequilibraE Model#

[1]:
import uuid
from os.path import join
from tempfile import gettempdir

from aequilibrae.utils.create_example import create_example

from mapmatcher import MapMatcher
from mapmatcher.examples import nauru_data
[2]:
nauru_gps = nauru_data()

# Let's see if the data has all the fields we need
nauru_gps.head()
[2]:
x y timestamp gps_fix_id vehicle_unique_id geometry
0 166.942502 -0.546496 2018-05-09 18:13:56 1 2 POINT (166.9425 -0.5465)
1 166.943424 -0.546774 2018-05-09 18:14:05 2 2 POINT (166.94342 -0.54677)
2 166.943201 -0.547001 2018-05-09 18:14:08 3 2 POINT (166.9432 -0.547)
3 166.940958 -0.549704 2018-05-09 18:14:39 4 2 POINT (166.94096 -0.5497)
4 166.940674 -0.550305 2018-05-09 18:14:45 5 2 POINT (166.94067 -0.5503)

Since it does not, let’s fix it

[3]:
nauru_gps.rename(columns={"x": "longitude", "y": "latitude", "vehicle_unique_id": "trace_id"}, inplace=True)

We get our AequilibraE model for Nauru and create the map-mather from this model We also need to provide the transportation mode we want to consider for the map-matching

[4]:
project = create_example(join(gettempdir(), uuid.uuid4().hex), "nauru")

# We need to have at least one centroid connector to the model due to a bug in AequilibraE 0.9.5
project.conn.execute("Update Nodes set is_centroid=1 where node_id = 1")
mmatcher = MapMatcher.from_aequilibrae(project, "c")
/opt/hostedtoolcache/Python/3.10.15/x64/lib/python3.10/site-packages/aequilibrae/project/network/network.py:327: FutureWarning: Downcasting object dtype arrays on .fillna, .ffill, .bfill is deprecated and will change in a future version. Call result.infer_objects(copy=False) instead. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`
  df = pd.read_sql(sql, conn).fillna(value=np.nan)

let’s add the GPS data to the map-matcher and run it!

[5]:
mmatcher.load_gps_traces(nauru_gps)
mmatcher.map_match(parallel_threads=1)
CRITICAL:root:Building up data structures
building trips: 100%|██████████| 100/100 [00:02<00:00, 43.10it/s]
Map matching trips:   0%|          | 0/100 [00:00<?, ?it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True  True  True False  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True  True  True
  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False False False  True  True  True  True  True  True  True  True  True
 False False False  True False False]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:   6%|▌         | 6/100 [00:00<00:05, 17.25it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False  True False  True  True  True  True False False False  True  True
  True  True  True False  True  True  True False False False]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  11%|█         | 11/100 [00:00<00:05, 16.50it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False False False False False False False False False False False False
 False False False False]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  13%|█▎        | 13/100 [00:00<00:07, 11.99it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True  True  True  True  True  True  True  True  True  True  True  True
  True False False  True  True  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False False False  True  True  True  True False  True False  True  True
  True  True  True  True  True  True  True  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  17%|█▋        | 17/100 [00:01<00:06, 12.01it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False False  True  True  True False  True  True  True  True  True  True
  True False  True  True  True  True  True  True  True False  True False]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False False False  True  True  True  True False  True  True  True False
  True  True  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  19%|█▉        | 19/100 [00:01<00:10,  7.90it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False  True False False  True  True  True  True  True  True  True  True
  True  True  True  True  True False False  True  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  20%|██        | 20/100 [00:02<00:12,  6.42it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True  True  True  True  True  True  True  True  True  True  True  True
 False  True  True False False False False False]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  21%|██        | 21/100 [00:02<00:14,  5.39it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True False  True  True  True  True  True  True False False
  True  True  True  True  True False False False False  True  True False
  True  True  True  True  True  True  True  True False False]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  25%|██▌       | 25/100 [00:03<00:11,  6.55it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True  True  True  True  True  True  True  True  True  True  True False
 False False  True False False  True  True False False  True  True  True
  True False]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  33%|███▎      | 33/100 [00:03<00:05, 11.47it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True  True  True  True False  True  True  True False  True False False
 False  True  True  True False False  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True False  True
  True  True  True  True False False  True  True  True False  True False
  True False  True  True  True False False  True False]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  36%|███▌      | 36/100 [00:03<00:07,  8.80it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True False False False  True  True  True False False  True  True  True
 False False  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  39%|███▉      | 39/100 [00:04<00:06,  9.07it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True  True  True  True False  True  True  True  True  True  True False
 False False  True  True  True  True  True  True  True False  True  True
 False  True  True False]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  42%|████▏     | 42/100 [00:04<00:06,  8.48it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True False False  True False
 False False False False False False  True False False  True  True False
  True  True  True  True  True  True  True  True  True  True  True  True
  True False False False False  True  True  True  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  45%|████▌     | 45/100 [00:05<00:07,  7.58it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False False False False False  True False  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True False  True  True
  True  True False False]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  53%|█████▎    | 53/100 [00:05<00:04, 10.99it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True  True  True  True  True  True  True  True  True False  True  True
  True  True  True  True  True  True False False False  True  True  True
  True False  True  True False False]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  62%|██████▏   | 62/100 [00:06<00:02, 13.85it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True  True False  True False  True  True  True  True  True  True  True
  True False False False  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  64%|██████▍   | 64/100 [00:06<00:02, 12.41it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  66%|██████▌   | 66/100 [00:06<00:03,  8.90it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True  True  True  True  True False False False False  True  True False
  True  True  True  True  True  True  True  True  True  True  True  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  69%|██████▉   | 69/100 [00:07<00:03,  8.70it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False False  True  True  True  True  True  True  True  True False False
  True  True  True  True False  True False  True  True  True  True False
  True False  True False  True  True  True False False False False  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  70%|███████   | 70/100 [00:07<00:04,  6.98it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False False False  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True False  True  True  True
  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  73%|███████▎  | 73/100 [00:07<00:03,  7.37it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True False False  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True False  True  True  True  True
  True False  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True False  True  True  True
  True  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  76%|███████▌  | 76/100 [00:08<00:03,  7.45it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False  True  True False False  True  True  True False  True  True  True
 False False  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  79%|███████▉  | 79/100 [00:08<00:02,  8.43it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True  True False  True False False  True  True False  True  True  True
  True  True  True False  True  True  True  True  True False  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  80%|████████  | 80/100 [00:08<00:02,  6.76it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[False False False  True  True  True  True  True  True  True  True  True
  True  True  True False  True  True  True  True  True False False  True
  True  True  True  True  True  True  True  True False False  True  True
 False False False False False  True False False False False  True  True
  True  True False  True  True  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips:  93%|█████████▎| 93/100 [00:09<00:00, 14.03it/s]/home/runner/work/mapmatcher/mapmatcher/mapmatcher/trip.py:378: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '[ True False  True  True  True  True  True  True  True  True  True  True
  True  True  True  True  True False  True  True]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  self._waypoints.loc[:, "ping_is_covered"] = self._waypoints.intersects(self.path_shape.buffer(buffer))[:]
Map matching trips: 100%|██████████| 100/100 [00:09<00:00, 10.23it/s]
[6]:
for trip in mmatcher.trips:
    if trip.success:
        break
[7]:
import folium
import geopandas as gpd
import numpy as np

Create a geometry list from the GeoDataFrame

[8]:
trace = trip.trace.to_crs(4326)
geo_df_list = [[point.xy[1][0], point.xy[0][0], ts] for point, ts in zip(trace.geometry, trace.timestamp)]

result_layer = folium.FeatureGroup("Map-match result")
trace_layer = folium.FeatureGroup("GPS traces")

# Iterate through list and add a marker for each GPS ping.
i = 0
for lat, lng, ts in geo_df_list:
    trace_layer.add_child(
        folium.CircleMarker(
            location=[lat, lng],
            radius=1,
            fill=True,  # Set fill to True
            color="black",
            tooltip=str(ts),
            fill_opacity=1.0,
        )
    )

gdf = gpd.GeoDataFrame({"d": [1]}, geometry=[trip.path_shape], crs=3857).to_crs(4326).explode(ignore_index=True)
for _, rec in gdf.iterrows():
    coords = rec.geometry.xy
    coordinates = [[y, x] for x, y in zip(coords[0], coords[1])]
    folium.PolyLine(coordinates, weight=5, color="red").add_to(result_layer)

map = folium.Map(location=[np.mean(coords[1]), np.mean(coords[0])], tiles="OpenStreetMap", zoom_start=15)

result_layer.add_to(map)
trace_layer.add_to(map)
folium.LayerControl(position="bottomright").add_to(map)
map
[8]:
Make this Notebook Trusted to load map: File -> Trust Notebook
[9]:
trip.result
[9]:
links direction milepost geometry
0 1228 -1 1124.584887 LINESTRING (166.92574 -0.51213, 166.92589 -0.5...
1 910 1 1175.350264 LINESTRING (166.92574 -0.51213, 166.92542 -0.5...
2 911 1 1194.939370 LINESTRING (166.92542 -0.51246, 166.9253 -0.51...
3 912 1 1201.665519 LINESTRING (166.9253 -0.51258, 166.92488 -0.51...
4 1240 1 1208.386598 LINESTRING (166.92488 -0.51302, 166.92511 -0.5...
5 1240 -1 1215.107678 LINESTRING (166.92488 -0.51302, 166.92511 -0.5...
6 913 1 1276.267386 LINESTRING (166.92488 -0.51302, 166.92451 -0.5...
7 914 1 1290.152053 LINESTRING (166.92451 -0.51343, 166.92443 -0.5...
8 915 1 1292.893482 LINESTRING (166.92443 -0.51353, 166.92426 -0.5...
9 916 1 1344.025141 LINESTRING (166.92426 -0.5137, 166.92394 -0.51...
10 917 1 1416.300787 LINESTRING (166.92394 -0.51404, 166.9235 -0.51...
11 918 1 1423.168806 LINESTRING (166.9235 -0.51452, 166.92308 -0.51...
12 919 1 1437.002929 LINESTRING (166.92308 -0.51497, 166.92299 -0.5...
13 920 1 1452.636599 LINESTRING (166.92299 -0.51507, 166.9229 -0.51...
14 921 1 1488.030956 LINESTRING (166.9229 -0.51517, 166.92268 -0.51...
15 922 1 1523.208037 LINESTRING (166.92268 -0.51541, 166.9225 -0.51...
16 923 1 1568.370584 LINESTRING (166.9225 -0.51567, 166.92231 -0.51...
17 924 1 1599.011011 LINESTRING (166.92231 -0.51603, 166.92218 -0.5...
18 925 1 1601.218148 LINESTRING (166.92218 -0.51627, 166.92206 -0.5...
19 926 1 1638.344782 LINESTRING (166.92206 -0.51643, 166.92183 -0.5...
20 927 1 1671.654432 LINESTRING (166.92183 -0.51667, 166.9216 -0.51...
21 1116 -1 1682.671559 LINESTRING (166.92088 -0.51726, 166.92091 -0.5...
22 1226 -1 1693.861510 LINESTRING (166.9206 -0.51753, 166.92047 -0.51...
23 931 1 1706.166402 LINESTRING (166.9206 -0.51753, 166.9205 -0.51758)
24 932 1 1755.165865 LINESTRING (166.9205 -0.51758, 166.92014 -0.51...
25 933 1 1768.063688 LINESTRING (166.92014 -0.51784, 166.91926 -0.5...
26 934 1 1775.853776 LINESTRING (166.91926 -0.51859, 166.91878 -0.5...
27 935 1 1779.828479 LINESTRING (166.91878 -0.5191, 166.91854 -0.51...
28 936 1 1800.035146 LINESTRING (166.91854 -0.51937, 166.91842 -0.5...
29 937 1 1820.835860 LINESTRING (166.91842 -0.5195, 166.91828 -0.51...
30 938 1 1828.613960 LINESTRING (166.91828 -0.51963, 166.9177 -0.52...
31 939 1 1906.245998 LINESTRING (166.9177 -0.52003, 166.91715 -0.52...
32 940 1 1964.071072 LINESTRING (166.91715 -0.52046, 166.91675 -0.5...
33 941 1 2047.465681 LINESTRING (166.91675 -0.5208, 166.91617 -0.52...
34 942 1 2054.335952 LINESTRING (166.91617 -0.52127, 166.9157 -0.52...
35 943 1 2061.268315 LINESTRING (166.9157 -0.52167, 166.91565 -0.52...
36 944 1 2116.540548 LINESTRING (166.91565 -0.52171, 166.91527 -0.5...
37 945 1 2144.694510 LINESTRING (166.91527 -0.52203, 166.91507 -0.5...
38 946 1 2172.066185 LINESTRING (166.91507 -0.52219, 166.9149 -0.52...
39 947 1 2199.383492 LINESTRING (166.9149 -0.52237, 166.91476 -0.52...
40 948 1 2202.123860 LINESTRING (166.91476 -0.52257, 166.91464 -0.5...
41 949 1 2205.246512 LINESTRING (166.91464 -0.52279, 166.91454 -0.5...
42 950 1 2236.437781 LINESTRING (166.91454 -0.52305, 166.91443 -0.5...
43 951 1 2239.368459 LINESTRING (166.91443 -0.52331, 166.91438 -0.5...