From 09e5a2d4e25991131b472bd6b593e4c7710d0ec5 Mon Sep 17 00:00:00 2001 From: "Phyks (Lucas Verney)" Date: Sun, 25 Nov 2018 23:21:48 +0100 Subject: [PATCH] Show nearest reports, handling the area of the report (not only as a point, but polygon as well) --- scripts/opendata/works.py | 46 ++++- src/components/Map.vue | 110 +++++++---- src/constants.js | 3 + src/store/actions.js | 4 +- src/tools/geometry.js | 393 ++++++++++++++++++++++++++++++++++++++ src/tools/index.js | 21 -- src/views/Map.vue | 13 +- 7 files changed, 515 insertions(+), 75 deletions(-) create mode 100644 src/tools/geometry.js diff --git a/scripts/opendata/works.py b/scripts/opendata/works.py index ae44a63..e399ffd 100755 --- a/scripts/opendata/works.py +++ b/scripts/opendata/works.py @@ -17,7 +17,8 @@ import requests from functools import partial -from shapely.geometry import LineString, MultiPolygon, Point, Polygon +from shapely.geometry import (LineString, MultiPolygon, MultiLineString, + MultiPoint, Point) from shapely.geometry import mapping, shape from shapely.ops import transform @@ -596,22 +597,49 @@ def process_opendata(name, data, report_type=REPORT_TYPE): # Report geographical shape if 'geo_shape' in fields: - geo_shape = shape(fields['geo_shape']) + maybe_multi_geo_shape = shape(fields['geo_shape']) else: - geo_shape = shape(item['geometry']) + maybe_multi_geo_shape = shape(item['geometry']) - if isinstance(geo_shape, MultiPolygon): - # Split multipolygons into multiple polygons + geo_shapes = [] + if ( + isinstance(maybe_multi_geo_shape, MultiPolygon) + or isinstance(maybe_multi_geo_shape, MultiPoint) + ): + # Split MultiPolygon into multiple Polygon + # Same for MultiPoint positions = [ p.centroid - for p in geo_shape + for p in maybe_multi_geo_shape ] - else: + geo_shapes = [ + p + for p in maybe_multi_geo_shape + ] + elif isinstance(maybe_multi_geo_shape, MultiLineString): + # Split MultiLineString into multiple LineString positions = [ - geo_shape.centroid + p.interpolate(0.5, normalized=True) + for p in maybe_multi_geo_shape ] + geo_shapes = [ + p + for p in maybe_multi_geo_shape + ] + elif isinstance(maybe_multi_geo_shape, LineString): + # LineString, interpolate midpoint + positions = [ + maybe_multi_geo_shape.interpolate(0.5, normalized=True) + ] + geo_shapes = [maybe_multi_geo_shape] + else: + # Polygon or Point + positions = [ + maybe_multi_geo_shape.centroid + ] + geo_shapes = [maybe_multi_geo_shape] - for position in positions: + for (geo_shape, position) in zip(geo_shapes, positions): # Check if this precise position is already in the database if transform(project, position) in current_reports_points: logging.info( diff --git a/src/components/Map.vue b/src/components/Map.vue index 664df9b..00a1c0f 100644 --- a/src/components/Map.vue +++ b/src/components/Map.vue @@ -28,6 +28,7 @@