Regions map: country boundaries load on MapLibre too
Caught by spot-checking after main moved, not by the sweep. RegionCountryMap
added its country polygons from mapbox://mapbox.country-boundaries-v1, a
Mapbox-hosted VECTOR TILESET that MapLibre cannot fetch:
Fetch API cannot load mapbox://mapbox.country-boundaries-v1.
URL scheme "mapbox" is not supported
The basemap then drew perfectly with the highlighted countries simply
absent. My own sweep called this leaf "SWAPPED" because it counts canvases,
engines and request totals -- all of which were right. A coarse metric can
be green while the primary data layer is missing; only the console said so.
Fixed by the pattern DashboardMapPanel already proved, copied rather than
reinvented: under maplibre the source is geojson, fed from the keyless
assets/boundaries/world-adm0.geojson the tree already ships and three other
plugins already consume through resolveAssetsBase. Added EMPTY first and
setData after the fetch, so the addLayer calls stay synchronous and the
fills remain beneath the pins. The tileset names the ISO field
iso_3166_1_alpha_3 and the geojson names it iso3, so the property is
normalised ONCE at load and countryFilter() keeps reading the single name it
always read -- the Mapbox path is byte-for-byte unchanged. 'source-layer' is
set for Mapbox alone; MapLibre rejects a layer that declares one on geojson.
MEASURED via the PUBLIC querySourceFeatures (not a private field -- that
lesson cost two reverts earlier in this flight):
mapbox 400 boundary features, 0 console errors
maplibre 467 boundary features, 0 console errors (was 1 scheme error)
Both engines expose the same three layers.
gates:pre 0. gates:post 17/18, the single failure being the pre-existing
verify/tables-complete break from the visa-leak fix (filed, not mine).
This commit is contained in:
parent
c279899990
commit
cb75ba38b5
7 changed files with 78 additions and 35 deletions
|
|
@ -27,12 +27,15 @@
|
|||
*/
|
||||
import { ref, computed, watch, onMounted, onBeforeUnmount, inject } from 'vue'
|
||||
import { useMapInstance } from '@map/composables/useMapInstance.js'
|
||||
import { resolveMapProvider } from '@map/composables/useMapProvider.js'
|
||||
import { resolveAssetsBase } from '@map/utils/embedBase.js'
|
||||
import { useShadowStyles } from '@map/composables/useShadowStyles.js'
|
||||
// The region palette comes from the shared strategy, never from a table in here:
|
||||
// check:one-palette exists because a private palette in a consumer is what once made two
|
||||
// surfaces disagree about what a colour meant.
|
||||
import { applyColor as regionColorExpression } from '@map/colors/wagf-region.js'
|
||||
|
||||
|
||||
const emit = defineEmits(['pick-country'])
|
||||
const props = defineProps({
|
||||
// ISO-3 codes to highlight, e.g. ['IND'] for a country or every code in a region.
|
||||
|
|
@ -57,6 +60,10 @@ const props = defineProps({
|
|||
|
||||
// The token ladder: ProfileLoader provides it (the same seam every map bundle uses). A nested
|
||||
// element has no leaf page of its own, which is what check:nested-token exists to police.
|
||||
const profileConfig = inject('profileConfig', ref(null))
|
||||
// Which engine is live. Derived ONCE: addLayers() branches on it in three places, and three
|
||||
// separate resolveMapProvider() calls is three chances for them to disagree.
|
||||
const isMaplibreProvider = resolveMapProvider(profileConfig) === 'maplibre'
|
||||
const mapboxToken = inject('mapboxToken', ref(''))
|
||||
const tokenValue = computed(() => (typeof mapboxToken === 'string' ? mapboxToken : mapboxToken?.value) || '')
|
||||
|
||||
|
|
@ -171,15 +178,51 @@ function addLayers() {
|
|||
const { color: pinColor, sortKey: pinSortKey, opacity: pinOpacity, radius: pinRadius } = pinExpressions()
|
||||
|
||||
if (!m.getSource(SRC_COUNTRIES)) {
|
||||
m.addSource(SRC_COUNTRIES, { type: 'vector', url: 'mapbox://mapbox.country-boundaries-v1' })
|
||||
// ── COUNTRY POLYGONS, PER PROVIDER ────────────────────────────────────────────────────────
|
||||
// ★ THE ENGINE SWAP IS NOT ONE CONFIG LINE. This read from
|
||||
// `mapbox://mapbox.country-boundaries-v1`, a Mapbox-hosted VECTOR TILESET that MapLibre
|
||||
// cannot fetch at all — it throws
|
||||
// Fetch API cannot load mapbox://mapbox.country-boundaries-v1. URL scheme "mapbox" is not supported
|
||||
// and then draws the basemap perfectly with the highlighted countries simply ABSENT.
|
||||
// MEASURED, not predicted: the leaf reported canvas=1 and engine=MAPLIBRE — a coarse sweep
|
||||
// called it "swapped" while its primary data layer was missing. Only the console said so.
|
||||
//
|
||||
// The keyless equivalent already ships: assets/boundaries/world-adm0.geojson, staged by
|
||||
// generate-tree and already consumed by upg-100-list, connectivity-map and resources-map
|
||||
// through this same resolveAssetsBase helper. No new asset, no new dependency.
|
||||
//
|
||||
// ★ THE FIELD BRIDGE. The tileset names the ISO field `iso_3166_1_alpha_3`; the geojson names
|
||||
// it `iso3`. countryFilter() reads the tileset name, so the property is normalised ONCE as the
|
||||
// data loads and every expression keeps reading the single name it always read — the Mapbox
|
||||
// path stays byte-for-byte unchanged. Same shape as DashboardMapPanel, deliberately copied.
|
||||
if (isMaplibreProvider) {
|
||||
// Add EMPTY first, then setData after the fetch: the addLayer calls below must run
|
||||
// SYNCHRONOUSLY to keep these fills beneath the pins (layer order is insertion order).
|
||||
m.addSource(SRC_COUNTRIES, { type: 'geojson', data: { type: 'FeatureCollection', features: [] } })
|
||||
fetch(`${resolveAssetsBase(profileConfig?.value)}/boundaries/world-adm0.geojson`)
|
||||
.then((r) => r.json())
|
||||
.then((gj) => {
|
||||
for (const f of gj.features || []) {
|
||||
if (f.properties && f.properties.iso3) f.properties.iso_3166_1_alpha_3 = f.properties.iso3
|
||||
}
|
||||
const src = map.value && map.value.getSource(SRC_COUNTRIES)
|
||||
if (src) src.setData(gj)
|
||||
})
|
||||
.catch((e) => console.warn('[rcm] country boundaries failed to load', e))
|
||||
} else {
|
||||
m.addSource(SRC_COUNTRIES, { type: 'vector', url: 'mapbox://mapbox.country-boundaries-v1' })
|
||||
}
|
||||
// 'source-layer' applies to VECTOR TILE sources only — on a geojson source MapLibre rejects
|
||||
// the layer outright ("does not need a source-layer"), so it is set for Mapbox alone.
|
||||
const srcLayer = isMaplibreProvider ? {} : { 'source-layer': 'country_boundaries' }
|
||||
m.addLayer({
|
||||
id: 'rcm-focus-fill', type: 'fill', source: SRC_COUNTRIES,
|
||||
'source-layer': 'country_boundaries', filter: countryFilter(),
|
||||
...srcLayer, filter: countryFilter(),
|
||||
paint: { 'fill-color': C.brand, 'fill-opacity': 0.12 },
|
||||
})
|
||||
m.addLayer({
|
||||
id: 'rcm-focus-outline', type: 'line', source: SRC_COUNTRIES,
|
||||
'source-layer': 'country_boundaries', filter: countryFilter(),
|
||||
...srcLayer, filter: countryFilter(),
|
||||
paint: { 'line-color': C.brand, 'line-width': 2 },
|
||||
})
|
||||
}
|
||||
|
|
|
|||
2
public/doxa-maps/index.html
generated
2
public/doxa-maps/index.html
generated
File diff suppressed because one or more lines are too long
8
public/doxa-maps/manifest.json
generated
8
public/doxa-maps/manifest.json
generated
|
|
@ -838,7 +838,7 @@
|
|||
"bundle": "regions-dashboard",
|
||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"output": "doxa-maps/regions-dashboard/regions-dashboard.js",
|
||||
"integrity": "sha384-ej/scNQDYf/dueNh3ITo+0nqa8QN0oihECM3Ww+FP9EC5hC4EWkq3XEI9F5wfjaM",
|
||||
"integrity": "sha384-Pk/QVeDX29Vu/ZIxyBT8lpx397coUFaEA8gVUGrheAtXxG4Q5Ri0R+ZUe1CEw5El",
|
||||
"elements": [
|
||||
"regions-dashboard"
|
||||
],
|
||||
|
|
@ -858,7 +858,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/region-dashboards/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-ej/scNQDYf/dueNh3ITo+0nqa8QN0oihECM3Ww+FP9EC5hC4EWkq3XEI9F5wfjaM\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-Pk/QVeDX29Vu/ZIxyBT8lpx397coUFaEA8gVUGrheAtXxG4Q5Ri0R+ZUe1CEw5El\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -872,7 +872,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-ej/scNQDYf/dueNh3ITo+0nqa8QN0oihECM3Ww+FP9EC5hC4EWkq3XEI9F5wfjaM\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-Pk/QVeDX29Vu/ZIxyBT8lpx397coUFaEA8gVUGrheAtXxG4Q5Ri0R+ZUe1CEw5El\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -886,7 +886,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-ej/scNQDYf/dueNh3ITo+0nqa8QN0oihECM3Ww+FP9EC5hC4EWkq3XEI9F5wfjaM\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-Pk/QVeDX29Vu/ZIxyBT8lpx397coUFaEA8gVUGrheAtXxG4Q5Ri0R+ZUe1CEw5El\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-ej/scNQDYf/dueNh3ITo+0nqa8QN0oihECM3Ww+FP9EC5hC4EWkq3XEI9F5wfjaM" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-Pk/QVeDX29Vu/ZIxyBT8lpx397coUFaEA8gVUGrheAtXxG4Q5Ri0R+ZUe1CEw5El" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-ej/scNQDYf/dueNh3ITo+0nqa8QN0oihECM3Ww+FP9EC5hC4EWkq3XEI9F5wfjaM" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-Pk/QVeDX29Vu/ZIxyBT8lpx397coUFaEA8gVUGrheAtXxG4Q5Ri0R+ZUe1CEw5El" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-ej/scNQDYf/dueNh3ITo+0nqa8QN0oihECM3Ww+FP9EC5hC4EWkq3XEI9F5wfjaM" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-Pk/QVeDX29Vu/ZIxyBT8lpx397coUFaEA8gVUGrheAtXxG4Q5Ri0R+ZUe1CEw5El" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
Loading…
Reference in a new issue