Loading...
Loading...
Geospatial Analysis provides workflows for satellite imagery processing, GIS operations with GeoPandas, spatial statistics, and Earth observation data analysis.
npx skill4agent add itallstartedwithaidea/agent-skills geospatial-analysisgraph TD
A[Spatial Data Input] --> B{Data Type}
B -->|Raster| C[Satellite Imagery Processing]
B -->|Vector| D[GeoPandas Operations]
C --> E[Band Math + Indices: NDVI, NDWI]
E --> F[Classification / Change Detection]
D --> G[Spatial Joins + Overlay]
G --> H[Spatial Statistics]
F --> I[Raster-Vector Integration]
H --> I
I --> J[Cartographic Output]
J --> K[Publication Map]import geopandas as gpd
import rasterio
from rasterio.mask import mask
from shapely.geometry import Point
import numpy as np
from pysal.explore import esda
from pysal.lib import weights
import matplotlib.pyplot as plt
import contextily as cx
def load_and_reproject(filepath: str, target_crs: str = "EPSG:4326") -> gpd.GeoDataFrame:
gdf = gpd.read_file(filepath)
return gdf.to_crs(target_crs)
def spatial_join_points_to_polygons(
points: gpd.GeoDataFrame, polygons: gpd.GeoDataFrame
) -> gpd.GeoDataFrame:
assert points.crs == polygons.crs, "CRS mismatch: reproject before joining"
return gpd.sjoin(points, polygons, how="inner", predicate="within")
def compute_ndvi(nir_path: str, red_path: str) -> np.ndarray:
with rasterio.open(nir_path) as nir_src, rasterio.open(red_path) as red_src:
nir = nir_src.read(1).astype(np.float32)
red = red_src.read(1).astype(np.float32)
ndvi = np.where((nir + red) > 0, (nir - red) / (nir + red), 0)
return ndvi
def spatial_autocorrelation(gdf: gpd.GeoDataFrame, column: str) -> dict:
w = weights.Queen.from_dataframe(gdf)
w.transform = "r"
moran = esda.Moran(gdf[column], w)
return {
"morans_i": moran.I,
"p_value": moran.p_sim,
"z_score": moran.z_sim,
"significant": moran.p_sim < 0.05,
"interpretation": "Clustered" if moran.I > 0 and moran.p_sim < 0.05 else
"Dispersed" if moran.I < 0 and moran.p_sim < 0.05 else
"Random",
}
def publication_map(gdf: gpd.GeoDataFrame, column: str, title: str, output: str):
fig, ax = plt.subplots(1, 1, figsize=(10, 8))
gdf.plot(column=column, ax=ax, legend=True, cmap="YlOrRd", edgecolor="0.5", linewidth=0.3)
cx.add_basemap(ax, crs=gdf.crs.to_string(), source=cx.providers.CartoDB.Positron)
ax.set_title(title, fontsize=14, fontweight="bold")
ax.set_axis_off()
fig.tight_layout()
fig.savefig(output, dpi=300, bbox_inches="tight")
plt.close(fig)| Platform | Support | Notes |
|---|---|---|
| Cursor | Full | Python + geospatial libs |
| VS Code | Full | Jupyter + map rendering |
| Windsurf | Full | Scientific Python |
| Claude Code | Full | Pipeline generation |
| Cline | Full | GIS workflows |
| aider | Partial | Code generation only |
geospatialgeopandassatellite-imageryndvispatial-statisticsgisrasteriocartographyearth-observation