Overview

The most relevant protected-area source patterns in the sibling framework projects come from:

Those projects point to a useful operational split:

Why it matters

Official access patterns

const wdpaVectorTiles =
  "https://data-gis.unep-wcmc.org/server/rest/services/Hosted/wdpa_latest_vts/VectorTileServer/tile/{z}/{y}/{x}.pbf";

const wdpaFeatureService =
  "https://data-gis.unep-wcmc.org/server/rest/services/ProtectedSites/The_World_Database_of_Protected_Areas/FeatureServer/1";

const kbaWms =
  "https://birdlaa8.birdlife.org/geoserver/gwc/service/wms?service=WMS&request=GetMap&layers=birdlife_dz:ibas_global_2024_wm&styles=&format=image/png&transparent=true&version=1.1.1&height=256&width=256&srs=EPSG:3857&bbox={bbox-epsg-3857}";

const kbaWfs =
  "https://birdlaa8.birdlife.org/geoserver/wfs?SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=birdlife_dz:ibas_pol_20240515_wm_selected&OUTPUTFORMAT=application/json";

({wdpaVectorTiles, wdpaFeatureService, kbaWms, kbaWfs})

Run the fetches locally

The repo now contains example fetch scripts:

Use them like this:

./scripts/protected-areas/fetch_wdpa_feature_server.sh \
  34.6 -22.45 35.6 -21.2 \
  data/protected-areas/temane_wdpa.geojson
./scripts/protected-areas/fetch_kba_wfs.sh \
  data/protected-areas/kba_global.geojson

Those commands are deliberately simple. In production, you would usually add clipping, simplification, and metadata capture before publishing the layers into a browser map.

Core dataset families

Dataset What it captures Why it helps Important caution
WDPA Formally protected and conserved areas Good first-pass legal and management context Status, category, and update handling require care
KBA Sites of global biodiversity importance Flags ecological sensitivity beyond legal designation Not every KBA implies the same project constraint
National conservation layers Country-specific reserves, wetlands, or habitat systems Often more locally relevant Coverage and schema vary a lot

Live WDPA service example

This is a live browser map using the official WDPA access pattern from the sibling framework projects: vector tiles for broad context plus a FeatureServer-backed fill layer for richer attributes.

const wdpaMapContainer = html`<div class="dynamic-map-frame"><div class="dynamic-map" style="height: 560px"></div></div>`;
const wdpaMapTarget = wdpaMapContainer.firstElementChild;

const wdpaMap = new maplibregl.Map({
  container: wdpaMapTarget,
  style: "https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json",
  center: [18, 5],
  zoom: 1.4,
  attributionControl: true,
  maplibreLogo: true
});

wdpaMap.addControl(new maplibregl.NavigationControl(), "top-right");

wdpaMap.on("load", () => {
  wdpaMap.addSource("wdpa-vector", {
    type: "vector",
    tiles: [wdpaVectorTiles],
    promoteId: "id"
  });

  wdpaMap.addLayer({
    id: "wdpa-vector-fill",
    type: "fill",
    source: "wdpa-vector",
    "source-layer": "WDPA_poly_latest",
    paint: {
      "fill-color": "#8b8f95",
      "fill-opacity": 0.14
    }
  });

  const srcId = "wdpa-feature-service";
  const service = new FeatureService(srcId, wdpaMap, {url: wdpaFeatureService});

  wdpaMap.addLayer({
    id: "wdpa-feature-fill",
    source: srcId,
    type: "fill",
    paint: {
      "fill-opacity": 0.42,
      "fill-color": [
        "match",
        ["get", "iucn_cat"],
        "Ia", "#B42222",
        "Ib", "#68e94e",
        "II", "#1ea503",
        "III", "#d388dd",
        "IV", "#FC4E2A",
        "V", "#FEB24C",
        "VI", "#FED976",
        "Not Assigned", "#898a90",
        "#e2e3e9"
      ]
    }
  });

  wdpaMap.on("mouseenter", "wdpa-feature-fill", () => {
    wdpaMap.getCanvas().style.cursor = "pointer";
  });
  wdpaMap.on("mouseleave", "wdpa-feature-fill", () => {
    wdpaMap.getCanvas().style.cursor = "";
  });

  wdpaMap.on("click", "wdpa-feature-fill", (event) => {
    const feature = event.features?.[0];
    if (!feature) return;
    new maplibregl.Popup()
      .setLngLat(event.lngLat)
      .setHTML(`
        <div class="popup-table">
          <div><strong>Name</strong><span>${feature.properties?.name ?? "—"}</span></div>
          <div><strong>Designation</strong><span>${feature.properties?.desig_eng ?? feature.properties?.desig ?? "—"}</span></div>
          <div><strong>IUCN</strong><span>${feature.properties?.iucn_cat ?? "—"}</span></div>
          <div><strong>Type</strong><span>${feature.properties?.desig_type ?? "—"}</span></div>
        </div>
      `)
      .addTo(wdpaMap);
  });

  invalidation.then(() => {
    service.destroySource();
    wdpaMap.remove();
  });
});

wdpaMapContainer

KBA notes

The KBA source projects make a second useful point: KBA data is often best treated as a distinct analytical layer rather than folded invisibly into a generic “protected areas” class.

KBA attributes such as site name, country, region, and trigger context can be highly valuable for early biodiversity review, even before specialist habitat interpretation begins.

const kbaAccessPattern = {
  wms: kbaWms,
  wfs: kbaWfs,
  localScript: "./scripts/protected-areas/fetch_kba_wfs.sh"
};

kbaAccessPattern

Workflow and method

  1. Load WDPA and KBA separately.
  2. Use official remote services for discovery and broad context.
  3. Export or clip local copies for project-scale work.
  4. Preserve original source attributes in raw layers.
  5. Build a harmonized screening table for reporting.
  6. Document what is global context versus what is legally determinative.

Local screening-layer example

Not every page needs a live global service map. For method discussion, a local polygon sample is often clearer.

const berkshireTowns = await FileAttachment("../data/examples/berkshire-towns.geojson").json();
const berkshireAcecs = await FileAttachment("../data/examples/berkshire-acecs.geojson").json();

renderGeojsonMap({
  title: "Local conservation-screening figure",
  subtitle: "A Berkshire sample used here to demonstrate how protected-area style screening behaves as a local static figure.",
  layers: [
    {data: berkshireTowns, fill: "none", stroke: "#d7b97a", strokeWidth: 0.7, opacity: 0.7},
    {data: berkshireAcecs, fill: "#d66b63", stroke: "#f1b0a9", strokeWidth: 0.9, opacity: 0.34}
  ]
})

Outputs

Typical outputs:

Limitations