@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/README.rst +1 -1
- package/package.json +1 -1
- package/src/annotation.js +137 -17
- package/src/controls/controls.js +133 -229
- package/src/controls/info.js +2 -0
- package/src/controls/paths.js +143 -0
- package/src/controls/systems.js +18 -9
- package/src/flatmap-viewer.js +14 -25
- package/src/interactions.js +150 -165
- package/src/layers.js +2 -2
- package/src/pathways.js +110 -93
- package/src/styling.js +71 -48
- package/src/systems.js +54 -31
- package/src/utils.js +18 -0
- package/static/css/flatmap-viewer.css +12 -0
- package/src/controls/newcontrols.js +0 -617
- package/src/editor.js +0 -198
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
|
-
|
|
52
|
-
//==========================
|
|
53
|
+
export class PathManager
|
|
53
54
|
{
|
|
54
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
this.
|
|
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.
|
|
116
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
135
|
-
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
this.
|
|
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 (
|
|
142
|
-
this.
|
|
116
|
+
if (pathType in pathTypes) {
|
|
117
|
+
this.__pathsByType[pathType] = paths;
|
|
118
|
+
const pathDefn = pathTypes[pathType];
|
|
143
119
|
} else {
|
|
144
|
-
this.
|
|
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
|
|
162
|
-
if (
|
|
163
|
-
&& this.
|
|
164
|
-
if (
|
|
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(
|
|
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_(
|
|
167
|
+
addPathsToFeatureSet_(pathIds, featureSet)
|
|
175
168
|
//======================================
|
|
176
169
|
{
|
|
177
|
-
for (const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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.
|
|
210
|
-
this.addPathsToFeatureSet_(this.
|
|
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.
|
|
221
|
-
this.addPathsToFeatureSet_(this.
|
|
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.
|
|
241
|
-
for (const pathId of this.
|
|
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.
|
|
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
|
-
|
|
301
|
-
|
|
280
|
+
__typeFeatureIds(pathType)
|
|
281
|
+
//========================
|
|
302
282
|
{
|
|
303
283
|
const featureIds = new Set();
|
|
304
|
-
if (pathType in this.
|
|
305
|
-
this.addPathsToFeatureSet_(this.
|
|
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],
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
467
|
-
super(id, `path-${
|
|
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],
|
|
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.
|
|
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],
|
|
515
|
-
['boolean', ['feature-state', 'active'], false],
|
|
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
|
-
|
|
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.
|
|
527
|
-
['boolean', ['feature-state', 'active'], false], 0.
|
|
528
|
-
|
|
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
|
-
|
|
532
|
-
|
|
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],
|
|
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'
|