diff --git a/obs/face/geojson/ExportRoadAnnotations.py b/obs/face/geojson/ExportRoadAnnotations.py index e399fd8..f216bd3 100644 --- a/obs/face/geojson/ExportRoadAnnotations.py +++ b/obs/face/geojson/ExportRoadAnnotations.py @@ -43,16 +43,26 @@ def add_measurements(self, measurements): for sample in measurements: self.n_samples += 1 # filter measurements + if not ("OSM_way_id" in sample): + continue; + way_id = sample["OSM_way_id"] + way_orientation = 1 if sample["OSM_way_orientation"] == -1 else 0 + if sample["latitude"] is None or sample["longitude"] is None or sample["distance_overtaker"] is None \ or self.only_confirmed_measurements and (sample["confirmed"] is not True) \ or not sample["has_OSM_annotations"]: + if not (way_id in self.way_statistics): + way = self.map_source.get_way_by_id(way_id) + if way: + self.way_statistics[way_id] = WayStatistics(way_id, way) + if way_id in self.way_statistics and sample["speed"] != 0: + self.way_statistics[way_id].n_ticks[way_orientation] += 1 + continue self.n_valid += 1 - way_id = sample["OSM_way_id"] value = sample["distance_overtaker"] - way_orientation = sample["OSM_way_orientation"] self.map_source.ensure_coverage([sample["latitude"]], [sample["longitude"]]) @@ -68,13 +78,15 @@ def add_measurements(self, measurements): self.n_grouped += 1 else: logging.warning("way not found in map") + self.way_statistics[way_id].n_ticks[way_orientation] += 1 def finalize(self): log.info("%s samples, %s valid", self.n_samples, self.n_valid) features = [] for way_stats in self.way_statistics.values(): way_stats.finalize() - if not any(way_stats.valid): +# if not any(way_stats.valid): + if not any(way_stats.n_ticks): continue for i in range(1 if way_stats.oneway else 2): @@ -91,19 +103,14 @@ def finalize(self): coordinates = [] feature = {"type": "Feature", - "properties": {"distance_overtaker_mean": way_stats.d_mean[i], - "distance_overtaker_median": way_stats.d_median[i], - "distance_overtaker_minimum": way_stats.d_minimum[i], - "distance_overtaker_n": way_stats.n[i], - "distance_overtaker_n_below_limit": way_stats.n_lt_limit[i], - "distance_overtaker_n_above_limit": way_stats.n_geq_limit[i], - "distance_overtaker_limit": way_stats.d_limit, - "distance_overtaker_measurements": way_stats.samples[i], + "properties": {"distance_overtaker_limit": way_stats.d_limit, + "distance_overtaker_measurements": sorted(way_stats.samples[i], key = float), "zone": way_stats.zone, "direction": direction, "name": way_stats.name, "way_id": way_stats.way_id, "valid": way_stats.valid[i], + "ticks": way_stats.n_ticks[i], }, "geometry": {"type": "LineString", "coordinates": coordinates}} @@ -124,12 +131,10 @@ def __init__(self, way_id, way): self.n = [0, 0] self.n_lt_limit = [0, 0] self.n_geq_limit = [0, 0] + self.n_ticks = [0, 0] self.way_id = way_id self.valid = [False, False] - self.d_mean = [0, 0] - self.d_median = [0, 0] - self.d_minimum = [0, 0] self.zone = "unknown" self.oneway = False @@ -156,19 +161,11 @@ def __init__(self, way_id, way): def add_sample(self, sample, orientation): if np.isfinite(sample): - i = 1 if orientation == -1 else 0 - self.samples[i].append(sample) + self.samples[orientation].append(sample) return self def finalize(self): for i in range(2): samples = np.array(self.samples[i]) if len(samples) > 0: - self.n[i] = len(samples) - self.d_mean[i] = np.mean(samples) - self.d_median[i] = np.median(samples) - self.d_minimum[i] = np.min(samples) - if self.d_limit is not None: - self.n_lt_limit[i] = int((samples < self.d_limit).sum()) - self.n_geq_limit[i] = int((samples >= self.d_limit).sum()) self.valid[i] = True diff --git a/obs/face/osm/DataSource.py b/obs/face/osm/DataSource.py index fb536d8..5f4d22c 100644 --- a/obs/face/osm/DataSource.py +++ b/obs/face/osm/DataSource.py @@ -65,9 +65,10 @@ def add_tile(self, tile): # add way objects, and store for way_id, way in ways.items(): if way_id not in self.ways: - w = Way(way_id, way, nodes) - self.ways[way_id] = w - self.way_container.insert(w) + w = Way.create(way_id, way, nodes, 100) + self.ways.update(w) + for id in w: + self.way_container.insert(w[id]) # update tile list self.loaded_tiles.append(tile) diff --git a/obs/face/osm/Way.py b/obs/face/osm/Way.py index 689c742..729051c 100644 --- a/obs/face/osm/Way.py +++ b/obs/face/osm/Way.py @@ -4,7 +4,7 @@ class Way: - def __init__(self, way_id, way, all_nodes): + def __init__(self, way_id, way, nodes_way): self.way_id = way_id if "tags" in way: @@ -13,8 +13,6 @@ def __init__(self, way_id, way, all_nodes): self.tags = {} # determine points - nodes_way = [all_nodes[i] for i in way["nodes"]] - lat = np.array([n["lat"] for n in nodes_way]) lon = np.array([n["lon"] for n in nodes_way]) self.points_lat_lon = np.stack((lat, lon), axis=1) @@ -35,10 +33,47 @@ def __init__(self, way_id, way, all_nodes): # direction dx = np.diff(x) dy = np.diff(y) + self.seg_length = np.hypot(dx, dy) self.direction = np.arctan2(dy, dx) self.directionality_bicycle, self.directionality_motorized = self.get_way_directionality(way) + @staticmethod + def create(way_id, way, all_nodes, max_len): + ways = {} + # determine points + nodes = [all_nodes[i] for i in way["nodes"]] + lat = np.array([n["lat"] for n in nodes]) + lon = np.array([n["lon"] for n in nodes]) + + # bounding box + a = (min(lat), min(lon)) + b = (max(lat), max(lon)) + + # define the local map around the center of the bounding box + lat_0 = (a[0] + b[0]) * 0.5 + lon_0 = (a[1] + b[1]) * 0.5 + local_map = LocalMap(lat_0, lon_0) + x, y = local_map.transfer_to(lat, lon) + dx = np.diff(x) + dy = np.diff(y) + seg_length = np.hypot(dx, dy) + + slen = 0 + first = 0 + if len(dx) > 0: + for i in range(len(seg_length)): + slen += seg_length[i] + if (slen > max_len and i != first): + id = str(way_id)+'.'+str(i) + ways[id] = Way(id, way, nodes[first:i+1]) + first = i + slen = 0 + id = str(way_id) + ways[id] = Way(id, way, nodes[first:]) + return ways + + def get_axis_aligned_bounding_box(self): return self.a, self.b diff --git a/visualization/OBS.js b/visualization/OBS.js index 7a66aac..b3378bf 100644 --- a/visualization/OBS.js +++ b/visualization/OBS.js @@ -172,11 +172,12 @@ class Palette { paletteUrban = new Palette( { - 0.0: [64, 0, 0, 255], - 1.4999: [196, 0, 0, 255], - 1.5: [196, 196, 0, 255], - 2.0: [0, 196, 0, 255], - 2.55: [0, 255, 0, 255], + 0.0: [196, 0, 0, 255], + 0.8: [196, 0, 0, 255], + 1.3: [245, 141, 0, 255], + 1.5: [94, 188, 7, 255], + 2.0: [94, 188, 7, 255], + 2.55: [0, 196, 0, 255], }, [0, 0, 196, 255] ) diff --git a/visualization/measurements.html b/visualization/measurements.html index f1194c5..bd68bcd 100644 --- a/visualization/measurements.html +++ b/visualization/measurements.html @@ -104,43 +104,39 @@