22import os
33
44from mapswipe_workers .project_types .base .project import BaseProject
5- from mapswipe_workers .definitions import DATA_PATH , CustomError , logger
5+ from mapswipe_workers .definitions import (
6+ DATA_PATH ,
7+ CustomError ,
8+ logger ,
9+ MAX_INPUT_GEOMETRIES ,
10+ )
611from mapswipe_workers .project_types .tile_map_service_grid .group import Group
712from mapswipe_workers .utils import tile_grouping_functions as grouping_functions
813from mapswipe_workers .project_types .base .tile_server import BaseTileServer
@@ -14,6 +19,7 @@ def __init__(self, project_draft: dict):
1419 super ().__init__ (project_draft )
1520 self .project_type = project_draft ["projectType" ]
1621 self .groupSize = project_draft ["groupSize" ]
22+ # Note: this will be overwritten by validate_geometry in mapswipe_workers.py
1723 self .geometry = project_draft ["geometry" ]
1824 self .zoomLevel = int (project_draft .get ("zoomLevel" , 18 ))
1925 self .tileServer = vars (BaseTileServer (project_draft ["tileServer" ]))
@@ -58,19 +64,29 @@ def validate_geometries(self):
5864 raise CustomError (f"Empty file. " )
5965
6066 # check if more than 1 geometry is provided
61- elif layer .GetFeatureCount () > 1 :
67+ elif layer .GetFeatureCount () > MAX_INPUT_GEOMETRIES :
6268 logger .warning (
6369 f"{ self .projectId } "
6470 f" - validate geometry - "
65- f"Input file contains more than one geometry. "
66- f"Make sure to provide exact one input geometry."
71+ f"Input file contains more than { MAX_INPUT_GEOMETRIES } geometries. "
72+ f"Make sure to provide less than { MAX_INPUT_GEOMETRIES } geometries."
73+ )
74+ raise CustomError (
75+ f"Input file contains more than { MAX_INPUT_GEOMETRIES } geometries. "
6776 )
68- raise CustomError (f"Input file contains more than one geometry. " )
6977
78+ project_area = 0
79+ geometry_collection = ogr .Geometry (ogr .wkbMultiPolygon )
7080 # check if the input geometry is a valid polygon
7181 for feature in layer :
7282 feat_geom = feature .GetGeometryRef ()
7383 geom_name = feat_geom .GetGeometryName ()
84+ # add geometry to geometry collection
85+ if geom_name == "MULTIPOLYGON" :
86+ for singlepart_polygon in feat_geom :
87+ geometry_collection .AddGeometry (singlepart_polygon )
88+ if geom_name == "POLYGON" :
89+ geometry_collection .AddGeometry (feat_geom )
7490 if not feat_geom .IsValid ():
7591 logger .warning (
7692 f"{ self .projectId } "
@@ -91,9 +107,6 @@ def validate_geometries(self):
91107 )
92108 raise CustomError (f"Invalid geometry type: { geom_name } . " )
93109
94- # get geometry as wkt
95- wkt_geometry = feat_geom .ExportToWkt ()
96-
97110 # check size of project make sure its smaller than 5,000 sqkm
98111 # for doing this we transform the geometry
99112 # into Mollweide projection (EPSG Code 54009)
@@ -105,47 +118,47 @@ def validate_geometries(self):
105118
106119 transform = osr .CoordinateTransformation (source , target )
107120 feat_geom .Transform (transform )
108- project_area = feat_geom .GetArea () / 1000000
109-
110- # calculate max area based on zoom level
111- # for zoom level 18 this will be 5000 square kilometers
112- # max zoom level is 22
113- if self .zoomLevel > 22 :
114- raise CustomError (
115- f"zoom level is to large (max: 22): { self .zoomLevel } ."
116- )
121+ project_area = + feat_geom .GetArea () / 1000000
117122
118- max_area = (23 - int (self .zoomLevel )) * (23 - int (self .zoomLevel )) * 200
123+ # calculate max area based on zoom level
124+ # for zoom level 18 this will be 5000 square kilometers
125+ # max zoom level is 22
126+ if self .zoomLevel > 22 :
127+ raise CustomError (f"zoom level is to large (max: 22): { self .zoomLevel } ." )
119128
120- if project_area > max_area :
121- logger .warning (
122- f"{ self .projectId } "
123- f" - validate geometry - "
124- f"Project is to large: { project_area } sqkm. "
125- f"Please split your projects into smaller sub-projects and resubmit"
126- )
127- raise CustomError (
128- f"Project is to large: { project_area } sqkm. "
129- f"Max area for zoom level { self .zoomLevel } = { max_area } sqkm"
130- )
129+ max_area = (23 - int (self .zoomLevel )) * (23 - int (self .zoomLevel )) * 200
130+
131+ if project_area > max_area :
132+ logger .warning (
133+ f"{ self .projectId } "
134+ f" - validate geometry - "
135+ f"Project is to large: { project_area } sqkm. "
136+ f"Please split your projects into smaller sub-projects and resubmit"
137+ )
138+ raise CustomError (
139+ f"Project is to large: { project_area } sqkm. "
140+ f"Max area for zoom level { self .zoomLevel } = { max_area } sqkm"
141+ )
131142
132143 del datasource
133144 del layer
134145
135146 self .validInputGeometries = raw_input_file
136-
137147 logger .info (
138148 f"{ self .projectId } " f" - validate geometry - " f"input geometry is correct."
139149 )
140150
141- return wkt_geometry
151+ dissolved_geometry = geometry_collection .UnionCascaded ()
152+ wkt_geometry_collection = dissolved_geometry .ExportToWkt ()
153+
154+ return wkt_geometry_collection
142155
143156 def create_groups (self ):
144157 """
145158 The function to create groups from the project extent
146159 """
147160 # first step get properties of each group from extent
148- raw_groups = grouping_functions .extent_to_slices (
161+ raw_groups = grouping_functions .extent_to_groups (
149162 self .validInputGeometries , self .zoomLevel , self .groupSize
150163 )
151164
0 commit comments