From 7d0eb3975dd0079b299ef7498a4451f747b8fbf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Wed, 8 Nov 2017 15:58:41 +0100 Subject: [PATCH] add contains_points to mpl utils and move mpl utils to mapdata --- src/c3nav/{routing => mapdata}/utils/mpl.py | 32 ++++++++++++++------- src/c3nav/routing/level.py | 2 +- src/c3nav/routing/room.py | 2 +- 3 files changed, 23 insertions(+), 13 deletions(-) rename src/c3nav/{routing => mapdata}/utils/mpl.py (73%) diff --git a/src/c3nav/routing/utils/mpl.py b/src/c3nav/mapdata/utils/mpl.py similarity index 73% rename from src/c3nav/routing/utils/mpl.py rename to src/c3nav/mapdata/utils/mpl.py index 6c5f6343..6ee644cd 100644 --- a/src/c3nav/routing/utils/mpl.py +++ b/src/c3nav/mapdata/utils/mpl.py @@ -1,7 +1,8 @@ from abc import ABC, abstractmethod +import numpy as np from matplotlib.path import Path -from shapely.geometry import MultiPolygon, Polygon +from shapely.geometry import GeometryCollection, MultiPolygon, Polygon from c3nav.mapdata.utils.geometry import assert_multipolygon @@ -36,6 +37,13 @@ class MplMultipolygonPath(MplPathProxy): return True return False + def contains_points(self, points): + result = np.full((len(points),), fill_value=False, dtype=np.bool) + for polygon in self.polygons: + ix = np.argwhere(np.logical_not(result)).flatten() + result[ix] = polygon.contains_points(points[ix]) + return result + class MplPolygonPath(MplPathProxy): def __init__(self, polygon): @@ -64,6 +72,15 @@ class MplPolygonPath(MplPathProxy): return True return False + def contains_points(self, points): + result = self.exterior.contains_points(points) + for interior in self.interiors: + if not result.any(): + break + ix = np.argwhere(result).flatten() + result[ix] = np.logical_not(interior.contains_points(points[ix])) + return result + def contains_point(self, point): if not self.exterior.contains_point(point): return False @@ -82,18 +99,11 @@ def shapely_to_mpl(geometry): """ if isinstance(geometry, Polygon): return MplPolygonPath(geometry) - elif isinstance(geometry, MultiPolygon) or geometry.is_empty: + elif isinstance(geometry, MultiPolygon) or geometry.is_empty or isinstance(geometry, GeometryCollection): return MplMultipolygonPath(geometry) raise TypeError def linearring_to_mpl_path(linearring): - vertices = [] - codes = [] - coords = list(linearring.coords) - vertices.extend(coords) - vertices.append(coords[0]) - codes.append(Path.MOVETO) - codes.extend([Path.LINETO] * (len(coords)-1)) - codes.append(Path.CLOSEPOLY) - return Path(vertices, codes, readonly=True) + return Path(np.array(linearring), + (Path.MOVETO, *([Path.LINETO] * (len(linearring.coords)-2)), Path.CLOSEPOLY), readonly=True) diff --git a/src/c3nav/routing/level.py b/src/c3nav/routing/level.py index 875bb6e6..7606fb1b 100644 --- a/src/c3nav/routing/level.py +++ b/src/c3nav/routing/level.py @@ -12,12 +12,12 @@ from shapely.geometry import CAP_STYLE, JOIN_STYLE, LineString from c3nav.mapdata.utils.geometry import assert_multilinestring, assert_multipolygon from c3nav.mapdata.utils.misc import get_public_private_area +from c3nav.mapdata.utils.mpl import shapely_to_mpl from c3nav.routing.point import GraphPoint from c3nav.routing.room import GraphRoom from c3nav.routing.utils.base import get_nearest_point from c3nav.routing.utils.coords import coord_angle from c3nav.routing.utils.draw import _ellipse_bbox, _line_coords -from c3nav.routing.utils.mpl import shapely_to_mpl class GraphLevel(): diff --git a/src/c3nav/routing/room.py b/src/c3nav/routing/room.py index 1728c34a..c3452957 100644 --- a/src/c3nav/routing/room.py +++ b/src/c3nav/routing/room.py @@ -8,11 +8,11 @@ from shapely.geometry import CAP_STYLE, JOIN_STYLE, LineString from shapely.ops import cascaded_union from c3nav.mapdata.utils.geometry import assert_multilinestring, assert_multipolygon +from c3nav.mapdata.utils.mpl import shapely_to_mpl from c3nav.routing.area import GraphArea from c3nav.routing.connection import GraphConnection from c3nav.routing.point import GraphPoint from c3nav.routing.utils.coords import get_coords_angles -from c3nav.routing.utils.mpl import shapely_to_mpl class GraphRoom():