|
9 | 9 | import pandas as pd |
10 | 10 |
|
11 | 11 | sys.path.insert(1, '../..') |
12 | | -from helpers.functions_for_examples import get_categories |
| 12 | +from helpers.functions_for_examples import get_categories, merge_adjacent_detections, read_dets_and_aoi |
13 | 13 | import helpers.misc as misc |
14 | 14 |
|
15 | 15 | from loguru import logger |
|
62 | 62 | logger.success(f"Done! All files already exist in folder {OUTPUT_DIR}. Exiting.") |
63 | 63 | sys.exit(0) |
64 | 64 |
|
65 | | - logger.info("Loading split AoI tiles as a GeoPandas DataFrame...") |
66 | | - tiles_gdf = gpd.read_file('split_aoi_tiles.geojson') |
67 | | - tiles_gdf = tiles_gdf.to_crs(2056) |
68 | | - if 'year_tile' in tiles_gdf.keys(): |
69 | | - tiles_gdf['year_tile'] = tiles_gdf.year_tile.astype(int) |
70 | | - logger.success(f"Done! {len(tiles_gdf)} features were found.") |
71 | | - |
72 | | - logger.info("Loading detections as a GeoPandas DataFrame...") |
73 | | - |
74 | | - detections_gdf = gpd.GeoDataFrame() |
75 | | - |
76 | | - for dataset, dets_file in DETECTION_FILES.items(): |
77 | | - detections_ds_gdf = gpd.read_file(dets_file) |
78 | | - detections_ds_gdf[f'dataset'] = dataset |
79 | | - detections_gdf = pd.concat([detections_gdf, detections_ds_gdf], axis=0, ignore_index=True) |
80 | | - detections_gdf = detections_gdf.to_crs(2056) |
81 | | - detections_gdf['area'] = detections_gdf.area |
82 | | - detections_gdf['det_id'] = detections_gdf.index |
83 | | - if 'year_det' in detections_gdf.keys(): |
84 | | - detections_gdf['year_det'] = detections_gdf.year_det.astype(int) |
85 | | - logger.success(f"Done! {len(detections_gdf)} features were found.") |
| 65 | + tiles_gdf, detections_gdf = read_dets_and_aoi(DETECTION_FILES) |
86 | 66 |
|
87 | 67 | # Merge features |
88 | 68 | logger.info(f"Merge adjacent polygons overlapping tiles with a buffer of {DISTANCE} m...") |
89 | 69 | detections_all_years_gdf = gpd.GeoDataFrame() |
90 | 70 |
|
91 | 71 | # Process detection by year |
92 | 72 | for year in detections_gdf.year_det.unique(): |
93 | | - detections_by_year_gdf = detections_gdf[detections_gdf['year_det']==year] |
94 | | - |
95 | | - detections_buffer_gdf = detections_by_year_gdf.copy() |
96 | | - detections_buffer_gdf['geometry'] = detections_by_year_gdf.geometry.buffer(DISTANCE, resolution=2) |
97 | | - |
98 | | - # Saves the id of polygons contained entirely within the tile (no merging with adjacent tiles), to avoid merging them if they are at a distance of less than thd |
99 | | - detections_tiles_join_gdf = gpd.sjoin(tiles_gdf, detections_buffer_gdf, how='left', predicate='contains') |
100 | | - remove_det_list = detections_tiles_join_gdf.det_id.unique().tolist() |
101 | | - |
102 | | - detections_within_tiles_gdf = detections_by_year_gdf[detections_by_year_gdf.det_id.isin(remove_det_list)].drop_duplicates(subset=['det_id'], ignore_index=True) |
103 | | - detections_overlap_tiles_gdf = detections_by_year_gdf[~detections_by_year_gdf.det_id.isin(remove_det_list)].drop_duplicates(subset=['det_id'], ignore_index=True) |
104 | | - |
105 | | - # Merge polygons within the thd distance |
106 | | - detections_overlap_tiles_gdf.loc[:, 'geometry'] = detections_overlap_tiles_gdf.buffer(DISTANCE, resolution=2) |
107 | | - detections_dissolve_gdf = detections_overlap_tiles_gdf[['det_id', 'geometry']].dissolve(as_index=False) |
108 | | - detections_merge_gdf = detections_dissolve_gdf.explode(ignore_index=True) |
109 | | - del detections_dissolve_gdf, detections_overlap_tiles_gdf |
110 | | - |
111 | | - if detections_merge_gdf.isnull().values.any(): |
112 | | - detections_merge_gdf = gpd.GeoDataFrame() |
113 | | - else: |
114 | | - detections_merge_gdf.geometry = detections_merge_gdf.buffer(-DISTANCE, resolution=2) |
115 | | - |
116 | | - # Spatially join merged detection with raw ones to retrieve relevant information (score, area,...) |
117 | | - detections_merge_gdf['index_merge'] = detections_merge_gdf.index |
118 | | - detections_join_gdf = gpd.sjoin(detections_merge_gdf, detections_by_year_gdf, how='inner', predicate='intersects') |
119 | | - |
120 | | - det_class_all = [] |
121 | | - det_score_all = [] |
122 | | - |
123 | | - for id in detections_merge_gdf.index_merge.unique(): |
124 | | - detections_by_year_gdf = detections_join_gdf.copy() |
125 | | - detections_by_year_gdf = detections_by_year_gdf[(detections_by_year_gdf['index_merge']==id)] |
126 | | - detections_by_year_gdf.rename(columns={'score_left': 'score'}, inplace=True) |
127 | | - det_score_all.append(detections_by_year_gdf['score'].mean()) |
128 | | - detections_by_year_gdf = detections_by_year_gdf.dissolve(by='det_class', aggfunc='sum', as_index=False) |
129 | | - # Keep class of largest det |
130 | | - if len(detections_by_year_gdf) > 0: |
131 | | - detections_by_year_gdf['det_class'] = detections_by_year_gdf.loc[detections_by_year_gdf['area'] == detections_by_year_gdf['area'].max(), |
132 | | - 'det_class'].iloc[0] |
133 | | - det_class = detections_by_year_gdf['det_class'].drop_duplicates().tolist() |
134 | | - else: |
135 | | - det_class = [0] |
136 | | - det_class_all.append(det_class[0]) |
137 | | - |
138 | | - detections_merge_gdf['det_class'] = det_class_all |
139 | | - detections_merge_gdf['score'] = det_score_all |
140 | | - |
141 | | - complete_merge_dets_gdf = pd.merge(detections_merge_gdf, detections_join_gdf[['index_merge', 'year_det'] + ([] if 'dataset' in detections_merge_gdf.columns else ['dataset'])], on='index_merge') |
| 73 | + complete_merge_dets_gdf, detections_within_tiles_gdf = merge_adjacent_detections(detections_gdf, tiles_gdf, year, DISTANCE) |
142 | 74 | detections_all_years_gdf = pd.concat([detections_all_years_gdf, complete_merge_dets_gdf, detections_within_tiles_gdf], ignore_index=True) |
143 | 75 |
|
144 | | - del complete_merge_dets_gdf, detections_merge_gdf, detections_by_year_gdf, detections_within_tiles_gdf, detections_join_gdf |
145 | | - |
146 | 76 | # get classe ids |
147 | 77 | CATEGORIES = os.path.join('category_ids.json') |
148 | 78 | categories_info_df, _ = get_categories(CATEGORIES) |
|
0 commit comments