My aim is to create a map-making algorithm. So I have GPS data of user travel, Valhalla map matching is perfect solution for my use case, But where GPS track route inside home, office or parking slot, Then Valhalla map matching provide the nearest road.
After Map Matching
So, After Map matching yellow highways tracking is perfect So that is not issued, But inside green area (garden) many straight lines shows, And that is not I'm assuming, Is there any solution available where Inside the green area (garden) Also shows some of the coordinates which are not noisy.
So basically need to combination of Valhalla map matching and some noisy coordinates' removal.
Any solution?
I tried using the Valhalla output and oringinal coordinates. If enough nearby coordinates are identified in the original, the Noisy method will eliminate the noisy coordinates and replace them with output that map matches the Valhalla.
Here is code, Please review it
import requests
import json
from geoJsonToCoords import geoJsonToCoords
from common import extractCoordinates, haversineDistance, saveIntoJSFile
from sklearn.cluster import DBSCAN
import numpy as np
df_rawGPS_points = geoJsonToCoords('./example/1.geojson')
meili_coordinates = df_rawGPS_points.to_json(orient='records')
meili_head = '{"shape":'
meili_tail = ""","search_radius": 300, "shape_match":"map_snap", "costing":"auto", "format":"osrm"}"""
meili_request_body = meili_head + meili_coordinates + meili_tail
url = "http://localhost:8002/trace_route"
headers = {'Content-type': 'application/json'}
data = str(meili_request_body)
r = requests.post(url, data=data, headers=headers)
if r.status_code == 200:
response_text = json.loads(r.text)
# a = valhalla, b= orignal
valhalla_c, original_c = extractCoordinates(
df_rawGPS_points, response_text)
a = original_c
b = valhalla_c
print("a>>", valhalla_c, len(valhalla_c))
print("b>>", original_c, len(original_c))
all_coordinates = np.array(a + b)
eps = 0.05
min_samples = 2
dbscan = DBSCAN(eps=eps, min_samples=min_samples, metric=haversineDistance)
labels = dbscan.fit_predict(np.radians(all_coordinates))
cluster_counts = {}
for label in labels:
if label != -1:
cluster_counts[label] = cluster_counts.get(label, 0) + 1
high_density_clusters = [label for label,
count in cluster_counts.items() if count > 2]
result = []
for coord_a, coord_b, label in zip(a, b, labels):
if label in high_density_clusters:
result.append(coord_b)
else:
result.append(coord_a)
print("result >>>", result)
saveIntoJSFile(result)
And Functions are
def extractCoordinates(df_rawGPS_points, response):
import pandas as pd
import json
resp = str(response['tracepoints'])
resp = resp.replace("'waypoint_index': None", "'waypoint_index': '#'")
resp = resp.replace(
"None", "{'matchings_index': '#', 'name': '', 'waypoint_index': '#', 'alternatives_count': 0, 'distance': 0, 'location': [0.0, 0.0]}")
resp = resp.replace("'", '"')
resp = json.dumps(resp)
resp = json.loads(resp)
df_response = pd.read_json(resp)
df_response = df_response[['name', 'distance', 'location']]
df_trip_optimized = pd.merge(
df_rawGPS_points, df_response, left_index=True, right_index=True)
a = [coord[::-1] for coord in df_trip_optimized['location'].tolist()]
b = df_trip_optimized[['lat', 'lon']].values.tolist()
return a, b
def haversineDistance(coord1, coord2):
from math import radians, sin, cos, sqrt, atan2
R = 6371.0
lat1, lon1 = coord1
lat2, lon2 = coord2
lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])
dlat = lat2 - lat1
dlon = lon2 - lon1
a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = R * c
return distance
def dtwDistance(seq1, seq2):
import numpy as np
from scipy.spatial.distance import euclidean
n, m = len(seq1), len(seq2)
cost = np.inf * np.ones((n, m))
cost[0, 0] = euclidean(seq1[0], seq2[0])
for i in range(1, n):
for j in range(1, m):
cost[i, j] = euclidean(seq1[i], seq2[j]) + \
min(cost[i-1, j], cost[i, j-1], cost[i-1, j-1])
return cost[-1, -1]