openlayers Β· diff

git:20260905.8bfedb9 to git:20260905.0cee6ed

117 added, 118 removed. Audit A to B.

---
name: openlayers
description: >-
Expert coding skill for building enterprise-grade, high-performance web maps with
OpenLayers. USE WHEN the user wants to create a map, render raster tile layers
(MapTiler Streets, Satellite, Outdoor, Topo, Dataviz), display GeoJSON, KML, or GPX data,
build GIS and spatial analysis tools, add geometry drawing or editing tools
(ol/interaction/Draw, Modify, Snap), create point clustering or heatmaps, handle
reprojection and custom CRS (EPSG:4326, EPSG:3857, Swiss LV95, British National Grid via proj4),
integrate Cloud-Optimized GeoTIFFs (COG), enterprise OGC services (WMS, WMTS, WFS),
integrate maps in React, Next.js, Vue, or Svelte, or build an interactive web GIS app.
Also USE WHEN the user mentions OpenLayers, ol/Map, ol/View, ol/layer, ol/source, or ol/interaction.
license: MIT
metadata:
author: mapsnippets
homepage: https://mapsnippets.org/
---
# OpenLayers β€” Agent Skill πŸŒπŸ—ΊοΈ
> The authoritative AI coding standard for building modular, high-performance web mapping applications with **OpenLayers** and modern raster tile services.
Maintained by **[MapSnippets](https://mapsnippets.org/)** β€” Open-source geospatial snippets, guides, and agent tools.
---
- ## ⚑ Architectural Scope & Data Reference Invariants
+ ## ⚑ Architectural Scope & Design Principles
* **Native Library Focus:** This skill focuses strictly on pure, native **OpenLayers** (`ol/Map`, `ol/View`, `ol/layer/Tile`, `ol/source/XYZ`, `ol/layer/Vector`, `ol/source/Vector`, `ol/proj`, `ol/interaction/*`). All generated code must use modular ES imports from the `ol` package.
* **MapTiler as Data Source:** MapTiler Cloud provides high-DPI raster XYZ tiles (512px @2x), geocoding, elevation, and static maps.
* **Strictly Raster Basemaps:** OpenLayers maps in this skill use **native high-DPI raster basemaps (`ol/layer/Tile` + `ol/source/XYZ`)** paired with rich client-side vector data layers (`ol/layer/Vector` + `ol/source/Vector` for GeoJSON, KML, GPX, digitization, clustering, and spatial analysis). For client-side vector tiles with MapLibre style JSON, use MapLibre GL JS instead.
+ * **Architecture-First Reliability:** OpenLayers is a modular GIS framework with built-in CAD interactions and strict projection transformations. Following lifecycle and projection contracts guarantees rock-solid execution.
---
- ## ⚑ Critical Invariants & Rules
+ ## πŸ“ Core Structural Design Contracts
- Follow these rules on every OpenLayers code generation to prevent bugs:
+ ### 1. Universal Map Lifecycle & Projection Contract
+ Every OpenLayers implementation must fulfill these four lifecycle rules:
- ### 1. πŸ“¦ Strict Modular ES Imports (No Global `ol.*`)
- * **Never use legacy `new ol.Map(...)` global objects.**
- * **Always use modular ES imports**:
- ```javascript
- import Map from "ol/Map.js";
- import View from "ol/View.js";
- import TileLayer from "ol/layer/Tile.js";
- import XYZ from "ol/source/XYZ.js";
- import { fromLonLat, toLonLat } from "ol/proj.js";
- import "ol/ol.css"; // Mandatory CSS import
- ```
+ ```html
+ <!-- 1. Mandatory CSS Container Contract -->
+ <style>
+ body { margin: 0; padding: 0; }
+ #map { width: 100%; height: 100vh; position: relative; }
+ </style>
+ <div id="map"></div>
- ### 2. 🌍 Projection Conversion Rule (`fromLonLat`)
- * OpenLayers views use **`EPSG:3857` (Spherical Mercator in meters)** by default.
- * GPS and GeoJSON coordinates use **`EPSG:4326` `[longitude, latitude]`**.
- * **Rule:** Always wrap coordinates in `fromLonLat([lng, lat])` when setting map center, adding markers, or panning:
- ```javascript
- const prague = fromLonLat([14.4378, 50.0755]); // [lng, lat] -> [x, y] in meters
- view.setCenter(prague);
- ```
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v10.10.0/ol.css" />
+ <script src="https://cdn.jsdelivr.net/npm/ol@v10.10.0/dist/ol.js"></script>
- ### 3. πŸ–ΌοΈ Crisp High-DPI 512px Raster Basemaps (`ol/source/XYZ`) & Tile URL Rules
- * **512px is the Default on MapTiler Cloud:**
- * **512px Standard:** `https://api.maptiler.com/maps/streets-v4/{z}/{x}/{y}.png?key=YOUR_API_KEY`
- * **512px Retina (@2x):** `https://api.maptiler.com/maps/streets-v4/{z}/{x}/{y}@2x.png?key=YOUR_API_KEY`
- * ⚠️ **CRITICAL GOTCHA: NEVER use `/512/` in the URL path** β€” `.../maps/streets-v4/512/...` is **INVALID** and returns HTTP errors. 512px tiles have no size prefix in their path.
- * **256px Legacy Tiles:** Only 256px tiles require an explicit size path: `.../maps/streets-v4/256/{z}/{x}/{y}.png` (or `@2x.png`).
- * When using raster tile layers with 512px tiles in OpenLayers, configure `tileSize: 512` and `maxZoom: 22`:
- ```javascript
- // 512px Retina Basemap (@2x - Recommended for crisp displays)
- const basemap = new TileLayer({
- source: new XYZ({
- url: "https://api.maptiler.com/maps/streets-v4/{z}/{x}/{y}@2x.png?key=YOUR_API_KEY",
- tilePixelRatio: 2,
- tileSize: 512,
- maxZoom: 22,
- attributions: '<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OSM</a>'
+ <script>
+ // 2. Strict Projection Contract: OpenLayers Views operate in EPSG:3857 (meters).
+ // Always convert GPS [longitude, latitude] to Spherical Mercator via fromLonLat:
+ const centerCoord = ol.proj.fromLonLat([14.4378, 50.0755]); // [lng, lat] -> [x, y] in meters
+
+ // 3. Map & High-DPI 512px Basemap Constructor Contract
+ const map = new ol.Map({
+ target: 'map',
+ layers: [
+ new ol.layer.Tile({
+ source: new ol.source.XYZ({
+ url: 'https://api.maptiler.com/maps/streets-v4/{z}/{x}/{y}@2x.png?key=YOUR_API_KEY',
+ tilePixelRatio: 2,
+ tileSize: 512,
+ maxZoom: 22,
+ attributions: '<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a>'
+ })
+ })
+ ],
+ view: new ol.View({
+ center: centerCoord,
+ zoom: 12
})
});
- ```
- ### 4. 🧹 Component Lifecycle & Memory Teardown
- * Always call `map.setTarget(null)` when unmounting components in single-page apps (React, Vue, Svelte) to prevent memory leaks and detached WebGL/canvas contexts:
- ```javascript
- // React cleanup
- useEffect(() => {
- const map = new Map({ target: mapRef.current, ... });
- return () => map.setTarget(null);
- }, []);
- ```
+ // 4. Memory Teardown Contract (For SPAs / React / Vue unmount)
+ // map.setTarget(null); // Detaches DOM and frees canvas resources
+ </script>
+ ```
- ### 5. πŸ”‘ Free Basemap API Key Prompting Invariant
- * If the user does not provide an API key, use `YOUR_API_KEY` as the placeholder in generated code AND always include a friendly reminder guiding the user:
+ * ⚠️ **API Key Prompting Rule:** If the user does not provide an API key, use `YOUR_API_KEY` in code and include this prompt:
> *"To display the map tiles, get a free MapTiler API key (100,000 monthly tile requests) at: https://docs.maptiler.com/cloud/api/authentication-key/"*
+ * ⚠️ **Tile URL Path Rule:** Never use `/512/` in the raster URL path β€” `.../maps/streets-v4/512/...` is **INVALID** on MapTiler Cloud. 512px tiles are native defaults and have no size prefix in their path.
---
- ## ⚑ Fast Search Topic Router
+ ### 2. Native CAD Interaction Architecture (No Third-Party Drawing Plugins)
+ Unlike Leaflet or MapLibre, **OpenLayers includes full CAD vector digitizing natively**. Never install third-party drawing plugins for OpenLayers:
- To quickly find the exact OpenLayers implementation guide or API specification, use direct directory routing:
+ ```javascript
+ const drawSource = new ol.source.Vector();
+ const drawLayer = new ol.layer.Vector({
+ source: drawSource,
+ style: new ol.style.Style({
+ fill: new ol.style.Fill({ color: 'rgba(0, 132, 255, 0.25)' }),
+ stroke: new ol.style.Stroke({ color: '#0084FF', width: 2.5 })
+ })
+ });
+ map.addLayer(drawLayer);
+ // 1. Draw Geometry (Point, LineString, Polygon, Circle, Box)
+ const draw = new ol.interaction.Draw({ source: drawSource, type: 'Polygon' });
+ map.addInteraction(draw);
+
+ // 2. Vertex Editing (Add, Drag, Delete vertices)
+ const modify = new ol.interaction.Modify({ source: drawSource });
+ map.addInteraction(modify);
+
+ // 3. Magnetic Snapping (Snaps crosshair to existing vertices and lines)
+ const snap = new ol.interaction.Snap({ source: drawSource });
+ map.addInteraction(snap); // Snap MUST be added AFTER Draw and Modify!
+
+ // Extract GeoJSON
+ draw.on('drawend', (e) => {
+ const geojson = new ol.format.GeoJSON().writeFeature(e.feature, {
+ featureProjection: 'EPSG:3857',
+ dataProjection: 'EPSG:4326'
+ });
+ console.log('Drawn feature GeoJSON:', geojson);
+ });
+ ```
+
+ ---
+
+ ### 3. Coordinate Systems & Proj4js Registration Contract
+ OpenLayers natively supports `EPSG:3857` and `EPSG:4326`. For all national grid systems (Swiss LV95, British National Grid, UTM), register via `proj4`:
+
+ ```javascript
+ // 1. Define custom projection string
+ proj4.defs("EPSG:2056", "+proj=somerc +lat_0=46.9524055555556 +lon_0=7.43958333333333 +k_0=1 +x_0=2600000 +y_0=1200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs +type=crs");
+
+ // 2. Register with OpenLayers database immediately
+ ol.proj.proj4.register(proj4);
+
+ // 3. Use directly on View or coordinate transformers
+ const centerInLV95 = ol.proj.fromLonLat([8.5417, 47.3769], "EPSG:2056");
+ ```
+
+ ---
+
+ ### 4. Ecosystem Capability & Extension Matrix
+
+ | Capability | Architecture | Standard Implementation | Reference |
+ | :--- | :--- | :--- | :--- |
+ | **CAD Digitizing** | **Native Core** | `ol.interaction.Draw`, `Modify`, `Snap` | [`examples/draw-modify-snap.md`](examples/draw-modify-snap.md) |
+ | **Point Clustering** | **Native Core** | `ol.source.Cluster` wrapping `ol.source.Vector` | [`examples/clustering.md`](examples/clustering.md) |
+ | **Heatmap Density** | **Native Core** | `ol.layer.Heatmap` with radius and blur expressions | [`examples/heatmaps.md`](examples/heatmaps.md) |
+ | **UI Card Popups** | **Native Core** | `ol.Overlay` with `positioning` and `autoPan` | [`examples/popup-overlay.md`](examples/popup-overlay.md) |
+ | **Layer Swipe Wiper**| **Native Canvas / ol-ext**| Layer `prerender`/`postrender` clip or `ol-ext` (`Swipe`) | [`examples/layer-swipe.md`](examples/layer-swipe.md) |
+ | **Custom National CRS**| **Extension Required** | `proj4` registration before map creation | [`references/plugins-catalog.md`](references/plugins-catalog.md) |
+ | **Vector Style JSON** | **Extension Required** | `ol-mapbox-style` (`olms.apply(map, url)`) | [`references/plugins-catalog.md`](references/plugins-catalog.md) |
+ | **Layer Group Switcher**| **Extension Required** | `ol-layerswitcher` or custom button bar | [`references/plugins-catalog.md`](references/plugins-catalog.md) |
+
+ ---
+
+ ## ⚑ Fast Search Topic Router
+
| Category | Location | Contents |
| :--- | :--- | :--- |
- | **Task Examples** | **[examples/INDEX.md](examples/INDEX.md)** | **56 atomic runnable recipes** with full HTML, CSS, and modular ES imports across Raster Basemaps, Digitization, Clustering, WebGL, Enterprise OGC, and COG |
+ | **Task Examples** | **[examples/INDEX.md](examples/INDEX.md)** | **56 atomic runnable recipes** across Raster Basemaps, Digitization, Clustering, WebGL, Enterprise OGC, and COG |
| **Core API & Architecture** | **[references/INDEX.md](references/INDEX.md)** | Declarative specifications for Map & View, Layers & Sources, Interactions & Controls, Styling & Renderers, and Projections |
- | **Advanced GIS & WebGL** | `references/spatial-*`, `advanced-*`, `ogc-*` | Precision tracing, WebGL COG shaders, WMS/WMTS/WFS, raster reprojection, and canvas animations |
- | **Ecosystem & Services** | `references/plugins-catalog.md`, `references/frameworks.md`, `patterns-*`, `basemaps-*` | Extension catalog (`ol-ext`, `proj4`, `ol-mapbox-style`), React/Vue/Svelte, Planet v4 raster basemaps |
+ | **Plugins & Extensions** | **[references/plugins-catalog.md](references/plugins-catalog.md)** | Extension catalog (`ol-ext`, `proj4`, `ol-mapbox-style`, `ol-layerswitcher`, `ol-contextmenu`) |
+ | **Basemaps & Schemas** | `references/basemaps-*`, `references/raster-basemaps-*` | MapTiler Planet v4 high-DPI raster tile URLs and REST endpoints |
+ | **Package Versions** | **[references/versions.md](references/versions.md)** | Pinned production releases for OpenLayers (`v10.10.0`) and companion packages |
---
## πŸ§ͺ Runnable Task Examples (`examples/`)
- All task examples are self-contained with complete HTML, CSS, and modular ES imports (`import Map from "ol/Map.js"`) using MapTiler Planet v4 raster basemaps. Browse **[examples/INDEX.md](examples/INDEX.md)** for the complete categorized catalog:
+ Browse **[examples/INDEX.md](examples/INDEX.md)** for the complete categorized catalog:
- [examples/basic-raster-map.md](examples/basic-raster-map.md) β€” Crisp 512px Retina raster basemap with `TileLayer`, `XYZ`, and MapTiler Streets v4.
- [examples/geojson-choropleth.md](examples/geojson-choropleth.md) β€” Dynamic choropleth styling functions, HTML legend, and hover highlight.
- [examples/draw-modify-snap.md](examples/draw-modify-snap.md) β€” Interactive GIS editing with `Draw`, `Modify`, and `Snap` magnetic vertices.
- [examples/clustering.md](examples/clustering.md) β€” High-performance point aggregation via `ol/source/Cluster` and animated zoom.
- [examples/popup-overlay.md](examples/popup-overlay.md) β€” `ol/Overlay` card anchoring, coordinate display, and `autoPan` animation.
- [examples/measure-distance-area.md](examples/measure-distance-area.md) β€” Geodesic distance and area measurement tool with `ol/sphere`.
- [examples/layer-swipe.md](examples/layer-swipe.md) β€” Split-screen layer swipe comparison using canvas `prerender` clipping.
- [examples/wms-getfeatureinfo.md](examples/wms-getfeatureinfo.md) β€” Enterprise OGC `TileWMS` integration and `GetFeatureInfo` spatial inspection.
- [examples/heatmaps.md](examples/heatmaps.md) β€” Continuous density gradient heatmaps via `ol/layer/Heatmap`.
- - [examples/drag-and-drop.md](examples/drag-and-drop.md) β€” Drag-and-drop loader parsing local `.geojson`, `.gpx`, and `.kml` files.
- - [examples/url-link-sync.md](examples/url-link-sync.md) β€” Bidirectional URL synchronization with `ol/interaction/Link`.
- [examples/cog-geotiff-rendering.md](examples/cog-geotiff-rendering.md) β€” Direct Cloud-Optimized GeoTIFF raster ingestion via HTTP byte-range chunks.
- - [examples/cog-ndvi-band-math.md](examples/cog-ndvi-band-math.md) β€” Real-time GPU NDVI vegetation index calculation from Sentinel-2 bands.
- - [examples/webgl-points-100k.md](examples/webgl-points-100k.md) β€” 100,000+ points rendered at 60 FPS using WebGL.
- - *...and 42 more task recipes in [examples/INDEX.md](examples/INDEX.md).*
-
- ---
-
- ## πŸ“š Core API & Architecture References (`references/`)
-
- Deep architectural and schema reference files live under `references/` and should be loaded on demand:
- - [references/INDEX.md](references/INDEX.md) β€” **Master API reference index & router**.
- - [references/api-catalog.md](references/api-catalog.md) β€” **Official OpenLayers API Directory** (293 classes & modules mapped to `openlayers.org/en/latest/apidoc/`).
- - [references/api-map-and-view.md](references/api-map-and-view.md) β€” `ol/Map`, `ol/View`, `ol/Overlay`, view animations, resolutions, and event dictionary.
- - [references/api-layers-and-sources.md](references/api-layers-and-sources.md) β€” `TileLayer`, `VectorLayer`, `WebGLTile`, `WebGLPoints`, `Heatmap`, `Cluster`.
- - [references/api-styling-and-renderers.md](references/api-styling-and-renderers.md) β€” `ol/style/Style`, `Fill`, `Stroke`, `Icon`, `Text`, dynamic style functions, Flat Style Expressions.
- - [references/api-interactions-and-controls.md](references/api-interactions-and-controls.md) β€” `Draw`, `Modify`, `Select`, `Snap`, `Translate`, `ScaleLine`, custom controls.
- - [references/api-projections-and-geom.md](references/api-projections-and-geom.md) β€” `ol/proj`, `proj4` registration (LV95, BNG), `ol/geom/*`, `ol/format/GeoJSON`.
- - [references/spatial-analysis-and-editing.md](references/spatial-analysis-and-editing.md) β€” Precision drawing, boundary tracing (`trace: true`), and Turf.js spatial analysis.
- - [references/advanced-webgl-and-cog.md](references/advanced-webgl-and-cog.md) β€” Cloud-Optimized GeoTIFF (COG) ingestion and real-time NDVI WebGL band math.
- - [references/ogc-wms-wmts-wfs.md](references/ogc-wms-wmts-wfs.md) β€” Enterprise OGC services (WMS, WMTS, WFS) and GetFeatureInfo.
- - [references/advanced-reprojection-and-grids.md](references/advanced-reprojection-and-grids.md) β€” On-the-fly raster reprojection, Proj4js, and custom CRS grids.
- - [references/canvas-effects-and-animations.md](references/canvas-effects-and-animations.md) β€” Spyglass lens, flight pulse rings, and high-res PDF/PNG exports.
- - [references/raster-basemaps-xyz.md](references/raster-basemaps-xyz.md) β€” Native raster XYZ basemaps, Retina `@2x`, layer switching, and performance tuning.
- - [references/frameworks.md](references/frameworks.md) β€” React (`useRef`/`useEffect`), Next.js App Router SSR fix, Vue 3, Svelte.
- - [references/patterns-gotchas.md](references/patterns-gotchas.md) β€” Top 10 OpenLayers bugs (Null Island coordinates, projection mismatch, double-render).
- - [references/prompt-benchmarks.md](references/prompt-benchmarks.md) β€” 10 practical prompt benchmarks for evaluation.
- - [references/basemaps-and-terrain.md](references/basemaps-and-terrain.md) β€” Production endpoints for `streets-v4`, `outdoor-v4`, `satellite-v4`, `dataviz-v4-dark`.
- - [references/geocoding-and-services.md](references/geocoding-and-services.md) β€” Forward/reverse geocoding autocomplete, static maps, and elevation.
- - [references/installation-and-cdn.md](references/installation-and-cdn.md) β€” NPM, yarn, pnpm, bun setup and CDN scripts (`ol.js`, `ol.css`).
-
- ---
-
- ## πŸ—ΊοΈ Quickstart Pattern: High-DPI 512px Raster Basemap (`ol/source/XYZ`)
-
- ```javascript
- import Map from "ol/Map.js";
- import View from "ol/View.js";
- import TileLayer from "ol/layer/Tile.js";
- import XYZ from "ol/source/XYZ.js";
- import { fromLonLat } from "ol/proj.js";
- import "ol/ol.css";
-
- const map = new Map({
- target: "map",
- layers: [
- new TileLayer({
- source: new XYZ({
- url: "https://api.maptiler.com/maps/streets-v4/{z}/{x}/{y}@2x.png?key=YOUR_API_KEY",
- tilePixelRatio: 2,
- tileSize: 512,
- maxZoom: 22,
- attributions: '<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>'
- })
- })
- ],
- view: new View({
- center: fromLonLat([14.4378, 50.0755]), // [lng, lat] Prague
- zoom: 13
- })
- });
- ```
+ - *...and 46 more task recipes in [examples/INDEX.md](examples/INDEX.md).*