Distance in meters

This commit is contained in:
Ilya Zverev 2017-04-24 17:54:16 +03:00
parent c61ae158af
commit 59510d6052
3 changed files with 17 additions and 13 deletions

View file

@ -15,7 +15,7 @@ except ImportError:
OVERPASS_SERVER = 'http://overpass-api.de/api/'
BBOX_PADDING = 0.1 # in degrees
MAX_DISTANCE = 0.001 # how far can object be to be considered a match. 0.001 dg is ~110 m
MAX_DISTANCE = 100 # how far can object be to be considered a match, in meters
class SourcePoint:
@ -27,6 +27,12 @@ class SourcePoint:
self.lon = lon
self.tags = {} if tags is None else tags
def distance(self, other):
"""Calculate distance in meters."""
dx = math.radians(self.lon - other.lon) * math.cos(0.5 * math.radians(self.lat + other.lat))
dy = math.radians(self.lat - other.lat)
return 6378137 * math.sqrt(dx*dx + dy*dy)
def __len__(self):
return 2
@ -337,10 +343,7 @@ class OsmConflator:
# Modify
props['marker-color'] = '#0000ff' if ref else '#660000'
if ref:
# Calculate distance in meters
dx = (ref.lon - after.lon) * math.cos(0.5 * (ref.lat + after.lat))
dy = ref.lat - after.lat
props['ref_distance'] = round(63781370 * math.sqrt(dx*dx + dy*dy)) / 10.0
props['ref_distance'] = round(10 * ref.distance(after)) / 10.0
props['ref_coords'] = [ref.lon, ref.lat]
# Find tags that were superseeded by OSM tags
unused_tags = {}
@ -404,13 +407,13 @@ class OsmConflator:
"""
if not self.osmdata:
return
# KDTree distance is squared, so we square the max_distance
max_distance = pow(self.profile.get('max_distance', MAX_DISTANCE), 2)
max_distance = self.profile.get('max_distance', MAX_DISTANCE)
osm_kd = kdtree.create(list(self.osmdata.values()))
count_matched = 0
dist = []
for sp, v in self.dataset.items():
osm_point, distance = osm_kd.search_nn(v)
osm_point, _ = osm_kd.search_nn(v)
distance = None if osm_point is None else v.distance(osm_point.data)
if osm_point is not None and distance <= max_distance:
dist.append((distance, sp, osm_point.data))
needs_sorting = True
@ -426,8 +429,9 @@ class OsmConflator:
for i in range(len(dist)-1, -1, -1):
if dist[i][2] == osm_point:
nearest = osm_kd.search_nn(self.dataset[dist[i][1]])
distance = None if nearest is None else self.dataset[dist[i][1]].distance(nearest[0].data)
if nearest and nearest[1] <= max_distance:
new_point, distance = nearest
new_point = nearest[0]
dist[i] = (distance, dist[i][1], new_point.data)
needs_sorting = i == 0 or distance < dist[0][0]
else:

View file

@ -12,8 +12,8 @@ query = [('shop', '~supermarket|mall'), ('name', '~Ашан|АШАН')]
master_tags = ('name', 'opening_hours', 'phone', 'website')
# Empty dict so we don't add a fixme tag to unmatched objects
tag_unmatched = {}
# Coordinates are VERY approximate, so increasing max distance to ~1 km
max_distance = 0.01
# Coordinates are VERY approximate, so increasing max distance to 1 km
max_distance = 1000
# For some reason, functions here cannot use variables defined above
# And defining them as "global" moves these from locals() to globals()

View file

@ -16,8 +16,8 @@ dataset_id = 'mos_parking'
query = [('amenity', 'vending_machine'), ('vending', 'parking_tickets')]
# Use bbox from dataset points (default). False = query whole world, [minlat, minlon, maxlat, maxlon] to override
bbox = True
# How close OSM point should be to register a match. Default is 0.001 (~110 m)
max_distance = 0.0003 # ~30 m
# How close OSM point should be to register a match, in meters. Default is 100
max_distance = 30
# Delete objects that match query tags but not dataset? False is the default
delete_unmatched = False
# If set, and delete_unmatched is False, modify tags on unmatched objects instead