@abi-software/flatmap-viewer 2.4.0-a.2 → 2.4.1-b.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 +1 -1
- package/package.json +2 -2
- package/src/contextmenu.js +2 -2
- package/src/controls/minimap.js +2 -2
- package/src/controls/systems.js +1 -1
- package/src/controls/taxons.js +73 -0
- package/src/flatmap-viewer.js +66 -10
- package/src/interactions.js +46 -21
- package/src/styling.js +30 -14
- package/src/utils.js +5 -1
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.4.
|
|
41
|
+
* ``npm install @abi-software/flatmap-viewer@2.4.1-b.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.4.
|
|
3
|
+
"version": "2.4.1-b.2",
|
|
4
4
|
"description": "Flatmap viewer using Maplibre GL",
|
|
5
5
|
"repository": "https://github.com/AnatomicMaps/flatmap-viewer.git",
|
|
6
6
|
"main": "src/main.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"bezier-js": "^6.1.0",
|
|
27
27
|
"html-es6cape": "^2.0.2",
|
|
28
28
|
"jspanel4": "^4.16.1",
|
|
29
|
-
"maplibre-gl": ">=
|
|
29
|
+
"maplibre-gl": ">=3.0.0",
|
|
30
30
|
"minisearch": "^2.2.1",
|
|
31
31
|
"polylabel": "^1.1.0"
|
|
32
32
|
},
|
package/src/contextmenu.js
CHANGED
|
@@ -22,7 +22,7 @@ limitations under the License.
|
|
|
22
22
|
|
|
23
23
|
//==============================================================================
|
|
24
24
|
|
|
25
|
-
import
|
|
25
|
+
import maplibregl from 'maplibre-gl';
|
|
26
26
|
|
|
27
27
|
//==============================================================================
|
|
28
28
|
|
|
@@ -64,7 +64,7 @@ export class ContextMenu
|
|
|
64
64
|
this._flatmap = flatmap;
|
|
65
65
|
this._map = flatmap.map;
|
|
66
66
|
this._closeCallback = closeCallback;
|
|
67
|
-
this._popup = new
|
|
67
|
+
this._popup = new maplibregl.Popup({
|
|
68
68
|
closeButton: true,
|
|
69
69
|
closeOnClick: true,
|
|
70
70
|
className: 'flatmap-contextmenu-popup',
|
package/src/controls/minimap.js
CHANGED
|
@@ -45,7 +45,7 @@ limitations under the License.
|
|
|
45
45
|
|
|
46
46
|
//==============================================================================
|
|
47
47
|
|
|
48
|
-
import
|
|
48
|
+
import maplibregl from 'maplibre-gl';
|
|
49
49
|
|
|
50
50
|
//==============================================================================
|
|
51
51
|
|
|
@@ -146,7 +146,7 @@ export class MinimapControl
|
|
|
146
146
|
|
|
147
147
|
// Create the actual minimap
|
|
148
148
|
|
|
149
|
-
this._miniMap = new
|
|
149
|
+
this._miniMap = new maplibregl.Map({
|
|
150
150
|
attributionControl: false,
|
|
151
151
|
container: container,
|
|
152
152
|
style: map.getStyle(),
|
package/src/controls/systems.js
CHANGED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
|
|
3
|
+
Flatmap viewer and annotation tool
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2019 - 2023 David Brooks
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License.
|
|
9
|
+
You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
See the License for the specific language governing permissions and
|
|
17
|
+
limitations under the License.
|
|
18
|
+
|
|
19
|
+
**/
|
|
20
|
+
//==============================================================================
|
|
21
|
+
|
|
22
|
+
import { Control } from './controls';
|
|
23
|
+
|
|
24
|
+
//==============================================================================
|
|
25
|
+
|
|
26
|
+
export class TaxonsControl extends Control
|
|
27
|
+
{
|
|
28
|
+
constructor(flatmap)
|
|
29
|
+
{
|
|
30
|
+
super(flatmap, 'taxon', 'taxons');
|
|
31
|
+
this.__taxonIds = flatmap.taxonIdentifiers.sort();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
_addControlDetails()
|
|
35
|
+
//==================
|
|
36
|
+
{
|
|
37
|
+
let lines = 0;
|
|
38
|
+
let enabled = 0;
|
|
39
|
+
for (const taxonId of this.__taxonIds) {
|
|
40
|
+
const input = this._addControlLine(`${this.__prefix}${taxonId}`, taxonId);
|
|
41
|
+
input.checked = true;
|
|
42
|
+
enabled += 1;
|
|
43
|
+
lines += 1;
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
enabled: enabled,
|
|
47
|
+
total: lines
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
_enableAll(enable)
|
|
52
|
+
//================
|
|
53
|
+
{
|
|
54
|
+
for (const taxonId of this.__taxonIds) {
|
|
55
|
+
const checkbox = document.getElementById(`${this.__prefix}${taxonId}`);
|
|
56
|
+
if (checkbox) {
|
|
57
|
+
checkbox.checked = enable;
|
|
58
|
+
this.__flatmap.enableConnectivityByTaxonIds(taxonId, enable);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
__enableControl(id, enable)
|
|
64
|
+
//=========================
|
|
65
|
+
{
|
|
66
|
+
for (const taxonId of this.__taxonIds) {
|
|
67
|
+
if (id === taxonId) {
|
|
68
|
+
this.__flatmap.enableConnectivityByTaxonIds(taxonId, enable);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
}
|
package/src/flatmap-viewer.js
CHANGED
|
@@ -49,6 +49,15 @@ const MAP_MAKER_SEPARATE_LAYERS_VERSION = 1.4;
|
|
|
49
49
|
|
|
50
50
|
//==============================================================================
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* The taxon identifier used when none has been given.
|
|
54
|
+
*
|
|
55
|
+
* @type {string}
|
|
56
|
+
*/
|
|
57
|
+
export const UNCLASSIFIED_TAXON_ID = 'NCBITaxon:2787823'; // unclassified entries
|
|
58
|
+
|
|
59
|
+
//==============================================================================
|
|
60
|
+
|
|
52
61
|
/**
|
|
53
62
|
* Maps are not created directly but instead are created and loaded by
|
|
54
63
|
* :meth:`LoadMap` of :class:`MapManager`.
|
|
@@ -79,6 +88,7 @@ class FlatMap
|
|
|
79
88
|
this.__modelToFeatureIds = new Map();
|
|
80
89
|
this.__mapSourceToFeatureIds = new Map();
|
|
81
90
|
this.__annIdToFeatureId = new Map();
|
|
91
|
+
this.__taxonToFeatureIds = new Map();
|
|
82
92
|
|
|
83
93
|
for (const [featureId, annotation] of Object.entries(mapDescription.annotations)) {
|
|
84
94
|
this.__addAnnotation(featureId, annotation);
|
|
@@ -331,6 +341,26 @@ class FlatMap
|
|
|
331
341
|
}
|
|
332
342
|
}
|
|
333
343
|
|
|
344
|
+
/**
|
|
345
|
+
* Show or hide connectivity features observed in particular species.
|
|
346
|
+
*
|
|
347
|
+
* @param {string | Array.<string>} taxonId(s) A single taxon identifier
|
|
348
|
+
* or an array of identifiers.
|
|
349
|
+
* @param {boolean} enable Show or hide connectivity paths and features.
|
|
350
|
+
* Defaults to ``true`` (show)
|
|
351
|
+
*/
|
|
352
|
+
enableConnectivityByTaxonIds(taxonIds, enable=true)
|
|
353
|
+
//=================================================
|
|
354
|
+
{
|
|
355
|
+
if (this._userInteractions !== null) {
|
|
356
|
+
if (Array.isArray(taxonIds)) {
|
|
357
|
+
this._userInteractions.enableConnectivityByTaxonIds(taxonIds, enable);
|
|
358
|
+
} else {
|
|
359
|
+
this._userInteractions.enableConnectivityByTaxonIds([taxonIds], enable);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
334
364
|
/**
|
|
335
365
|
* Hide or show centrelines and nodes.
|
|
336
366
|
*
|
|
@@ -511,17 +541,31 @@ class FlatMap
|
|
|
511
541
|
}
|
|
512
542
|
}
|
|
513
543
|
|
|
514
|
-
|
|
544
|
+
__updateFeatureIdMapEntry(propertyId, featureIdMap, featureId)
|
|
515
545
|
//======================================================
|
|
516
546
|
{
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
547
|
+
const featureIds = featureIdMap.get(propertyId);
|
|
548
|
+
if (featureIds) {
|
|
549
|
+
featureIds.push(featureId);
|
|
550
|
+
} else {
|
|
551
|
+
featureIdMap.set(propertyId, [featureId]);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
__updateFeatureIdMap(property, featureIdMap, annotation, missingId=null)
|
|
556
|
+
//======================================================================
|
|
557
|
+
{
|
|
558
|
+
if (property in annotation && annotation[property].length) {
|
|
559
|
+
const propertyId = annotation[property];
|
|
560
|
+
if (Array.isArray(propertyId)) {
|
|
561
|
+
for (const id of propertyId) {
|
|
562
|
+
this.__updateFeatureIdMapEntry(id, featureIdMap, annotation.featureId);
|
|
563
|
+
}
|
|
522
564
|
} else {
|
|
523
|
-
|
|
565
|
+
this.__updateFeatureIdMapEntry(propertyId, featureIdMap, annotation.featureId);
|
|
524
566
|
}
|
|
567
|
+
} else if (missingId !== null) {
|
|
568
|
+
this.__updateFeatureIdMapEntry(missingId, featureIdMap, annotation.featureId);
|
|
525
569
|
}
|
|
526
570
|
}
|
|
527
571
|
|
|
@@ -533,6 +577,7 @@ class FlatMap
|
|
|
533
577
|
this.__updateFeatureIdMap('dataset', this.__datasetToFeatureIds, ann);
|
|
534
578
|
this.__updateFeatureIdMap('models', this.__modelToFeatureIds, ann);
|
|
535
579
|
this.__updateFeatureIdMap('source', this.__mapSourceToFeatureIds, ann);
|
|
580
|
+
this.__updateFeatureIdMap('taxons', this.__taxonToFeatureIds, ann, UNCLASSIFIED_TAXON_ID);
|
|
536
581
|
this.__annIdToFeatureId.set(ann.id, featureId);
|
|
537
582
|
}
|
|
538
583
|
|
|
@@ -610,6 +655,17 @@ class FlatMap
|
|
|
610
655
|
return [...this.__modelToFeatureIds.keys()]
|
|
611
656
|
}
|
|
612
657
|
|
|
658
|
+
/**
|
|
659
|
+
* The taxon identifiers of species which the map's connectivity has been observed in.
|
|
660
|
+
*
|
|
661
|
+
* @type {string|Array.<string>}
|
|
662
|
+
*/
|
|
663
|
+
get taxonIdentifiers()
|
|
664
|
+
//====================
|
|
665
|
+
{
|
|
666
|
+
return [...this.__taxonToFeatureIds.keys()]
|
|
667
|
+
}
|
|
668
|
+
|
|
613
669
|
/**
|
|
614
670
|
* Datasets associated with the map.
|
|
615
671
|
*
|
|
@@ -817,7 +873,7 @@ class FlatMap
|
|
|
817
873
|
/**
|
|
818
874
|
* Get a list of the flatmap's layers.
|
|
819
875
|
*
|
|
820
|
-
* @return {Array
|
|
876
|
+
* @return {Array.<{id: string, description: string, enabled: boolean}>} An array with layer details
|
|
821
877
|
*/
|
|
822
878
|
getLayers()
|
|
823
879
|
//=========
|
|
@@ -845,7 +901,7 @@ class FlatMap
|
|
|
845
901
|
/**
|
|
846
902
|
* Get a list of a FC flatmap's systems.
|
|
847
903
|
*
|
|
848
|
-
* @return {Array
|
|
904
|
+
* @return {Array.<{id: string, name: string, colour: string, enabled: boolean}>} An array with system details
|
|
849
905
|
*/
|
|
850
906
|
getSystems()
|
|
851
907
|
//==========
|
|
@@ -970,7 +1026,7 @@ class FlatMap
|
|
|
970
1026
|
'models',
|
|
971
1027
|
'nodeId',
|
|
972
1028
|
'source',
|
|
973
|
-
'
|
|
1029
|
+
'taxons',
|
|
974
1030
|
'hyperlinks'
|
|
975
1031
|
];
|
|
976
1032
|
const jsonProperties = [
|
package/src/interactions.js
CHANGED
|
@@ -22,7 +22,7 @@ limitations under the License.
|
|
|
22
22
|
|
|
23
23
|
//==============================================================================
|
|
24
24
|
|
|
25
|
-
import
|
|
25
|
+
import maplibregl from 'maplibre-gl';
|
|
26
26
|
|
|
27
27
|
import {default as turfArea} from '@turf/area';
|
|
28
28
|
import {default as turfBBox} from '@turf/bbox';
|
|
@@ -45,6 +45,7 @@ import {AnnotatedControl, BackgroundControl, LayerControl, NerveControl,
|
|
|
45
45
|
import {PathControl} from './controls/paths';
|
|
46
46
|
import {SearchControl} from './controls/search';
|
|
47
47
|
import {SystemsControl} from './controls/systems';
|
|
48
|
+
import {TaxonsControl} from './controls/taxons';
|
|
48
49
|
|
|
49
50
|
import * as utils from './utils';
|
|
50
51
|
|
|
@@ -80,12 +81,13 @@ function bounds(feature)
|
|
|
80
81
|
|
|
81
82
|
//==============================================================================
|
|
82
83
|
|
|
83
|
-
function expandBounds(bbox1, bbox2)
|
|
84
|
-
|
|
84
|
+
function expandBounds(bbox1, bbox2, padding)
|
|
85
|
+
//==========================================
|
|
85
86
|
{
|
|
86
|
-
return (bbox1 === null) ? bbox2
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
return (bbox1 === null) ? [bbox2[0]-padding.lng, bbox2[1]-padding.lat,
|
|
88
|
+
bbox2[2]+padding.lng, bbox2[3]+padding.lat]
|
|
89
|
+
: [Math.min(bbox1[0], bbox2[0]-padding.lng), Math.min(bbox1[1], bbox2[1]-padding.lat),
|
|
90
|
+
Math.max(bbox1[2], bbox2[2]+padding.lng), Math.max(bbox1[3], bbox2[3]+padding.lat)
|
|
89
91
|
];
|
|
90
92
|
}
|
|
91
93
|
|
|
@@ -158,11 +160,12 @@ export class UserInteractions
|
|
|
158
160
|
}
|
|
159
161
|
|
|
160
162
|
// Note features that are FC systems
|
|
161
|
-
|
|
162
163
|
this.__systemsManager = new SystemsManager(this._flatmap, this, featuresEnabled);
|
|
163
164
|
|
|
164
|
-
//
|
|
165
|
+
// All taxons of connectivity paths are enabled by default
|
|
166
|
+
this.__enabledConnectivityTaxons = new Set(this._flatmap.taxonIdentifiers);
|
|
165
167
|
|
|
168
|
+
// Add various controls when running standalone
|
|
166
169
|
if (flatmap.options.standalone) {
|
|
167
170
|
// Add a control to search annotations if option set
|
|
168
171
|
this._map.addControl(new SearchControl(flatmap));
|
|
@@ -185,11 +188,14 @@ export class UserInteractions
|
|
|
185
188
|
this._map.addControl(new NerveControl(flatmap, this._layerManager, {showCentrelines: false}));
|
|
186
189
|
}
|
|
187
190
|
|
|
188
|
-
// SCKAN path and SYSTEMS controls for FC maps
|
|
189
191
|
if (flatmap.options.style === 'functional') {
|
|
192
|
+
// SCKAN path and SYSTEMS controls for FC maps
|
|
190
193
|
this._map.addControl(new SystemsControl(flatmap, this.__systemsManager.systems));
|
|
191
194
|
this._map.addControl(new SCKANControl(flatmap, flatmap.options.layerOptions));
|
|
192
195
|
this._map.addControl(new AnnotatedControl(this, flatmap.options.layerOptions));
|
|
196
|
+
} else {
|
|
197
|
+
// Connectivity taxon control for AC maps
|
|
198
|
+
this._map.addControl(new TaxonsControl(flatmap));
|
|
193
199
|
}
|
|
194
200
|
}
|
|
195
201
|
|
|
@@ -615,7 +621,7 @@ export class UserInteractions
|
|
|
615
621
|
{
|
|
616
622
|
options = utils.setDefaults(options, {
|
|
617
623
|
noZoomIn: false,
|
|
618
|
-
padding: 10
|
|
624
|
+
padding: 10 // pixels
|
|
619
625
|
});
|
|
620
626
|
if (featureIds.length) {
|
|
621
627
|
this.unselectFeatures();
|
|
@@ -624,16 +630,20 @@ export class UserInteractions
|
|
|
624
630
|
const bounds = this._map.getBounds().toArray();
|
|
625
631
|
bbox = [...bounds[0], ...bounds[1]];
|
|
626
632
|
}
|
|
633
|
+
// Convert pixel padding to LngLat and apply it to a feature's bounds
|
|
634
|
+
const padding = this._map.unproject({x: options.padding, y: options.padding});
|
|
635
|
+
padding.lng -= bbox[0];
|
|
636
|
+
padding.lat = bbox[3] - padding.lat;
|
|
627
637
|
for (const featureId of featureIds) {
|
|
628
638
|
const annotation = this._flatmap.annotation(featureId);
|
|
629
639
|
if (annotation) {
|
|
630
640
|
if (this.selectFeature(featureId)) {
|
|
631
|
-
bbox = expandBounds(bbox, annotation.bounds);
|
|
641
|
+
bbox = expandBounds(bbox, annotation.bounds, padding);
|
|
632
642
|
if ('type' in annotation && annotation.type.startsWith('line')) {
|
|
633
643
|
for (const pathFeatureId of this.__pathManager.lineFeatureIds([featureId])) {
|
|
634
644
|
if (this.selectFeature(pathFeatureId)) {
|
|
635
645
|
const pathAnnotation = this._flatmap.annotation(pathFeatureId)
|
|
636
|
-
bbox = expandBounds(bbox, pathAnnotation.bounds);
|
|
646
|
+
bbox = expandBounds(bbox, pathAnnotation.bounds, padding);
|
|
637
647
|
}
|
|
638
648
|
}
|
|
639
649
|
}
|
|
@@ -642,7 +652,7 @@ export class UserInteractions
|
|
|
642
652
|
}
|
|
643
653
|
if (bbox !== null) {
|
|
644
654
|
this._map.fitBounds(bbox, {
|
|
645
|
-
padding:
|
|
655
|
+
padding: 0,
|
|
646
656
|
animate: false
|
|
647
657
|
});
|
|
648
658
|
}
|
|
@@ -694,7 +704,7 @@ export class UserInteractions
|
|
|
694
704
|
this._map.panTo(location);
|
|
695
705
|
}
|
|
696
706
|
this.setModal_();
|
|
697
|
-
this._currentPopup = new
|
|
707
|
+
this._currentPopup = new maplibregl.Popup(options).addTo(this._map);
|
|
698
708
|
this._currentPopup.on('close', this.__onCloseCurrentPopup.bind(this));
|
|
699
709
|
this._currentPopup.setLngLat(location);
|
|
700
710
|
if (typeof content === 'object') {
|
|
@@ -955,7 +965,7 @@ export class UserInteractions
|
|
|
955
965
|
html = `<span>${header}</span><br/>${html}`;
|
|
956
966
|
}
|
|
957
967
|
if (html !== '') {
|
|
958
|
-
this._tooltip = new
|
|
968
|
+
this._tooltip = new maplibregl.Popup({
|
|
959
969
|
closeButton: false,
|
|
960
970
|
closeOnClick: false,
|
|
961
971
|
maxWidth: 'none',
|
|
@@ -1127,6 +1137,21 @@ export class UserInteractions
|
|
|
1127
1137
|
this._layerManager.enableSckanPaths(sckanState, enable);
|
|
1128
1138
|
}
|
|
1129
1139
|
|
|
1140
|
+
enableConnectivityByTaxonIds(taxonIds, enable=true)
|
|
1141
|
+
//=================================================
|
|
1142
|
+
{
|
|
1143
|
+
if (enable) {
|
|
1144
|
+
for (const taxonId of taxonIds) {
|
|
1145
|
+
this.__enabledConnectivityTaxons.add(taxonId);
|
|
1146
|
+
}
|
|
1147
|
+
} else {
|
|
1148
|
+
for (const taxonId of taxonIds) {
|
|
1149
|
+
this.__enabledConnectivityTaxons.delete(taxonId);
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
this._layerManager.setFilter({taxons: [...this.__enabledConnectivityTaxons.values()]});
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1130
1155
|
excludeAnnotated(exclude=false)
|
|
1131
1156
|
//=============================
|
|
1132
1157
|
{
|
|
@@ -1190,8 +1215,8 @@ export class UserInteractions
|
|
|
1190
1215
|
// order to apply a scale transform we need to create marker icons
|
|
1191
1216
|
// inside the marker container <div>.
|
|
1192
1217
|
const colour = options.colour || '#005974';
|
|
1193
|
-
const markerHTML = options.element ? new
|
|
1194
|
-
: new
|
|
1218
|
+
const markerHTML = options.element ? new maplibregl.Marker({element: options.element})
|
|
1219
|
+
: new maplibregl.Marker({color: colour});
|
|
1195
1220
|
|
|
1196
1221
|
const markerElement = document.createElement('div');
|
|
1197
1222
|
const markerIcon = document.createElement('div');
|
|
@@ -1201,9 +1226,9 @@ export class UserInteractions
|
|
|
1201
1226
|
markerElement.appendChild(markerIcon);
|
|
1202
1227
|
|
|
1203
1228
|
const markerPosition = this.__markerPosition(featureId, annotation);
|
|
1204
|
-
const marker = new
|
|
1205
|
-
|
|
1206
|
-
|
|
1229
|
+
const marker = new maplibregl.Marker(markerElement)
|
|
1230
|
+
.setLngLat(markerPosition)
|
|
1231
|
+
.addTo(this._map);
|
|
1207
1232
|
markerElement.addEventListener('mouseenter',
|
|
1208
1233
|
this.markerMouseEvent_.bind(this, marker, anatomicalId));
|
|
1209
1234
|
markerElement.addEventListener('mousemove',
|
|
@@ -1345,7 +1370,7 @@ export class UserInteractions
|
|
|
1345
1370
|
|
|
1346
1371
|
element.addEventListener('click', e => this.__clearActiveMarker());
|
|
1347
1372
|
|
|
1348
|
-
this._tooltip = new
|
|
1373
|
+
this._tooltip = new maplibregl.Popup({
|
|
1349
1374
|
closeButton: false,
|
|
1350
1375
|
closeOnClick: false,
|
|
1351
1376
|
maxWidth: 'none',
|
package/src/styling.js
CHANGED
|
@@ -26,7 +26,8 @@ export const VECTOR_TILES_SOURCE = 'vector-tiles';
|
|
|
26
26
|
|
|
27
27
|
//==============================================================================
|
|
28
28
|
|
|
29
|
-
import {
|
|
29
|
+
import {UNCLASSIFIED_TAXON_ID} from './flatmap-viewer';
|
|
30
|
+
import {PATH_STYLE_RULES} from './pathways';
|
|
30
31
|
|
|
31
32
|
//==============================================================================
|
|
32
33
|
|
|
@@ -374,24 +375,24 @@ function sckanFilter(options)
|
|
|
374
375
|
: options.sckan.toLowerCase();
|
|
375
376
|
const sckanFilter =
|
|
376
377
|
sckanState == 'none' ? [
|
|
377
|
-
['!has', 'sckan']
|
|
378
|
+
['!', ['has', 'sckan']]
|
|
378
379
|
] :
|
|
379
380
|
sckanState == 'valid' ? [[
|
|
380
381
|
'any',
|
|
381
|
-
['!has', 'sckan'],
|
|
382
|
+
['!', ['has', 'sckan']],
|
|
382
383
|
[
|
|
383
384
|
'all',
|
|
384
385
|
['has', 'sckan'],
|
|
385
|
-
['==', 'sckan', true]
|
|
386
|
+
['==', ['get', 'sckan'], true]
|
|
386
387
|
]
|
|
387
388
|
]] :
|
|
388
389
|
sckanState == 'invalid' ? [[
|
|
389
390
|
'any',
|
|
390
|
-
['!has', 'sckan'],
|
|
391
|
+
['!', ['has', 'sckan']],
|
|
391
392
|
[
|
|
392
393
|
'all',
|
|
393
394
|
['has', 'sckan'],
|
|
394
|
-
['!=', 'sckan', true]
|
|
395
|
+
['!=', ['get', 'sckan'], true]
|
|
395
396
|
]
|
|
396
397
|
]] :
|
|
397
398
|
[ ];
|
|
@@ -411,7 +412,6 @@ export class AnnotatedPathLayer extends VectorStyleLayer
|
|
|
411
412
|
{
|
|
412
413
|
return [
|
|
413
414
|
'all',
|
|
414
|
-
['==', '$type', 'LineString'],
|
|
415
415
|
...sckanFilter(options)
|
|
416
416
|
];
|
|
417
417
|
}
|
|
@@ -481,22 +481,38 @@ export class PathLineLayer extends VectorStyleLayer
|
|
|
481
481
|
makeFilter(options={})
|
|
482
482
|
{
|
|
483
483
|
const sckan_filter = sckanFilter(options);
|
|
484
|
+
let taxonFilter = [];
|
|
485
|
+
if ('taxons' in options) {
|
|
486
|
+
if (options.taxons.length) {
|
|
487
|
+
taxonFilter.push('any');
|
|
488
|
+
for (const taxon of options.taxons) {
|
|
489
|
+
if (taxon !== UNCLASSIFIED_TAXON_ID) {
|
|
490
|
+
taxonFilter.push(['in', taxon, ['get', 'taxons']]);
|
|
491
|
+
} else {
|
|
492
|
+
taxonFilter.push(['case', ['has', 'taxons'], false, true]);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
taxonFilter = [taxonFilter];
|
|
496
|
+
} else {
|
|
497
|
+
taxonFilter.push(false);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
484
500
|
|
|
485
501
|
return this.__dashed ? [
|
|
486
502
|
'all',
|
|
487
|
-
['==', '
|
|
488
|
-
|
|
489
|
-
...
|
|
503
|
+
['==', ['get', 'type'], 'line-dash'],
|
|
504
|
+
...sckan_filter,
|
|
505
|
+
...taxonFilter
|
|
490
506
|
] : [
|
|
491
507
|
'all',
|
|
492
|
-
['==', '$type', 'LineString'],
|
|
493
508
|
[
|
|
494
509
|
'any',
|
|
495
|
-
['==', 'type', 'bezier'],
|
|
510
|
+
['==', ['get', 'type'], 'bezier'],
|
|
496
511
|
[
|
|
497
512
|
'all',
|
|
498
|
-
['==', 'type',
|
|
499
|
-
...sckan_filter
|
|
513
|
+
['==', ['get', 'type'], 'line'],
|
|
514
|
+
...sckan_filter,
|
|
515
|
+
...taxonFilter
|
|
500
516
|
]
|
|
501
517
|
]
|
|
502
518
|
];
|
package/src/utils.js
CHANGED
|
@@ -22,6 +22,10 @@ limitations under the License.
|
|
|
22
22
|
|
|
23
23
|
//==============================================================================
|
|
24
24
|
|
|
25
|
+
const NO_NORMALISATION = ['http', 'https', 'urn', 'NCBITaxon'];
|
|
26
|
+
|
|
27
|
+
//==============================================================================
|
|
28
|
+
|
|
25
29
|
export class List extends Array {
|
|
26
30
|
constructor(iterable=null) {
|
|
27
31
|
super();
|
|
@@ -101,7 +105,7 @@ export function normaliseId(id)
|
|
|
101
105
|
}
|
|
102
106
|
const parts = id.split(':')
|
|
103
107
|
const lastPart = parts[parts.length - 1]
|
|
104
|
-
if (
|
|
108
|
+
if (NO_NORMALISATION.includes(parts[0]) || !'0123456789'.includes(lastPart[0])) {
|
|
105
109
|
return id;
|
|
106
110
|
}
|
|
107
111
|
parts[parts.length - 1] = lastPart.padStart(8, '0');
|