gis-mapping

SKILL.md

Required Plugins

Superpowers plugin: MUST be active for all work using this skill. Use throughout the entire build pipeline — design decisions, code generation, debugging, quality checks, and any task where it offers enhanced capabilities. If superpowers provides a better way to accomplish something, prefer it over the default approach.

Frontend Design plugin (webapp-gui-design): MUST be active for all visual output from this skill. Use for design system work, component styling, layout decisions, colour selection, typography, responsive design, and visual QA.

GIS Mapping (Leaflet-First)

Quick Summary

  • Leaflet-first mapping for web apps (default engine)
  • Optional OpenStreetMap tiles or other providers
  • Location selection (marker, polygon, rectangle) + map UI patterns
  • Geofencing enforcement with client + server validation (see geofencing.md)
  • Performance, clustering, and safe storage of spatial data

Capability Index (Leaflet-First)

Use this index to load only the section you need. Details live in skills/gis-mapping/references/leaflet-capabilities.md.

  1. Basic Mapping & Visualization (core Leaflet)
  2. Spatial Queries (Turf.js)
  3. Geocoding (Nominatim or Leaflet Control Geocoder)
  4. Buffering & Zone Analysis (Turf.js)
  5. Heatmaps & Density (leaflet.heat)
  6. Routing & Network Analysis (OSRM / GraphHopper + leaflet-routing-machine)
  7. Drawing & Editing (leaflet.draw / Geoman)
  8. Measurement Tools (leaflet-measure or custom)
  9. Clustering & Aggregation (leaflet.markercluster)
  10. Spatial Analysis (Turf.js)
  11. Time-Based Analysis (custom + heat)
  12. Export & Printing (html2canvas/jsPDF + GeoJSON export)

When to Use

  • You need interactive maps for customers, assets, farms, or delivery zones
  • Users must select or edit locations on a map
  • You must enforce geo-fencing or boundary validation
  • You need GIS data display with filters, legends, and clustering

Key Patterns

  • Leaflet is the default mapping engine.
  • Always include attribution for the chosen tile provider.
  • Capture geometry in GeoJSON and validate server-side.
  • Use bounding-box checks before deeper polygon math.
  • Cluster markers when data is large or dense.
  • Store optional tile provider API keys in system settings (e.g., osm_api_key) and load them at runtime.
  • Default to terrain tiles (OpenTopoMap) for administrative borders.

Leaflet Standardization (BIRDC)

  • Use a shared Leaflet configuration for tile URLs, attribution, and defaults.
  • Prefer a shared loader or include pattern so Leaflet CSS/JS is consistent across pages.
  • Use public/farmer-profile.php as the canonical Leaflet UI reference.

Stack Choices (Frontend)

  • Leaflet (default): Lightweight, fastest to implement, best for most apps.
  • OpenLayers (optional): Heavyweight GIS controls and projections.
  • MapLibre GL JS (optional): Vector tiles, smoother at scale.

Data Model & Storage

  • Point: latitude + longitude (DECIMAL(10,7))
  • Polygon/Boundary: Store as GeoJSON (TEXT/JSON)
  • Metadata: location_label, address, last_updated_at

Recommended formats:

  • GeoJSON for portability across JS + backend
  • WKT only if your DB tooling depends on it

Map Initialization (Leaflet)

<link
  rel="stylesheet"
  href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
const map = L.map("map").setView([0.3476, 32.5825], 12);
const osmApiKey = window.osmApiKey || "";
const osmTileUrl = osmApiKey
  ? `https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?api_key=${osmApiKey}`
  : "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";

const osm = L.tileLayer(osmTileUrl, {
  attribution: "© OpenStreetMap contributors",
  maxZoom: 19,
});

const terrain = L.tileLayer(
  "https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
  {
    attribution: "© OpenTopoMap",
    maxZoom: 17,
  },
);

terrain.addTo(map);

Location Selection Patterns

Marker (Point)

  • Single click adds/updates a marker
  • Store coordinates in hidden inputs
let marker;
map.on("click", (e) => {
  if (marker) map.removeLayer(marker);
  marker = L.marker(e.latlng).addTo(map);
  document.querySelector("#latitude").value = e.latlng.lat;
  document.querySelector("#longitude").value = e.latlng.lng;
});

Polygon / Rectangle (Area)

Use Leaflet Draw or Geoman. Store GeoJSON geometry.

const drawn = new L.FeatureGroup().addTo(map);
const drawControl = new L.Control.Draw({
  draw: { polygon: true, rectangle: true, marker: false, circle: false },
  edit: { featureGroup: drawn },
});
map.addControl(drawControl);

map.on("draw:created", (e) => {
  drawn.clearLayers();
  drawn.addLayer(e.layer);
  document.querySelector("#boundary_geojson").value = JSON.stringify(
    e.layer.toGeoJSON(),
  );
});

Geofencing (Overview)

Geofencing must be enforced at two levels:

  • UI constraint: prevent invalid selections in the browser
  • Server constraint: verify boundaries in backend validation

See geofencing.md for full patterns, point-in-polygon checks, and multi-geometry rules.

UI Patterns

  • Filters + stats in a side card, map in a large canvas
  • Legend to toggle categories (customer groups, territories)
  • Clustering when markers exceed ~200

Performance & UX

  • Debounce search and map redraw
  • Use marker clustering or server-side tiling
  • Lazy load heavy layers
  • Simplify large polygons for UI display

Backend Validation

Always validate coordinates server-side:

  • Ensure latitude is between -90 and 90
  • Ensure longitude is between -180 and 180
  • Enforce geofence boundaries with the same logic as UI
  • Load optional tile provider keys (for example osm_api_key) from system settings when building map pages

Privacy & Security

  • Location data is sensitive: protect with permissions
  • Never trust client-only validation
  • Avoid exposing private coordinates without authorization

Recommended Plugins

  • Leaflet Draw or Leaflet Geoman (drawing tools)
  • Leaflet MarkerCluster (performance)
  • Leaflet Control Geocoder (search)
  • Turf.js (geospatial analysis)

References

  • geofencing.md (sub-skill)
  • references/leaflet-capabilities.md
  • references/leaflet-arcgis-equivalents.md (index)
Weekly Installs
20
GitHub Stars
3
First Seen
Feb 18, 2026
Installed on
opencode20
gemini-cli20
github-copilot20
codex20
kimi-cli20
amp20