Use shapely projection instead of brute force.

Converts the landmap to use MultiPolygon instead of a collection of
polygons, since Shapely has explicit support for this.

Because we've done that, we can use a single projection from a line
instead of brute forcing the extent of the front line.

This makes turn processing ~66% faster (3 seconds to 1.8).

There are probably other places this should be used.
This commit is contained in:
Dan Albert
2020-12-24 00:54:57 -08:00
parent 2a65916f7c
commit b9138acbc8
11 changed files with 42 additions and 23 deletions

View File

@@ -447,11 +447,11 @@ class ConflictTheater:
if self.is_on_land(point):
return False
for exclusion_zone in self.landmap[1]:
for exclusion_zone in self.landmap.exclusion_zones:
if poly_contains(point.x, point.y, exclusion_zone):
return False
for sea in self.landmap[2]:
for sea in self.landmap.sea_zones:
if poly_contains(point.x, point.y, sea):
return True
@@ -462,14 +462,13 @@ class ConflictTheater:
return True
is_point_included = False
for inclusion_zone in self.landmap[0]:
if poly_contains(point.x, point.y, inclusion_zone):
is_point_included = True
if poly_contains(point.x, point.y, self.landmap.inclusion_zones):
is_point_included = True
if not is_point_included:
return False
for exclusion_zone in self.landmap[1]:
for exclusion_zone in self.landmap.exclusion_zones:
if poly_contains(point.x, point.y, exclusion_zone):
return False
@@ -484,7 +483,7 @@ class ConflictTheater:
nearest_points = []
if not self.landmap:
raise RuntimeError("Landmap not initialized")
for inclusion_zone in self.landmap[0]:
for inclusion_zone in self.landmap.inclusion_zones:
nearest_pair = ops.nearest_points(point, inclusion_zone)
nearest_points.append(nearest_pair[1])
min_distance = point.distance(nearest_points[0]) # type: geometry.Point

View File

@@ -1,11 +1,17 @@
from dataclasses import dataclass
import pickle
from typing import Collection, Optional, Tuple
from typing import Optional, Tuple, Union
import logging
from shapely import geometry
from shapely.geometry import MultiPolygon, Polygon
Zone = Collection[Tuple[float, float]]
Landmap = Tuple[Collection[geometry.Polygon], Collection[geometry.Polygon], Collection[geometry.Polygon]]
@dataclass(frozen=True)
class Landmap:
inclusion_zones: MultiPolygon
exclusion_zones: MultiPolygon
sea_zones: MultiPolygon
def load_landmap(filename: str) -> Optional[Landmap]:
@@ -17,7 +23,7 @@ def load_landmap(filename: str) -> Optional[Landmap]:
return None
def poly_contains(x, y, poly:geometry.Polygon):
def poly_contains(x, y, poly: Union[MultiPolygon, Polygon]):
return poly.contains(geometry.Point(x, y))