From 3c454abe4f74262c0658409c67042c9c5b1d8ea8 Mon Sep 17 00:00:00 2001 From: Wang Boyu Date: Sun, 3 Apr 2022 14:16:48 -0400 Subject: [PATCH] bring back __geo_interface__ functions --- mesa_geo/geoagent.py | 20 ++++++++++++++++++++ mesa_geo/geospace.py | 17 +++++++++++++---- mesa_geo/visualization/MapModule.py | 25 ++++++++++++++++--------- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/mesa_geo/geoagent.py b/mesa_geo/geoagent.py index 14b4a8f9..b3d8ea86 100644 --- a/mesa_geo/geoagent.py +++ b/mesa_geo/geoagent.py @@ -8,7 +8,10 @@ import warnings import geopandas as gpd +import pyproj from mesa import Agent +from shapely.ops import transform +from shapely.geometry import mapping from shapely.geometry.base import BaseGeometry @@ -27,10 +30,27 @@ def __init__(self, unique_id, model, shape): self.shape = shape self._geom = self.shape._geom + def get_transformed_geometry(self, transformer): + """ + Return the transformed geometry given a transformer. + """ + return transform(transformer.transform, self.shape) + def step(self): """Advance one step.""" pass + def __geo_interface__(self): + """Return a GeoJSON Feature. + Removes shape from attributes. + """ + properties = dict(vars(self)) + properties["model"] = str(self.model) + shape = properties.pop("shape") + shape = transform(self.model.space.Transformer.transform, shape) + + return {"type": "Feature", "geometry": mapping(shape), "properties": properties} + class AgentCreator: """Create GeoAgents from files, GeoDataFrames, GeoJSON or Shapely objects.""" diff --git a/mesa_geo/geospace.py b/mesa_geo/geospace.py index 6e2be92a..b7ec4e57 100644 --- a/mesa_geo/geospace.py +++ b/mesa_geo/geospace.py @@ -1,9 +1,8 @@ import pyproj from libpysal import weights from rtree import index -from shapely.geometry import Point, mapping +from shapely.geometry import Point from shapely.prepared import prep -from shapely.ops import transform from mesa_geo.geoagent import GeoAgent @@ -38,7 +37,9 @@ def __init__(self, crs="epsg:3857"): """ self.crs = pyproj.CRS(crs) self.WGS84 = pyproj.CRS("epsg:4326") - self.Transformer = pyproj.Transformer.from_crs(self.crs, self.WGS84, always_xy=True) + self.Transformer = pyproj.Transformer.from_crs( + self.crs, self.WGS84, always_xy=True + ) self.bbox = None self._neighborhood = None @@ -94,7 +95,9 @@ def get_intersecting_agents(self, agent, other_agents=None): intersecting_agents = self.get_relation(agent, "intersects") return intersecting_agents - def get_neighbors_within_distance(self, agent, distance, center=False, relation="intersects"): + def get_neighbors_within_distance( + self, agent, distance, center=False, relation="intersects" + ): """Return a list of agents within `distance` of `agent`. Distance is measured as a buffer around the agent's shape, @@ -166,3 +169,9 @@ def update_bbox(self, bbox=None): @property def agents(self): return list(self.idx.agents.values()) + + @property + def __geo_interface__(self): + """Return a GeoJSON FeatureCollection.""" + features = [a.__geo_interface__() for a in self.agents] + return {"type": "FeatureCollection", "features": features} diff --git a/mesa_geo/visualization/MapModule.py b/mesa_geo/visualization/MapModule.py index 7f0a135c..f23dfc95 100644 --- a/mesa_geo/visualization/MapModule.py +++ b/mesa_geo/visualization/MapModule.py @@ -1,5 +1,4 @@ from shapely.geometry import mapping -from shapely.ops import transform from mesa_geo.visualization.ModularVisualization import VisualizationElement @@ -10,7 +9,9 @@ class MapModule(VisualizationElement): package_includes = ["leaflet.js", "LeafletMap.js"] local_includes = [] - def __init__(self, portrayal_method=None, view=[0, 0], zoom=10, map_height=500, map_width=500): + def __init__( + self, portrayal_method=None, view=[0, 0], zoom=10, map_height=500, map_width=500 + ): self.portrayal_method = portrayal_method self.map_height = map_height self.map_width = map_width @@ -20,11 +21,17 @@ def __init__(self, portrayal_method=None, view=[0, 0], zoom=10, map_height=500, self.js_code = "elements.push(" + new_element + ");" def render(self, model): - feature_collection = {"type": "FeatureCollection", - "features": [ - {"type": "Feature", - "geometry": mapping(transform(model.space.Transformer.transform, agent.shape)), - "properties": self.portrayal_method(agent) if self.portrayal_method else {}} - for agent in model.space.agents - ]} + feature_collection = {"type": "FeatureCollection", "features": []} + for agent in model.space.agents: + transformed_geometry = agent.get_transformed_geometry( + model.space.Transformer + ) + properties = self.portrayal_method(agent) if self.portrayal_method else {} + feature_collection["features"].append( + { + "type": "Feature", + "geometry": mapping(transformed_geometry), + "properties": properties, + } + ) return feature_collection