@@ -89,41 +89,44 @@ def _clip_vector_to_bounding_box(
8989 Returns:
9090 None
9191 """
92- working_file_path = None
93- print (target_projection_wkt )
94- if target_projection_wkt :
95- app .logger .debug ("REPROJECTING VECTOR..." )
96- working_file_path = target_vector_path .replace ('.fgb' , '-projected.fgb' )
97- try :
98- pygeoprocessing .reproject_vector (source_vector_path ,
99- target_projection_wkt , working_file_path ,
100- driver_name = 'FlatGeobuf' )
101- source_vector_path = working_file_path
102- except Exception :
103- app .logger .exception ("Failed to reproject vector; aborting" )
104- os .remove (working_file_path )
105- raise
92+ shapely_mask = shapely .prepared .prep (
93+ shapely .geometry .box (* target_bounding_box ))
10694
107- shapely_mask = shapely .prepared .prep (shapely .geometry .box (* target_bounding_box ))
108-
109- app .logger .debug ("OPENING BASE VECTOR..." )
95+ app .logger .debug ("Opening base vector..." )
11096 base_vector = gdal .OpenEx (source_vector_path , gdal .OF_VECTOR )
11197 base_layer = base_vector .GetLayer ()
98+ base_layer .SetSpatialFilterRect (* target_bounding_box )
11299 base_layer_defn = base_layer .GetLayerDefn ()
113100 base_geom_type = base_layer .GetGeomType ()
101+ base_srs = base_layer .GetSpatialRef ()
102+
103+ if target_projection_wkt is not None :
104+ target_srs = osr .SpatialReference ()
105+ target_srs .ImportFromWkt (target_projection_wkt )
106+ coord_trans = osr .CreateCoordinateTransformation (base_srs , target_srs )
107+ else :
108+ target_srs = base_srs
114109
115- app .logger .debug ("SETTING UP TARGET ..." )
110+ app .logger .debug ("Setting up target ..." )
116111 target_driver = gdal .GetDriverByName ('FlatGeobuf' )
117112 target_vector = target_driver .Create (
118113 target_vector_path , 0 , 0 , 0 , gdal .GDT_Unknown )
119114 target_layer = target_vector .CreateLayer (
120- base_layer_defn .GetName (), base_layer . GetSpatialRef () , base_geom_type )
115+ base_layer_defn .GetName (), target_srs , base_geom_type )
121116 target_layer .CreateFields (base_layer .schema )
122117
123- app .logger .debug ("CLIPPING VECTOR ..." )
118+ app .logger .debug ("Clipping vector ..." )
124119 target_layer .StartTransaction ()
125120 invalid_feature_count = 0
121+ n_processed = 0
122+ last_log_msg_time = time .time ()
126123 for feature in base_layer :
124+ now = time .time ()
125+ if now >= last_log_msg_time + 2.0 :
126+ app .logger .debug (f"Processed { n_processed } features so far" )
127+ last_log_msg_time = now
128+ n_processed += 1
129+
127130 invalid = False
128131 geometry = feature .GetGeometryRef ()
129132 try :
@@ -137,11 +140,14 @@ def _clip_vector_to_bounding_box(
137140 # Check for intersection rather than use gdal.Layer.Clip()
138141 # to preserve the shape of the polygons
139142 if shapely_mask .intersects (shapely_geom ):
140- new_feature = ogr .Feature (target_layer .GetLayerDefn ())
141- new_feature .SetGeometry (ogr .CreateGeometryFromWkb (
142- shapely_geom .wkb ))
143- for field_name , field_value in feature .items ().items ():
144- new_feature .SetField (field_name , field_value )
143+ # This appears to use the network WAY less
144+ new_feature = ogr .Feature .Clone (feature )
145+
146+ # If we need to, transform the geometry
147+ if target_projection_wkt is not None :
148+ geometry .Transform (coord_trans )
149+ new_feature .SetGeometry (geometry )
150+
145151 target_layer .CreateFeature (new_feature )
146152 else :
147153 invalid = True
@@ -164,9 +170,6 @@ def _clip_vector_to_bounding_box(
164170 target_layer = None
165171 target_vector = None
166172
167- if working_file_path :
168- os .remove (working_file_path )
169-
170173
171174@functools .lru_cache
172175def cached_file_info (vsi_file_path , file_type ):
@@ -179,7 +182,7 @@ def cached_file_info(vsi_file_path, file_type):
179182 raise
180183 elif file_type == VECTOR :
181184 try :
182- return pygeoprocessing .get_vector_info (f"/vsicurl/ { vsi_file_path } " )
185+ return pygeoprocessing .get_vector_info (vsi_file_path )
183186 except Exception :
184187 app .logger .error ("Failed to read vector info for %s" , vsi_file_path )
185188 raise
@@ -302,11 +305,10 @@ def clip():
302305 source_file_path = f'/vsicurl/{ parameters ["file_url" ]} '
303306 if source_file_type == VECTOR :
304307 # Temporarily hard-code path to NOAA shorelines flatgeobuf
305- source_file_path = "https://storage.googleapis.com/jupyter-app-temp-storage/noaa_us_shorelines.fgb"
308+ source_file_path = "/vsicurl/ https://storage.googleapis.com/jupyter-app-temp-storage/noaa_us_shorelines.fgb"
306309# source_file_path = source_file_path.replace('.mvt', '.shp')
307310
308311 source_file_info = cached_file_info (source_file_path , source_file_type )
309- app .logger .info (f"\n { source_file_info } \n " )
310312
311313 if source_file_type == RASTER :
312314 app .logger .info ("CLIPPING RASTER..." )
@@ -351,9 +353,6 @@ def clip():
351353 try :
352354 target_projection_wkt = _epsg_to_wkt (
353355 parameters ["target_epsg" ])
354- target_bbox = pygeoprocessing .transform_bounding_box (
355- target_bbox , source_file_info ['projection_wkt' ],
356- target_projection_wkt )
357356 except KeyError :
358357 target_projection_wkt = None
359358
0 commit comments