Merge pull request #77 from bagage/feature/user-layers
Allow user to add custom layers
This commit is contained in:
commit
d08bc38719
3 changed files with 153 additions and 0 deletions
17
index.html
17
index.html
|
|
@ -121,6 +121,23 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Layers modal window -->
|
||||||
|
<div class="modal fade" id="custom_layers" tabindex="-1" role="dialog" aria-labelledby="Layers window" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<h4 class="modal-title">Customize layers</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<input class="form-control" type="text" id="layer_name" spellcheck="true" wrap="off" placeholder="Custom layer name. (ex: OpenStreetMap)"></input>
|
||||||
|
<input class="form-control" type="text" id="layer_url" spellcheck="false" wrap="off" placeholder="Custom layer URL. (ex: https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png)"></input>
|
||||||
|
|
||||||
|
<button type="button" id="custom_layers_add_base" class="btn btn-success">Add base layer</button>
|
||||||
|
<button type="button" id="custom_layers_add_overlay" class="btn btn-success">Add overlay</button>
|
||||||
|
<button type="button" id="custom_layers_remove" class="btn btn-danger">Remove selection</button>
|
||||||
|
<table id="custom_layers_table"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- About modal window -->
|
<!-- About modal window -->
|
||||||
<div class="modal fade" id="about" tabindex="-1" role="dialog" aria-labelledby="About window" aria-hidden="true">
|
<div class="modal fade" id="about" tabindex="-1" role="dialog" aria-labelledby="About window" aria-hidden="true">
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,8 @@ BR.Map = {
|
||||||
|
|
||||||
L.control.scale().addTo(map);
|
L.control.scale().addTo(map);
|
||||||
|
|
||||||
|
new BR.Layers().init(map, layersControl, baseLayers, overlays);
|
||||||
|
|
||||||
// expose map instance for console debugging
|
// expose map instance for console debugging
|
||||||
BR.debug = BR.debug || {};
|
BR.debug = BR.debug || {};
|
||||||
BR.debug.map = map;
|
BR.debug.map = map;
|
||||||
|
|
|
||||||
134
js/control/Layers.js
Normal file
134
js/control/Layers.js
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
BR.Layers = L.Class.extend({
|
||||||
|
|
||||||
|
_loadLayers: function() {
|
||||||
|
this._customLayers = {};
|
||||||
|
|
||||||
|
if (BR.Util.localStorageAvailable()) {
|
||||||
|
var layers = JSON.parse(localStorage.getItem("map/customLayers"));
|
||||||
|
for (a in layers) {
|
||||||
|
this._addLayer(a, layers[a].layer, layers[a].isOverlay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_loadTable: function() {
|
||||||
|
var layersData = [];
|
||||||
|
for (layer in this._customLayers) {
|
||||||
|
layersData.push([layer, this._customLayers[layer].layer._url, this._customLayers[layer].isOverlay ? "Overlay" : "Layer"]);
|
||||||
|
}
|
||||||
|
if (this._layersTable != null) {
|
||||||
|
this._layersTable.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._layersTable = $('#custom_layers_table').DataTable({
|
||||||
|
data: layersData,
|
||||||
|
info: false,
|
||||||
|
searching: false,
|
||||||
|
paging: false,
|
||||||
|
columns: [
|
||||||
|
{ title: "Name" },
|
||||||
|
{ title: "URL" },
|
||||||
|
{ title: "Type" }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
init: function(map, layersControl, baseLayers, overlays) {
|
||||||
|
this._layersControl = layersControl;
|
||||||
|
this._map = map;
|
||||||
|
this._layers = {}
|
||||||
|
for (var l in overlays)
|
||||||
|
this._layers[l] = [overlays[l], true];
|
||||||
|
for (var l in baseLayers)
|
||||||
|
this._layers[l] = [baseLayers[l], false];
|
||||||
|
|
||||||
|
L.DomUtil.get('custom_layers_add_base').onclick = L.bind(this._addBaseLayer, this);
|
||||||
|
L.DomUtil.get('custom_layers_add_overlay').onclick = L.bind(this._addOverlay, this);
|
||||||
|
L.DomUtil.get('custom_layers_remove').onclick = L.bind(this._remove, this);
|
||||||
|
|
||||||
|
this._loadLayers();
|
||||||
|
this._loadTable();
|
||||||
|
|
||||||
|
var table = this._layersTable;
|
||||||
|
$('#custom_layers_table tbody').on( 'click', 'tr', function () {
|
||||||
|
if ( $(this).hasClass('selected') ) {
|
||||||
|
$(this).removeClass('selected');
|
||||||
|
} else {
|
||||||
|
table.$('tr.selected').removeClass('selected');
|
||||||
|
$(this).addClass('selected');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addLayer = L.easyButton(
|
||||||
|
'fa-plus-square',
|
||||||
|
function () {
|
||||||
|
$('#custom_layers').modal();
|
||||||
|
},
|
||||||
|
'Add or remove custom layers',
|
||||||
|
{
|
||||||
|
position: 'topright'
|
||||||
|
}
|
||||||
|
).addTo(map);
|
||||||
|
},
|
||||||
|
|
||||||
|
_remove: function(evt) {
|
||||||
|
var row = this._layersTable.row('.selected').data();
|
||||||
|
if (row != null) {
|
||||||
|
var name = row[0];
|
||||||
|
this._layersControl.removeLayer(this._customLayers[name].layer);
|
||||||
|
this._map.removeLayer(this._customLayers[name].layer);
|
||||||
|
delete this._customLayers[name];
|
||||||
|
this._layersTable.row('.selected').remove().draw( false );
|
||||||
|
this._sync();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_addFromInput: function(isOverlay) {
|
||||||
|
var layer_name = L.DomUtil.get('layer_name').value;
|
||||||
|
var layer_url = L.DomUtil.get('layer_url').value;
|
||||||
|
if (layer_name.length > 0 && layer_url.length > 0)
|
||||||
|
this._addLayer(layer_name, layer_url, isOverlay);
|
||||||
|
},
|
||||||
|
|
||||||
|
_addBaseLayer: function(evt) {
|
||||||
|
this._addFromInput(false);
|
||||||
|
},
|
||||||
|
_addOverlay: function(evt) {
|
||||||
|
this._addFromInput(true);
|
||||||
|
},
|
||||||
|
|
||||||
|
_addLayer: function(layerName, layerUrl, isOverlay) {
|
||||||
|
if (layerName in this._layers)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (layerName in this._customLayers)
|
||||||
|
return
|
||||||
|
|
||||||
|
try {
|
||||||
|
var layer = L.tileLayer(layerUrl);
|
||||||
|
|
||||||
|
this._customLayers[layerName] = {layer: layer, isOverlay: isOverlay};
|
||||||
|
|
||||||
|
if (isOverlay) {
|
||||||
|
this._layersControl.addOverlay(layer, layerName);
|
||||||
|
} else {
|
||||||
|
this._layersControl.addBaseLayer(layer, layerName);
|
||||||
|
}
|
||||||
|
this._loadTable();
|
||||||
|
this._sync();
|
||||||
|
return layer;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Oops:", e);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_sync: function() {
|
||||||
|
if (BR.Util.localStorageAvailable()) {
|
||||||
|
localStorage.setItem("map/customLayers", JSON.stringify(this._customLayers, function(k, v) {
|
||||||
|
// dont write Leaflet.Layer in localStorage; simply keep the URL
|
||||||
|
return v._url || v;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue