From b9ed6ecd570726207a1e974ff2b4b9218125154e Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Fri, 19 Jun 2026 17:09:52 +0530 Subject: [PATCH 01/18] chnages for antyodaya --- computing/misc/antyodaya_local_compute.py | 25 ++++++++--------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/computing/misc/antyodaya_local_compute.py b/computing/misc/antyodaya_local_compute.py index 9911ba18..698c32e6 100644 --- a/computing/misc/antyodaya_local_compute.py +++ b/computing/misc/antyodaya_local_compute.py @@ -26,7 +26,7 @@ from computing.local_compute_helper import ( PROJECT_ROOT, build_output_vector_path, - load_precomputed_watersheds, + load_precomputed_panchayat, read_validated_vector_file, write_vector_output, validate_geometry, @@ -39,17 +39,8 @@ GEOSERVER_WORKSPACE = "antyodaya_2020" -def _compute_antyodaya_for_watersheds(watersheds_gdf, antyodaya_gdf): - """ - Spatially filters Antyodaya features with watershed/ROI boundaries. - """ - if antyodaya_gdf.empty: - return antyodaya_gdf - - if watersheds_gdf.crs and antyodaya_gdf.crs and watersheds_gdf.crs != antyodaya_gdf.crs: - antyodaya_gdf = antyodaya_gdf.to_crs(watersheds_gdf.crs) - - outer_boundary = watersheds_gdf.geometry.unary_union +def _compute_antyodaya_for_panchayat(panchayat_gdf, antyodaya_gdf): + outer_boundary = panchayat_gdf.geometry.unary_union # Precise intersection check antyodaya_in_roi = antyodaya_gdf[antyodaya_gdf.intersects(outer_boundary)].copy() @@ -77,7 +68,7 @@ def generate_antyodaya_data_local( ): if state and district and block: layer_name = f"antyodaya20_{valid_gee_text(district.lower())}_{valid_gee_text(block.lower())}" - watersheds_gdf, watershed_source = load_precomputed_watersheds( + panchayat_gdf, watershed_source = load_precomputed_panchayat( state=state, district=district, block=block, @@ -88,22 +79,22 @@ def generate_antyodaya_data_local( if not roi_path or not asset_suffix: raise ValueError("ROI path and asset_suffix are required for custom runs.") layer_name = f"antyodaya20_{valid_gee_text(asset_suffix).lower()}" - watersheds_gdf = read_validated_vector_file(roi_path, f"Invalid ROI file: {roi_path}") + panchayat_gdf = read_validated_vector_file(roi_path, f"Invalid ROI file: {roi_path}") print(f"ROI source: {roi_path}") if not os.path.exists(PAN_INDIA_ANTYODAYA_2020): raise FileNotFoundError(f"PAN INDIA Antyodaya file not found at {PAN_INDIA_ANTYODAYA_2020}") print("Loading Antyodaya data overlapping ROI...") - antyodaya_gdf = gpd.read_file(PAN_INDIA_ANTYODAYA_2020, mask=watersheds_gdf) + antyodaya_gdf = gpd.read_file(PAN_INDIA_ANTYODAYA_2020, mask=panchayat_gdf) antyodaya_gdf = validate_geometry(antyodaya_gdf) if antyodaya_gdf.empty: print("Warning: PAN INDIA Antyodaya file has no valid geometries overlapping ROI") else: print(f"Loaded {len(antyodaya_gdf)} Antyodaya features") - result_gdf = _compute_antyodaya_for_watersheds( - watersheds_gdf=watersheds_gdf, + result_gdf = _compute_antyodaya_for_panchayat( + panchayat_gdf=panchayat_gdf, antyodaya_gdf=antyodaya_gdf, ) print(f"Final valid Antyodaya features after spatial filter: {len(result_gdf)}") From 41c2615c5c74125064d4c492fbbee658cf50ef59 Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Fri, 19 Jun 2026 17:31:12 +0530 Subject: [PATCH 02/18] chnages for antyodaya --- computing/misc/antyodaya_local_compute.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/computing/misc/antyodaya_local_compute.py b/computing/misc/antyodaya_local_compute.py index 698c32e6..cc2e7daf 100644 --- a/computing/misc/antyodaya_local_compute.py +++ b/computing/misc/antyodaya_local_compute.py @@ -40,10 +40,13 @@ def _compute_antyodaya_for_panchayat(panchayat_gdf, antyodaya_gdf): + if antyodaya_gdf.empty: + return antyodaya_gdf + outer_boundary = panchayat_gdf.geometry.unary_union - # Precise intersection check - antyodaya_in_roi = antyodaya_gdf[antyodaya_gdf.intersects(outer_boundary)].copy() + # Clip Antyodaya geometries to the panchayat boundary + antyodaya_in_roi = gpd.clip(antyodaya_gdf, outer_boundary).copy() # Final cleanup antyodaya_in_roi = antyodaya_in_roi[~antyodaya_in_roi.geometry.is_empty] From 0b19b3d22c8951abf65206ca12b27428ea95ec0e Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 17:13:55 +0530 Subject: [PATCH 03/18] chnages for livestocks --- computing/misc/livestocks_local_compute.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/computing/misc/livestocks_local_compute.py b/computing/misc/livestocks_local_compute.py index 67120c27..afd9b4da 100644 --- a/computing/misc/livestocks_local_compute.py +++ b/computing/misc/livestocks_local_compute.py @@ -54,27 +54,21 @@ def _coerce_nullable_integer_columns(gdf): gdf[column] = gdf[column].astype("Int64") return gdf -def _compute_livestocks_for_watersheds(watersheds_gdf, livestocks_gdf): - """ - Spatially filters Livestock features with watershed/ROI boundaries. - """ +def _compute_livestocks_for_watersheds(panchayat_gdf, livestocks_gdf): if livestocks_gdf.empty: return livestocks_gdf - - if watersheds_gdf.crs and livestocks_gdf.crs and watersheds_gdf.crs != livestocks_gdf.crs: - livestocks_gdf = livestocks_gdf.to_crs(watersheds_gdf.crs) - outer_boundary = watersheds_gdf.geometry.unary_union + outer_boundary = panchayat_gdf.geometry.unary_union - # Precise intersection check - livestocks_in_roi = livestocks_gdf[livestocks_gdf.intersects(outer_boundary)].copy() + # Clip Antyodaya geometries to the panchayat boundary + livestocks_in_roi = gpd.clip(livestocks_gdf, outer_boundary).copy() - # Final cleanup + livestocks_in_roi = livestocks_gdf[livestocks_gdf.intersects(outer_boundary)].copy() livestocks_in_roi = livestocks_in_roi[~livestocks_in_roi.geometry.is_empty] livestocks_in_roi = livestocks_in_roi[livestocks_in_roi.geometry.is_valid] livestocks_in_roi = livestocks_in_roi[livestocks_in_roi.geometry.notna()] - return _coerce_nullable_integer_columns(livestocks_in_roi) + return livestocks_in_roi @app.task(bind=True) From bee525bbd6e4268804799cf7e98ab9313dda224d Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 17:24:01 +0530 Subject: [PATCH 04/18] chnages for livestocks --- computing/misc/livestocks_local_compute.py | 48 ++++------------------ 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/computing/misc/livestocks_local_compute.py b/computing/misc/livestocks_local_compute.py index afd9b4da..0518c4f0 100644 --- a/computing/misc/livestocks_local_compute.py +++ b/computing/misc/livestocks_local_compute.py @@ -11,7 +11,7 @@ from computing.local_compute_helper import ( PROJECT_ROOT, build_output_vector_path, - load_precomputed_watersheds, + load_precomputed_panchayat, read_validated_vector_file, write_vector_output, validate_geometry, @@ -23,38 +23,7 @@ GEOSERVER_WORKSPACE = "livestocks" -INTEGER_COLUMNS = ( - "pc11_village_id", - "pc11_state_id", - "pc11_district_id", - "pc11_subdistrict_id", - "cattle_male", - "cattle_female", - "cattle_total", - "buffalo_male", - "buffalo_female", - "buffalo_total", - "sheep_male", - "sheep_female", - "sheep_total", - "goat_male", - "goat_female", - "goat_total", - "pig_male", - "pig_female", - "pig_total", -) - -def _coerce_nullable_integer_columns(gdf): - """ - Ensure the livestock columns are the correct integer types. - """ - for column in INTEGER_COLUMNS: - if column in gdf.columns: - gdf[column] = gdf[column].astype("Int64") - return gdf - -def _compute_livestocks_for_watersheds(panchayat_gdf, livestocks_gdf): +def _compute_livestocks_for_panchayat(panchayat_gdf, livestocks_gdf): if livestocks_gdf.empty: return livestocks_gdf @@ -86,33 +55,32 @@ def generate_livestocks_data_local( ): if state and district and block: layer_name = f"livestocks_{valid_gee_text(district.lower())}_{valid_gee_text(block.lower())}" - watersheds_gdf, watershed_source = load_precomputed_watersheds( + panchayat_gdf, watershed_source = load_precomputed_panchayat( state=state, district=district, block=block, precomputed_roi_dir=precomputed_roi_dir, ) - print(f"Watershed boundary source: {watershed_source}") else: if not roi_path or not asset_suffix: raise ValueError("ROI path and asset_suffix are required for custom runs.") layer_name = f"livestocks_{valid_gee_text(asset_suffix).lower()}" - watersheds_gdf = read_validated_vector_file(roi_path, f"Invalid ROI file: {roi_path}") + panchayat_gdf = read_validated_vector_file(roi_path, f"Invalid ROI file: {roi_path}") print(f"ROI source: {roi_path}") if not os.path.exists(PAN_INDIA_LIVESTOCKS): raise FileNotFoundError(f"PAN INDIA Livestocks file not found at {PAN_INDIA_LIVESTOCKS}") print("Loading Livestocks data overlapping ROI...") - livestocks_gdf = gpd.read_file(PAN_INDIA_LIVESTOCKS, mask=watersheds_gdf) + livestocks_gdf = gpd.read_file(PAN_INDIA_LIVESTOCKS, mask=panchayat_gdf) livestocks_gdf = validate_geometry(livestocks_gdf) if livestocks_gdf.empty: print("Warning: PAN INDIA Livestocks file has no valid geometries overlapping ROI") else: print(f"Loaded {len(livestocks_gdf)} Livestock features") - result_gdf = _compute_livestocks_for_watersheds( - watersheds_gdf=watersheds_gdf, + result_gdf = _compute_livestocks_for_panchayat( + panchayat_gdf=panchayat_gdf, livestocks_gdf=livestocks_gdf, ) print(f"Final valid Livestock features after spatial filter: {len(result_gdf)}") @@ -152,7 +120,7 @@ def generate_livestocks_data_local( block=block, layer_name=layer_name, asset_id=asset_id, - dataset_name="Livestock Census", + dataset_name="Livestock Census 2019", misc={"is_generated_locally": True}, ) if layer_id: From 934e5772634a924f37fea4e43b110e4aabbe9d09 Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 17:28:00 +0530 Subject: [PATCH 05/18] chnages for livestocks --- computing/misc/livestocks_local_compute.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/computing/misc/livestocks_local_compute.py b/computing/misc/livestocks_local_compute.py index 0518c4f0..cc62f768 100644 --- a/computing/misc/livestocks_local_compute.py +++ b/computing/misc/livestocks_local_compute.py @@ -31,8 +31,6 @@ def _compute_livestocks_for_panchayat(panchayat_gdf, livestocks_gdf): # Clip Antyodaya geometries to the panchayat boundary livestocks_in_roi = gpd.clip(livestocks_gdf, outer_boundary).copy() - - livestocks_in_roi = livestocks_gdf[livestocks_gdf.intersects(outer_boundary)].copy() livestocks_in_roi = livestocks_in_roi[~livestocks_in_roi.geometry.is_empty] livestocks_in_roi = livestocks_in_roi[livestocks_in_roi.geometry.is_valid] livestocks_in_roi = livestocks_in_roi[livestocks_in_roi.geometry.notna()] From 37954fcf933c9eb83aa0bf13bb9c3067388691aa Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 17:32:47 +0530 Subject: [PATCH 06/18] chnages for livestocks --- computing/misc/livestocks_local_compute.py | 33 +++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/computing/misc/livestocks_local_compute.py b/computing/misc/livestocks_local_compute.py index cc62f768..c14e8660 100644 --- a/computing/misc/livestocks_local_compute.py +++ b/computing/misc/livestocks_local_compute.py @@ -23,6 +23,37 @@ GEOSERVER_WORKSPACE = "livestocks" +INTEGER_COLUMNS = ( + "pc11_village_id", + "pc11_state_id", + "pc11_district_id", + "pc11_subdistrict_id", + "cattle_male", + "cattle_female", + "cattle_total", + "buffalo_male", + "buffalo_female", + "buffalo_total", + "sheep_male", + "sheep_female", + "sheep_total", + "goat_male", + "goat_female", + "goat_total", + "pig_male", + "pig_female", + "pig_total", +) + +def _coerce_nullable_integer_columns(gdf): + """ + Ensure the livestock columns are the correct integer types. + """ + for column in INTEGER_COLUMNS: + if column in gdf.columns: + gdf[column] = gdf[column].astype("Int64") + return gdf + def _compute_livestocks_for_panchayat(panchayat_gdf, livestocks_gdf): if livestocks_gdf.empty: return livestocks_gdf @@ -35,7 +66,7 @@ def _compute_livestocks_for_panchayat(panchayat_gdf, livestocks_gdf): livestocks_in_roi = livestocks_in_roi[livestocks_in_roi.geometry.is_valid] livestocks_in_roi = livestocks_in_roi[livestocks_in_roi.geometry.notna()] - return livestocks_in_roi + return _coerce_nullable_integer_columns(livestocks_in_roi) @app.task(bind=True) From 059bb6b547974800fa41741d14cd33006f145400 Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 18:47:52 +0530 Subject: [PATCH 07/18] chnages for livestocks --- computing/misc/drainage_density_local_compute.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/computing/misc/drainage_density_local_compute.py b/computing/misc/drainage_density_local_compute.py index 3591194b..3bf8e5d5 100644 --- a/computing/misc/drainage_density_local_compute.py +++ b/computing/misc/drainage_density_local_compute.py @@ -14,6 +14,7 @@ load_precomputed_watersheds, read_validated_vector_file, write_vector_output, + validate_geometry, ) from computing.config_loader import ( @@ -40,9 +41,6 @@ def _load_drainage_lines_for_roi(watersheds_gdf): - bounds = watersheds_gdf.geometry.total_bounds - bbox_geom = box(*bounds) - print(f"Loading drainage lines from: {PAN_INDIA_DRAINAGE_LINES_GPKG_PATH}") if not os.path.exists(PAN_INDIA_DRAINAGE_LINES_GPKG_PATH): # Fallback to checking common locations if the exact path is missing @@ -50,8 +48,9 @@ def _load_drainage_lines_for_roi(watersheds_gdf): f"Warning: {PAN_INDIA_DRAINAGE_LINES_GPKG_PATH} not found. Drainage density calculation will fail." ) - lines_gdf = gpd.read_file(PAN_INDIA_DRAINAGE_LINES_GPKG_PATH, bbox=bbox_geom) - print(f"Loaded {len(lines_gdf)} drainage line features within bounding box") + lines_gdf = gpd.read_file(PAN_INDIA_DRAINAGE_LINES_GPKG_PATH, mask=watersheds_gdf) + lines_gdf = validate_geometry(lines_gdf) + print(f"Loaded {len(lines_gdf)} drainage line features within ROI mask") return lines_gdf @@ -67,7 +66,12 @@ def _compute_drainage_density(watersheds_gdf, drainage_lines_gdf): for index, watershed in watersheds_gdf.iterrows(): # Clip drainage lines to this watershed boundary - clipped_lines = gpd.clip(drainage_lines_gdf, watershed.geometry) + clipped_lines = gpd.clip(drainage_lines_gdf, watershed.geometry).copy() + + # Final cleanup + clipped_lines = clipped_lines[~clipped_lines.geometry.is_empty] + clipped_lines = clipped_lines[clipped_lines.geometry.is_valid] + clipped_lines = clipped_lines[clipped_lines.geometry.notna()] # Area in km² (area_in_ha / 100) area_km2 = watershed["area_in_ha"] / 100 From 41426d48a2ecd9c36033439cd268d7ad6d13b001 Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 18:58:09 +0530 Subject: [PATCH 08/18] chnages for livestocks --- .../misc/drainage_density_local_compute.py | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/computing/misc/drainage_density_local_compute.py b/computing/misc/drainage_density_local_compute.py index 3bf8e5d5..a94275cd 100644 --- a/computing/misc/drainage_density_local_compute.py +++ b/computing/misc/drainage_density_local_compute.py @@ -59,10 +59,27 @@ def _compute_drainage_density(watersheds_gdf, drainage_lines_gdf): Core calculation logic for Drainage Density. Matches the GEE version's methodology. """ - # Reproject to metric CRS for accurate length/area calculation - # (7755 is India-specific metric projection) - drainage_lines_gdf = drainage_lines_gdf.to_crs(crs=7755) - watersheds_gdf = watersheds_gdf.to_crs(crs=7755) + if drainage_lines_gdf.empty: + # Initialize columns even if no drainage lines + watersheds_gdf["drainage_density_std"] = 0.0 + watersheds_gdf["drainage_density_weighted"] = 0.0 + watersheds_gdf["drainage_density_stream"] = str([0.0]*11) + watersheds_gdf["stream_length_km"] = str([0.0]*11) + return watersheds_gdf + + # Clip to the outer boundary of watersheds_gdf + outer_boundary = watersheds_gdf.geometry.unary_union + drainage_lines_gdf = gpd.clip(drainage_lines_gdf, outer_boundary).copy() + + # Final cleanup of the global clip + drainage_lines_gdf = drainage_lines_gdf[~drainage_lines_gdf.geometry.is_empty] + drainage_lines_gdf = drainage_lines_gdf[drainage_lines_gdf.geometry.is_valid] + drainage_lines_gdf = drainage_lines_gdf[drainage_lines_gdf.geometry.notna()] + + # # Reproject to metric CRS for accurate length/area calculation + # # (7755 is India-specific metric projection) + # drainage_lines_gdf = drainage_lines_gdf.to_crs(crs=7755) + # watersheds_gdf = watersheds_gdf.to_crs(crs=7755) for index, watershed in watersheds_gdf.iterrows(): # Clip drainage lines to this watershed boundary From ac1eb6e1f94e64de9419206f11d8793a307c03dd Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 19:08:00 +0530 Subject: [PATCH 09/18] chnages for livestocks --- computing/misc/drainage_density_local_compute.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/computing/misc/drainage_density_local_compute.py b/computing/misc/drainage_density_local_compute.py index a94275cd..f01c3c25 100644 --- a/computing/misc/drainage_density_local_compute.py +++ b/computing/misc/drainage_density_local_compute.py @@ -76,10 +76,6 @@ def _compute_drainage_density(watersheds_gdf, drainage_lines_gdf): drainage_lines_gdf = drainage_lines_gdf[drainage_lines_gdf.geometry.is_valid] drainage_lines_gdf = drainage_lines_gdf[drainage_lines_gdf.geometry.notna()] - # # Reproject to metric CRS for accurate length/area calculation - # # (7755 is India-specific metric projection) - # drainage_lines_gdf = drainage_lines_gdf.to_crs(crs=7755) - # watersheds_gdf = watersheds_gdf.to_crs(crs=7755) for index, watershed in watersheds_gdf.iterrows(): # Clip drainage lines to this watershed boundary From 8fb03f6674898bef6f715aed47ac4989313a3b1b Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 20:49:07 +0530 Subject: [PATCH 10/18] chnages for livestocks --- computing/misc/facilities_proximity_local_compute.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/computing/misc/facilities_proximity_local_compute.py b/computing/misc/facilities_proximity_local_compute.py index 9f28eb6a..20a0efc4 100644 --- a/computing/misc/facilities_proximity_local_compute.py +++ b/computing/misc/facilities_proximity_local_compute.py @@ -26,21 +26,13 @@ def _compute_proximity_for_panchayat(panchayat_gdf, facilities_gdf): - """ - Filters facilities to strictly those intersecting the panchayat boundaries, - without altering/clipping their geometries. - """ if facilities_gdf.empty: return facilities_gdf - # Ensure CRS matches - if panchayat_gdf.crs and facilities_gdf.crs and panchayat_gdf.crs != facilities_gdf.crs: - facilities_gdf = facilities_gdf.to_crs(panchayat_gdf.crs) - outer_boundary = panchayat_gdf.geometry.unary_union # Keep facilities that intersect the boundary, geometries unchanged - facilities_in_roi = facilities_gdf[facilities_gdf.intersects(outer_boundary)].copy() + facilities_in_roi = gpd.clip(facilities_gdf, outer_boundary).copy() # Final cleanup facilities_in_roi = facilities_in_roi[~facilities_in_roi.geometry.is_empty] @@ -64,7 +56,7 @@ def generate_facilities_proximity_local( sync_layer_metadata=True, ): if state and district and block: - layer_name = f"facilities_{valid_gee_text(district.lower())}_{valid_gee_text(block.lower())}" + layer_name = f"facilities_12_{valid_gee_text(district.lower())}_{valid_gee_text(block.lower())}" panchayat_gdf, panchayat_source = load_precomputed_panchayat( state=state, district=district, From 19aaf9812a09044927393c21033b18f40405de39 Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 22:14:46 +0530 Subject: [PATCH 11/18] chnages for livestocks --- computing/misc/facilities_proximity_local_compute.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/computing/misc/facilities_proximity_local_compute.py b/computing/misc/facilities_proximity_local_compute.py index 20a0efc4..68e24a56 100644 --- a/computing/misc/facilities_proximity_local_compute.py +++ b/computing/misc/facilities_proximity_local_compute.py @@ -39,6 +39,17 @@ def _compute_proximity_for_panchayat(panchayat_gdf, facilities_gdf): facilities_in_roi = facilities_in_roi[facilities_in_roi.geometry.is_valid] facilities_in_roi = facilities_in_roi[facilities_in_roi.geometry.notna()] + # Rename NAME to censusname + if "NAME" in facilities_in_roi.columns: + facilities_in_roi = facilities_in_roi.rename(columns={"NAME": "censusname"}) + + # Add state, district, tehsil from panchayat_gdf + for col in ["state", "district", "tehsil"]: + if col in panchayat_gdf.columns: + # Assign the value for the tehsil (taking the first valid row) + first_val = panchayat_gdf[col].dropna().iloc[0] if not panchayat_gdf[col].dropna().empty else None + facilities_in_roi[col] = first_val + return facilities_in_roi From a1714a0a5a0e813389214433e43e6a67ce601d8f Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 22:37:07 +0530 Subject: [PATCH 12/18] chnages for livestocks --- computing/misc/facilities_proximity_local_compute.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/computing/misc/facilities_proximity_local_compute.py b/computing/misc/facilities_proximity_local_compute.py index 68e24a56..7cd4225d 100644 --- a/computing/misc/facilities_proximity_local_compute.py +++ b/computing/misc/facilities_proximity_local_compute.py @@ -67,7 +67,7 @@ def generate_facilities_proximity_local( sync_layer_metadata=True, ): if state and district and block: - layer_name = f"facilities_12_{valid_gee_text(district.lower())}_{valid_gee_text(block.lower())}" + layer_name = f"facilities_{valid_gee_text(district.lower())}_{valid_gee_text(block.lower())}" panchayat_gdf, panchayat_source = load_precomputed_panchayat( state=state, district=district, From 633c17696da2515c4f80a752b25cfcdd778768ab Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 22:49:25 +0530 Subject: [PATCH 13/18] chnages for livestocks --- .../mws/mws_connectivity_local_compute.py | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/computing/mws/mws_connectivity_local_compute.py b/computing/mws/mws_connectivity_local_compute.py index e1765896..5c94d0a3 100644 --- a/computing/mws/mws_connectivity_local_compute.py +++ b/computing/mws/mws_connectivity_local_compute.py @@ -32,23 +32,15 @@ def _compute_mws_connectivity_for_watersheds(watersheds_gdf, mws_gdf): - mws_in_roi = mws_gdf.copy() - - if mws_in_roi.empty: + if mws_gdf.empty: print("No MWS connectivity found within the outer boundary.") - return mws_in_roi - - print(f"MWS connectivity within outer boundary: {len(mws_in_roi)}") + return mws_gdf - # Step 2: Spatial join to clip results to individual watersheds - mws_in_roi = gpd.sjoin( - mws_in_roi, - watersheds_gdf[["geometry"]], # no uid, no collision - how="inner", - predicate="intersects", - ).drop(columns=["index_right"], errors="ignore") + # Step 1: Clip to the outer boundary of watersheds + outer_boundary = watersheds_gdf.geometry.unary_union + mws_in_roi = gpd.clip(mws_gdf, outer_boundary).copy() - # Step 3: Drop empty/invalid geometries + # Step 2: Drop empty/invalid geometries mws_in_roi = fix_invalid_geometry_in_gdf(mws_in_roi) mws_in_roi = mws_in_roi[ mws_in_roi.geometry.notna() From 5ad1d947c876ef323eeca862ff09cc929ffad182 Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 22:50:34 +0530 Subject: [PATCH 14/18] chnages for livestocks --- computing/mws/mws_connectivity_local_compute.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/computing/mws/mws_connectivity_local_compute.py b/computing/mws/mws_connectivity_local_compute.py index 5c94d0a3..4407eaa9 100644 --- a/computing/mws/mws_connectivity_local_compute.py +++ b/computing/mws/mws_connectivity_local_compute.py @@ -68,7 +68,7 @@ def mws_connectivity_vector( sync_layer_metadata=True, ): if state and district and block: - layer_name = f"{valid_gee_text(district.lower())}_{valid_gee_text(block.lower())}_mws_connectivity" + layer_name = f"{valid_gee_text(district.lower())}_{valid_gee_text(block.lower())}_12_mws_connectivity" watersheds_gdf, watershed_source = load_precomputed_watersheds( state=state, district=district, From 8aa62fd4782716d7cfbb38ed734eda64d85202ab Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 22:57:10 +0530 Subject: [PATCH 15/18] chnages for livestocks --- computing/config_loader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/computing/config_loader.py b/computing/config_loader.py index 41df82d9..ca131f04 100644 --- a/computing/config_loader.py +++ b/computing/config_loader.py @@ -149,7 +149,7 @@ def _output_entry(module: str, index: int = 0) -> dict: PAN_INDIA_SLOPE_PERCENTAGE_PATH = PROJECT_ROOT / "data/base_layers/Pan_India_slope_percentage.tif" LOCAL_SLOPE_PERCENTAGE_OUTPUT = PROJECT_ROOT / "data/layers/slope_percentage" -PAN_INDIA_MWS_CONNECTIVITY_PATH = PROJECT_ROOT / "data/layers/mws_connectivity/Pan_India_mws_connectivity.geojson" +PAN_INDIA_MWS_CONNECTIVITY_PATH = PROJECT_ROOT / "data/base_layers/Pan_India_mws_connectivity.geojson" LOCAL_MWS_CONNECTIVITY_OUTPUT = PROJECT_ROOT / "data/layers/mws_connectivity/mws_connectivity_local" LOCAL_MWS_CENTROID_OUTPUT = PROJECT_ROOT / "data/layers/mws_centroid" From ed7886281ccec6b792410453c6628a318fd0d578 Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 22:59:30 +0530 Subject: [PATCH 16/18] chnages for livestocks --- computing/config_loader.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/computing/config_loader.py b/computing/config_loader.py index ca131f04..813709b5 100644 --- a/computing/config_loader.py +++ b/computing/config_loader.py @@ -3,7 +3,8 @@ import yaml _CONFIG_PATH = Path(__file__).resolve().parent / "config.yaml" -PROJECT_ROOT = Path(__file__).resolve().parents[1] +# PROJECT_ROOT = Path(__file__).resolve().parents[1] +PROJECT_ROOT = Path("/home/cfpt-jedi/developer/repos/core-stack-backend") def _load(): From f43c9ff3c0fdea87680dc1aa6e3b3925950af584 Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sat, 20 Jun 2026 23:31:26 +0530 Subject: [PATCH 17/18] chnages for livestocks --- computing/mws/mws_connectivity_local_compute.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/computing/mws/mws_connectivity_local_compute.py b/computing/mws/mws_connectivity_local_compute.py index 4407eaa9..5c94d0a3 100644 --- a/computing/mws/mws_connectivity_local_compute.py +++ b/computing/mws/mws_connectivity_local_compute.py @@ -68,7 +68,7 @@ def mws_connectivity_vector( sync_layer_metadata=True, ): if state and district and block: - layer_name = f"{valid_gee_text(district.lower())}_{valid_gee_text(block.lower())}_12_mws_connectivity" + layer_name = f"{valid_gee_text(district.lower())}_{valid_gee_text(block.lower())}_mws_connectivity" watersheds_gdf, watershed_source = load_precomputed_watersheds( state=state, district=district, From edd39a0125759eb4c32c088b577a6041137fd755 Mon Sep 17 00:00:00 2001 From: "shiv.prakash1" Date: Sun, 21 Jun 2026 00:00:22 +0530 Subject: [PATCH 18/18] chnages for livestocks --- .../misc/drainage_density_local_compute.py | 39 ++++++------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/computing/misc/drainage_density_local_compute.py b/computing/misc/drainage_density_local_compute.py index f01c3c25..932bec86 100644 --- a/computing/misc/drainage_density_local_compute.py +++ b/computing/misc/drainage_density_local_compute.py @@ -14,7 +14,6 @@ load_precomputed_watersheds, read_validated_vector_file, write_vector_output, - validate_geometry, ) from computing.config_loader import ( @@ -41,6 +40,9 @@ def _load_drainage_lines_for_roi(watersheds_gdf): + bounds = watersheds_gdf.geometry.total_bounds + bbox_geom = box(*bounds) + print(f"Loading drainage lines from: {PAN_INDIA_DRAINAGE_LINES_GPKG_PATH}") if not os.path.exists(PAN_INDIA_DRAINAGE_LINES_GPKG_PATH): # Fallback to checking common locations if the exact path is missing @@ -48,9 +50,8 @@ def _load_drainage_lines_for_roi(watersheds_gdf): f"Warning: {PAN_INDIA_DRAINAGE_LINES_GPKG_PATH} not found. Drainage density calculation will fail." ) - lines_gdf = gpd.read_file(PAN_INDIA_DRAINAGE_LINES_GPKG_PATH, mask=watersheds_gdf) - lines_gdf = validate_geometry(lines_gdf) - print(f"Loaded {len(lines_gdf)} drainage line features within ROI mask") + lines_gdf = gpd.read_file(PAN_INDIA_DRAINAGE_LINES_GPKG_PATH, bbox=bbox_geom) + print(f"Loaded {len(lines_gdf)} drainage line features within bounding box") return lines_gdf @@ -59,32 +60,14 @@ def _compute_drainage_density(watersheds_gdf, drainage_lines_gdf): Core calculation logic for Drainage Density. Matches the GEE version's methodology. """ - if drainage_lines_gdf.empty: - # Initialize columns even if no drainage lines - watersheds_gdf["drainage_density_std"] = 0.0 - watersheds_gdf["drainage_density_weighted"] = 0.0 - watersheds_gdf["drainage_density_stream"] = str([0.0]*11) - watersheds_gdf["stream_length_km"] = str([0.0]*11) - return watersheds_gdf - - # Clip to the outer boundary of watersheds_gdf - outer_boundary = watersheds_gdf.geometry.unary_union - drainage_lines_gdf = gpd.clip(drainage_lines_gdf, outer_boundary).copy() - - # Final cleanup of the global clip - drainage_lines_gdf = drainage_lines_gdf[~drainage_lines_gdf.geometry.is_empty] - drainage_lines_gdf = drainage_lines_gdf[drainage_lines_gdf.geometry.is_valid] - drainage_lines_gdf = drainage_lines_gdf[drainage_lines_gdf.geometry.notna()] - + # Reproject to metric CRS for accurate length/area calculation + # (7755 is India-specific metric projection) + drainage_lines_gdf = drainage_lines_gdf.to_crs(crs=7755) + watersheds_gdf = watersheds_gdf.to_crs(crs=7755) for index, watershed in watersheds_gdf.iterrows(): # Clip drainage lines to this watershed boundary - clipped_lines = gpd.clip(drainage_lines_gdf, watershed.geometry).copy() - - # Final cleanup - clipped_lines = clipped_lines[~clipped_lines.geometry.is_empty] - clipped_lines = clipped_lines[clipped_lines.geometry.is_valid] - clipped_lines = clipped_lines[clipped_lines.geometry.notna()] + clipped_lines = gpd.clip(drainage_lines_gdf, watershed.geometry) # Area in km² (area_in_ha / 100) area_km2 = watershed["area_in_ha"] / 100 @@ -202,4 +185,4 @@ def drainage_density( update_layer_sync_status(layer_id=layer_id, sync_to_geoserver=True) print(f"Sync Data for layer_id: {layer_id}") - return True + return True \ No newline at end of file