@abi-software/flatmap-viewer 2.3.0-b.2 → 2.3.2-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/src/pathways.js CHANGED
@@ -22,6 +22,8 @@ limitations under the License.
22
22
 
23
23
  //==============================================================================
24
24
 
25
+ import { reverseMap } from './utils';
26
+
25
27
  export const PATHWAYS_LAYER = 'pathways';
26
28
 
27
29
  //==============================================================================
@@ -37,8 +39,8 @@ const PATH_TYPES = [
37
39
  { type: "symp-pre", label: "Sympathetic pre-ganglionic", colour: "#EA3423"},
38
40
  { type: "symp-post", label: "Sympathetic post-ganglionic", colour: "#EA3423", dashed: true},
39
41
  { type: "other", label: "Other neuron type", colour: "#888"},
40
- { type: "arterial", label: "Arterial blood vessel", colour: "#F00"},
41
- { type: "venous", label: "Venous blood vessel", colour: "#2F6EBA"},
42
+ { type: "arterial", label: "Arterial blood vessel", colour: "#F00", enabled: false},
43
+ { type: "venous", label: "Venous blood vessel", colour: "#2F6EBA", enabled: false},
42
44
  { type: "centreline", label: "Nerve centrelines", colour: "#CCC", enabled: false},
43
45
  { type: "error", label: "Paths with errors or warnings", colour: "#FF0"}
44
46
  ];
@@ -48,28 +50,11 @@ export const PATH_STYLE_RULES =
48
50
 
49
51
  //==============================================================================
50
52
 
51
- function reverseMap(mapping)
52
- //==========================
53
+ export class PathManager
53
54
  {
54
- const reverse = {};
55
- for (const [key, values] of Object.entries(mapping)) {
56
- for (const value of values) {
57
- if (value in reverse) {
58
- reverse[value].add(key);
59
- } else {
60
- reverse[value] = new Set([key]);
61
- }
62
- }
63
- }
64
- return reverse;
65
- }
66
-
67
- //==============================================================================
68
-
69
- export class Pathways
70
- {
71
- constructor(flatmap)
55
+ constructor(flatmap, ui, enabled=true)
72
56
  {
57
+ this.__ui = ui;
73
58
  this.__connectivityModelPaths = {}; // modelId: [pathIds]
74
59
  this.__pathToConnectivityModel = {};
75
60
  if ('models' in flatmap.pathways) {
@@ -82,14 +67,19 @@ export class Pathways
82
67
  }
83
68
  this.__pathModelPaths = {}; // pathModelId: [pathIds]
84
69
  this.__pathToPathModel = {};
70
+
71
+ this.__paths = {};
72
+ const pathLines = {}; // pathId: [lineIds]
73
+ const pathNerves = {}; // pathId: [nerveIds]
85
74
  if ('paths' in flatmap.pathways) {
86
- this._pathLines = {}; // pathId: [lineIds]
87
- this._pathNerves = {}; // pathId: [nerveIds]
88
- this._pathNodes = {}; // pathId: [nodeIds]
89
75
  for (const [pathId, path] of Object.entries(flatmap.pathways.paths)) {
90
- this._pathLines[pathId] = path.lines;
91
- this._pathNerves[pathId] = path.nerves;
92
- this._pathNodes[pathId] = path.nodes;
76
+ pathLines[pathId] = path.lines;
77
+ pathNerves[pathId] = path.nerves;
78
+ this.__paths[pathId] = path;
79
+ for (const lineId of path.lines) {
80
+ this.__ui.enableFeature(lineId, enabled, true);
81
+ }
82
+ this.__paths[pathId].systemCount = 0;
93
83
  if ('models' in path) {
94
84
  const modelId = path['models'];
95
85
  if (!(modelId in this.__pathModelPaths)) {
@@ -99,30 +89,12 @@ export class Pathways
99
89
  this.__pathToPathModel[pathId] = modelId;
100
90
  }
101
91
  }
102
- } else {
103
- // To be deprecated...
104
- this._pathLines = flatmap.pathways['path-lines']; // pathId: [lineIds]
105
- this._pathNerves = flatmap.pathways['path-nerves']; // pathId: [nerveIds]
106
- if ('path-nodes' in flatmap.pathways) {
107
- this._pathNodes = flatmap.pathways['path-nodes']; // pathId: [nodeIds]
108
- } else {
109
- this._pathNodes = {};
110
- for (const path of Object.keys(this._pathLines)) {
111
- this._pathNodes[path] = [];
112
- }
113
- }
114
92
  }
115
- this._linePaths = reverseMap(this._pathLines); // lineId: [pathIds]
116
- this._nervePaths = reverseMap(this._pathNerves); // nerveId: [pathIds]
93
+ this.__pathsByLine = reverseMap(pathLines); // lineId: [pathIds]
94
+ this.__pathsByNerve = reverseMap(pathNerves); // nerveId: [pathIds]
117
95
 
118
96
  const nodePaths = flatmap.pathways['node-paths'];
119
- if (!('start-paths' in nodePaths)) {
120
- this._nodePaths = nodePaths; // nodeId: [pathIds]
121
- } else { // Original format, deprecated
122
- this._nodePaths = nodePaths['start-paths'];
123
- this.extendNodePaths_(nodePaths['through-paths']);
124
- this.extendNodePaths_(nodePaths['end-paths']);
125
- }
97
+ this._nodePaths = nodePaths; // nodeId: [pathIds]
126
98
  const featureIds = new Set();
127
99
  for (const paths of Object.values(this._nodePaths)) {
128
100
  this.addPathsToFeatureSet_(paths, featureIds);
@@ -130,20 +102,28 @@ export class Pathways
130
102
  this._allFeatureIds = featureIds;
131
103
 
132
104
  // Construct a list of path types we know about
133
- const pathTypes = [];
134
- for (const pathType of PATH_TYPES) {
135
- pathTypes.push(pathType.type);
105
+ const pathTypes = {};
106
+ this.__pathtypeEnabled = {};
107
+ for (const pathTypeDefn of PATH_TYPES) {
108
+ pathTypes[pathTypeDefn.type] = pathTypeDefn;
109
+ this.__pathtypeEnabled[pathTypeDefn.type] = !('enabled' in pathTypeDefn) || pathTypeDefn.enabled;
136
110
  }
137
- // Map unknown path types to ``other``
138
- this.__typePaths = {};
139
- this.__typePaths['other'] = [];
111
+
112
+ // Set path types, mapping unknown path types to ``other``
113
+ this.__pathsByType = {};
114
+ this.__pathsByType['other'] = [];
140
115
  for (const [pathType, paths] of Object.entries(flatmap.pathways['type-paths'])) {
141
- if (pathTypes.indexOf(pathType) >= 0) {
142
- this.__typePaths[pathType] = paths;
116
+ if (pathType in pathTypes) {
117
+ this.__pathsByType[pathType] = paths;
118
+ const pathDefn = pathTypes[pathType];
143
119
  } else {
144
- this.__typePaths['other'].push(...paths);
120
+ this.__pathsByType['other'].push(...paths);
121
+ this.__pathtypeEnabled[pathType] = false;
145
122
  }
146
123
  }
124
+ // Assign types to individual paths
125
+ this.__assignPathTypes();
126
+
147
127
  // Nerve centrelines are a special case with their own controls
148
128
  this.__haveCentrelines = false;
149
129
  }
@@ -154,44 +134,44 @@ export class Pathways
154
134
  return this.__haveCentrelines;
155
135
  }
156
136
 
137
+ __assignPathTypes()
138
+ //=================
139
+ {
140
+ for (const [pathType, paths] of Object.entries(this.__pathsByType)) {
141
+ for (const pathId of paths) {
142
+ this.__paths[pathId].pathType = pathType;
143
+ }
144
+ }
145
+ }
146
+
157
147
  pathTypes()
158
148
  //=========
159
149
  {
160
150
  const pathTypes = [];
161
- for (const pathType of PATH_TYPES) {
162
- if (pathType.type in this.__typePaths
163
- && this.__typePaths[pathType.type].length > 0) {
164
- if (pathType.type === 'centreline') {
151
+ for (const pathTypeDefn of PATH_TYPES) {
152
+ if (pathTypeDefn.type in this.__pathsByType
153
+ && this.__pathsByType[pathTypeDefn.type].length > 0) {
154
+ if (pathTypeDefn.type === 'centreline') {
165
155
  this.__haveCentrelines = true;
166
156
  } else {
167
- pathTypes.push(pathType);
157
+ pathTypes.push({
158
+ ...pathTypeDefn,
159
+ enabled: this.__pathtypeEnabled[pathTypeDefn.type]
160
+ });
168
161
  }
169
162
  }
170
163
  }
171
164
  return pathTypes;
172
165
  }
173
166
 
174
- addPathsToFeatureSet_(paths, featureSet)
167
+ addPathsToFeatureSet_(pathIds, featureSet)
175
168
  //======================================
176
169
  {
177
- for (const path of paths) {
178
- if (path in this._pathLines) {
179
- this._pathLines[path].forEach(lineId => featureSet.add(lineId));
180
- this._pathNerves[path].forEach(nerveId => featureSet.add(nerveId));
181
- this._pathNodes[path].forEach(nodeId => featureSet.add(nodeId));
182
- }
183
- }
184
- }
185
-
186
- extendNodePaths_(nodePaths)
187
- //=========================
188
- {
189
- for (const [key, values] of Object.entries(nodePaths)) {
190
- if (key in this._nodePaths) {
191
- this._nodePaths[key].push(...values);
192
- } else {
193
- this._nodePaths[key] = values;
194
- }
170
+ for (const pathId of pathIds) {
171
+ const path = this.__paths[pathId];
172
+ path.lines.forEach(lineId => featureSet.add(lineId));
173
+ path.nerves.forEach(nerveId => featureSet.add(nerveId));
174
+ path.nodes.forEach(nodeId => featureSet.add(nodeId));
195
175
  }
196
176
  }
197
177
 
@@ -206,8 +186,8 @@ export class Pathways
206
186
  {
207
187
  const featureIds = new Set();
208
188
  for (const lineId of lineIds) {
209
- if (lineId in this._linePaths) {
210
- this.addPathsToFeatureSet_(this._linePaths[lineId], featureIds);
189
+ if (lineId in this.__pathsByLine) {
190
+ this.addPathsToFeatureSet_(this.__pathsByLine[lineId], featureIds);
211
191
  }
212
192
  }
213
193
  return featureIds;
@@ -217,8 +197,8 @@ export class Pathways
217
197
  //======================
218
198
  {
219
199
  const featureIds = new Set();
220
- if (nerveId in this._nervePaths) {
221
- this.addPathsToFeatureSet_(this._nervePaths[nerveId], featureIds);
200
+ if (nerveId in this.__pathsByNerve) {
201
+ this.addPathsToFeatureSet_(this.__pathsByNerve[nerveId], featureIds);
222
202
  }
223
203
  return featureIds;
224
204
  }
@@ -237,8 +217,8 @@ export class Pathways
237
217
  //=====================
238
218
  {
239
219
  const properties = Object.assign({}, feature.properties);
240
- if (feature.id in this._linePaths) {
241
- for (const pathId of this._linePaths[feature.id]) {
220
+ if (feature.id in this.__pathsByLine) {
221
+ for (const pathId of this.__pathsByLine[feature.id]) {
242
222
  // There should only be a single path for a line
243
223
  if (pathId in this.__pathToConnectivityModel) {
244
224
  properties['connectivity'] = this.__pathToConnectivityModel[pathId];
@@ -249,7 +229,7 @@ export class Pathways
249
229
  }
250
230
  /*
251
231
  if (!('connectivity' in properties)) {
252
- for (const pathId of this._nervePaths[feature.id]) {
232
+ for (const pathId of this.__pathsByNerve[feature.id]) {
253
233
  if (pathId in this.__pathToConnectivityModel) {
254
234
  properties['connectivity'] = this.__pathToConnectivityModel[pathId];
255
235
  break;
@@ -297,16 +277,53 @@ export class Pathways
297
277
  return featureIds;
298
278
  }
299
279
 
300
- typeFeatureIds(pathType)
301
- //======================
280
+ __typeFeatureIds(pathType)
281
+ //========================
302
282
  {
303
283
  const featureIds = new Set();
304
- if (pathType in this.__typePaths) {
305
- this.addPathsToFeatureSet_(this.__typePaths[pathType], featureIds);
284
+ if (pathType in this.__pathsByType) {
285
+ this.addPathsToFeatureSet_(this.__pathsByType[pathType], featureIds);
306
286
  }
307
287
  return featureIds;
308
288
  }
309
289
 
290
+ enablePathsBySystem(system, enable, force=false)
291
+ //==============================================
292
+ {
293
+ for (const pathId of system.pathIds) {
294
+ const path = this.__paths[pathId];
295
+ if (this.__pathtypeEnabled[path.pathType]
296
+ && (force
297
+ || enable && path.systemCount === 0
298
+ || !enable && path.systemCount == 1)) {
299
+ // and type(pathId) is enabled...
300
+ const featureIds = new Set();
301
+ this.addPathsToFeatureSet_([pathId], featureIds)
302
+ for (const featureId of featureIds) {
303
+ this.__ui.enableFeature(featureId, enable, force);
304
+ }
305
+ }
306
+ path.systemCount += (enable ? 1 : -1);
307
+ if (path.systemCount < 0) {
308
+ path.systemCount = 0;
309
+ }
310
+ // TODO? Show connectors and parent components of these paths??
311
+ }
312
+ }
313
+
314
+ enablePathsByType(pathType, enable, force=false)
315
+ //==============================================
316
+ {
317
+ if (force
318
+ || enable && !this.__pathtypeEnabled[pathType]
319
+ || !enable && this.__pathtypeEnabled[pathType]) {
320
+ for (const featureId of this.__typeFeatureIds(pathType)) {
321
+ this.__ui.enableFeature(featureId, enable, force);
322
+ }
323
+ this.__pathtypeEnabled[pathType] = enable;
324
+ }
325
+ }
326
+
310
327
  nodePathModels(nodeId)
311
328
  //====================
312
329
  {
package/src/styling.js CHANGED
@@ -33,6 +33,7 @@ import {PATH_STYLE_RULES} from './pathways.js';
33
33
  const COLOUR_ACTIVE = 'blue';
34
34
  const COLOUR_ANNOTATED = '#0F0';
35
35
  const COLOUR_SELECTED = '#0F0';
36
+ const COLOUR_HIDDEN = '#D8D8D8';
36
37
 
37
38
  const CENTRELINE_ACTIVE = '#444';
38
39
  const CENTRELINE_COLOUR = '#CCC';
@@ -44,6 +45,17 @@ const NERVE_SELECTED = 'red';
44
45
 
45
46
  //==============================================================================
46
47
 
48
+ const STROKE_INTERPOLATION = [
49
+ 'interpolate',
50
+ ['exponential', 2],
51
+ ['zoom'],
52
+ 2, ["*", ['var', 'width'], ["^", 2, -0.5]],
53
+ 7, ["*", ['var', 'width'], ["^", 2, 2.5]],
54
+ 9, ["*", ['var', 'width'], ["^", 2, 4.0]]
55
+ ];
56
+
57
+ //==============================================================================
58
+
47
59
  class VectorStyleLayer
48
60
  {
49
61
  constructor(id, suffix, sourceLayer)
@@ -135,14 +147,13 @@ export class FeatureFillLayer extends VectorStyleLayer
135
147
 
136
148
  paintStyle(options, changes=false)
137
149
  {
138
- const ghostColour = '#D8D8D8'; // Function of BG colour?
139
150
  const coloured = !('colour' in options) || options.colour;
140
151
  const dimmed = 'dimmed' in options && options.dimmed;
141
152
  const paintStyle = {
142
153
  'fill-color': [
143
154
  'case',
144
155
  ['boolean', ['feature-state', 'selected'], false], COLOUR_SELECTED,
145
- ['boolean', ['feature-state', 'hidden'], false], ghostColour,
156
+ ['boolean', ['feature-state', 'hidden'], false], COLOUR_HIDDEN,
146
157
  ['has', 'colour'], ['get', 'colour'],
147
158
  ['boolean', ['feature-state', 'active'], false], coloured ? '#D88' : '#CCC',
148
159
  'white' // background colour? body colour ??
@@ -195,6 +206,8 @@ export class FeatureBorderLayer extends VectorStyleLayer
195
206
  const dimmed = 'dimmed' in options && options.dimmed;
196
207
  const activeRasterLayer = 'activeRasterLayer' in options && options.activeRasterLayer;
197
208
  const lineColour = [ 'case' ];
209
+ lineColour.push(['boolean', ['feature-state', 'hidden'], false]);
210
+ lineColour.push(COLOUR_HIDDEN);
198
211
  lineColour.push(['boolean', ['feature-state', 'selected'], false]);
199
212
  lineColour.push(FEATURE_SELECTED_BORDER);
200
213
  if (coloured && outlined) {
@@ -270,8 +283,7 @@ export class FeatureLineLayer extends VectorStyleLayer
270
283
  constructor(id, sourceLayer, options={})
271
284
  {
272
285
  const dashed = ('dashed' in options && options.dashed);
273
- const filterType = dashed ? 'line-dash' : 'line';
274
- super(id, `feature-${filterType}`, sourceLayer);
286
+ super(id, `feature-${dashed ? 'line-dash' : 'line'}`, sourceLayer);
275
287
  this.__dashed = dashed;
276
288
  }
277
289
 
@@ -298,6 +310,7 @@ export class FeatureLineLayer extends VectorStyleLayer
298
310
  const paintStyle = {
299
311
  'line-color': [
300
312
  'case',
313
+ ['boolean', ['feature-state', 'hidden'], false], COLOUR_HIDDEN,
301
314
  ['boolean', ['feature-state', 'selected'], false], COLOUR_SELECTED,
302
315
  ['boolean', ['feature-state', 'active'], false], coloured ? '#888' : '#CCC',
303
316
  ['has', 'colour'], ['get', 'colour'],
@@ -306,6 +319,7 @@ export class FeatureLineLayer extends VectorStyleLayer
306
319
  ],
307
320
  'line-opacity': [
308
321
  'case',
322
+ ['boolean', ['feature-state', 'hidden'], false], 0.01,
309
323
  ['boolean', ['feature-state', 'selected'], false], 1.0,
310
324
  ['has', 'colour'], 1.0,
311
325
  ['boolean', ['feature-state', 'active'], false], 1.0,
@@ -319,14 +333,8 @@ export class FeatureLineLayer extends VectorStyleLayer
319
333
  ['boolean', ['feature-state', 'selected'], false], 1.2,
320
334
  ['boolean', ['feature-state', 'active'], false], 1.2,
321
335
  options.authoring ? 0.7 : 0.5
322
- ], [
323
- 'interpolate',
324
- ['exponential', 2],
325
- ['zoom'],
326
- 2, ["*", ['var', 'width'], ["^", 2, -0.5]],
327
- 7, ["*", ['var', 'width'], ["^", 2, 2.5]],
328
- 9, ["*", ['var', 'width'], ["^", 2, 4.0]]
329
- ]
336
+ ],
337
+ STROKE_INTERPOLATION
330
338
  ]
331
339
  // Need to vary width based on zoom??
332
340
  // Or opacity??
@@ -429,13 +437,7 @@ export class AnnotatedPathLayer extends VectorStyleLayer
429
437
  ['*', 1.2, ['case', ['has', 'stroke-width'], ['get', 'stroke-width'], 1.0]],
430
438
  0.0
431
439
  ],
432
- ['interpolate',
433
- ['exponential', 2],
434
- ['zoom'],
435
- 2, ["*", ['var', 'width'], ["^", 2, -0.5]],
436
- 7, ["*", ['var', 'width'], ["^", 2, 2.5]],
437
- 9, ["*", ['var', 'width'], ["^", 2, 4.0]]
438
- ]
440
+ STROKE_INTERPOLATION
439
441
  ]
440
442
  };
441
443
  return super.changedPaintStyle(paintStyle, changes);
@@ -463,9 +465,10 @@ export class PathLineLayer extends VectorStyleLayer
463
465
  constructor(id, sourceLayer, options={})
464
466
  {
465
467
  const dashed = ('dashed' in options && options.dashed);
466
- const filterType = dashed ? 'line-dash' : 'line';
467
- super(id, `path-${filterType}`, sourceLayer);
468
+ const highlight = ('highlight' in options && options.highlight);
469
+ super(id, `path${highlight ? '-highlight' : ''}-${dashed ? 'line-dash' : 'line'}`, sourceLayer);
468
470
  this.__dashed = dashed;
471
+ this.__highlight = highlight;
469
472
  }
470
473
 
471
474
  makeFilter(options={})
@@ -499,42 +502,51 @@ export class PathLineLayer extends VectorStyleLayer
499
502
  'line-color': [
500
503
  'case',
501
504
  ['boolean', ['feature-state', 'selected'], false], COLOUR_SELECTED,
502
- ['boolean', ['feature-state', 'hidden'], false], '#CCC',
505
+ ['boolean', ['feature-state', 'hidden'], false], COLOUR_HIDDEN,
503
506
  ['==', ['get', 'type'], 'bezier'], 'red',
504
507
  ['==', ['get', 'kind'], 'unknown'], '#888',
505
508
  ...PATH_STYLE_RULES,
506
509
  '#888'
507
510
  ],
508
- 'line-opacity': [
511
+ 'line-opacity': this.__highlight ? [
509
512
  'case',
510
- ['boolean', ['feature-state', 'hidden'], false], 0.05,
513
+ ['boolean', ['feature-state', 'hidden'], false], 0.0,
514
+ ['boolean', ['get', 'invisible'], false], 0.0,
515
+ ['boolean', ['feature-state', 'selected'], false], 1.0,
516
+ ['boolean', ['feature-state', 'active'], false], 1.0,
517
+ 0.0
518
+ ] : [
519
+ 'case',
520
+ ['boolean', ['feature-state', 'hidden'], false], 0.01,
511
521
  ['==', ['get', 'type'], 'bezier'], 1.0,
512
522
  ['==', ['get', 'kind'], 'error'], 1.0,
513
523
  ['boolean', ['get', 'invisible'], false], 0.001,
514
- ['boolean', ['feature-state', 'selected'], false], 1.0,
515
- ['boolean', ['feature-state', 'active'], false], 1.0,
524
+ ['boolean', ['feature-state', 'selected'], false], 0.0,
525
+ ['boolean', ['feature-state', 'active'], false], 0.0,
516
526
  dimmed ? 0.1 : 0.8
517
527
  ],
518
528
  'line-width': [
519
529
  'let',
520
- 'width', ["*", [
521
- 'case',
530
+ 'width', [
531
+ "*",
532
+ this.__highlight ? ['case',
533
+ ['boolean', ['get', 'invisible'], false], 0.1,
534
+ ['boolean', ['feature-state', 'selected'], false], 0.6,
535
+ ['boolean', ['feature-state', 'active'], false], 0.9,
536
+ 0.0
537
+ ] : [
538
+ 'case',
522
539
  ['==', ['get', 'type'], 'bezier'], 0.1,
523
540
  ['==', ['get', 'kind'], 'error'], 1,
524
541
  ['==', ['get', 'kind'], 'unknown'], 1,
525
542
  ['boolean', ['get', 'invisible'], false], 0.1,
526
- ['boolean', ['feature-state', 'selected'], false], 0.6,
527
- ['boolean', ['feature-state', 'active'], false], 0.9,
528
- 0.6
543
+ ['boolean', ['feature-state', 'selected'], false], 0.0,
544
+ ['boolean', ['feature-state', 'active'], false], 0.0,
545
+ 0.6
529
546
  ],
530
- ['case', ['has', 'stroke-width'], ['get', 'stroke-width'], 1.0]],
531
- ['interpolate',
532
- ['exponential', 2],
533
- ['zoom'],
534
- 2, ["*", ['var', 'width'], ["^", 2, -0.5]],
535
- 7, ["*", ['var', 'width'], ["^", 2, 2.5]],
536
- 9, ["*", ['var', 'width'], ["^", 2, 4.0]]
537
- ]
547
+ ['case', ['has', 'stroke-width'], ['get', 'stroke-width'], 1.0]
548
+ ],
549
+ STROKE_INTERPOLATION
538
550
  ]
539
551
  };
540
552
  if (this.__dashed) {
@@ -569,6 +581,24 @@ export class PathDashlineLayer extends PathLineLayer
569
581
 
570
582
  //==============================================================================
571
583
 
584
+ export class PathHighlightLayer extends PathLineLayer
585
+ {
586
+ constructor(id, sourceLayer)
587
+ {
588
+ super(id, sourceLayer, {highlight: true});
589
+ }
590
+ }
591
+
592
+ export class PathDashHighlightLayer extends PathLineLayer
593
+ {
594
+ constructor(id, sourceLayer)
595
+ {
596
+ super(id, sourceLayer, {dashed: true, highlight: true});
597
+ }
598
+ }
599
+
600
+ //==============================================================================
601
+
572
602
  class CentrelineLayer extends VectorStyleLayer
573
603
  {
574
604
  constructor(id, type, sourceLayer)
@@ -598,14 +628,7 @@ class CentrelineLayer extends VectorStyleLayer
598
628
  'let',
599
629
  'width',
600
630
  (this.__type == 'edge') ? 1.6 : 1.2,
601
- [
602
- 'interpolate',
603
- ['exponential', 2],
604
- ['zoom'],
605
- 2, ["*", ['var', 'width'], ["^", 2, -0.5]],
606
- 7, ["*", ['var', 'width'], ["^", 2, 2.5]],
607
- 9, ["*", ['var', 'width'], ["^", 2, 4.0]]
608
- ]
631
+ STROKE_INTERPOLATION
609
632
  ]
610
633
  // Need to vary width based on zoom??
611
634
  // Or opacity??
@@ -745,7 +768,7 @@ export class FeatureNerveLayer extends VectorStyleLayer
745
768
  'paint': {
746
769
  'line-color': [
747
770
  'case',
748
- ['boolean', ['feature-state', 'hidden'], false], '#CCC',
771
+ ['boolean', ['feature-state', 'hidden'], false], COLOUR_HIDDEN,
749
772
  ['boolean', ['feature-state', 'active'], false], NERVE_ACTIVE,
750
773
  ['boolean', ['feature-state', 'selected'], false], NERVE_SELECTED,
751
774
  '#888'