@abi-software/flatmap-viewer 2.3.0-a.6 → 2.3.0-b.1
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.rst +1 -1
- package/package.json +1 -1
- package/src/annotation.js +28 -9
- package/src/flatmap-viewer.js +25 -10
- package/src/interactions.js +39 -11
- package/src/layers.js +2 -0
- package/src/styling.js +88 -11
package/README.rst
CHANGED
|
@@ -38,7 +38,7 @@ The map server endpoint is specified as ``MAP_ENDPOINT`` in ``src/main.js``. It
|
|
|
38
38
|
Package Installation
|
|
39
39
|
====================
|
|
40
40
|
|
|
41
|
-
* ``npm install @abi-software/flatmap-viewer@2.3.0-
|
|
41
|
+
* ``npm install @abi-software/flatmap-viewer@2.3.0-b.1``
|
|
42
42
|
|
|
43
43
|
Documentation
|
|
44
44
|
-------------
|
package/package.json
CHANGED
package/src/annotation.js
CHANGED
|
@@ -119,8 +119,8 @@ export class Annotator
|
|
|
119
119
|
/*
|
|
120
120
|
const testUser = {name: 'Testing...'};
|
|
121
121
|
this.__setUser(testUser);
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
this.__authorised = true;
|
|
123
|
+
return Promise.resolve(testUser);
|
|
124
124
|
*/
|
|
125
125
|
const abortController = new AbortController();
|
|
126
126
|
setTimeout((panel) => {
|
|
@@ -147,7 +147,7 @@ export class Annotator
|
|
|
147
147
|
} else {
|
|
148
148
|
this.__setUser(user_data);
|
|
149
149
|
this.__authorised = true;
|
|
150
|
-
return user_data;
|
|
150
|
+
return Promise.resolve(user_data);
|
|
151
151
|
}
|
|
152
152
|
} else {
|
|
153
153
|
return Promise.resolve({error: `${response.status} ${response.statusText}`});
|
|
@@ -174,7 +174,7 @@ export class Annotator
|
|
|
174
174
|
});
|
|
175
175
|
if (response.ok) {
|
|
176
176
|
this.__authorised = false;
|
|
177
|
-
return
|
|
177
|
+
return response.json();
|
|
178
178
|
} else {
|
|
179
179
|
return Promise.resolve({error: `${response.status} ${response.statusText}`});
|
|
180
180
|
}
|
|
@@ -307,8 +307,8 @@ export class Annotator
|
|
|
307
307
|
listValues.push(inputField.value.trim());
|
|
308
308
|
}
|
|
309
309
|
const lastValue = field.update ? provenanceData[field.key] || [] : [];
|
|
310
|
-
const oldValues = lastValue.map(v => v.trim()).filter(v => (v !== '')).sort();
|
|
311
|
-
const newValues = listValues.map(v => v.trim()).filter(v => (v !== '')).sort();
|
|
310
|
+
const oldValues = lastValue.map(v => v.trim()).filter(v => (v !== '')).sort(Intl.Collator().compare);
|
|
311
|
+
const newValues = listValues.map(v => v.trim()).filter(v => (v !== '')).sort(Intl.Collator().compare);
|
|
312
312
|
if (oldValues.length !== newValues.length
|
|
313
313
|
|| oldValues.filter(v => !newValues.includes(v)).length > 0) {
|
|
314
314
|
newProperties[field.key] = newValues;
|
|
@@ -336,7 +336,7 @@ export class Annotator
|
|
|
336
336
|
}
|
|
337
337
|
}, UPDATE_TIMEOUT, panel);
|
|
338
338
|
|
|
339
|
-
const url = this.__flatmap.
|
|
339
|
+
const url = this.__flatmap.makeServerUrl(this.__currentFeatureId, 'annotator/');
|
|
340
340
|
const response = await fetch(url, {
|
|
341
341
|
headers: { "Content-Type": "application/json; charset=utf-8" },
|
|
342
342
|
method: 'POST',
|
|
@@ -344,7 +344,7 @@ export class Annotator
|
|
|
344
344
|
signal: abortController.signal
|
|
345
345
|
});
|
|
346
346
|
if (response.ok) {
|
|
347
|
-
return
|
|
347
|
+
return response.json();
|
|
348
348
|
} else {
|
|
349
349
|
return Promise.resolve({error: `${response.status} ${response.statusText}`});
|
|
350
350
|
}
|
|
@@ -367,6 +367,7 @@ export class Annotator
|
|
|
367
367
|
if ('error' in response) {
|
|
368
368
|
this.__setStatusMessage(response.error);
|
|
369
369
|
} else {
|
|
370
|
+
this.__flatmap.setFeatureAnnotated(this.__currentFeatureId);
|
|
370
371
|
panel.close();
|
|
371
372
|
}
|
|
372
373
|
} else {
|
|
@@ -490,7 +491,7 @@ export class Annotator
|
|
|
490
491
|
'<span id="flatmap-annotation-lock" class="jsPanel-ftr-btn fa fa-lock"></span>',
|
|
491
492
|
],
|
|
492
493
|
contentFetch: {
|
|
493
|
-
resource: flatmap.
|
|
494
|
+
resource: flatmap.makeServerUrl(this.__currentFeatureId, 'annotator/'),
|
|
494
495
|
fetchInit: {
|
|
495
496
|
method: 'GET',
|
|
496
497
|
mode: 'cors',
|
|
@@ -525,6 +526,24 @@ export class Annotator
|
|
|
525
526
|
document.addEventListener('jspanelclosed', closedCallback, false);
|
|
526
527
|
}
|
|
527
528
|
|
|
529
|
+
async annotated_features()
|
|
530
|
+
//========================
|
|
531
|
+
{
|
|
532
|
+
const url = this.__flatmap.makeServerUrl('', 'annotator/');
|
|
533
|
+
const response = await fetch(url, {
|
|
534
|
+
headers: {
|
|
535
|
+
"Accept": "application/json; charset=utf-8",
|
|
536
|
+
"Cache-Control": "no-store"
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
if (response.ok) {
|
|
540
|
+
return response.json();
|
|
541
|
+
} else {
|
|
542
|
+
console.error(`Annotated features: ${response.status} ${response.statusText}`);
|
|
543
|
+
return Promise.resolve([]);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
528
547
|
}
|
|
529
548
|
|
|
530
549
|
//==============================================================================
|
package/src/flatmap-viewer.js
CHANGED
|
@@ -85,12 +85,12 @@ class FlatMap
|
|
|
85
85
|
|
|
86
86
|
for (const [id, source] of Object.entries(mapDescription.style.sources)) {
|
|
87
87
|
if (source.url) {
|
|
88
|
-
source.url = this.
|
|
88
|
+
source.url = this.makeServerUrl(source.url);
|
|
89
89
|
}
|
|
90
90
|
if (source.tiles) {
|
|
91
91
|
const tiles = [];
|
|
92
92
|
for (const tileUrl of source.tiles) {
|
|
93
|
-
tiles.push(this.
|
|
93
|
+
tiles.push(this.makeServerUrl(tileUrl));
|
|
94
94
|
}
|
|
95
95
|
source.tiles = tiles;
|
|
96
96
|
}
|
|
@@ -361,21 +361,23 @@ class FlatMap
|
|
|
361
361
|
{
|
|
362
362
|
if (!this._map.hasImage(id)) {
|
|
363
363
|
const image = await (path.startsWith('data:image') ? this.loadEncodedImage_(path)
|
|
364
|
-
: this.loadImage_(path.startsWith('/') ? this.
|
|
364
|
+
: this.loadImage_(path.startsWith('/') ? this.makeServerUrl(path)
|
|
365
365
|
: new URL(path, baseUrl)));
|
|
366
366
|
this._map.addImage(id, image, options);
|
|
367
367
|
}
|
|
368
368
|
}
|
|
369
369
|
|
|
370
|
-
|
|
371
|
-
|
|
370
|
+
makeServerUrl(url, resource='flatmap/')
|
|
371
|
+
//=====================================
|
|
372
372
|
{
|
|
373
|
-
if (url.startsWith('
|
|
374
|
-
return
|
|
375
|
-
} else if (
|
|
376
|
-
|
|
373
|
+
if (url.startsWith('http://') || url.startsWith('https://')) {
|
|
374
|
+
return url;
|
|
375
|
+
} else if (url.startsWith('/')) {
|
|
376
|
+
// We don't want embedded `{` and `}` characters escaped
|
|
377
|
+
return `${this._baseUrl}${resource}${this.__uuid}${url}`;
|
|
378
|
+
} else {
|
|
379
|
+
return `${this._baseUrl}${resource}${this.__uuid}/${url}`;
|
|
377
380
|
}
|
|
378
|
-
return url;
|
|
379
381
|
}
|
|
380
382
|
|
|
381
383
|
/**
|
|
@@ -470,6 +472,19 @@ class FlatMap
|
|
|
470
472
|
return this.__idToAnnotation.get(featureId.toString());
|
|
471
473
|
}
|
|
472
474
|
|
|
475
|
+
/**
|
|
476
|
+
* Flag the feature as having external annotation.
|
|
477
|
+
*
|
|
478
|
+
* @param {string} featureId The feature's identifier
|
|
479
|
+
*/
|
|
480
|
+
setFeatureAnnotated(featureId)
|
|
481
|
+
//============================
|
|
482
|
+
{
|
|
483
|
+
if (this._userInteractions !== null) {
|
|
484
|
+
this._userInteractions.setFeatureAnnotated(featureId);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
473
488
|
__updateFeatureIdMap(property, featureIdMap, annotation)
|
|
474
489
|
//======================================================
|
|
475
490
|
{
|
package/src/interactions.js
CHANGED
|
@@ -144,14 +144,13 @@ export class UserInteractions
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
this.__featureIdToMapId = new Map();
|
|
148
|
+
this.__setupAnnotation();
|
|
149
|
+
|
|
150
|
+
// Note features that are FC systems
|
|
148
151
|
|
|
149
152
|
this.__systems = new Map();
|
|
150
|
-
for (const [id, ann] of
|
|
151
|
-
const feature = this.mapFeature_(id);
|
|
152
|
-
if (feature !== undefined) {
|
|
153
|
-
this._map.setFeatureState(feature, { 'annotated': true });
|
|
154
|
-
}
|
|
153
|
+
for (const [id, ann] of this._flatmap.annotations) {
|
|
155
154
|
if (ann['fc-class'] === 'fc-class:System') {
|
|
156
155
|
if (this.__systems.has(ann.name)) {
|
|
157
156
|
this.__systems.get(ann.name).featureIds.push(ann.featureId)
|
|
@@ -197,10 +196,6 @@ export class UserInteractions
|
|
|
197
196
|
}
|
|
198
197
|
}
|
|
199
198
|
|
|
200
|
-
// Add annotation capabilities
|
|
201
|
-
|
|
202
|
-
this.__annotator = new Annotator(flatmap);
|
|
203
|
-
|
|
204
199
|
// Handle mouse events
|
|
205
200
|
|
|
206
201
|
this._map.on('click', this.clickEvent_.bind(this));
|
|
@@ -254,6 +249,39 @@ export class UserInteractions
|
|
|
254
249
|
}
|
|
255
250
|
}
|
|
256
251
|
|
|
252
|
+
async __setupAnnotation()
|
|
253
|
+
//=======================
|
|
254
|
+
{
|
|
255
|
+
// Add annotation capability
|
|
256
|
+
|
|
257
|
+
this.__annotator = new Annotator(this._flatmap);
|
|
258
|
+
const annotated_features = await this.__annotator.annotated_features();
|
|
259
|
+
|
|
260
|
+
// Flag features that have annotations
|
|
261
|
+
|
|
262
|
+
for (const [mapId, ann] of this._flatmap.annotations) {
|
|
263
|
+
this.__featureIdToMapId.set(ann.id, mapId);
|
|
264
|
+
const feature = this.mapFeature_(mapId);
|
|
265
|
+
if (feature !== undefined) {
|
|
266
|
+
this._map.setFeatureState(feature, { 'map-annotation': true });
|
|
267
|
+
if (annotated_features.indexOf(ann.id) >= 0) {
|
|
268
|
+
this._map.setFeatureState(feature, { 'annotated': true });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
setFeatureAnnotated(featureId)
|
|
275
|
+
//============================
|
|
276
|
+
{
|
|
277
|
+
// featureId v's geoJSON id
|
|
278
|
+
const mapId = this.__featureIdToMapId.get(featureId);
|
|
279
|
+
const feature = this.mapFeature_(mapId);
|
|
280
|
+
if (feature !== undefined) {
|
|
281
|
+
this._map.setFeatureState(feature, { 'annotated': true });
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
257
285
|
setPaint(options)
|
|
258
286
|
//===============
|
|
259
287
|
{
|
|
@@ -447,7 +475,7 @@ export class UserInteractions
|
|
|
447
475
|
let smallestFeature = null;
|
|
448
476
|
for (const feature of features) {
|
|
449
477
|
if (feature.geometry.type.includes('Polygon')
|
|
450
|
-
&& this._map.getFeatureState(feature)['
|
|
478
|
+
&& this._map.getFeatureState(feature)['map-annotation']) {
|
|
451
479
|
const polygon = turf.geometry(feature.geometry.type, feature.geometry.coordinates);
|
|
452
480
|
const area = turfArea(polygon);
|
|
453
481
|
if (smallestFeature === null || smallestArea > area) {
|
package/src/layers.js
CHANGED
|
@@ -154,6 +154,8 @@ class MapFeatureLayers extends MapStylingLayers
|
|
|
154
154
|
if (this.__map.getSource('vector-tiles')
|
|
155
155
|
.vectorLayerIds
|
|
156
156
|
.indexOf(pathwaysVectorSource) >= 0) {
|
|
157
|
+
this.__addStyleLayer(style.AnnotatedPathLayer, PATHWAYS_LAYER);
|
|
158
|
+
|
|
157
159
|
this.__addStyleLayer(style.CentrelineEdgeLayer, PATHWAYS_LAYER);
|
|
158
160
|
this.__addStyleLayer(style.CentrelineTrackLayer, PATHWAYS_LAYER);
|
|
159
161
|
|
package/src/styling.js
CHANGED
|
@@ -30,6 +30,20 @@ import {PATH_STYLE_RULES} from './pathways.js';
|
|
|
30
30
|
|
|
31
31
|
//==============================================================================
|
|
32
32
|
|
|
33
|
+
const COLOUR_ACTIVE = 'blue';
|
|
34
|
+
const COLOUR_ANNOTATED = '#0F0';
|
|
35
|
+
const COLOUR_SELECTED = '#0F0';
|
|
36
|
+
|
|
37
|
+
const CENTRELINE_ACTIVE = '#444';
|
|
38
|
+
const CENTRELINE_COLOUR = '#CCC';
|
|
39
|
+
|
|
40
|
+
const FEATURE_SELECTED_BORDER = 'black';
|
|
41
|
+
|
|
42
|
+
const NERVE_ACTIVE = '#222';
|
|
43
|
+
const NERVE_SELECTED = 'red';
|
|
44
|
+
|
|
45
|
+
//==============================================================================
|
|
46
|
+
|
|
33
47
|
class VectorStyleLayer
|
|
34
48
|
{
|
|
35
49
|
constructor(id, suffix, sourceLayer)
|
|
@@ -126,7 +140,7 @@ export class FeatureFillLayer extends VectorStyleLayer
|
|
|
126
140
|
const paintStyle = {
|
|
127
141
|
'fill-color': [
|
|
128
142
|
'case',
|
|
129
|
-
['boolean', ['feature-state', 'selected'], false],
|
|
143
|
+
['boolean', ['feature-state', 'selected'], false], COLOUR_SELECTED,
|
|
130
144
|
['has', 'colour'], ['get', 'colour'],
|
|
131
145
|
['boolean', ['feature-state', 'active'], false], coloured ? '#D88' : '#CCC',
|
|
132
146
|
'white' // background colour? body colour ??
|
|
@@ -180,11 +194,13 @@ export class FeatureBorderLayer extends VectorStyleLayer
|
|
|
180
194
|
const activeRasterLayer = 'activeRasterLayer' in options && options.activeRasterLayer;
|
|
181
195
|
const lineColour = [ 'case' ];
|
|
182
196
|
lineColour.push(['boolean', ['feature-state', 'selected'], false]);
|
|
183
|
-
lineColour.push(
|
|
197
|
+
lineColour.push(FEATURE_SELECTED_BORDER);
|
|
184
198
|
if (coloured && outlined) {
|
|
185
199
|
lineColour.push(['boolean', ['feature-state', 'active'], false]);
|
|
186
|
-
lineColour.push(
|
|
200
|
+
lineColour.push(COLOUR_ACTIVE);
|
|
187
201
|
}
|
|
202
|
+
lineColour.push(['boolean', ['feature-state', 'annotated'], false]);
|
|
203
|
+
lineColour.push(COLOUR_ANNOTATED);
|
|
188
204
|
lineColour.push(['has', 'colour']);
|
|
189
205
|
lineColour.push(['get', 'colour']);
|
|
190
206
|
lineColour.push('#444');
|
|
@@ -199,6 +215,8 @@ export class FeatureBorderLayer extends VectorStyleLayer
|
|
|
199
215
|
}
|
|
200
216
|
lineOpacity.push(['boolean', ['feature-state', 'selected'], false]);
|
|
201
217
|
lineOpacity.push(0.9);
|
|
218
|
+
lineOpacity.push(['boolean', ['feature-state', 'annotated'], false]);
|
|
219
|
+
lineOpacity.push(0.9);
|
|
202
220
|
if (activeRasterLayer) {
|
|
203
221
|
lineOpacity.push((outlined && !dimmed) ? 0.3 : 0.1);
|
|
204
222
|
} else {
|
|
@@ -215,6 +233,8 @@ export class FeatureBorderLayer extends VectorStyleLayer
|
|
|
215
233
|
lineWidth.push(['boolean', ['feature-state', 'active'], false]);
|
|
216
234
|
lineWidth.push(1.5);
|
|
217
235
|
}
|
|
236
|
+
lineWidth.push(['boolean', ['feature-state', 'annotated'], false]);
|
|
237
|
+
lineWidth.push(3.5);
|
|
218
238
|
lineWidth.push(['has', 'colour']);
|
|
219
239
|
lineWidth.push(0.7);
|
|
220
240
|
lineWidth.push((coloured && outlined) ? 0.5 : 0.1);
|
|
@@ -276,7 +296,7 @@ export class FeatureLineLayer extends VectorStyleLayer
|
|
|
276
296
|
const paintStyle = {
|
|
277
297
|
'line-color': [
|
|
278
298
|
'case',
|
|
279
|
-
['boolean', ['feature-state', 'selected'], false],
|
|
299
|
+
['boolean', ['feature-state', 'selected'], false], COLOUR_SELECTED,
|
|
280
300
|
['boolean', ['feature-state', 'active'], false], coloured ? '#888' : '#CCC',
|
|
281
301
|
['has', 'colour'], ['get', 'colour'],
|
|
282
302
|
['==', ['get', 'type'], 'network'], '#AFA202',
|
|
@@ -338,6 +358,63 @@ export class FeatureDashLineLayer extends FeatureLineLayer
|
|
|
338
358
|
|
|
339
359
|
//==============================================================================
|
|
340
360
|
|
|
361
|
+
export class AnnotatedPathLayer extends VectorStyleLayer
|
|
362
|
+
{
|
|
363
|
+
constructor(id, sourceLayer)
|
|
364
|
+
{
|
|
365
|
+
super(id, 'annotated-path', sourceLayer);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
paintStyle(options={}, changes=false)
|
|
369
|
+
{
|
|
370
|
+
const dimmed = 'dimmed' in options && options.dimmed;
|
|
371
|
+
const paintStyle = {
|
|
372
|
+
'line-color': COLOUR_ANNOTATED,
|
|
373
|
+
'line-dasharray': [5, 0.5, 3, 0.5],
|
|
374
|
+
'line-opacity': [
|
|
375
|
+
'case',
|
|
376
|
+
['boolean', ['feature-state', 'hidden'], false], 0.05,
|
|
377
|
+
['boolean', ['feature-state', 'annotated'], false],
|
|
378
|
+
(dimmed ? 0.1 : 0.8),
|
|
379
|
+
0.6
|
|
380
|
+
],
|
|
381
|
+
'line-width': [
|
|
382
|
+
'let',
|
|
383
|
+
'width',
|
|
384
|
+
['case',
|
|
385
|
+
['boolean', ['feature-state', 'annotated'], false],
|
|
386
|
+
['*', 1.2, ['case', ['has', 'stroke-width'], ['get', 'stroke-width'], 1.0]],
|
|
387
|
+
0.0
|
|
388
|
+
],
|
|
389
|
+
['interpolate',
|
|
390
|
+
['exponential', 2],
|
|
391
|
+
['zoom'],
|
|
392
|
+
2, ["*", ['var', 'width'], ["^", 2, -0.5]],
|
|
393
|
+
7, ["*", ['var', 'width'], ["^", 2, 2.5]],
|
|
394
|
+
9, ["*", ['var', 'width'], ["^", 2, 4.0]]
|
|
395
|
+
]
|
|
396
|
+
]
|
|
397
|
+
};
|
|
398
|
+
return super.changedPaintStyle(paintStyle, changes);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
style(options)
|
|
402
|
+
{
|
|
403
|
+
const dimmed = 'dimmed' in options && options.dimmed;
|
|
404
|
+
return {
|
|
405
|
+
...super.style(),
|
|
406
|
+
'type': 'line',
|
|
407
|
+
'filter': ['==', '$type', 'LineString'],
|
|
408
|
+
'paint': this.paintStyle(options),
|
|
409
|
+
'layout': {
|
|
410
|
+
'line-cap': 'square'
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
//==============================================================================
|
|
417
|
+
|
|
341
418
|
export class PathLineLayer extends VectorStyleLayer
|
|
342
419
|
{
|
|
343
420
|
constructor(id, sourceLayer, options={})
|
|
@@ -402,7 +479,7 @@ export class PathLineLayer extends VectorStyleLayer
|
|
|
402
479
|
const paintStyle = {
|
|
403
480
|
'line-color': [
|
|
404
481
|
'case',
|
|
405
|
-
['boolean', ['feature-state', 'selected'], false],
|
|
482
|
+
['boolean', ['feature-state', 'selected'], false], COLOUR_SELECTED,
|
|
406
483
|
['boolean', ['feature-state', 'hidden'], false], '#CCC',
|
|
407
484
|
['==', ['get', 'type'], 'bezier'], 'red',
|
|
408
485
|
['==', ['get', 'kind'], 'unknown'], '#888',
|
|
@@ -487,9 +564,9 @@ class CentrelineLayer extends VectorStyleLayer
|
|
|
487
564
|
const paintStyle = {
|
|
488
565
|
'line-color': (this.__type == 'edge') ? '#000' : [
|
|
489
566
|
'case',
|
|
490
|
-
['boolean', ['feature-state', 'selected'], false],
|
|
491
|
-
['boolean', ['feature-state', 'active'], false],
|
|
492
|
-
|
|
567
|
+
['boolean', ['feature-state', 'selected'], false], COLOUR_SELECTED,
|
|
568
|
+
['boolean', ['feature-state', 'active'], false], CENTRELINE_ACTIVE,
|
|
569
|
+
CENTRELINE_COLOUR
|
|
493
570
|
],
|
|
494
571
|
'line-opacity': [
|
|
495
572
|
'case',
|
|
@@ -650,8 +727,8 @@ export class FeatureNerveLayer extends VectorStyleLayer
|
|
|
650
727
|
'line-color': [
|
|
651
728
|
'case',
|
|
652
729
|
['boolean', ['feature-state', 'hidden'], false], '#CCC',
|
|
653
|
-
['boolean', ['feature-state', 'active'], false],
|
|
654
|
-
['boolean', ['feature-state', 'selected'], false],
|
|
730
|
+
['boolean', ['feature-state', 'active'], false], NERVE_ACTIVE,
|
|
731
|
+
['boolean', ['feature-state', 'selected'], false], NERVE_SELECTED,
|
|
655
732
|
'#888'
|
|
656
733
|
],
|
|
657
734
|
'line-opacity': [
|
|
@@ -702,7 +779,7 @@ export class NervePolygonBorder extends VectorStyleLayer
|
|
|
702
779
|
'paint': {
|
|
703
780
|
'line-color': [
|
|
704
781
|
'case',
|
|
705
|
-
['boolean', ['feature-state', 'active'], false],
|
|
782
|
+
['boolean', ['feature-state', 'active'], false], COLOUR_ACTIVE,
|
|
706
783
|
['boolean', ['feature-state', 'selected'], false], 'red',
|
|
707
784
|
'#444'
|
|
708
785
|
],
|