Skip to content
Back to skills

Geojson Mapbox Spatial Analysis

ASecurity

Perform in-browser spatial analysis, GeoJSON feature processing, Turf.js geometric computations (buffers, convex hulls, Voronoi polygons, centroids), and Mapbox GL JS / MapLibre vector tile styling. Trigger when rendering interactive map layers, visualizing spatial datasets, or computing client-side geographic boundaries.

  • 8 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 29, 2026
ai-agentstypescriptgoexpressgitperformance

Works with

  • cli

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add hamzabellouch/agent-skills --skill geojson-mapbox-spatial-analysis --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Geojson Mapbox Spatial Analysis?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Geojson Mapbox Spatial Analysis
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/hamzabellouch-geojson-mapbox-spatial-analysis/badge)](https://www.skillsdirectory.com/skills/hamzabellouch-geojson-mapbox-spatial-analysis)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: geojson-mapbox-spatial-analysis
metadata:
  category: Geospatial and GIS Engineering
description: Perform in-browser spatial analysis, GeoJSON feature processing, Turf.js geometric computations (buffers, convex hulls, Voronoi polygons, centroids), and Mapbox GL JS / MapLibre vector tile styling. Trigger when rendering interactive map layers, visualizing spatial datasets, or computing client-side geographic boundaries.
compatibility: Mapbox GL JS v2+, MapLibre GL v3+, Turf.js v7+, GeoJSON RFC 7946
---

# GeoJSON & Mapbox Spatial Analysis Skill Guide

This skill governs client-side geospatial data manipulation, vector tile rendering, and spatial geometric algorithms using Turf.js and Mapbox GL / MapLibre.

---

## 1. GeoJSON Client Pipeline

```text
[ Raw GeoJSON FeatureCollection ] (RFC 7946)
             |
             v
[ Turf.js Geospatial Processing Engine ]
  |-- Calculate Centroids & Bounding Boxes
  |-- Generate Buffer Zones (e.g. 500m catchment)
  |-- Convex Hull / Voronoi Tessellation
             |
             v
[ Mapbox GL / MapLibre Vector Renderer ]
  |-- Add Source: type: 'geojson', cluster: true
  |-- Choropleth Fill Layer with Data-Driven Expressions
  |-- Symbol & Cluster Count Overlays
```

---

## 2. Production Implementation Patterns

### A. Client-Side Spatial Analysis with Turf.js (TypeScript)

```typescript
import * as turf from "@turf/turf";
import type { FeatureCollection, Point, Polygon } from "geojson";

export interface SpatialCoverageResult {
  hull: turf.Feature<Polygon>;
  centroid: turf.Feature<Point>;
  bufferedAreaKm2: number;
}

/**
 * Calculates spatial catchment area and convex hull around a cluster of store points.
 */
export function analyzeClusterCoverage(points: FeatureCollection<Point>, bufferRadiusKm: number = 2.0): SpatialCoverageResult {
  if (!points.features || points.features.length === 0) {
    throw new Error("Cannot analyze empty feature collection");
  }

  // 1. Calculate geographic centroid
  const centroid = turf.centroid(points);

  // 2. Compute minimum bounding convex hull
  const hull = turf.convex(points);
  if (!hull) {
    throw new Error("At least 3 non-collinear points required for convex hull");
  }

  // 3. Generate buffer around all points and dissolve into single polygon
  const buffered = turf.buffer(points, bufferRadiusKm, { units: "kilometers" });
  const dissolved = turf.dissolve(buffered);

  // 4. Calculate total square kilometer area
  const areaM2 = turf.area(dissolved);
  const bufferedAreaKm2 = areaM2 / 1_000_000;

  return {
    hull,
    centroid,
    bufferedAreaKm2,
  };
}
```

### B. High-Performance Mapbox Layer & Clustering Setup

```typescript
import mapboxgl from "mapbox-gl";

export function initializeClusteredMap(map: mapboxgl.Map, geojsonUrl: string) {
  map.on("load", () => {
    // 1. Add clustered GeoJSON source
    map.addSource("incidents", {
      type: "geojson",
      data: geojsonUrl,
      cluster: true,
      clusterMaxZoom: 14, // Max zoom to cluster points on
      clusterRadius: 50,  // Radius of each cluster when clustering points (pixels)
    });

    // 2. Clustered Circle Layer with Data Expressions
    map.addLayer({
      id: "clusters",
      type: "circle",
      source: "incidents",
      filter: ["has", "point_count"],
      paint: {
        "circle-color": [
          "step",
          ["get", "point_count"],
          "#51bbd6", 20,
          "#f1f075", 100,
          "#f28cb1"
        ],
        "circle-radius": [
          "step",
          ["get", "point_count"],
          18, 20,
          24, 100,
          32
        ],
      },
    });

    // 3. Cluster Count Label Layer
    map.addLayer({
      id: "cluster-count",
      type: "symbol",
      source: "incidents",
      filter: ["has", "point_count"],
      layout: {
        "text-field": "{point_count_abbreviated}",
        "text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
        "text-size": 12,
      },
    });

    // 4. Unclustered Individual Point Layer
    map.addLayer({
      id: "unclustered-point",
      type: "circle",
      source: "incidents",
      filter: ["!", ["has", "point_count"]],
      paint: {
        "circle-color": "#11b4da",
        "circle-radius": 6,
        "circle-stroke-width": 1,
        "circle-stroke-color": "#fff",
      },
    });
  });
}
```

---

## 3. Best Practices & Optimization

1. **RFC 7946 Standard Coordinate Order:** Always enforce `[longitude, latitude]` order. Never invert to `[latitude, longitude]`.
2. **GeoJSON Simplification:** When transmitting large polygon boundaries to the browser, apply Douglas-Peucker simplification (`turf.simplify`) with tolerance thresholds to reduce payload size by up to 80%.
3. **Avoid Re-Adding Sources:** Update data in place using `source.setData(newGeoJson)` rather than calling `map.removeSource` and `map.addSource`.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…