ixmaps-gl 0.2.14 → 0.2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/ixmaps-gl.js +183 -48
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -101,6 +101,31 @@ an id wins, a polygon's position is flat's shape center (the vertex mean in Merc
|
|
|
101
101
|
`chartlower` (else `layerupper`/`layerlower`) hide a theme outside their scales; `.filter()` takes
|
|
102
102
|
flat's grammar (`WHERE a > 5 AND b NOT x`, `LIKE`, `IN`, `BETWEEN`, `$field$`, or a plain regex).
|
|
103
103
|
|
|
104
|
+
### Handle API
|
|
105
|
+
|
|
106
|
+
The main interface is flat's handle chain: `ixmaps.map()` — or `ixmaps.map("name")` for the map
|
|
107
|
+
with that `name` in its `Map()` options, so several maps on one page can be addressed separately
|
|
108
|
+
(no name: the last built map, as in flat). From the map handle, `map("name").theme("themename")`
|
|
109
|
+
returns the theme handle (flat's `themeApi`):
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
ixmaps.map("map1").theme("mytheme").changeStyle("scale:1.2", "factor");
|
|
113
|
+
ixmaps.map().theme("mytheme").show(); // also hide(), toggle(), remove(),
|
|
114
|
+
// replace(theme), markClass(n), unmarkClass(n)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The historic global forms remain as compatibility wrappers and dispatch on arity: the canonical
|
|
118
|
+
theme-first `ixmaps.changeThemeStyle(themeId, "style:value", "set")` and `ixmaps.removeTheme(id)`
|
|
119
|
+
(htmlgui.js), the handle method `map().changeThemeStyle(theme, style, flag)`, and the older
|
|
120
|
+
map-first pages calling `ixmaps.changeThemeStyle(null|mapName, themeId, style, flag)` /
|
|
121
|
+
`ixmaps.removeTheme(null|mapName, id)` / `ixmaps.setBasemapOpacity(null|mapName, opacity, mode)`
|
|
122
|
+
— where a registered map name targets that map and a null or unknown name the last built one.
|
|
123
|
+
The `ixmaps.Map(div, opts, callback)` callback receives the builder for its own
|
|
124
|
+
`.options().view().layer()` chain, which also carries flat's mapApi handle methods
|
|
125
|
+
(`setView`, `replace`, `show`, `getThemes`, … — htmlgui_flat.js), each delegated to the handle
|
|
126
|
+
of that map's options name — so a page that keeps the callback object as its map handle,
|
|
127
|
+
as flat pages do, works unmodified.
|
|
128
|
+
|
|
104
129
|
### Zoom levels
|
|
105
130
|
|
|
106
131
|
Zoom numbers in the ixmaps API are ixmaps-flat's, i.e. Leaflet's (256px tiles):
|
package/ixmaps-gl.js
CHANGED
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
// ---------------------------------------------------------------
|
|
83
83
|
// this engine's release (= package.json "version", checked by
|
|
84
84
|
// test/unit/version.test.mjs); ixmaps.glVersion, and logged once at start
|
|
85
|
-
const IXMAPS_GL_VERSION = '0.2.
|
|
85
|
+
const IXMAPS_GL_VERSION = '0.2.15';
|
|
86
86
|
|
|
87
87
|
const LIB_URLS = {
|
|
88
88
|
// Bumped 3.6.2 -> 5.x (2026-09-21, globe-projection compat fix): native
|
|
@@ -1951,6 +1951,10 @@
|
|
|
1951
1951
|
// per-map handle — most real pages only ever build one map anyway. Set
|
|
1952
1952
|
// once per successful build(), just before it returns engineApi below.
|
|
1953
1953
|
let _lastMapApi = null;
|
|
1954
|
+
// flat's map instance registry (htmlgui_flat.js 2416): the built maps by
|
|
1955
|
+
// their Map() options name — ixmaps.map("name") is the handle of THAT
|
|
1956
|
+
// map, ixmaps.map() stays the last built one
|
|
1957
|
+
const _mapApis = Object.create(null);
|
|
1954
1958
|
// resolves with the first built map's API: ixmaps.map() calls a page
|
|
1955
1959
|
// makes while the map is still building wait for it
|
|
1956
1960
|
let _resolveMapReady;
|
|
@@ -3063,10 +3067,12 @@
|
|
|
3063
3067
|
function mount() {
|
|
3064
3068
|
map.on('move', updatePinnedTooltipPosition);
|
|
3065
3069
|
watchHoverTooltip();
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
+
// anchor inside the map container: map.project() gives container-
|
|
3071
|
+
// relative pixels, and styling the page's own body (relative) breaks
|
|
3072
|
+
// any page element absolutely positioned against it (AirBnB's
|
|
3073
|
+
// #onmap-buttons on a zero-height all-float body flew off-screen)
|
|
3074
|
+
el.style.position = el.style.position || 'relative';
|
|
3075
|
+
el.appendChild(pinnedTooltipEl);
|
|
3070
3076
|
}
|
|
3071
3077
|
return { getTooltip, onClick, mount };
|
|
3072
3078
|
}
|
|
@@ -3080,7 +3086,7 @@
|
|
|
3080
3086
|
// layoutLegends().
|
|
3081
3087
|
// ---------------------------------------------------------------
|
|
3082
3088
|
function createLegend(ctx) {
|
|
3083
|
-
const { builder, map, el, overlay, runtimes, engineApi, built, refresh, scheduleRefresh, notifyRedraw } = ctx;
|
|
3089
|
+
const { builder, map, el, overlay, runtimes, engineApi, built, refresh, scheduleRefresh, notifyRedraw, quietRefresh } = ctx;
|
|
3084
3090
|
let addLegendPanel = () => {};
|
|
3085
3091
|
let setLegendOption = () => {};
|
|
3086
3092
|
let updateSubTheme = () => {};
|
|
@@ -3228,15 +3234,28 @@
|
|
|
3228
3234
|
legendStack = document.createElement('div');
|
|
3229
3235
|
legendStack.className = 'ix-legend-stack';
|
|
3230
3236
|
legendStack.style.cssText = 'position:absolute;' + legendAlignCss + 'z-index:6;width:280px;'
|
|
3231
|
-
+ 'display:flex;flex-direction:column;max-height:
|
|
3237
|
+
+ 'display:flex;flex-direction:column;max-height:66.6%;overflow-y:auto;'
|
|
3232
3238
|
+ 'border-radius:6px;box-shadow:' + shadow + ';pointer-events:auto;';
|
|
3233
3239
|
if (!document.getElementById('ix-legend-stack-css')) {
|
|
3234
3240
|
const css = document.createElement('style');
|
|
3235
3241
|
css.id = 'ix-legend-stack-css';
|
|
3236
|
-
|
|
3242
|
+
// the slider rules are flat's own legend.css .slider block
|
|
3243
|
+
// (355-411) — its two duplicate blocks resolved to what the
|
|
3244
|
+
// cascade actually shows: a 5px rounded grey track at 0.7
|
|
3245
|
+
// opacity (1 on hover) and a green thumb
|
|
3246
|
+
css.textContent = '.ix-legend-stack>.ix-native-legend:not([data-ixoff])~.ix-native-legend:not([data-ixoff]){border-top:1px solid rgba(128,128,128,.35)}'
|
|
3247
|
+
+ '.ix-legend-stack input[type=range]{-webkit-appearance:none;appearance:none;height:5px;border-radius:10px;background:rgba(155,155,155,0.3);border:solid #888 0px;outline:none;opacity:0.7;transition:opacity .2s;}'
|
|
3248
|
+
+ '.ix-legend-stack input[type=range]:hover{opacity:1;}'
|
|
3249
|
+
+ '.ix-legend-stack input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:14px;border-radius:0.5em;background:#4CAF50;cursor:pointer;}'
|
|
3250
|
+
+ '.ix-legend-stack input[type=range]::-moz-range-thumb{width:25px;height:25px;border-radius:50%;background:#4CAF50;cursor:pointer;}';
|
|
3237
3251
|
document.head.appendChild(css);
|
|
3238
3252
|
}
|
|
3239
|
-
|
|
3253
|
+
// flat anchors its legend inside the map div (#map-legend), so the
|
|
3254
|
+
// panel's max-height resolves against the MAP's height — the stack's
|
|
3255
|
+
// former parent anchor collapsed it to 0 on pages whose body has
|
|
3256
|
+
// only floated children (height 0)
|
|
3257
|
+
el.style.position = el.style.position || 'relative';
|
|
3258
|
+
el.appendChild(legendStack);
|
|
3240
3259
|
return legendStack;
|
|
3241
3260
|
};
|
|
3242
3261
|
// map.setLegend(value): the `legend` map option at runtime, same values as
|
|
@@ -3281,7 +3300,7 @@
|
|
|
3281
3300
|
rt._triggerRedraw = () => { refresh(); };
|
|
3282
3301
|
if (subThemeCapable(rt)) rt._onMarksChanged = () => updateSubTheme(rt);
|
|
3283
3302
|
if (!legendOn || !el.parentElement || !legendApplies(rt)) return;
|
|
3284
|
-
el.
|
|
3303
|
+
el.style.position = el.style.position || 'relative';
|
|
3285
3304
|
{
|
|
3286
3305
|
// .type("...|NOLEGEND") — the fourth real legend-related type()
|
|
3287
3306
|
// token: opts a theme OUT of the legend entirely (real engine's
|
|
@@ -3328,23 +3347,22 @@
|
|
|
3328
3347
|
// would hand the dark look a light bg here: its dark branch never
|
|
3329
3348
|
// ran for this map, its light bg would clash with dark rows/text)
|
|
3330
3349
|
if (!rt.style.legendtheme) legendColors.bg = looksDark ? '#111' : flatLook.bg;
|
|
3331
|
-
// max-height:66% resolves against el
|
|
3332
|
-
//
|
|
3333
|
-
//
|
|
3334
|
-
//
|
|
3335
|
-
//
|
|
3336
|
-
//
|
|
3337
|
-
//
|
|
3338
|
-
//
|
|
3339
|
-
//
|
|
3340
|
-
//
|
|
3341
|
-
//
|
|
3342
|
-
// it just overflows its flex parent instead.
|
|
3350
|
+
// max-height:66.6% resolves against el's own height (the map
|
|
3351
|
+
// container, which always has a definite height for the map
|
|
3352
|
+
// itself to render into) since this panel sits in the stack,
|
|
3353
|
+
// absolutely positioned inside el. flex:0 1 auto + min-height:0
|
|
3354
|
+
// lets the panel SHRINK to the stack's 2/3 cap so the ROWS
|
|
3355
|
+
// wrapper (its own flex:1 1 auto + min-height:0 below) scrolls
|
|
3356
|
+
// internally while the header/description/slider stay fixed —
|
|
3357
|
+
// with flex:0 0 auto the panel grew past the cap and the whole
|
|
3358
|
+
// stack scrolled instead. text-align:left: the page body may
|
|
3359
|
+
// centre everything (the AirBnB port does), the legend is left
|
|
3360
|
+
// aligned chrome.
|
|
3343
3361
|
// one box for every theme, as flat's #map-legend (legend.js
|
|
3344
3362
|
// 2200-2460): the panels stack in the legend stack in theme
|
|
3345
3363
|
// order, a line between them (see layoutLegends)
|
|
3346
|
-
panel.style.cssText = 'position:relative;flex:0
|
|
3347
|
-
+ 'display:flex;flex-direction:column;'
|
|
3364
|
+
panel.style.cssText = 'position:relative;flex:0 1 auto;min-height:0;overflow:hidden;'
|
|
3365
|
+
+ 'display:flex;flex-direction:column;text-align:left;'
|
|
3348
3366
|
+ 'background:' + legendColors.bg + ';color:' + legendColors.fg + ';font:12px/1.4 -apple-system,Arial,sans-serif;'
|
|
3349
3367
|
+ 'padding:10px 12px 12px;pointer-events:auto;';
|
|
3350
3368
|
const stack = legendStackEl(legendColors.shadow);
|
|
@@ -3783,12 +3801,12 @@
|
|
|
3783
3801
|
slider.min = isOpacitySlider ? '0' : '25';
|
|
3784
3802
|
slider.max = isOpacitySlider ? '100' : '200';
|
|
3785
3803
|
slider.value = String(initialPct);
|
|
3786
|
-
slider.style.cssText = 'width:
|
|
3804
|
+
slider.style.cssText = 'width:50%;margin-top:0.4em;'; // flat's own inline slider style (legend.js 2392)
|
|
3787
3805
|
slider.addEventListener('input', () => {
|
|
3788
3806
|
const pct = parseInt(slider.value, 10);
|
|
3789
3807
|
sliderRow.querySelector('.ix-legend-scale-val').textContent = pct;
|
|
3790
3808
|
rt.setStyle(isOpacitySlider ? { fillopacity: pct / 100 } : { scale: pct / 100 });
|
|
3791
|
-
|
|
3809
|
+
quietRefresh();
|
|
3792
3810
|
});
|
|
3793
3811
|
bodyEl.appendChild(slider);
|
|
3794
3812
|
}
|
|
@@ -4179,12 +4197,14 @@
|
|
|
4179
4197
|
attributionBox.set(this._attributionText != null ? this._attributionText : this.mapOptions.attribution);
|
|
4180
4198
|
this._setAttribution = text => attributionBox.set(text);
|
|
4181
4199
|
|
|
4182
|
-
if (this._legendHtml
|
|
4200
|
+
if (this._legendHtml) {
|
|
4183
4201
|
const legendEl = document.createElement('div');
|
|
4184
4202
|
legendEl.style.cssText = 'position:absolute;top:0;left:0;z-index:5;pointer-events:none';
|
|
4185
4203
|
legendEl.innerHTML = this._legendHtml;
|
|
4186
|
-
|
|
4187
|
-
|
|
4204
|
+
// inside the map container, never the page's body (see the pinned
|
|
4205
|
+
// tooltip mount) — styling body breaks page-positioned elements
|
|
4206
|
+
el.style.position = el.style.position || 'relative';
|
|
4207
|
+
el.appendChild(legendEl);
|
|
4188
4208
|
}
|
|
4189
4209
|
|
|
4190
4210
|
// themes are addressed by either the layer()'s own name (e.g. "AREU")
|
|
@@ -5228,9 +5248,18 @@
|
|
|
5228
5248
|
// the native legend: createLegend (its four hooks are what the rest
|
|
5229
5249
|
// of the map calls — panels, the legend option, sub-themes, layout)
|
|
5230
5250
|
({ addLegendPanel, setLegendOption, updateSubTheme, layoutLegends } =
|
|
5231
|
-
createLegend({ builder, map, el, overlay, runtimes, engineApi, built, refresh, scheduleRefresh, notifyRedraw
|
|
5251
|
+
createLegend({ builder, map, el, overlay, runtimes, engineApi, built, refresh, scheduleRefresh, notifyRedraw,
|
|
5252
|
+
// flat's legend slider (legend.js 2839-2854) patches the style and
|
|
5253
|
+
// calls redrawTheme — a per-theme redraw that does NOT fire
|
|
5254
|
+
// htmlgui_onDrawTheme, so a page's own onDrawTheme hook (this
|
|
5255
|
+
// port's hookStatistics re-applying its own slider's scale)
|
|
5256
|
+
// only reasserts on the next full redraw (pan/zoom). refresh()
|
|
5257
|
+
// here would notify synchronously and clobber the new scale in
|
|
5258
|
+
// the same tick — this quiet variant is that flat behavior.
|
|
5259
|
+
quietRefresh: () => { refreshLayers(); } }));
|
|
5232
5260
|
|
|
5233
5261
|
_lastMapApi = engineApi;
|
|
5262
|
+
if (this.mapOptions && this.mapOptions.name) _mapApis[this.mapOptions.name] = engineApi;
|
|
5234
5263
|
// ?ixgl-debug: ixmaps.__glDebug.check() reports, for the moment it is
|
|
5235
5264
|
// called, every theme's geometry problems (invalid or mixed-dimension
|
|
5236
5265
|
// coordinates, a shape far larger than the theme's others) and what
|
|
@@ -5296,6 +5325,27 @@
|
|
|
5296
5325
|
}
|
|
5297
5326
|
}
|
|
5298
5327
|
|
|
5328
|
+
// GL-PORT COMPAT: flat's ixmaps.Map(div, opts, cb) hands the callback a
|
|
5329
|
+
// mapApi HANDLE (htmlgui_flat.js 904-935) — a real page keeps it and
|
|
5330
|
+
// calls its methods on it (__map.setView(...), __map.replace(...) —
|
|
5331
|
+
// AirBnB's city selector). This engine hands the callback the BUILDER
|
|
5332
|
+
// for its own .options().view().layer() chain; the builder here also
|
|
5333
|
+
// carries flat's handle methods, delegated to the map handle of THIS
|
|
5334
|
+
// map's options name (calls before the map exists wait for it, exactly
|
|
5335
|
+
// as ixmaps.map() does). The builder's own methods with different
|
|
5336
|
+
// semantics — layer, view, options, require, attribution, on — keep
|
|
5337
|
+
// theirs and are not overridden.
|
|
5338
|
+
for (const m of ['replace', 'add', 'remove', 'removeTheme', 'replaceTheme', 'changeThemeStyle', 'setThemeStyle',
|
|
5339
|
+
'refreshTheme', 'redrawTheme', 'setBasemapOpacity', 'setMapType', 'setMapTypeId', 'mapType', 'resize',
|
|
5340
|
+
'loadProject', 'project', 'setThemeVisible', 'setThemeTimeFrame', 'show', 'hide', 'getZoom', 'getThemeObj',
|
|
5341
|
+
'getThemes', 'theme', 'setView']) {
|
|
5342
|
+
if (!MapBuilder.prototype[m]) {
|
|
5343
|
+
MapBuilder.prototype[m] = function (...args) {
|
|
5344
|
+
return mapHandle(this.mapOptions && this.mapOptions.name)[m](...args);
|
|
5345
|
+
};
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
|
|
5299
5349
|
// named createMap (not Map) so it doesn't shadow the built-in ES6 Map
|
|
5300
5350
|
// class used throughout this file — a real bug caught during testing
|
|
5301
5351
|
// (every `new Map()` below silently resolved to *this* function instead)
|
|
@@ -11423,22 +11473,73 @@
|
|
|
11423
11473
|
try { hook.call(global.ixmaps, themeIdOf(rt)); } catch (e) { console.error('[ixmaps-gl] htmlgui_onNewTheme:', e); }
|
|
11424
11474
|
}
|
|
11425
11475
|
|
|
11426
|
-
// flat's ixmaps.
|
|
11427
|
-
//
|
|
11428
|
-
//
|
|
11476
|
+
// flat's ixmaps.themeApi (htmlgui_flat.js 1112-1196): the theme handle a
|
|
11477
|
+
// page gets from map().theme(name) — changeStyle is flat's canonical
|
|
11478
|
+
// global changeThemeStyle(szThemeName, szStyle, szFlag) (htmlgui.js 2050)
|
|
11479
|
+
// in handle form; show / hide / toggle are setThemeVisible, remove the map
|
|
11480
|
+
// handle's. flat's own markClass delegates 3-arg — a stale call against
|
|
11481
|
+
// htmlgui.js's 2-arg markThemeClass (2196) — the canonical form is used
|
|
11482
|
+
// here. Theme ids are global (the registry), so the map binding only
|
|
11483
|
+
// matters for replace.
|
|
11484
|
+
function themeApi(szMap, szTheme) {
|
|
11485
|
+
this.szMap = szMap || null;
|
|
11486
|
+
this.szTheme = szTheme || null;
|
|
11487
|
+
}
|
|
11488
|
+
themeApi.prototype = {
|
|
11489
|
+
changeStyle(szStyle, szFlag) { compatChangeThemeStyle(this.szTheme, szStyle, szFlag); return this; },
|
|
11490
|
+
markClass(nClass) { markThemeClass(this.szTheme, nClass); return this; },
|
|
11491
|
+
unmarkClass(nClass) { unmarkThemeClass(this.szTheme, nClass); return this; },
|
|
11492
|
+
show() { mapHandle(this.szMap).setThemeVisible(this.szTheme, true); return this; },
|
|
11493
|
+
hide() { mapHandle(this.szMap).setThemeVisible(this.szTheme, false); return this; },
|
|
11494
|
+
toggle() {
|
|
11495
|
+
const rt = _globalThemeRegistry.get(this.szTheme);
|
|
11496
|
+
mapHandle(this.szMap).setThemeVisible(this.szTheme, rt ? !!rt._hidden : false);
|
|
11497
|
+
return this;
|
|
11498
|
+
},
|
|
11499
|
+
remove() { mapHandle(this.szMap).remove(this.szTheme); return this; },
|
|
11500
|
+
replace(theme, flag) { mapHandle(this.szMap).replaceTheme(this.szTheme, theme, flag); return this; }
|
|
11501
|
+
};
|
|
11502
|
+
|
|
11503
|
+
// flat's ixmaps.map() / ixmaps.api(szMap) — the running map's handle
|
|
11504
|
+
// (htmlgui.js 173ff, htmlgui_flat.js mapApi 1283). Its methods act on the
|
|
11505
|
+
// map named by szMap (its Map() options name) or, without a name, the
|
|
11506
|
+
// last built map; called while the map is still building, they run once
|
|
11507
|
+
// it is ready.
|
|
11429
11508
|
const MAP_HANDLE_METHODS = ['replace', 'add', 'remove', 'removeTheme', 'replaceTheme', 'changeThemeStyle', 'setThemeStyle',
|
|
11430
11509
|
'refreshTheme', 'setBasemapOpacity', 'setMapType', 'setMapTypeId', 'mapType', 'resize', 'view', 'options', 'layer', 'loadProject', 'require', 'setThemeVisible', 'setThemeTimeFrame', 'attribution'];
|
|
11431
|
-
const
|
|
11432
|
-
|
|
11433
|
-
|
|
11434
|
-
|
|
11435
|
-
|
|
11436
|
-
|
|
11437
|
-
|
|
11510
|
+
const _mapHandles = Object.create(null);
|
|
11511
|
+
function makeMapHandle(szMap) {
|
|
11512
|
+
const h = {};
|
|
11513
|
+
const api = () => (szMap && _mapApis[szMap]) || _lastMapApi;
|
|
11514
|
+
for (const m of MAP_HANDLE_METHODS) {
|
|
11515
|
+
h[m] = (...args) => {
|
|
11516
|
+
const a = api();
|
|
11517
|
+
if (a) { const r = a[m](...args); return r === a ? h : r; }
|
|
11518
|
+
_mapReady.then(ready => ready[m](...args));
|
|
11519
|
+
return h;
|
|
11520
|
+
};
|
|
11521
|
+
}
|
|
11522
|
+
h.getZoom = () => { const a = api(); return a ? a.getZoom() : undefined; };
|
|
11523
|
+
h.getThemeObj = id => getThemeObj(id);
|
|
11524
|
+
// flat's mapApi.theme(szTheme) (htmlgui_flat.js 1571): the theme handle
|
|
11525
|
+
h.theme = szTheme => new themeApi(szMap, szTheme);
|
|
11526
|
+
// flat's mapApi aliases (htmlgui_flat.js 1286+): show/hide a theme,
|
|
11527
|
+
// redrawTheme (refreshTheme here), project (loadProject), getThemes(),
|
|
11528
|
+
// setView (view, both flat's object form and (array, zoom))
|
|
11529
|
+
h.show = id => h.setThemeVisible(id, true);
|
|
11530
|
+
h.hide = id => h.setThemeVisible(id, false);
|
|
11531
|
+
h.redrawTheme = id => h.refreshTheme(id);
|
|
11532
|
+
h.project = (...a) => h.loadProject(...a);
|
|
11533
|
+
h.setView = (...a) => h.view(...a);
|
|
11534
|
+
h.getThemes = () => [...new Set(_globalThemeRegistry.values())].map(rt => getThemeObj(themeIdOf(rt))).filter(Boolean);
|
|
11535
|
+
return h;
|
|
11536
|
+
}
|
|
11537
|
+
const _mapHandle = makeMapHandle(null);
|
|
11538
|
+
function mapHandle(szMap) {
|
|
11539
|
+
if (!szMap) return _mapHandle;
|
|
11540
|
+
if (!_mapHandles[szMap]) _mapHandles[szMap] = makeMapHandle(szMap);
|
|
11541
|
+
return _mapHandles[szMap];
|
|
11438
11542
|
}
|
|
11439
|
-
_mapHandle.getZoom = () => (_lastMapApi ? _lastMapApi.getZoom() : undefined);
|
|
11440
|
-
_mapHandle.getThemeObj = id => getThemeObj(id);
|
|
11441
|
-
function mapHandle() { return _mapHandle; }
|
|
11442
11543
|
|
|
11443
11544
|
// flat's ixmaps.formatValue(value, precision, flag) (ui/js/tools/format.js),
|
|
11444
11545
|
// which user chart scripts call: thousands separated by "." (BLANK: a
|
|
@@ -12013,10 +12114,44 @@
|
|
|
12013
12114
|
return _lastMapApi.loadProject(src, flags);
|
|
12014
12115
|
}
|
|
12015
12116
|
|
|
12117
|
+
// flat's global compat forms come in two arities: the canonical
|
|
12118
|
+
// theme-first signatures — changeThemeStyle(szThemeName, szStyle, szFlag)
|
|
12119
|
+
// (htmlgui.js 2050, with its duplicate-leading shift, 2052),
|
|
12120
|
+
// removeTheme(szThemeId) (1884), setBasemapOpacity(nOpacity, szMode)
|
|
12121
|
+
// (1409) — and the older map-first pages calling
|
|
12122
|
+
// (null|szMap, szId, ...) — PNRR passes an explicit null. Arity tells
|
|
12123
|
+
// them apart; theme ids are global (the registry), so the leading map
|
|
12124
|
+
// argument only matters for setBasemapOpacity, where a registered map
|
|
12125
|
+
// name targets that map and null or an unknown name the last built one.
|
|
12126
|
+
function themeStyleArgs(a) {
|
|
12127
|
+
if (a.length >= 4) a = a.slice(1);
|
|
12128
|
+
else if (a[0] === a[1]) a = a.slice(1);
|
|
12129
|
+
return a;
|
|
12130
|
+
}
|
|
12131
|
+
function compatChangeThemeStyle(...a) {
|
|
12132
|
+
const [szId, szStyle, szFlag] = themeStyleArgs(a);
|
|
12133
|
+
return _mapHandle.changeThemeStyle(szId, szStyle, szFlag);
|
|
12134
|
+
}
|
|
12135
|
+
function compatRemoveTheme(...a) {
|
|
12136
|
+
return _mapHandle.remove(a.length >= 2 ? a[1] : a[0]);
|
|
12137
|
+
}
|
|
12138
|
+
function compatSetBasemapOpacity(...a) {
|
|
12139
|
+
if (a.length >= 3) {
|
|
12140
|
+
const api = (a[0] && _mapApis[a[0]]) || _lastMapApi;
|
|
12141
|
+
if (api) api.setBasemapOpacity(a[1], a[2]);
|
|
12142
|
+
return;
|
|
12143
|
+
}
|
|
12144
|
+
return _mapHandle.setBasemapOpacity(a[0], a[1]);
|
|
12145
|
+
}
|
|
12146
|
+
|
|
12016
12147
|
global.ixmaps = {
|
|
12017
12148
|
layer, Layer: layer, Map: createMap, setExternalData: setExternalDataBridge, getThemeObj, data: ixmapsData,
|
|
12018
12149
|
szResourceBase: ixmapsSzResourceBase, getProjectString, setProjectJSON, loadProject,
|
|
12019
12150
|
markThemeClass, unmarkThemeClass, getBoundingBox, setTitle, setTitleBox, refreshTheme, formatValue: flatFormatValue,
|
|
12151
|
+
// flat's ixmaps.__formatValue (ui/js/tools/legend.js 451-553) — pages call
|
|
12152
|
+
// it for statistics/legend values; legend's own variant differs from
|
|
12153
|
+
// format.js's only in the SPACE flag, which flatFormatValue covers too
|
|
12154
|
+
__formatValue: flatFormatValue,
|
|
12020
12155
|
map: mapHandle, getZoom, getThemeDefinitionObj, embeddedSVG,
|
|
12021
12156
|
// flat's theme list: the theme objects of every theme
|
|
12022
12157
|
getThemes: () => [...new Set(_globalThemeRegistry.values())].map(rt => getThemeObj(themeIdOf(rt))).filter(Boolean),
|
|
@@ -12033,11 +12168,11 @@
|
|
|
12033
12168
|
setAttribution: (text) => { if (_lastMapApi && _lastMapApi.setAttribution) _lastMapApi.setAttribution(text); },
|
|
12034
12169
|
htmlgui_setAttributionString: (text) => { if (_lastMapApi && _lastMapApi.setAttribution) _lastMapApi.setAttribution(text); },
|
|
12035
12170
|
htmlgui_getAttributionString: () => (_lastMapApi && _lastMapApi.getAttribution ? _lastMapApi.getAttribution() : ''),
|
|
12036
|
-
changeThemeStyle:
|
|
12037
|
-
removeTheme:
|
|
12171
|
+
changeThemeStyle: compatChangeThemeStyle,
|
|
12172
|
+
removeTheme: compatRemoveTheme,
|
|
12038
12173
|
// flat's time slider: show the records of a theme (null = all themes) whose timefield lies in [min, max)
|
|
12039
12174
|
setThemeTimeFrame: (szId, nMin, nMax) => _mapHandle.setThemeTimeFrame(szId, nMin, nMax),
|
|
12040
|
-
setBasemapOpacity:
|
|
12175
|
+
setBasemapOpacity: compatSetBasemapOpacity,
|
|
12041
12176
|
// this engine's version (flat's own ixmaps.version numbers flat)
|
|
12042
12177
|
glVersion: IXMAPS_GL_VERSION,
|
|
12043
12178
|
// flat always has this page hook (its layer legend tool defines it,
|
|
@@ -12062,7 +12197,7 @@
|
|
|
12062
12197
|
// engine runs in a Node vm there); deliberately NOT on the ixmaps object
|
|
12063
12198
|
global.__ixmapsGlInternals = {
|
|
12064
12199
|
IXMAPS_GL_VERSION, youtubeClickToPlay, symbolsFlagCompat, tooltipTable, legendRowLabels, scaleDenom, cssColorAlpha, aggregatedCategoricalClass, dominantDopacityAlpha, isAggregatedCategoricalChoropleth, computeBubblePackLayout, isolatedBubblePackLayout, sequenceLayout, multiQuadOffsets, pixelOffsetLngLat,
|
|
12065
|
-
normalizeTheme, projectThemeToDefinition, withoutProjectCode, groupRecordCount, resolveBasemapStyleUrl, resolveMapTypeColor, LayerBuilder, LayerRuntime, typeStyleNumbers, styleNum,
|
|
12200
|
+
normalizeTheme, projectThemeToDefinition, withoutProjectCode, groupRecordCount, resolveBasemapStyleUrl, resolveMapTypeColor, LayerBuilder, LayerRuntime, MapBuilder, typeStyleNumbers, styleNum,
|
|
12066
12201
|
resolveScriptUrl, isTrustedScriptUrl, loadProcessingScript, loadBrokerData, applyBrokerThemePatch, makeBrokerTheme,
|
|
12067
12202
|
equalIntervalBreaks, quantileBreaks, naturalBreaks, evenStrideSample, jenksBreakValues, partsFromBreakValues, resolvePartsClass,
|
|
12068
12203
|
computeAlphaStats, computeMultiFieldClasses, computeDominantStats, resolveDominantClass, computeComposeColorStats,
|
|
@@ -12071,7 +12206,7 @@
|
|
|
12071
12206
|
flatToMapLibreZoom, mapLibreToFlatZoom, scaleDenominatorAt, resolveZoomReference, resolveAggregationPx, valuesHiddenByScale,
|
|
12072
12207
|
fetchLayerData, parseCsvText, dataTableRows, geometryRowsToFeatureCollection, filterFlatValues, applyField100, field100Binding, rangeClassLegendTotals, resolveAggregateValue, classValueSeparate, cellAggregatedValues, oneHot, groupCoLocated, aggregateOnGrid, GridAggregateIndex, flatRangeParts, aggregateField100, valueRadius, itemPlotGeometry, itemAnchor, objectZoomFactor, resolveZoomReference, defaultNormalSizeValue,
|
|
12073
12208
|
applyWhereFilter, joinChartPositions, flatLookupKey, flatShapeCenter, chartHiddenByScale, glowHiddenByScale, isSymbolChart, flatChartAlignOffset, flatChartBranch, flatValueText, categoryValueRecord, flatDerivateRgb, flatChartTextRgb, flatGroupedValue, flatNoBreaks, featuresHiddenByScale, boxHiddenByScale, flatShadowOn, snapToAggregationGrid,
|
|
12074
|
-
flatFormatValue,
|
|
12209
|
+
flatFormatValue, themeStyleArgs,
|
|
12075
12210
|
dataCacheKey, dataCacheDisabled, cachedLayerData, featuresBounds, wantsZoomToExtent, legendIsOn,
|
|
12076
12211
|
};
|
|
12077
12212
|
global.__setFilter = __setFilter;
|