@abi-software/flatmap-viewer 2.3.0-a.5 → 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 +34 -12
- 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
|
}
|
|
@@ -245,15 +245,17 @@ export class Annotator
|
|
|
245
245
|
for (const field of ANNOTATION_FIELDS) {
|
|
246
246
|
html.push('<div class="flatmap-annotation-entry">');
|
|
247
247
|
html.push(` <label for="${field.key}">${field.prompt}:</label>`);
|
|
248
|
-
const value = field.update ? provenanceData[field.key] || '' : '';
|
|
249
248
|
if (field.kind === 'textbox') {
|
|
249
|
+
const value = field.update ? provenanceData[field.key] || '' : '';
|
|
250
250
|
html.push(` <textarea rows="5" cols="40" id="${field.key}" name="${field.key}">${value.trim()}</textarea>`)
|
|
251
251
|
} else if (!('kind' in field) || field.kind !== 'list') {
|
|
252
|
+
const value = field.update ? provenanceData[field.key] || '' : '';
|
|
252
253
|
html.push(` <input type="text" size="40" id="${field.key}" name="${field.key}" value="${value.trim()}"/>`)
|
|
253
254
|
} else { // field.kind === 'list'
|
|
255
|
+
const listValues = field.update ? provenanceData[field.key] || [] : [];
|
|
254
256
|
html.push(' <div class="multiple">')
|
|
255
257
|
for (let n = 1; n <= field.size; n++) {
|
|
256
|
-
const fieldValue = (n <=
|
|
258
|
+
const fieldValue = (n <= listValues.length) ? listValues[n-1].trim() : '';
|
|
257
259
|
html.push(` <input type="text" size="40" id="${field.key}_${n}" name="${field.key}" value="${fieldValue}"/>`)
|
|
258
260
|
}
|
|
259
261
|
html.push(' </div>')
|
|
@@ -290,8 +292,8 @@ export class Annotator
|
|
|
290
292
|
const newProperties = {};
|
|
291
293
|
let propertiesChanged = false;
|
|
292
294
|
for (const field of ANNOTATION_FIELDS) {
|
|
293
|
-
const lastValue = field.update ? provenanceData[field.key] || '' : '';
|
|
294
295
|
if (!('kind' in field) || field.kind !== 'list') {
|
|
296
|
+
const lastValue = field.update ? provenanceData[field.key] || '' : '';
|
|
295
297
|
const inputField = document.getElementById(field.key);
|
|
296
298
|
const newValue = inputField.value.trim();
|
|
297
299
|
if (newValue !== lastValue.trim()) {
|
|
@@ -304,8 +306,9 @@ export class Annotator
|
|
|
304
306
|
const inputField = document.getElementById(`${field.key}_${n}`);
|
|
305
307
|
listValues.push(inputField.value.trim());
|
|
306
308
|
}
|
|
307
|
-
const
|
|
308
|
-
const
|
|
309
|
+
const lastValue = field.update ? provenanceData[field.key] || [] : [];
|
|
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);
|
|
309
312
|
if (oldValues.length !== newValues.length
|
|
310
313
|
|| oldValues.filter(v => !newValues.includes(v)).length > 0) {
|
|
311
314
|
newProperties[field.key] = newValues;
|
|
@@ -333,7 +336,7 @@ export class Annotator
|
|
|
333
336
|
}
|
|
334
337
|
}, UPDATE_TIMEOUT, panel);
|
|
335
338
|
|
|
336
|
-
const url = this.__flatmap.
|
|
339
|
+
const url = this.__flatmap.makeServerUrl(this.__currentFeatureId, 'annotator/');
|
|
337
340
|
const response = await fetch(url, {
|
|
338
341
|
headers: { "Content-Type": "application/json; charset=utf-8" },
|
|
339
342
|
method: 'POST',
|
|
@@ -341,7 +344,7 @@ export class Annotator
|
|
|
341
344
|
signal: abortController.signal
|
|
342
345
|
});
|
|
343
346
|
if (response.ok) {
|
|
344
|
-
return
|
|
347
|
+
return response.json();
|
|
345
348
|
} else {
|
|
346
349
|
return Promise.resolve({error: `${response.status} ${response.statusText}`});
|
|
347
350
|
}
|
|
@@ -364,6 +367,7 @@ export class Annotator
|
|
|
364
367
|
if ('error' in response) {
|
|
365
368
|
this.__setStatusMessage(response.error);
|
|
366
369
|
} else {
|
|
370
|
+
this.__flatmap.setFeatureAnnotated(this.__currentFeatureId);
|
|
367
371
|
panel.close();
|
|
368
372
|
}
|
|
369
373
|
} else {
|
|
@@ -487,7 +491,7 @@ export class Annotator
|
|
|
487
491
|
'<span id="flatmap-annotation-lock" class="jsPanel-ftr-btn fa fa-lock"></span>',
|
|
488
492
|
],
|
|
489
493
|
contentFetch: {
|
|
490
|
-
resource: flatmap.
|
|
494
|
+
resource: flatmap.makeServerUrl(this.__currentFeatureId, 'annotator/'),
|
|
491
495
|
fetchInit: {
|
|
492
496
|
method: 'GET',
|
|
493
497
|
mode: 'cors',
|
|
@@ -522,6 +526,24 @@ export class Annotator
|
|
|
522
526
|
document.addEventListener('jspanelclosed', closedCallback, false);
|
|
523
527
|
}
|
|
524
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
|
+
|
|
525
547
|
}
|
|
526
548
|
|
|
527
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
|
],
|