@abi-software/flatmap-viewer 2.3.0-b.1 → 2.3.1-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/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';
@@ -141,13 +142,14 @@ export class FeatureFillLayer extends VectorStyleLayer
141
142
  'fill-color': [
142
143
  'case',
143
144
  ['boolean', ['feature-state', 'selected'], false], COLOUR_SELECTED,
145
+ ['boolean', ['feature-state', 'hidden'], false], COLOUR_HIDDEN,
144
146
  ['has', 'colour'], ['get', 'colour'],
145
147
  ['boolean', ['feature-state', 'active'], false], coloured ? '#D88' : '#CCC',
146
148
  'white' // background colour? body colour ??
147
149
  ],
148
150
  'fill-opacity': [
149
151
  'case',
150
- ['boolean', ['feature-state', 'hidden'], false], 0.01,
152
+ ['boolean', ['feature-state', 'hidden'], false], 0.1,
151
153
  ['boolean', ['feature-state', 'selected'], false], 0.7,
152
154
  ['has', 'opacity'], ['get', 'opacity'],
153
155
  ['has', 'colour'], 1.0,
@@ -193,6 +195,8 @@ export class FeatureBorderLayer extends VectorStyleLayer
193
195
  const dimmed = 'dimmed' in options && options.dimmed;
194
196
  const activeRasterLayer = 'activeRasterLayer' in options && options.activeRasterLayer;
195
197
  const lineColour = [ 'case' ];
198
+ lineColour.push(['boolean', ['feature-state', 'hidden'], false]);
199
+ lineColour.push(COLOUR_HIDDEN);
196
200
  lineColour.push(['boolean', ['feature-state', 'selected'], false]);
197
201
  lineColour.push(FEATURE_SELECTED_BORDER);
198
202
  if (coloured && outlined) {
@@ -296,6 +300,7 @@ export class FeatureLineLayer extends VectorStyleLayer
296
300
  const paintStyle = {
297
301
  'line-color': [
298
302
  'case',
303
+ ['boolean', ['feature-state', 'hidden'], false], COLOUR_HIDDEN,
299
304
  ['boolean', ['feature-state', 'selected'], false], COLOUR_SELECTED,
300
305
  ['boolean', ['feature-state', 'active'], false], coloured ? '#888' : '#CCC',
301
306
  ['has', 'colour'], ['get', 'colour'],
@@ -304,6 +309,7 @@ export class FeatureLineLayer extends VectorStyleLayer
304
309
  ],
305
310
  'line-opacity': [
306
311
  'case',
312
+ ['boolean', ['feature-state', 'hidden'], false], 0.01,
307
313
  ['boolean', ['feature-state', 'selected'], false], 1.0,
308
314
  ['has', 'colour'], 1.0,
309
315
  ['boolean', ['feature-state', 'active'], false], 1.0,
@@ -358,6 +364,38 @@ export class FeatureDashLineLayer extends FeatureLineLayer
358
364
 
359
365
  //==============================================================================
360
366
 
367
+ function sckanFilter(options)
368
+ {
369
+ const sckanState = !'sckan' in options ? 'all'
370
+ : options.sckan.toLowerCase();
371
+ const sckanFilter =
372
+ sckanState == 'none' ? [
373
+ ['!has', 'sckan']
374
+ ] :
375
+ sckanState == 'valid' ? [[
376
+ 'any',
377
+ ['!has', 'sckan'],
378
+ [
379
+ 'all',
380
+ ['has', 'sckan'],
381
+ ['==', 'sckan', true]
382
+ ]
383
+ ]] :
384
+ sckanState == 'invalid' ? [[
385
+ 'any',
386
+ ['!has', 'sckan'],
387
+ [
388
+ 'all',
389
+ ['has', 'sckan'],
390
+ ['!=', 'sckan', true]
391
+ ]
392
+ ]] :
393
+ [ ];
394
+ return sckanFilter;
395
+ }
396
+
397
+ //==============================================================================
398
+
361
399
  export class AnnotatedPathLayer extends VectorStyleLayer
362
400
  {
363
401
  constructor(id, sourceLayer)
@@ -365,6 +403,15 @@ export class AnnotatedPathLayer extends VectorStyleLayer
365
403
  super(id, 'annotated-path', sourceLayer);
366
404
  }
367
405
 
406
+ makeFilter(options={})
407
+ {
408
+ return [
409
+ 'all',
410
+ ['==', '$type', 'LineString'],
411
+ ...sckanFilter(options)
412
+ ];
413
+ }
414
+
368
415
  paintStyle(options={}, changes=false)
369
416
  {
370
417
  const dimmed = 'dimmed' in options && options.dimmed;
@@ -404,7 +451,7 @@ export class AnnotatedPathLayer extends VectorStyleLayer
404
451
  return {
405
452
  ...super.style(),
406
453
  'type': 'line',
407
- 'filter': ['==', '$type', 'LineString'],
454
+ 'filter': this.makeFilter(options),
408
455
  'paint': this.paintStyle(options),
409
456
  'layout': {
410
457
  'line-cap': 'square'
@@ -427,31 +474,7 @@ export class PathLineLayer extends VectorStyleLayer
427
474
 
428
475
  makeFilter(options={})
429
476
  {
430
- const sckanState = !'sckan' in options ? 'all'
431
- : options.sckan.toLowerCase();
432
- const sckan_filter =
433
- sckanState == 'none' ? [
434
- ['!has', 'sckan']
435
- ] :
436
- sckanState == 'valid' ? [[
437
- 'any',
438
- ['!has', 'sckan'],
439
- [
440
- 'all',
441
- ['has', 'sckan'],
442
- ['==', 'sckan', true]
443
- ]
444
- ]] :
445
- sckanState == 'invalid' ? [[
446
- 'any',
447
- ['!has', 'sckan'],
448
- [
449
- 'all',
450
- ['has', 'sckan'],
451
- ['!=', 'sckan', true]
452
- ]
453
- ]] :
454
- [ ];
477
+ const sckan_filter = sckanFilter(options);
455
478
 
456
479
  return this.__dashed ? [
457
480
  'all',
@@ -480,7 +503,7 @@ export class PathLineLayer extends VectorStyleLayer
480
503
  'line-color': [
481
504
  'case',
482
505
  ['boolean', ['feature-state', 'selected'], false], COLOUR_SELECTED,
483
- ['boolean', ['feature-state', 'hidden'], false], '#CCC',
506
+ ['boolean', ['feature-state', 'hidden'], false], COLOUR_HIDDEN,
484
507
  ['==', ['get', 'type'], 'bezier'], 'red',
485
508
  ['==', ['get', 'kind'], 'unknown'], '#888',
486
509
  ...PATH_STYLE_RULES,
@@ -488,7 +511,7 @@ export class PathLineLayer extends VectorStyleLayer
488
511
  ],
489
512
  'line-opacity': [
490
513
  'case',
491
- ['boolean', ['feature-state', 'hidden'], false], 0.05,
514
+ ['boolean', ['feature-state', 'hidden'], false], 0.01,
492
515
  ['==', ['get', 'type'], 'bezier'], 1.0,
493
516
  ['==', ['get', 'kind'], 'error'], 1.0,
494
517
  ['boolean', ['get', 'invisible'], false], 0.001,
@@ -504,7 +527,7 @@ export class PathLineLayer extends VectorStyleLayer
504
527
  ['==', ['get', 'kind'], 'error'], 1,
505
528
  ['==', ['get', 'kind'], 'unknown'], 1,
506
529
  ['boolean', ['get', 'invisible'], false], 0.1,
507
- ['boolean', ['feature-state', 'selected'], false], 0.6,
530
+ ['boolean', ['feature-state', 'selected'], false], 2.0,
508
531
  ['boolean', ['feature-state', 'active'], false], 0.9,
509
532
  0.6
510
533
  ],
@@ -726,7 +749,7 @@ export class FeatureNerveLayer extends VectorStyleLayer
726
749
  'paint': {
727
750
  'line-color': [
728
751
  'case',
729
- ['boolean', ['feature-state', 'hidden'], false], '#CCC',
752
+ ['boolean', ['feature-state', 'hidden'], false], COLOUR_HIDDEN,
730
753
  ['boolean', ['feature-state', 'active'], false], NERVE_ACTIVE,
731
754
  ['boolean', ['feature-state', 'selected'], false], NERVE_SELECTED,
732
755
  '#888'
package/src/systems.js CHANGED
@@ -16,61 +16,84 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
16
  See the License for the specific language governing permissions and
17
17
  limitations under the License.
18
18
 
19
- ******************************************************************************/
20
-
21
-
22
- import { Control } from './controls';
23
-
19
+ **/
24
20
  //==============================================================================
25
21
 
26
22
  export class SystemsManager
27
23
  {
28
- constructor()
29
- {
30
-
31
- }
32
- }
33
-
34
- //==============================================================================
35
-
36
- export class SystemsControl extends Control
37
- {
38
- constructor(flatmap, systems)
24
+ constructor(flatmap, ui, enabled=true)
39
25
  {
40
- super(flatmap, 'system', 'systems');
41
- this.__systems = systems;
26
+ this.__ui = ui;
27
+ this.__systems = new Map();
28
+ this.__enabledChildren = new Map();
29
+ for (const [id, ann] of flatmap.annotations) {
30
+ if (ann['fc-class'] === 'fc-class:System') {
31
+ if (this.__systems.has(ann.name)) {
32
+ this.__systems.get(ann.name).featureIds.push(ann.featureId)
33
+ } else {
34
+ this.__systems.set(ann.name, {
35
+ id: ann.name.replaceAll(' ', '_'),
36
+ colour: ann.colour,
37
+ featureIds: [ ann.featureId ],
38
+ enabled: enabled,
39
+ pathIds: ('path-ids' in ann) ? ann['path-ids'] : []
40
+ });
41
+ }
42
+ for (const childId of ann['children']) {
43
+ if (enabled) {
44
+ const enabledCount = (this.__enabledChildren.has(childId))
45
+ ? this.__enabledChildren.get(childId)
46
+ : 0;
47
+ this.__enabledChildren.set(childId, enabledCount + 1);
48
+ } else {
49
+ this.__enabledChildren.set(childId, 0);
50
+ }
51
+ }
52
+ }
53
+ }
42
54
  }
43
55
 
44
- __innerLinesHTML()
45
- //================
56
+ get systems()
57
+ //===========
46
58
  {
47
- const html = [];
59
+ const systems = [];
48
60
  for (const [name, system] of this.__systems.entries()) {
49
- html.push(`<label for="${this.__prefix}${system.id}" style="background: ${system.colour};">${name}</label><input id="${this.__prefix}${system.id}" type="checkbox" checked/>`);
61
+ systems.push({
62
+ name: name,
63
+ id: system.id,
64
+ colour: system.colour,
65
+ enabled: system.enabled
66
+ });
50
67
  }
51
- return html;
68
+ return systems;
52
69
  }
53
70
 
54
- __enableAll(enable)
55
- //=================
71
+ enable(systemName, enable=true)
72
+ //=============================
56
73
  {
57
- for (const [name, system] of this.__systems.entries()) {
58
- const checkbox = document.getElementById(`${this.__prefix}${system.id}`);
59
- if (checkbox) {
60
- checkbox.checked = enable;
61
- this.__flatmap.enableSystem(name, enable);
74
+ const system = this.__systems.get(systemName);
75
+ if (system !== undefined && enable !== system.enabled) {
76
+ for (const featureId of system.featureIds) {
77
+ const feature = this.__ui.mapFeature(featureId);
78
+ if (feature !== undefined) {
79
+ this.__ui.enableFeature(feature, enable);
80
+ for (const childFeatureId of feature.children) {
81
+ const enabledCount = this.__enabledChildren.get(childFeatureId);
82
+ if (enable && enabledCount === 0 || !enable && enabledCount == 1) {
83
+ this.__ui.enableFeatureWithChildren(childFeatureId, enable);
84
+ }
85
+ this.__enabledChildren.set(childFeatureId, enabledCount + (enable ? 1 : -1));
86
+ }
87
+ }
62
88
  }
63
- }
64
- }
89
+ system.enabled = enable;
65
90
 
66
- __enableControl(id, enable)
67
- //=========================
68
- {
69
- for (const [name, system] of this.__systems.entries()) {
70
- if (id === system.id) {
71
- this.__flatmap.enableSystem(name, enable);
91
+ // Enable/disable all paths associated with the system
92
+ for (const pathId of system.pathIds) {
93
+ this.__ui.enableFeature(this.__ui.mapFeature(pathId), enable);
72
94
  }
73
95
  }
74
96
  }
75
-
76
97
  }
98
+
99
+ //==============================================================================
@@ -342,6 +342,18 @@ label[for=layer-all-layers] {
342
342
  background-color: #BBB;
343
343
  }
344
344
 
345
+ #annotation-feature-selection
346
+ {
347
+ display: flex;
348
+ }
349
+
350
+ #annotation-feature-buttons
351
+ {
352
+ float: right;
353
+ padding-top: 10px;
354
+ padding-bottom: 10px;
355
+ }
356
+
345
357
  .jsPanel-title {
346
358
  font-size: 1.4em !important;
347
359
  font-weight: bold !important;
package/src/editor.js DELETED
@@ -1,198 +0,0 @@
1
- import { Bezier } from "bezier-js";
2
-
3
-
4
- class BezierCurve
5
- {
6
- constructor(id, ...points) {
7
- this.__id = id;
8
- this.__bezier = new Bezier(...points);
9
- }
10
-
11
- asGeoJSON(samples=100)
12
- {
13
- const coords = [];
14
- for (let ts = 0; ts <= samples; ts++) {
15
- const pt = this.__bezier.get(float(ts)/float(samples));
16
- coords.push([pt.x, pt.y]);
17
- }
18
- return {
19
- 'type': 'Feature',
20
- 'geometry': {
21
- 'type': 'LineString',
22
- 'coordinates': coords
23
- },
24
- 'properties': {
25
- 'bezier': this.__id
26
- }
27
- };
28
- }
29
-
30
- asPoints()
31
- {
32
- const geojson = [];
33
- for (const n of [0, 1, 2, 3]) {
34
- const pt = this.__bezier.points[n];
35
- geojson.push({
36
- 'type': 'Feature',
37
- 'geometry': {
38
- 'type': 'Point',
39
- 'coordinates': [pt.x, pt.y]
40
- },
41
- 'properties': {
42
- 'bezier': this.__id,
43
- 'point': n
44
- }
45
- });
46
- }
47
- return geojson;
48
- }
49
- }
50
-
51
-
52
- export class NetworkEditor
53
- {
54
- constructor(flatmap)
55
- {
56
- this.__map = flatmap.map;
57
- this.__canvas = this.__map.getCanvasContainer();
58
-
59
- this.__geojson = { // lines and points as separate sources???
60
- 'type': 'FeatureCollection',
61
- 'features': [
62
- {
63
- 'type': 'Feature',
64
- 'geometry': {
65
- 'type': 'Point',
66
- 'coordinates': [0, 0]
67
- },
68
- 'properties': {
69
- 'id': 0
70
- }
71
- }
72
- ]
73
- };
74
-
75
- // Add a single point to the map
76
- this.__map.addSource('curves', {
77
- 'type': 'geojson',
78
- 'data': this.__geojson
79
- });
80
-
81
- this.__map.addLayer({
82
- 'id': 'lines',
83
- 'type': 'line',
84
- 'source': 'curves',
85
- 'paint': {
86
- 'line-color': '#3887be'
87
- }
88
- });
89
- this.__map.addLayer({
90
- 'id': 'points',
91
- 'type': 'circle',
92
- 'source': 'curves',
93
- 'paint': {
94
- 'circle-radius': 10,
95
- 'circle-color': '#3887be'
96
- }
97
- });
98
-
99
- this.__currentPoint = null;
100
-
101
- this.__map.on('mouseenter', this.mouseEnter.bind(this));
102
- this.__map.on('mouseleave', this.mouseLeave.bind(this));
103
- this.__map.on('mousedown', this.mouseDown.bind(this));
104
- this.__map.on('touchstart', this.touchStart.bind(this));
105
- }
106
-
107
- addPoint(coords)
108
- {
109
- const nextId = this.__geojson.features.length;
110
- this.__geojson.features.push({
111
- 'type': 'Feature',
112
- 'geometry': {
113
- 'type': 'Point',
114
- 'coordinates': coords
115
- },
116
- 'properties': {
117
- 'id': nextId
118
- }
119
- });
120
- this.__map.getSource('curves').setData(this.__geojson);
121
- return nextId;
122
- }
123
-
124
- mouseEnter(e) {
125
- console.log('Mouse enter...');
126
-
127
- this.__map.setPaintProperty('lines', 'line-color', '#3bb2d0');
128
- this.__map.setPaintProperty('points', 'circle-color', '#3bb2d0');
129
- this.__canvas.style.cursor = 'move';
130
- }
131
-
132
-
133
- mouseLeave(e) {
134
- this.__map.setPaintProperty('lines', 'line-color', '#3887be');
135
- this.__map.setPaintProperty('points', 'circle-color', '#3887be');
136
- this.__canvas.style.cursor = '';
137
- }
138
-
139
-
140
- mouseDown(e) {
141
- console.log('Mouse down...')
142
- // Prevent the default map drag behavior.
143
- e.preventDefault();
144
-
145
-
146
- const features = this.__map.queryRenderedFeatures(e.point, {'layers': ['lines', 'points']});
147
- if (features.length === 0) {
148
- const coords = e.lngLat;
149
- this.__currentPoint = this.addPoint([coords.lng, coords.lat]);
150
- } else {
151
- const currentPoint = features[0].properties.id;
152
- if (this.__currentPoint === null) {
153
- this.__currentPoint = currentPoint;
154
- } else if (this.__currentPoint === currentPoint) {
155
- this.__currentPoint = null;
156
- }
157
- }
158
-
159
- this.__canvas.style.cursor = 'grab';
160
-
161
- this.__map.on('mousemove', this.onMove.bind(this));
162
- this.__map.once('mouseup', this.onUp.bind(this));
163
-
164
- }
165
-
166
- touchStart(e) {
167
- if (e.points.length !== 1) return;
168
-
169
- // Prevent the default map drag behavior.
170
- e.preventDefault();
171
-
172
- this.__map.on('touchmove', this.onMove.bind(this));
173
- this.__map.once('touchend', this.onUp.bind(this));
174
- }
175
-
176
- onMove(e) {
177
- console.log('Mouse move...')
178
-
179
- // Set a UI indicator for dragging.
180
- this.__canvas.style.cursor = 'grabbing'; // ????
181
-
182
- if (this.__currentPoint !== null) {
183
- const coords = e.lngLat;
184
- this.__geojson.features[this.__currentPoint].geometry.coordinates = [coords.lng, coords.lat];
185
- this.__map.getSource('curves').setData(this.__geojson);
186
- }
187
- }
188
-
189
- onUp(e) {
190
- console.log('End draw at', e.lngLat)
191
-
192
- this.__canvas.style.cursor = '';
193
-
194
- // Unbind mouse/touch events
195
- this.__map.off('mousemove', this.onMove.bind(this));
196
- this.__map.off('touchmove', this.onMove.bind(this));
197
- }
198
- }