@abi-software/flatmap-viewer 2.6.1 → 2.6.2

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 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.6.1``
41
+ * ``npm install @abi-software/flatmap-viewer@2.6.2``
42
42
 
43
43
  Documentation
44
44
  -------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/flatmap-viewer",
3
- "version": "2.6.1",
3
+ "version": "2.6.2",
4
4
  "description": "Flatmap viewer using Maplibre GL",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,7 +18,7 @@ limitations under the License.
18
18
 
19
19
  ******************************************************************************/
20
20
 
21
- export class Path3DControl
21
+ export class FlightPathControl
22
22
  {
23
23
  #button
24
24
  #container
@@ -26,9 +26,10 @@ export class Path3DControl
26
26
  #map = null
27
27
  #flatmap
28
28
 
29
- constructor(flatmap)
29
+ constructor(flatmap, enabled)
30
30
  {
31
31
  this.#flatmap = flatmap
32
+ this.#enabled = !!enabled
32
33
  }
33
34
 
34
35
  getDefaultPosition()
@@ -46,11 +47,15 @@ export class Path3DControl
46
47
  this.#button = document.createElement('button')
47
48
  this.#button.className = 'control-button text-button'
48
49
  this.#button.setAttribute('type', 'button')
49
- this.#button.setAttribute('aria-label', 'Show 3D paths')
50
+ this.#button.setAttribute('aria-label', 'Show flight paths')
50
51
  this.#button.textContent = '3D'
51
- this.#button.title = 'Show/hide 3D paths'
52
+ this.#button.title = 'Show/hide flight paths'
52
53
  this.#container.appendChild(this.#button)
53
54
  this.#container.addEventListener('click', this.onClick.bind(this))
55
+ if (this.#enabled) {
56
+ this.#button.classList.add('control-active')
57
+ this.__setBackground()
58
+ }
54
59
  return this.#container
55
60
  }
56
61
 
@@ -75,11 +80,11 @@ export class Path3DControl
75
80
  //=============
76
81
  {
77
82
  if (this.#button.classList.contains('control-active')) {
78
- this.#flatmap.enable3dPaths(false)
83
+ this.#flatmap.enableFlightPaths(false)
79
84
  this.#button.classList.remove('control-active')
80
85
  this.#enabled = false
81
86
  } else {
82
- this.#flatmap.enable3dPaths(true)
87
+ this.#flatmap.enableFlightPaths(true)
83
88
  this.#button.classList.add('control-active')
84
89
  this.#enabled = true
85
90
  }
@@ -901,15 +901,15 @@ class FlatMap
901
901
  }
902
902
 
903
903
  /**
904
- * Show/hide 3D path view.
904
+ * Show/hide flight path view.
905
905
  *
906
906
  * @param {boolean} [enable=true]
907
907
  */
908
- enable3dPaths(enable=true)
909
- //========================
908
+ enableFlightPaths(enable=true)
909
+ //============================
910
910
  {
911
911
  if (this._userInteractions !== null) {
912
- this._userInteractions.enable3dPaths(enable)
912
+ this._userInteractions.enableFlightPaths(enable)
913
913
  }
914
914
  }
915
915
 
@@ -1569,6 +1569,7 @@ export class MapManager
1569
1569
  * @arg options {Object} Configurable options for the map.
1570
1570
  * @arg options.background {string} Background colour of flatmap. Defaults to ``white``.
1571
1571
  * @arg options.debug {boolean} Enable debugging mode.
1572
+ * @arg options.flightPaths {boolean} Enable flight path (3D) view of neuron paths
1572
1573
  * @arg options.fullscreenControl {boolean} Add a ``Show full screen`` button to the map.
1573
1574
  * @arg options.layerOptions {Object} Options to control colour and outlines of features
1574
1575
  * @arg options.layerOptions.colour {boolean} Use colour fill (if available) for features. Defaults to ``true``.
@@ -43,7 +43,7 @@ import {AnnotatorControl, BackgroundControl, LayerControl, NerveControl,
43
43
  SCKANControl} from './controls/controls';
44
44
  import {AnnotationDrawControl, DRAW_ANNOTATION_LAYERS} from './controls/annotation'
45
45
  import {PathControl} from './controls/paths';
46
- import {Path3DControl} from './controls/paths3d'
46
+ import {FlightPathControl} from './controls/flightpaths'
47
47
  import {SearchControl} from './controls/search';
48
48
  import {MinimapControl} from './controls/minimap';
49
49
  import {SystemsControl} from './controls/systems';
@@ -180,12 +180,14 @@ export class UserInteractions
180
180
  const mapPathTypes = this.__pathManager.pathTypes();
181
181
 
182
182
  // Add and manage our layers. NB. this needs to after we have a
183
- // path manager but before path enabled state is set.
183
+ // path manager but before paths are enabled
184
184
 
185
185
  this._layerManager = new LayerManager(flatmap, this);
186
186
 
187
187
  // Set initial enabled state of paths
188
188
 
189
+ this.__pathManager.enablePathLines(true, true)
190
+
189
191
  for (const path of mapPathTypes) {
190
192
  this.__pathManager.enablePathsByType(path.type, path.enabled, true);
191
193
  }
@@ -251,7 +253,7 @@ export class UserInteractions
251
253
  this._map.addControl(new TaxonsControl(flatmap));
252
254
  }
253
255
 
254
- this._map.addControl(new Path3DControl(this));
256
+ this._map.addControl(new FlightPathControl(this, flatmap.options.flightPaths));
255
257
 
256
258
  if (flatmap.options.annotator) {
257
259
  this._map.addControl(new AnnotatorControl(flatmap));
@@ -265,6 +267,11 @@ export class UserInteractions
265
267
  this.#annotationDrawControl = new AnnotationDrawControl(flatmap, false)
266
268
  this._map.addControl(this.#annotationDrawControl)
267
269
 
270
+ // Set initial path viewing mode
271
+ if (flatmap.options.flightPaths === true) {
272
+ this._layerManager.setFlightPathMode(true)
273
+ }
274
+
268
275
  // Handle mouse events
269
276
 
270
277
  this._map.on('click', this.clickEvent_.bind(this));
@@ -456,10 +463,10 @@ export class UserInteractions
456
463
  this._layerManager.activate(layerId, enable);
457
464
  }
458
465
 
459
- enable3dPaths(enable=true)
460
- //========================
466
+ enableFlightPaths(enable=true)
467
+ //============================
461
468
  {
462
- this._layerManager.set3dMode(enable)
469
+ this._layerManager.setFlightPathMode(enable)
463
470
  }
464
471
 
465
472
  getSystems()
@@ -1305,6 +1312,7 @@ export class UserInteractions
1305
1312
  // Marker handling
1306
1313
 
1307
1314
  __markerPosition(featureId, annotation)
1315
+ //=====================================
1308
1316
  {
1309
1317
  if (this.__markerPositions.has(featureId)) {
1310
1318
  return this.__markerPositions.get(featureId);
@@ -1364,23 +1372,27 @@ export class UserInteractions
1364
1372
  markerOptions.className = options.className;
1365
1373
  }
1366
1374
  const markerPosition = this.__markerPosition(featureId, annotation);
1367
- const marker = new maplibregl.Marker(markerOptions)
1368
- .setLngLat(markerPosition)
1369
- .addTo(this._map);
1370
- markerElement.addEventListener('mouseenter',
1371
- this.markerMouseEvent_.bind(this, marker, anatomicalId));
1372
- markerElement.addEventListener('mousemove',
1373
- this.markerMouseEvent_.bind(this, marker, anatomicalId));
1374
- markerElement.addEventListener('mouseleave',
1375
- this.markerMouseEvent_.bind(this, marker, anatomicalId));
1376
- markerElement.addEventListener('click',
1377
- this.markerMouseEvent_.bind(this, marker, anatomicalId));
1378
-
1379
- this.__markerIdByMarker.set(marker, markerId);
1380
- this.__markerIdByFeatureId.set(+featureId, markerId);
1381
- this.__annotationByMarkerId.set(markerId, annotation);
1382
- if (!this.__featureEnabled(this.mapFeature(+featureId))) {
1383
- markerElement.style.visibility = 'hidden';
1375
+ if (options.cluster && this._layerManager) {
1376
+ this._layerManager.addMarkers([markerPosition])
1377
+ } else {
1378
+ const marker = new maplibregl.Marker(markerOptions)
1379
+ .setLngLat(markerPosition)
1380
+ .addTo(this._map);
1381
+ markerElement.addEventListener('mouseenter',
1382
+ this.markerMouseEvent_.bind(this, marker, anatomicalId));
1383
+ markerElement.addEventListener('mousemove',
1384
+ this.markerMouseEvent_.bind(this, marker, anatomicalId));
1385
+ markerElement.addEventListener('mouseleave',
1386
+ this.markerMouseEvent_.bind(this, marker, anatomicalId));
1387
+ markerElement.addEventListener('click',
1388
+ this.markerMouseEvent_.bind(this, marker, anatomicalId));
1389
+
1390
+ this.__markerIdByMarker.set(marker, markerId);
1391
+ this.__markerIdByFeatureId.set(+featureId, markerId);
1392
+ this.__annotationByMarkerId.set(markerId, annotation);
1393
+ if (!this.__featureEnabled(this.mapFeature(+featureId))) {
1394
+ markerElement.style.visibility = 'hidden';
1395
+ }
1384
1396
  }
1385
1397
  }
1386
1398
  }
@@ -135,7 +135,7 @@ class ArcDashedLayer extends ArcMapLayer
135
135
 
136
136
  //==============================================================================
137
137
 
138
- export class Paths3DLayer
138
+ export class FlightPathLayer
139
139
  {
140
140
  #arcLayers = new Map()
141
141
  #deckOverlay = null
@@ -366,13 +366,14 @@ export class Paths3DLayer
366
366
  source: 'vector-tiles',
367
367
  sourceLayer: `${pickedObject.layer}_${pickedObject['tile-layer']}`,
368
368
  properties: pickedObject,
369
- arc3dLayer: true
369
+ flightPath: true
370
370
  }
371
371
  }
372
372
 
373
373
  #setupDeckOverlay()
374
374
  //=================
375
375
  {
376
+ // One overlay layer for each path style
376
377
  [...this.#pathStyles.values()].filter(style => this.#pathManager.pathTypeEnabled(style.type))
377
378
  .forEach(style => this.#addArcLayer(style.type))
378
379
  this.#deckOverlay = new DeckOverlay({
@@ -27,7 +27,7 @@ import * as utils from '../utils.js';
27
27
 
28
28
  import * as style from './styling.js';
29
29
 
30
- import {Paths3DLayer} from './paths3d'
30
+ import {FlightPathLayer} from './flightpaths'
31
31
  import {PropertiesFilter} from './filter'
32
32
 
33
33
  const FEATURES_LAYER = 'features';
@@ -183,8 +183,8 @@ class MapFeatureLayers extends MapStylingLayers
183
183
  }
184
184
  }
185
185
 
186
- enablePaths2dLayer(visible)
187
- //=========================
186
+ setFlatPathMode(visible)
187
+ //======================
188
188
  {
189
189
  for (const layer of this.#pathLayers) {
190
190
  this.map.setLayoutProperty(layer.id, 'visibility', visible ? 'visible' : 'none')
@@ -266,7 +266,7 @@ class MapRasterLayers extends MapStylingLayers
266
266
  export class LayerManager
267
267
  {
268
268
  #featureLayers = new Map()
269
- #paths3dLayer = null
269
+ #flightPathLayer = null
270
270
  #rasterLayer = null
271
271
 
272
272
  constructor(flatmap, ui)
@@ -306,8 +306,8 @@ export class LayerManager
306
306
  this.__layerOptions));
307
307
  }
308
308
 
309
- // Support 3D path view
310
- this.#paths3dLayer = new Paths3DLayer(flatmap, ui)
309
+ // Support flight path view
310
+ this.#flightPathLayer = new FlightPathLayer(flatmap, ui)
311
311
  }
312
312
 
313
313
  get layers()
@@ -360,8 +360,8 @@ export class LayerManager
360
360
  //====================
361
361
  {
362
362
  let features = []
363
- if (this.#paths3dLayer) {
364
- features = this.#paths3dLayer.queryFeaturesAtPoint(point)
363
+ if (this.#flightPathLayer) {
364
+ features = this.#flightPathLayer.queryFeaturesAtPoint(point)
365
365
  }
366
366
  if (features.length === 0) {
367
367
  features = this.__map.queryRenderedFeatures(point)
@@ -372,16 +372,16 @@ export class LayerManager
372
372
  removeFeatureState(feature, key)
373
373
  //==============================
374
374
  {
375
- if (this.#paths3dLayer) {
376
- this.#paths3dLayer.removeFeatureState(feature.id, key)
375
+ if (this.#flightPathLayer) {
376
+ this.#flightPathLayer.removeFeatureState(feature.id, key)
377
377
  }
378
378
  }
379
379
 
380
380
  setFeatureState(feature, state)
381
381
  //=============================
382
382
  {
383
- if (this.#paths3dLayer) {
384
- this.#paths3dLayer.setFeatureState(feature.id, state)
383
+ if (this.#flightPathLayer) {
384
+ this.#flightPathLayer.setFeatureState(feature.id, state)
385
385
  }
386
386
  }
387
387
 
@@ -395,8 +395,8 @@ export class LayerManager
395
395
  for (const mapLayer of this.#featureLayers.values()) {
396
396
  mapLayer.setPaint(this.__layerOptions)
397
397
  }
398
- if (this.#paths3dLayer) {
399
- this.#paths3dLayer.setPaint(options)
398
+ if (this.#flightPathLayer) {
399
+ this.#flightPathLayer.setPaint(options)
400
400
  }
401
401
  }
402
402
 
@@ -407,7 +407,7 @@ export class LayerManager
407
407
  for (const mapLayer of this.#featureLayers.values()) {
408
408
  mapLayer.setFilter(this.__layerOptions);
409
409
  }
410
- if (this.#paths3dLayer) {
410
+ if (this.#flightPathLayer) {
411
411
  const sckanState = options.sckan || 'valid'
412
412
  const sckanFilter = (sckanState == 'none') ? {NOT: {HAS: 'sckan'}} :
413
413
  (sckanState == 'valid') ? {sckan: true} :
@@ -417,17 +417,17 @@ export class LayerManager
417
417
  if ('taxons' in options) {
418
418
  featureFilter.narrow({taxons: options.taxons})
419
419
  }
420
- this.#paths3dLayer.setFilter(featureFilter)
420
+ this.#flightPathLayer.setFilter(featureFilter)
421
421
  }
422
422
  }
423
423
 
424
- set3dMode(enable=true)
425
- //====================
424
+ setFlightPathMode(enable=true)
425
+ //============================
426
426
  {
427
- if (this.#paths3dLayer) {
428
- this.#paths3dLayer.enable(enable)
427
+ if (this.#flightPathLayer) {
428
+ this.#flightPathLayer.enable(enable)
429
429
  for (const mapLayer of this.#featureLayers.values()) {
430
- mapLayer.enablePaths2dLayer(!enable)
430
+ mapLayer.setFlatPathMode(!enable)
431
431
  }
432
432
  }
433
433
  }
package/src/pathways.js CHANGED
@@ -92,9 +92,6 @@ export class PathManager
92
92
  pathLines[pathId] = path.lines;
93
93
  pathNerves[pathId] = path.nerves;
94
94
  this.__paths[pathId] = path;
95
- for (const lineId of path.lines) {
96
- this.__ui.enableFeature(lineId, enabled, true);
97
- }
98
95
  this.__paths[pathId].systemCount = 0;
99
96
  if ('models' in path) {
100
97
  const modelId = path['models'];
@@ -316,6 +313,14 @@ export class PathManager
316
313
  return featureIds;
317
314
  }
318
315
 
316
+ enablePathLines(enable, force=false)
317
+ //==================================
318
+ {
319
+ for (const lineId of Object.keys(this.__pathsByLine)) {
320
+ this.__ui.enableFeature(lineId, enable, force)
321
+ }
322
+ }
323
+
319
324
  enablePathsBySystem(system, enable, force=false)
320
325
  //==============================================
321
326
  {