Skip to content

Commit f8a282e

Browse files
committed
extract vector creation, fix aoi poly creation
1 parent 495206b commit f8a282e

File tree

2 files changed

+56
-50
lines changed

2 files changed

+56
-50
lines changed

handler.py

+53-47
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,58 @@ def check_data(images):
349349
return True
350350

351351

352+
def create_vector(args, dmg_path, extent=None, in_poly_df=None):
353+
# Get files for creating vector data
354+
logger.info("Generating vector data")
355+
dmg_files = get_files(dmg_path)
356+
357+
# if not using input polys use threshold to filter out small polygons (likely false positives)
358+
if args.bldg_polys:
359+
polygons = features.create_polys(dmg_files, threshold=0)
360+
else:
361+
polygons = features.create_polys(dmg_files)
362+
363+
if args.bldg_polys:
364+
polygons = (
365+
in_poly_df.reset_index()
366+
.overlay(polygons, how="identity")
367+
.clip(extent, keep_geom_type=True)
368+
) # reset_index preserves a column independent id for joining later
369+
polygons = (
370+
polygons.groupby("index", as_index=False)
371+
.apply(lambda x: features.weight_dmg(x, args.destination_crs))
372+
.reset_index(
373+
drop=True
374+
) # resets multi-index created during grouping/dissolve process
375+
)
376+
polygons.set_crs(args.destination_crs)
377+
# BUG: create aoi before simplify as some versions/combos of shapely/geos create invalid geometries with overlapping features
378+
# see: https://github.com/geopandas/geopandas/issues/915
379+
aoi = features.create_aoi_poly(polygons)
380+
polygons.geometry = polygons.geometry.simplify(1)
381+
382+
# Create geojson -- do this before additional vector creation lest they fail out
383+
json_out = Path(args.output_directory).joinpath("vector") / "damage.geojson"
384+
polygons.to_file(json_out, driver="GeoJSON", index=False)
385+
386+
aoi = features.create_aoi_poly(polygons)
387+
centroids = features.create_centroids(polygons)
388+
389+
logger.info(f"Polygons created: {len(polygons)}")
390+
logger.info(
391+
f"Inferred hull area: {aoi.area}"
392+
) # Todo: Calculate area for pre/post/poly/aoi/intersect (the one that matters)
393+
394+
# Create geopackage
395+
logger.info("Writing output file")
396+
vector_out = Path(args.output_directory).joinpath("vector") / "damage.gpkg"
397+
features.write_output(
398+
polygons, vector_out, layer="damage"
399+
) # Todo: move this up to right after the polys are simplified to capture some vector data if script crashes
400+
features.write_output(aoi, vector_out, "aoi")
401+
features.write_output(centroids, vector_out, "centroids")
402+
403+
352404
def parse_args():
353405
parser = argparse.ArgumentParser(
354406
description="Create arguments for xView 2 handler."
@@ -782,53 +834,7 @@ def main():
782834
f_p = postprocess_and_write
783835
p.map(f_p, results_list)
784836

785-
# Get files for creating vector data
786-
logger.info("Generating vector data")
787-
dmg_files = get_files(Path(args.output_directory) / "dmg")
788-
789-
# if not using input polys use threshold to filter out small polygons (likely false positives)
790-
if args.bldg_polys:
791-
polygons = features.create_polys(dmg_files, threshold=0)
792-
else:
793-
polygons = features.create_polys(dmg_files)
794-
795-
if args.bldg_polys:
796-
polygons = (
797-
in_poly_df.reset_index()
798-
.overlay(polygons, how="identity")
799-
.clip(extent, keep_geom_type=True)
800-
) # reset_index preserves a column independent id for joining later
801-
polygons = (
802-
polygons.groupby("index", as_index=False)
803-
.apply(lambda x: features.weight_dmg(x, args.destination_crs))
804-
.reset_index(
805-
drop=True
806-
) # resets multi-index created during grouping/dissolve process
807-
)
808-
polygons.set_crs(args.destination_crs)
809-
810-
polygons.geometry = polygons.geometry.simplify(1)
811-
812-
# Create geojson -- do this before additional vector creation lest they fail out
813-
json_out = Path(args.output_directory).joinpath("vector") / "damage.geojson"
814-
polygons.to_file(json_out, driver="GeoJSON", index=False)
815-
816-
aoi = features.create_aoi_poly(polygons)
817-
centroids = features.create_centroids(polygons)
818-
819-
logger.info(f"Polygons created: {len(polygons)}")
820-
logger.info(
821-
f"Inferred hull area: {aoi.area}"
822-
) # Todo: Calculate area for pre/post/poly/aoi/intersect (the one that matters)
823-
824-
# Create geopackage
825-
logger.info("Writing output file")
826-
vector_out = Path(args.output_directory).joinpath("vector") / "damage.gpkg"
827-
features.write_output(
828-
polygons, vector_out, layer="damage"
829-
) # Todo: move this up to right after the polys are simplified to capture some vector data if script crashes
830-
features.write_output(aoi, vector_out, "aoi")
831-
features.write_output(centroids, vector_out, "centroids")
837+
create_vector(args, Path(args.output_directory) / "dmg", extent, in_poly_df)
832838

833839
# Create damage and overlay mosaics
834840
# Probably stop generating damage mosaic and create overlay from pre and vectors. Stop making overlay from chips

utils/features.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ def write_output(features, out_file, layer="features"):
3939
return out_file
4040

4141

42-
def create_aoi_poly(features):
42+
def create_aoi_poly(polygons):
4343

4444
"""
4545
Create convex hull polygon encompassing damage polygons
4646
:param features: Polygons to create hull around
4747
:return: GDF
4848
"""
49-
hull = features.dissolve().convex_hull
50-
df = geopandas.GeoDataFrame.from_features(hull, crs=features.crs)
49+
hull = polygons.unary_union.convex_hull
50+
df = geopandas.GeoDataFrame({'geometry': [hull]}, crs=polygons.crs)
5151
return df
5252

5353

0 commit comments

Comments
 (0)