mapshaper 0.6.112 → 0.6.113
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/mapshaper.js +386 -197
- package/package.json +3 -2
- package/www/basemap.js +6 -4
- package/www/elements.css +1 -1
- package/www/images/eye3.png +0 -0
- package/www/index.html +27 -8
- package/www/mapshaper-gui.js +227 -56
- package/www/mapshaper.js +386 -197
- package/www/modules.js +147 -0
- package/www/page.css +71 -34
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapshaper",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.113",
|
|
4
4
|
"description": "A tool for editing vector datasets for mapping and GIS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shapefile",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"delaunator": "^5.0.0",
|
|
53
53
|
"fflate": "0.8.2",
|
|
54
54
|
"flatbush": "^3.2.1",
|
|
55
|
+
"geographiclib-geodesic": "^2.2.0",
|
|
55
56
|
"geokdbush": "^1.1.0",
|
|
56
57
|
"iconv-lite": "^0.6.3",
|
|
57
58
|
"idb-keyval": "^6.2.0",
|
|
@@ -60,7 +61,7 @@
|
|
|
60
61
|
"msgpackr": "^1.10.1",
|
|
61
62
|
"opn": "^5.3.0",
|
|
62
63
|
"rw": "~1.3.3",
|
|
63
|
-
"sync-request": "
|
|
64
|
+
"sync-request": "6.1.0",
|
|
64
65
|
"tinyqueue": "^2.0.3"
|
|
65
66
|
},
|
|
66
67
|
"devDependencies": {
|
package/www/basemap.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
window.mapboxParams = {
|
|
2
|
-
js: 'https://api.mapbox.com/mapbox-gl-js/v2.11.1/mapbox-gl.js',
|
|
3
|
-
css: 'https://api.mapbox.com/mapbox-gl-js/v2.11.1/mapbox-gl.css',
|
|
2
|
+
// js: 'https://api.mapbox.com/mapbox-gl-js/v2.11.1/mapbox-gl.js',
|
|
3
|
+
// css: 'https://api.mapbox.com/mapbox-gl-js/v2.11.1/mapbox-gl.css',
|
|
4
|
+
js: 'https://api.mapbox.com/mapbox-gl-js/v3.15.0/mapbox-gl.js',
|
|
5
|
+
css: 'https://api.mapbox.com/mapbox-gl-js/v3.15.0/mapbox-gl.css',
|
|
4
6
|
production_key: 'pk.eyJ1IjoiZ3JhbW1hdGEiLCJhIjoiY21jZ2RlbGk1MGhvNzJrcHV2dTYzZWE2byJ9.btkRnRrPW75c0AlQ5lH2cg',
|
|
5
7
|
localhost_key: 'pk.eyJ1IjoiZ3JhbW1hdGEiLCJhIjoiY21jZ2Rna2hrMGo2ZjJqcHFxMHAycDlyMSJ9.q8FchhB-NAN_FGBHN0AJeg',
|
|
6
8
|
styles: [{
|
|
7
|
-
name: '
|
|
9
|
+
name: 'Reference map',
|
|
8
10
|
icon: 'images/thumb-map.jpg',
|
|
9
11
|
url: 'mapbox://styles/grammata/cl0ymri0f000214lc1mgtweqk'
|
|
10
12
|
}, {
|
|
11
|
-
name: 'Satellite',
|
|
13
|
+
name: 'Satellite image',
|
|
12
14
|
icon: 'images/thumb-satellite.jpg',
|
|
13
15
|
dark: true,
|
|
14
16
|
url: 'mapbox://styles/grammata/cl0ymvkkl004115mlgf5o442n'
|
package/www/elements.css
CHANGED
|
Binary file
|
package/www/index.html
CHANGED
|
@@ -164,7 +164,29 @@ precision=0.001. Click to see all options.</div></div></div></a>
|
|
|
164
164
|
</div>
|
|
165
165
|
|
|
166
166
|
<div class="display-options main-area popup-dialog">
|
|
167
|
-
|
|
167
|
+
|
|
168
|
+
<div class="info-box add-basemap-menu">
|
|
169
|
+
<!-- <div class="close2-btn"></div> -->
|
|
170
|
+
<h3>Add basemap layer</h3>
|
|
171
|
+
Name (optional)
|
|
172
|
+
<input type="text" class="add-layer-name" placeholder="">
|
|
173
|
+
<div class="menu-section">
|
|
174
|
+
Option 1: Mapbox style URL and key
|
|
175
|
+
<input type="text" class="add-mapbox-url" placeholder="mapbox://...">
|
|
176
|
+
<input type="text" class="add-mapbox-key" placeholder="key">
|
|
177
|
+
</div>
|
|
178
|
+
<div class="menu-section">
|
|
179
|
+
Option 2: raster tile URL template
|
|
180
|
+
<input type="text" class="add-template-url" placeholder="https://...">
|
|
181
|
+
<div><input type="checkbox" class="tms">TMS (reversed y-index)</div>
|
|
182
|
+
</div>
|
|
183
|
+
<div>
|
|
184
|
+
<div class="add-layer-btn btn dialog-btn">Add</div>
|
|
185
|
+
<div class="add-cancel-btn btn dialog-btn">Cancel</div>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
|
|
189
|
+
<div class="info-box display-main-options">
|
|
168
190
|
<div class="close2-btn"></div>
|
|
169
191
|
<h3>Display options</h3>
|
|
170
192
|
|
|
@@ -174,14 +196,11 @@ precision=0.001. Click to see all options.</div></div></div></a>
|
|
|
174
196
|
<div class="basemap-opts">
|
|
175
197
|
<h4>Basemaps</h4>
|
|
176
198
|
<p class="basemap-warning"></p>
|
|
177
|
-
<div class="basemap-styles basemap-buttons"></div>
|
|
178
|
-
<
|
|
179
|
-
<div>
|
|
180
|
-
<!-- <div class="close-btn btn dialog-btn">Close</div> -->
|
|
181
|
-
<div class="clear-btn btn dialog-btn disabled">Clear</div>
|
|
182
|
-
<div class="fade-btn btn dialog-btn disabled">Fade</div>
|
|
183
|
-
<!-- <div class="hide-btn btn dialog-btn disabled">Hide</div> -->
|
|
199
|
+
<!-- <div class="basemap-styles basemap-buttons"></div> -->
|
|
200
|
+
<div class="added-basemaps">
|
|
184
201
|
</div>
|
|
202
|
+
<p class="basemap-note"></p>
|
|
203
|
+
<div class="add-basemap"><span class="add-btn inline-btn btn">Add</span> a basemap</div>
|
|
185
204
|
</div>
|
|
186
205
|
</div>
|
|
187
206
|
</div>
|
package/www/mapshaper-gui.js
CHANGED
|
@@ -655,9 +655,14 @@
|
|
|
655
655
|
},
|
|
656
656
|
|
|
657
657
|
show: function(css) {
|
|
658
|
-
var tag = this.el && this.el.tagName;
|
|
658
|
+
// var tag = this.el && this.el.tagName;
|
|
659
659
|
if (!this.visible()) {
|
|
660
|
-
|
|
660
|
+
// don't assume 'display:block'
|
|
661
|
+
this.el?.style.removeProperty('display');
|
|
662
|
+
if (this.computedStyle().display == 'none') {
|
|
663
|
+
this.css('display', 'block');
|
|
664
|
+
}
|
|
665
|
+
// this.css('display', tag == 'SPAN' ? 'inline-block' : 'block');
|
|
661
666
|
this._hidden = false;
|
|
662
667
|
}
|
|
663
668
|
return this;
|
|
@@ -666,13 +671,15 @@
|
|
|
666
671
|
html: function(html) {
|
|
667
672
|
if (arguments.length == 0) {
|
|
668
673
|
return this.el.innerHTML;
|
|
669
|
-
} else {
|
|
670
|
-
this.el.innerHTML = html;
|
|
671
|
-
return this;
|
|
672
674
|
}
|
|
675
|
+
this.el.innerHTML = html;
|
|
676
|
+
return this;
|
|
673
677
|
},
|
|
674
678
|
|
|
675
679
|
text: function(str) {
|
|
680
|
+
if (arguments.length == 0) {
|
|
681
|
+
return this.el.innerText;
|
|
682
|
+
}
|
|
676
683
|
this.html(utils$1.htmlEscape(str));
|
|
677
684
|
return this;
|
|
678
685
|
},
|
|
@@ -1936,6 +1943,7 @@
|
|
|
1936
1943
|
.on('drop', ondrop)
|
|
1937
1944
|
.on('paste', onpaste);
|
|
1938
1945
|
area.node().addEventListener('paste', onpaste);
|
|
1946
|
+
// TODO: use same function for drop and paste
|
|
1939
1947
|
function ondrop(e) {
|
|
1940
1948
|
var files = e.dataTransfer.files;
|
|
1941
1949
|
var types = e.dataTransfer.types;
|
|
@@ -1946,7 +1954,7 @@
|
|
|
1946
1954
|
cb(e.dataTransfer.getData('text/uri-list').split(','));
|
|
1947
1955
|
} else if (types.includes('text/html')) {
|
|
1948
1956
|
// drag-dropping a highlighted link may pull in a chunk of html
|
|
1949
|
-
var urls = e.dataTransfer.getData('text/html')
|
|
1957
|
+
var urls = pastedHtmlToUrls(e.dataTransfer.getData('text/html'));
|
|
1950
1958
|
if (urls.length) {
|
|
1951
1959
|
cb(urls);
|
|
1952
1960
|
}
|
|
@@ -1955,7 +1963,7 @@
|
|
|
1955
1963
|
function onpaste(e) {
|
|
1956
1964
|
var types = Array.from(e.clipboardData.types || []).join(',');
|
|
1957
1965
|
var items = Array.from(e.clipboardData.items || []);
|
|
1958
|
-
var files;
|
|
1966
|
+
var files, str, urls;
|
|
1959
1967
|
if (GUI.textIsSelected()) {
|
|
1960
1968
|
// user is probably pasting text into an editable text field
|
|
1961
1969
|
return;
|
|
@@ -1971,12 +1979,22 @@
|
|
|
1971
1979
|
// formatted text can be available as both text/plain and text/html (e.g.
|
|
1972
1980
|
// a JSON data object copied from a GitHub issue).
|
|
1973
1981
|
//
|
|
1982
|
+
|
|
1983
|
+
// if html is present, it could be data (e.g. from Google Sheets) or a pasted link.
|
|
1984
|
+
// first we check for a link
|
|
1985
|
+
if (types.includes('text/html')) {
|
|
1986
|
+
urls = pastedHtmlToUrls(e.clipboardData.getData('text/html'));
|
|
1987
|
+
if (urls.length) {
|
|
1988
|
+
return cb(urls);
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1974
1991
|
if (types.includes('text/plain')) {
|
|
1975
1992
|
// text from clipboard (supported by Chrome, FF, Safari)
|
|
1976
1993
|
// TODO: handle FF case of string containing multiple file names.
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1994
|
+
str = e.clipboardData.getData('text/plain');
|
|
1995
|
+
urls = pastedTextToUrls(str);
|
|
1996
|
+
if (urls.length) {
|
|
1997
|
+
return cb(urls);
|
|
1980
1998
|
}
|
|
1981
1999
|
files = [pastedTextToFile(str)];
|
|
1982
2000
|
} else {
|
|
@@ -1998,6 +2016,21 @@
|
|
|
1998
2016
|
}
|
|
1999
2017
|
}
|
|
2000
2018
|
|
|
2019
|
+
function pastedHtmlToUrls(html) {
|
|
2020
|
+
var hrefRegex = /href\s*=\s*["']([^"']+)["']/gi;
|
|
2021
|
+
var matches = html.matchAll(hrefRegex);
|
|
2022
|
+
var urls = Array.from(matches, match => match[1]);
|
|
2023
|
+
return urls;
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
function pastedTextToUrls(str) {
|
|
2027
|
+
if (!looksLikeUrl(str)) return [];
|
|
2028
|
+
var regex = /https?:\/\/[^\s]+?(?=[\s,]|$)/g;
|
|
2029
|
+
var matches = str.matchAll(regex);
|
|
2030
|
+
var urls = Array.from(matches, match => match[0]);
|
|
2031
|
+
return urls;
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2001
2034
|
function pastedTextToFile(str) {
|
|
2002
2035
|
var type = internal.guessInputContentType(str);
|
|
2003
2036
|
var name;
|
|
@@ -2012,7 +2045,7 @@
|
|
|
2012
2045
|
return new File([blob], name);
|
|
2013
2046
|
}
|
|
2014
2047
|
|
|
2015
|
-
function
|
|
2048
|
+
function looksLikeUrl(str) {
|
|
2016
2049
|
return /^https?:\/\//.test(str);
|
|
2017
2050
|
}
|
|
2018
2051
|
|
|
@@ -2340,7 +2373,7 @@
|
|
|
2340
2373
|
function prepFilesForDownload(names) {
|
|
2341
2374
|
var items = names.map(function(name) {
|
|
2342
2375
|
var item = {name: name};
|
|
2343
|
-
if (
|
|
2376
|
+
if (looksLikeUrl(name)) {
|
|
2344
2377
|
item.url = name;
|
|
2345
2378
|
item.basename = GUI.getUrlFilename(name);
|
|
2346
2379
|
|
|
@@ -13548,6 +13581,12 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13548
13581
|
});
|
|
13549
13582
|
}
|
|
13550
13583
|
|
|
13584
|
+
var EMPTY_STYLE = {
|
|
13585
|
+
version: 8,
|
|
13586
|
+
sources: {},
|
|
13587
|
+
layers: []
|
|
13588
|
+
};
|
|
13589
|
+
|
|
13551
13590
|
function loadScript(url, cb) {
|
|
13552
13591
|
var script = document.createElement('script');
|
|
13553
13592
|
script.onload = cb;
|
|
@@ -13565,60 +13604,107 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13565
13604
|
}
|
|
13566
13605
|
|
|
13567
13606
|
function Basemap(gui) {
|
|
13568
|
-
var
|
|
13569
|
-
var
|
|
13570
|
-
var
|
|
13571
|
-
var
|
|
13607
|
+
var menuWrapper = gui.container.findChild('.display-options');
|
|
13608
|
+
var mainMenu = gui.container.findChild('.display-main-options');
|
|
13609
|
+
var addLayerMenu = gui.container.findChild('.add-basemap-menu').hide();
|
|
13610
|
+
var basemapList = gui.container.findChild('.added-basemaps');
|
|
13572
13611
|
var overlayButtons = gui.container.findChild('.basemap-overlay-buttons');
|
|
13573
13612
|
var container = gui.container.findChild('.basemap-container');
|
|
13574
13613
|
var basemapNote = gui.container.findChild('.basemap-note');
|
|
13575
|
-
var
|
|
13614
|
+
var addBasemap = gui.container.findChild('.add-basemap');
|
|
13615
|
+
var basemapWarning = gui.container.findChild('.basemap-warning').hide();
|
|
13576
13616
|
var mapEl = gui.container.findChild('.basemap');
|
|
13577
13617
|
var extentNote = El('div').addClass('basemap-prompt').appendTo(container).hide();
|
|
13578
13618
|
var params = window.mapboxParams;
|
|
13579
13619
|
var map;
|
|
13580
13620
|
var activeStyle;
|
|
13581
13621
|
var loading = false;
|
|
13582
|
-
var faded = false;
|
|
13622
|
+
// var faded = false;
|
|
13623
|
+
// var fadeBtn, clearBtn; // not in use
|
|
13624
|
+
var addBtn, addLayerBtn, cancelBtn;
|
|
13625
|
+
var customStyles = [];
|
|
13583
13626
|
|
|
13584
13627
|
if (params) {
|
|
13585
13628
|
// TODO: check page URL for compatibility with mapbox key
|
|
13586
13629
|
init();
|
|
13587
13630
|
} else {
|
|
13588
|
-
|
|
13631
|
+
menuWrapper.findChild('.basemap-opts').hide();
|
|
13589
13632
|
}
|
|
13590
13633
|
|
|
13591
13634
|
function init() {
|
|
13592
13635
|
gui.on('mode', function(e) {
|
|
13593
13636
|
if (e.prev == 'display_options') {
|
|
13594
|
-
|
|
13595
|
-
|
|
13637
|
+
// reset UI when leaving display options mode
|
|
13638
|
+
basemapWarning.hide();
|
|
13639
|
+
basemapNote.hide();
|
|
13640
|
+
// make sure secondary options menu gets closed
|
|
13641
|
+
mainMenu.show();
|
|
13642
|
+
addLayerMenu.hide();
|
|
13596
13643
|
}
|
|
13597
13644
|
if (e.name == 'display_options') {
|
|
13598
13645
|
onUpdate();
|
|
13599
13646
|
}
|
|
13600
13647
|
});
|
|
13601
13648
|
|
|
13602
|
-
|
|
13603
|
-
|
|
13604
|
-
|
|
13605
|
-
|
|
13606
|
-
|
|
13607
|
-
|
|
13649
|
+
customStyles = GUI.getSavedValue('custom_basemaps') || [];
|
|
13650
|
+
updateBasemapList();
|
|
13651
|
+
|
|
13652
|
+
addBtn = new SimpleButton(menuWrapper.findChild('.add-btn'));
|
|
13653
|
+
addBtn.on('click', function(e) {
|
|
13654
|
+
addLayerMenu.show();
|
|
13655
|
+
mainMenu.hide();
|
|
13608
13656
|
});
|
|
13609
13657
|
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13613
|
-
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
|
|
13658
|
+
addLayerBtn = new SimpleButton(menuWrapper.findChild('.add-layer-btn'));
|
|
13659
|
+
addLayerBtn.on('click', function(e) {
|
|
13660
|
+
var name = menuWrapper.findChild('.add-layer-name').el.value || 'Custom layer';
|
|
13661
|
+
var mapboxUrl = menuWrapper.findChild('.add-mapbox-url').el.value;
|
|
13662
|
+
var mapboxKey = menuWrapper.findChild('.add-mapbox-key')?.el?.value;
|
|
13663
|
+
var templateUrl = menuWrapper.findChild('.add-template-url').el.value;
|
|
13664
|
+
var style = {name};
|
|
13665
|
+
|
|
13666
|
+
if (mapboxUrl) {
|
|
13667
|
+
style.url = mapboxUrl;
|
|
13668
|
+
style.key = mapboxKey; // may be undefined
|
|
13669
|
+
style.type = 'mapbox';
|
|
13670
|
+
} else if (templateUrl) {
|
|
13671
|
+
style.url = templateUrl;
|
|
13672
|
+
style.type = menuWrapper.findChild('.tms').el.checked ? 'tms' : 'xyz';
|
|
13673
|
+
}
|
|
13674
|
+
|
|
13675
|
+
customStyles.push(style);
|
|
13676
|
+
updateBasemapList();
|
|
13677
|
+
showBasemap(style);
|
|
13678
|
+
addLayerMenu.hide();
|
|
13679
|
+
mainMenu.show();
|
|
13680
|
+
});
|
|
13681
|
+
|
|
13682
|
+
cancelBtn = new SimpleButton(menuWrapper.findChild('.add-cancel-btn'));
|
|
13683
|
+
cancelBtn.on('click', function() {
|
|
13684
|
+
addLayerMenu.hide();
|
|
13685
|
+
mainMenu.show();
|
|
13620
13686
|
});
|
|
13621
13687
|
|
|
13688
|
+
// fadeBtn = new SimpleButton(menuWrapper.findChild('.fade-btn'));
|
|
13689
|
+
// clearBtn = new SimpleButton(menuWrapper.findChild('.clear-btn'));
|
|
13690
|
+
// clearBtn.on('click', function() {
|
|
13691
|
+
// if (activeStyle) {
|
|
13692
|
+
// turnOffBasemap();
|
|
13693
|
+
// }
|
|
13694
|
+
// });
|
|
13695
|
+
|
|
13696
|
+
// fadeBtn.on('click', function() {
|
|
13697
|
+
// if (faded) {
|
|
13698
|
+
// mapEl.css('opacity', 1);
|
|
13699
|
+
// faded = false;
|
|
13700
|
+
// fadeBtn.text('Fade');
|
|
13701
|
+
// } else if (activeStyle) {
|
|
13702
|
+
// mapEl.css('opacity', 0.35);
|
|
13703
|
+
// faded = true;
|
|
13704
|
+
// fadeBtn.text('Unfade');
|
|
13705
|
+
// }
|
|
13706
|
+
// });
|
|
13707
|
+
|
|
13622
13708
|
gui.model.on('update', onUpdate);
|
|
13623
13709
|
|
|
13624
13710
|
gui.on('map_click', function() {
|
|
@@ -13627,10 +13713,10 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13627
13713
|
});
|
|
13628
13714
|
|
|
13629
13715
|
params.styles.forEach(function(style) {
|
|
13630
|
-
El('div')
|
|
13631
|
-
.html(`<div class="basemap-style-btn"><img src="${style.icon}"></img></div><div class="basemap-style-label">${style.name}</div>`)
|
|
13632
|
-
.appendTo(menuButtons)
|
|
13633
|
-
.findChild('.basemap-style-btn').on('click', onClick);
|
|
13716
|
+
// El('div')
|
|
13717
|
+
// .html(`<div class="basemap-style-btn"><img src="${style.icon}"></img></div><div class="basemap-style-label">${style.name}</div>`)
|
|
13718
|
+
// .appendTo(menuButtons)
|
|
13719
|
+
// .findChild('.basemap-style-btn').on('click', onClick);
|
|
13634
13720
|
|
|
13635
13721
|
El('div').addClass('basemap-overlay-btn basemap-style-btn')
|
|
13636
13722
|
.html(`<img src="${style.icon}"></img>`).on('click', onClick)
|
|
@@ -13644,7 +13730,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13644
13730
|
showBasemap(style);
|
|
13645
13731
|
}
|
|
13646
13732
|
updateButtons();
|
|
13647
|
-
// closeMenu();
|
|
13648
13733
|
}
|
|
13649
13734
|
});
|
|
13650
13735
|
}
|
|
@@ -13659,7 +13744,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13659
13744
|
function turnOffBasemap() {
|
|
13660
13745
|
activeStyle = null;
|
|
13661
13746
|
gui.map.setDisplayCRS(null);
|
|
13662
|
-
refresh();
|
|
13663
13747
|
}
|
|
13664
13748
|
|
|
13665
13749
|
function showBasemap(style) {
|
|
@@ -13668,20 +13752,98 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13668
13752
|
// Make sure that the selected layer style gets updated in gui-map.js
|
|
13669
13753
|
// gui.state.dark_basemap = style && style.dark || false;
|
|
13670
13754
|
if (map) {
|
|
13671
|
-
|
|
13755
|
+
setStyle(activeStyle);
|
|
13672
13756
|
refresh();
|
|
13673
13757
|
} else if (prepareMapView()) {
|
|
13674
13758
|
initMap();
|
|
13675
13759
|
}
|
|
13676
13760
|
}
|
|
13677
13761
|
|
|
13678
|
-
function
|
|
13679
|
-
|
|
13680
|
-
|
|
13762
|
+
function updateBasemapList() {
|
|
13763
|
+
var styles = params.styles.concat(customStyles);
|
|
13764
|
+
basemapList.empty();
|
|
13765
|
+
styles.forEach(function(style) {
|
|
13766
|
+
renderBasemapListItem(basemapList, style);
|
|
13767
|
+
});
|
|
13768
|
+
updateButtons();
|
|
13769
|
+
GUI.setSavedValue('custom_basemaps', customStyles);
|
|
13770
|
+
}
|
|
13771
|
+
|
|
13772
|
+
function isActiveStyle(style) {
|
|
13773
|
+
return style.url == activeStyle?.url;
|
|
13774
|
+
}
|
|
13775
|
+
|
|
13776
|
+
function renderBasemapListItem(parent, style) {
|
|
13777
|
+
var isCustomStyle = !!style.type;
|
|
13778
|
+
var el = El('div').html(`<div data-slug="${getStyleId(style)}" class="basemap-list-item"><img class="on-icon" src="images/eye3.png"><img class="off-icon" src="images/eye.png"> ${style.name} ${isCustomStyle ? '<img class="close-btn" draggable="false" src="images/close.png">' : ''}</div>`);
|
|
13779
|
+
el.appendTo(parent);
|
|
13780
|
+
el.findChild('.basemap-list-item').on('click', function() {
|
|
13781
|
+
if (isActiveStyle(style)) {
|
|
13782
|
+
turnOffBasemap();
|
|
13783
|
+
} else {
|
|
13784
|
+
showBasemap(style);
|
|
13785
|
+
}
|
|
13681
13786
|
});
|
|
13787
|
+
|
|
13788
|
+
var closeBtn = el.findChild('.close-btn');
|
|
13789
|
+
closeBtn?.on('click', function(e) {
|
|
13790
|
+
e.stopPropagation();
|
|
13791
|
+
customStyles = customStyles.filter(function(o) {
|
|
13792
|
+
return o.url != style.url;
|
|
13793
|
+
});
|
|
13794
|
+
updateBasemapList();
|
|
13795
|
+
if (isActiveStyle(style)) {
|
|
13796
|
+
turnOffBasemap();
|
|
13797
|
+
}
|
|
13798
|
+
});
|
|
13799
|
+
el.appendTo(parent);
|
|
13800
|
+
}
|
|
13801
|
+
|
|
13802
|
+
function getStyleId(style) {
|
|
13803
|
+
return ((style.name || '') + style.url).replace(/[^a-z0-9_]+/ig, '_');
|
|
13804
|
+
}
|
|
13805
|
+
|
|
13806
|
+
function setStyle(style) {
|
|
13807
|
+
// update mapbox access token (user-defined styles may have a different key)
|
|
13808
|
+
window.mapboxgl.accessToken = style.key || (window.location.hostname == 'localhost' ?
|
|
13809
|
+
params.localhost_key : params.production_key) || params.key;
|
|
13810
|
+
|
|
13811
|
+
if (style.type == 'mapbox' || !style.type) {
|
|
13812
|
+
map.setStyle(style.url);
|
|
13813
|
+
} else if (style.type == 'xyz' || style.type == 'tms') {
|
|
13814
|
+
map.setStyle({
|
|
13815
|
+
'version': 8,
|
|
13816
|
+
'sources': {
|
|
13817
|
+
'raster-tiles': {
|
|
13818
|
+
'type': 'raster',
|
|
13819
|
+
'tiles': [style.url],
|
|
13820
|
+
'scheme': style.type, // xyz or tms
|
|
13821
|
+
'tileSize': 256, // style.url.includes('@2x') ? 512 : 256
|
|
13822
|
+
}
|
|
13823
|
+
},
|
|
13824
|
+
'layers': [
|
|
13825
|
+
{
|
|
13826
|
+
'id': getStyleId(style),
|
|
13827
|
+
'type': 'raster',
|
|
13828
|
+
'source': 'raster-tiles',
|
|
13829
|
+
'minzoom': 0
|
|
13830
|
+
// 'maxzoom': 22
|
|
13831
|
+
}
|
|
13832
|
+
]
|
|
13833
|
+
});
|
|
13834
|
+
} else {
|
|
13835
|
+
error$1('unsupported map style:', style);
|
|
13836
|
+
}
|
|
13837
|
+
}
|
|
13838
|
+
|
|
13839
|
+
function updateButtons() {
|
|
13682
13840
|
overlayButtons.findChildren('.basemap-style-btn').forEach(function(el, i) {
|
|
13683
13841
|
el.classed('active', params.styles[i] == activeStyle);
|
|
13684
13842
|
});
|
|
13843
|
+
|
|
13844
|
+
menuWrapper.findChildren('.basemap-list-item').forEach(function(el, i) {
|
|
13845
|
+
el.classed('active', el.node().getAttribute('data-slug') == (activeStyle ? getStyleId(activeStyle) : ''));
|
|
13846
|
+
});
|
|
13685
13847
|
}
|
|
13686
13848
|
|
|
13687
13849
|
function onUpdate() {
|
|
@@ -13689,16 +13851,18 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13689
13851
|
var info = getDatasetCrsInfo(activeLyr?.dataset); // defaults to wgs84
|
|
13690
13852
|
var dataCRS = info.crs || null;
|
|
13691
13853
|
var displayCRS = gui.map.getDisplayCRS();
|
|
13854
|
+
var basemapsNotAvailable = !dataCRS || !displayCRS || !crsIsUsable(displayCRS) || !crsIsUsable(dataCRS);
|
|
13692
13855
|
var warning, note;
|
|
13693
13856
|
|
|
13694
|
-
|
|
13695
|
-
if (!dataCRS || !displayCRS || !crsIsUsable(displayCRS) || !crsIsUsable(dataCRS)) {
|
|
13857
|
+
if (basemapsNotAvailable) {
|
|
13696
13858
|
warning = 'This data is incompatible with the basemaps.';
|
|
13697
|
-
if (!internal.layerHasGeometry(activeLyr.layer)) {
|
|
13859
|
+
if (activeLyr && !internal.layerHasGeometry(activeLyr.layer)) {
|
|
13698
13860
|
warning += ' Reason: layer is missing geographic data';
|
|
13699
13861
|
} else if (!dataCRS) {
|
|
13700
13862
|
warning += ' Reason: unknown projection.';
|
|
13701
13863
|
}
|
|
13864
|
+
basemapList.hide();
|
|
13865
|
+
addBasemap.hide();
|
|
13702
13866
|
basemapWarning.html(warning).show();
|
|
13703
13867
|
basemapNote.hide();
|
|
13704
13868
|
overlayButtons.addClass('disabled');
|
|
@@ -13708,6 +13872,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13708
13872
|
note = `Note: basemaps use the Mercator projection.`;
|
|
13709
13873
|
basemapNote.text(note).show();
|
|
13710
13874
|
overlayButtons.show();
|
|
13875
|
+
basemapList.show();
|
|
13876
|
+
addBasemap.show();
|
|
13711
13877
|
overlayButtons.removeClass('disabled');
|
|
13712
13878
|
}
|
|
13713
13879
|
}
|
|
@@ -13735,17 +13901,17 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13735
13901
|
}
|
|
13736
13902
|
|
|
13737
13903
|
function initMap() {
|
|
13738
|
-
var accessToken = (window.location.hostname == 'localhost' ?
|
|
13739
|
-
|
|
13904
|
+
// var accessToken = (window.location.hostname == 'localhost' ?
|
|
13905
|
+
// params.localhost_key : params.production_key) || params.key;
|
|
13740
13906
|
if (!enabled() || map || loading) return;
|
|
13741
13907
|
loading = true;
|
|
13742
13908
|
loadStylesheet(params.css);
|
|
13743
13909
|
loadScript(params.js, function() {
|
|
13744
13910
|
map = new window.mapboxgl.Map({
|
|
13745
|
-
accessToken: accessToken,
|
|
13746
13911
|
logoPosition: 'bottom-left',
|
|
13747
13912
|
container: mapEl.node(),
|
|
13748
|
-
style: activeStyle.url,
|
|
13913
|
+
// style: activeStyle.url,
|
|
13914
|
+
style: EMPTY_STYLE, // initializing with empty style to support custom styles
|
|
13749
13915
|
bounds: getLonLatBounds(),
|
|
13750
13916
|
doubleClickZoom: false,
|
|
13751
13917
|
dragPan: false,
|
|
@@ -13754,8 +13920,10 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13754
13920
|
interactive: false,
|
|
13755
13921
|
keyboard: false,
|
|
13756
13922
|
maxPitch: 0,
|
|
13923
|
+
projection: 'mercator', // prevent globe view when zoomed out
|
|
13757
13924
|
renderWorldCopies: true // false // false prevents panning off the map
|
|
13758
13925
|
});
|
|
13926
|
+
setStyle(activeStyle);
|
|
13759
13927
|
map.on('load', function() {
|
|
13760
13928
|
loading = false;
|
|
13761
13929
|
refresh();
|
|
@@ -13804,8 +13972,11 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13804
13972
|
function refresh() {
|
|
13805
13973
|
var off = !enabled() || !map || loading || !activeStyle ||
|
|
13806
13974
|
!gui.map.getDisplayCRS(); // may be slow if getting bounds of many shapes
|
|
13807
|
-
fadeBtn.active(!off);
|
|
13808
|
-
clearBtn.active(!off);
|
|
13975
|
+
// fadeBtn.active(!off);
|
|
13976
|
+
// clearBtn.active(!off);
|
|
13977
|
+
|
|
13978
|
+
updateButtons();
|
|
13979
|
+
|
|
13809
13980
|
if (off) {
|
|
13810
13981
|
hide();
|
|
13811
13982
|
extentNote.hide();
|