Skip to main content
Glama

getis_ord_g

Identify statistically significant spatial clusters and hotspots in geographic data using the Getis-Ord G statistic for spatial pattern analysis.

Instructions

Compute Getis-Ord G for global hot spot analysis.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
shapefile_pathYes
dependent_varNoLAND_USE
target_crsNoEPSG:4326
distance_thresholdNo

Implementation Reference

  • The main handler function for the 'getis_ord_g' tool. It loads a shapefile, creates distance-based spatial weights, computes the global Getis-Ord G statistic using esda.G, handles islands, and returns G, p-value, z-score with data preview.
    @gis_mcp.tool()
    def getis_ord_g(
        shapefile_path: str,
        dependent_var: str = "LAND_USE",
        target_crs: str = "EPSG:4326",
        distance_threshold: float = 100000
    ) -> Dict[str, Any]:
        """Compute Getis-Ord G for global hot spot analysis."""
        try:
            # Clean backticks from string parameters
            shapefile_path = shapefile_path.replace("`", "")
            dependent_var = dependent_var.replace("`", "")
            target_crs = target_crs.replace("`", "")
    
            # Validate input file
            if not os.path.exists(shapefile_path):
                logger.error(f"Shapefile not found: {shapefile_path}")
                return {"status": "error", "message": f"Shapefile not found: {shapefile_path}"}
    
            # Load GeoDataFrame
            gdf = gpd.read_file(shapefile_path)
            
            # Validate dependent variable
            if dependent_var not in gdf.columns:
                logger.error(f"Dependent variable '{dependent_var}' not found in columns")
                return {"status": "error", "message": f"Dependent variable '{dependent_var}' not found in shapefile columns"}
    
            # Reproject to target CRS
            gdf = gdf.to_crs(target_crs)
    
            # Convert distance_threshold to degrees if using geographic CRS (e.g., EPSG:4326)
            effective_threshold = distance_threshold
            unit = "meters"
            if target_crs == "EPSG:4326":
                effective_threshold = distance_threshold / 111000
                unit = "degrees"
    
            # Extract dependent data
            dependent = gdf[dependent_var].values.astype(np.float64)
    
            # Create distance-based spatial weights matrix
            import libpysal
            import esda
            w = libpysal.weights.DistanceBand.from_dataframe(gdf, threshold=effective_threshold, binary=False)
            w.transform = 'r'
    
            # Handle islands
            for island in w.islands:
                w.weights[island] = [0] * len(w.weights[island])
                w.cardinalities[island] = 0
    
            # Getis-Ord G
            getis = esda.G(dependent, w)
    
            # Prepare GeoDataFrame preview
            preview = gdf[['geometry', dependent_var]].copy()
            preview['geometry'] = preview['geometry'].apply(lambda g: g.wkt)
            preview = preview.head(5).to_dict(orient="records")
    
            return {
                "status": "success",
                "message": f"Getis-Ord G analysis completed successfully (distance threshold: {effective_threshold} {unit})",
                "result": {
                    "shapefile_path": shapefile_path,
                    "getis_ord_g": {
                        "G": float(getis.G),
                        "p_value": float(getis.p_sim),
                        "z_score": float(getis.z_sim)
                    },
                    "data_preview": preview
                }
            }
        
        except Exception as e:
            logger.error(f"Error performing Getis-Ord G analysis: {str(e)}")
            return {"status": "error", "message": f"Failed to perform Getis-Ord G analysis: {str(e)}"}
  • GIS resource listing available PySAL/ESDA operations, including 'getis_ord_g'. This serves as a discovery mechanism for the tool.
    @gis_mcp.resource("gis://operations/esda")
    def get_spatial_operations() -> Dict[str, List[str]]:
        """List available spatial analysis operations. This is for esda library. They are using pysal library."""
        return {
            "operations": [
                "getis_ord_g",
                "morans_i",
                "gearys_c",
                "gamma_statistic",
                "moran_local",
                "getis_ord_g_local",
                "join_counts",
                "join_counts_local",
                "adbscan"
            ]
        }
  • Import of pysal_functions module in main.py, which triggers registration of all @gis_mcp.tool() decorators, including getis_ord_g.
    from . import (
        geopandas_functions,
        shapely_functions,
        rasterio_functions,
        pyproj_functions,
        pysal_functions,
    )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mahdin75/gis-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server