From ad80619071233fd86a22dda6bb6212d0a70b45a0 Mon Sep 17 00:00:00 2001 From: Karsten Prehn Date: Fri, 16 Sep 2022 16:22:16 +0200 Subject: [PATCH] Reduced size of buffer and fixed calculation errors on tiny water geoms --- discretizer/database.py | 2 +- discretizer/discretize.py | 10 ++++++---- discretizer/spatialfunctions.py | 9 ++++++--- discretizer/tilegrid.py | 4 ++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/discretizer/database.py b/discretizer/database.py index 471f8ac..31ec146 100644 --- a/discretizer/database.py +++ b/discretizer/database.py @@ -284,7 +284,7 @@ class TilesDatabase(BasicClass): _sql = f"""{_sql} WHERE ST_intersects({rectangle}, geometry);""" _results = self.connect_tiles_database( - _sql, user=user, password=password, host=host, database=database + _sql, user=user, password=password, host=host, database=database, pid=pid ) return _results diff --git a/discretizer/discretize.py b/discretizer/discretize.py index 4792d12..a9a2295 100644 --- a/discretizer/discretize.py +++ b/discretizer/discretize.py @@ -555,9 +555,11 @@ class Discretizer(Quadtile, Config): ) # Drop duplicate tiles from sea- and inland-water, so dissolving the combined tiles - # later by ID doesn't falsely sum up classification values - seawater_per_tile_gdf = seawater_per_tile_gdf.drop_duplicates(["id"]) - inlandwater_per_tile_gdf = inlandwater_per_tile_gdf.drop_duplicates(["id"]) + # later by ID doesn't falsely sum up classification values. There can be multiple + # spatially split water geometries in a level-18 tile (e.g. a small isthmus dividing + # the tile), so have to identify duplicates by geometry and not by quadkey. + seawater_per_tile_gdf = seawater_per_tile_gdf.drop_duplicates(["geometry"]) + inlandwater_per_tile_gdf = inlandwater_per_tile_gdf.drop_duplicates(["geometry"]) # Concatenate inland-water and sea-water tiles water_per_tile_gdf = seawater_per_tile_gdf.append(inlandwater_per_tile_gdf) @@ -576,7 +578,7 @@ class Discretizer(Quadtile, Config): self.log.debug(f"<[{pid}]> Dissolved into {_len} water polygon geometries.") # Remove duplicate tiles from concatenation step - water_per_tile_gdf = water_per_tile_gdf.drop_duplicates(["id"]) + water_per_tile_gdf = water_per_tile_gdf.drop_duplicates(["geometry"]) water_per_tile_gdf = water_per_tile_gdf.dissolve(by="id", as_index=False) assert len(water_per_tile_gdf.index) == _len diff --git a/discretizer/spatialfunctions.py b/discretizer/spatialfunctions.py index e751eb6..78adab8 100644 --- a/discretizer/spatialfunctions.py +++ b/discretizer/spatialfunctions.py @@ -348,10 +348,13 @@ class SpatialFunctions(BasicClass): proj_aea = Proj("+proj=aea +lat_1={} +lat_2={}".format(miny, maxy)) if isinstance(polygon, Polygon): + transformed_coordinates = [] _plg = mapping(polygon) - lon, lat = list(zip(*_plg["coordinates"][0])) - x, y = proj_aea(lon, lat) - proj_coords = {"type": "Polygon", "coordinates": [list(zip(x, y))]} + for ring in _plg["coordinates"]: + lon, lat = list(zip(*ring)) + x, y = proj_aea(lon, lat) + transformed_coordinates.append(list(zip(x, y))) + proj_coords = {"type": "Polygon", "coordinates": transformed_coordinates} area = shape(proj_coords).area elif isinstance(polygon, MultiPolygon): _plgs = [mapping(p) for p in list(polygon)] diff --git a/discretizer/tilegrid.py b/discretizer/tilegrid.py index 4f0da1d..86f6345 100644 --- a/discretizer/tilegrid.py +++ b/discretizer/tilegrid.py @@ -54,8 +54,8 @@ class TileGrid(Quadtile): super(TileGrid, self).__init__(config, **kwargs) - # Roughly four times the length of a tile's side at level 18 - self.buffer_size = 0.005 + # Roughly 1 meter in degree, given a sphere with a circumference of 40000 km + self.buffer_size = 0.00001 # FIXME Is this whole function even needed, anymore? Coastal tiles are # already classified in `Discretizer::static_data_in_quadkey` -- GitLab