Skip to content

Commit

Permalink
feat(build): Dinamically add and remove the layers control.
Browse files Browse the repository at this point in the history
Thanks to the @elesdoar work, here:
#285

Commented here by @B0jan too:
#298
  • Loading branch information
tombatossals committed Feb 23, 2014
1 parent 4398c10 commit ac0ce4b
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 109 deletions.
115 changes: 62 additions & 53 deletions dist/angular-leaflet-directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ angular.module("leaflet-directive").directive('geojson', function ($log, $rootSc
};
});

angular.module("leaflet-directive").directive('layers', function ($log, $q, leafletData, leafletHelpers, leafletMapDefaults, leafletLayerHelpers, leafletControlHelpers) {
angular.module("leaflet-directive").directive('layers', function ($log, $q, leafletData, leafletHelpers, leafletLayerHelpers, leafletControlHelpers) {
var _leafletLayers;

return {
Expand All @@ -440,12 +440,10 @@ angular.module("leaflet-directive").directive('layers', function ($log, $q, leaf
leafletScope = controller.getLeafletScope(),
layers = leafletScope.layers,
createLayer = leafletLayerHelpers.createLayer,
addControlLayers = leafletControlHelpers.addControlLayers,
isControlLayersAdded = false;
updateLayersControl = leafletControlHelpers.updateLayersControl,
isLayersControlVisible = false;

controller.getMap().then(function(map) {
var defaults = leafletMapDefaults.getDefaults(attrs.id);

// Do we have a baselayers property?
if (!isDefined(layers) || !isDefined(layers.baselayers) || Object.keys(layers.baselayers).length === 0) {
// No baselayers property
Expand All @@ -458,18 +456,9 @@ angular.module("leaflet-directive").directive('layers', function ($log, $q, leaf
leafletData.setLayers(leafletLayers, attrs.id);

leafletLayers.baselayers = {};
leafletLayers.controls = {};

// Setup the control options
var controlOptions = {
collapsed: defaults.controls.layers.collapsed,
posiiton: defaults.controls.layers.position
};
leafletLayers.controls.layers = new L.control.layers([], [], controlOptions);
leafletLayers.overlays = {};

if (isDefined(layers.options)) {
leafletLayers.controls.layers.options = layers.options;
}
var mapId = attrs.id;

// Setup all baselayers definitions
var oneVisibleLayer = false;
Expand All @@ -486,8 +475,6 @@ angular.module("leaflet-directive").directive('layers', function ($log, $q, leaf
map.addLayer(leafletLayers.baselayers[layerName]);
oneVisibleLayer = true;
}

leafletLayers.controls.layers.addBaseLayer(leafletLayers.baselayers[layerName], layers.baselayers[layerName].name);
}

// If there is no visible layer add first to the map
Expand All @@ -496,29 +483,24 @@ angular.module("leaflet-directive").directive('layers', function ($log, $q, leaf
}

// Setup the Overlays
leafletLayers.overlays = {};
for (layerName in layers.overlays) {
var newOverlayLayer = createLayer(layers.overlays[layerName]);
if (!isDefined(newOverlayLayer)) {
delete layers.overlays[layerName];
continue;
}
leafletLayers.overlays[layerName] = newOverlayLayer;
// Only add the visible overlays to the map, layer control manages the addition to the map
// of layers in its control
// Only add the visible overlays to the map
if (layers.overlays[layerName].visible === true) {
map.addLayer(leafletLayers.overlays[layerName]);
}
leafletLayers.controls.layers.addOverlay(leafletLayers.overlays[layerName], layers.overlays[layerName].name);
}

// Watch for the base layers
leafletScope.$watch('layers.baselayers', function(newBaseLayers) {
// Delete layers from the array
for (var name in leafletLayers.baselayers) {
if (!isDefined(newBaseLayers[name])) {
// Remove the layer from the control
leafletLayers.controls.layers.removeLayer(leafletLayers.baselayers[name]);
// Remove from the map if it's on it
if (map.hasLayer(leafletLayers.baselayers[name])) {
map.removeLayer(leafletLayers.baselayers[name]);
Expand All @@ -532,12 +514,10 @@ angular.module("leaflet-directive").directive('layers', function ($log, $q, leaf
var testBaseLayer = createLayer(newBaseLayers[newName]);
if (isDefined(testBaseLayer)) {
leafletLayers.baselayers[newName] = testBaseLayer;
// Only add the visible layer to the map, layer control manages the addition to the map
// of layers in its control
// Only add the visible layer to the map
if (newBaseLayers[newName].top === true) {
map.addLayer(leafletLayers.baselayers[newName]);
}
leafletLayers.controls.layers.addBaseLayer(leafletLayers.baselayers[newName], newBaseLayers[newName].name);
}
}
}
Expand All @@ -560,18 +540,15 @@ angular.module("leaflet-directive").directive('layers', function ($log, $q, leaf
map.addLayer(leafletLayers.baselayers[Object.keys(layers.baselayers)[0]]);
}

// Only add the layers switch selector control if we have more than one baselayer + overlay
isControlLayersAdded = addControlLayers(map, leafletLayers.controls.layers, newBaseLayers, layers.overlays, isControlLayersAdded);

// Only show the layers switch selector control if we have more than one baselayer + overlay
isLayersControlVisible = updateLayersControl(map, mapId, isLayersControlVisible, newBaseLayers, layers.overlays, leafletLayers);
}, true);

// Watch for the overlay layers
leafletScope.$watch('layers.overlays', function(newOverlayLayers) {
// Delete layers from the array
for (var name in leafletLayers.overlays) {
if (!isDefined(newOverlayLayers[name])) {
// Remove the layer from the control
leafletLayers.controls.layers.removeLayer(leafletLayers.overlays[name]);
// Remove from the map if it's on it
if (map.hasLayer(leafletLayers.overlays[name])) {
map.removeLayer(leafletLayers.overlays[name]);
Expand All @@ -587,7 +564,6 @@ angular.module("leaflet-directive").directive('layers', function ($log, $q, leaf
var testOverlayLayer = createLayer(newOverlayLayers[newName]);
if (isDefined(testOverlayLayer)) {
leafletLayers.overlays[newName] = testOverlayLayer;
leafletLayers.controls.layers.addOverlay(leafletLayers.overlays[newName], newOverlayLayers[newName].name);
if (newOverlayLayers[newName].visible === true) {
map.addLayer(leafletLayers.overlays[newName]);
}
Expand All @@ -603,8 +579,7 @@ angular.module("leaflet-directive").directive('layers', function ($log, $q, leaf
}

// Only add the layers switch selector control if we have more than one baselayer + overlay
isControlLayersAdded = addControlLayers(map, leafletLayers.controls.layers, layers.baselayers, newOverlayLayers, isControlLayersAdded);

isLayersControlVisible = updateLayersControl(map, mapId, isLayersControlVisible, layers.baselayers, newOverlayLayers, leafletLayers);
}, true);
});
}
Expand Down Expand Up @@ -1879,29 +1854,63 @@ angular.module("leaflet-directive").factory('leafletLayerHelpers', function ($ro
};
});

angular.module("leaflet-directive").factory('leafletControlHelpers', function ($rootScope, $log, leafletHelpers) {
var isObject = leafletHelpers.isObject;
angular.module("leaflet-directive").factory('leafletControlHelpers', function ($rootScope, $log, leafletHelpers, leafletMapDefaults) {
var isObject = leafletHelpers.isObject,
isDefined = leafletHelpers.isDefined;
var _layersControl;

var _controlLayersMustBeVisible = function(baselayers, overlays) {
var numberOfLayers = 0;
if (isObject(baselayers)) {
numberOfLayers += Object.keys(baselayers).length;
}
if (isObject(overlays)) {
numberOfLayers += Object.keys(overlays).length;
}
return numberOfLayers > 1;
};

var _createLayersControl = function(mapId) {
var defaults = leafletMapDefaults.getDefaults(mapId);
var controlOptions = {
collapsed: defaults.controls.layers.collapsed,
posiiton: defaults.controls.layers.position
};
return new L.control.layers([], [], controlOptions);
};

return {
addControlLayers: function(map, control, baselayers, overlays, loaded) {
var numberOfLayers = 0;
if (isObject(baselayers)) {
numberOfLayers += Object.keys(baselayers).length;
}
if (isObject(overlays)) {
numberOfLayers += Object.keys(overlays).length;
}
if (numberOfLayers > 1 && loaded === false) {
if (!map.hasLayer(control)) {
control.addTo(map);
layersControlMustBeVisible: _controlLayersMustBeVisible,

updateLayersControl: function(map, mapId, loaded, baselayers, overlays, leafletLayers) {
var i;

var mustBeLoaded = _controlLayersMustBeVisible(baselayers, overlays);
if (isDefined(_layersControl) && loaded) {
for (i in leafletLayers.baselayers) {
_layersControl.removeLayer(leafletLayers.baselayers[i]);
}
for (i in leafletLayers.overlays) {
_layersControl.removeLayer(leafletLayers.overlays[i]);
}
return true;
_layersControl.removeFrom(map);
}
if(numberOfLayers <= 1 && loaded === true){
//map.removeControl(control);
//return false;

if (mustBeLoaded) {
_layersControl = _createLayersControl(mapId);
for (i in baselayers) {
if (isDefined(leafletLayers.baselayers[i])) {
_layersControl.addBaseLayer(leafletLayers.baselayers[i], baselayers[i].name);
}
}
for (i in overlays) {
if (isDefined(leafletLayers.overlays[i])) {
_layersControl.addOverlay(leafletLayers.overlays[i], overlays[i].name);
}
}
_layersControl.addTo(map);
}
return loaded;
return mustBeLoaded;
}
};
});
Expand Down
4 changes: 2 additions & 2 deletions dist/angular-leaflet-directive.min.js

Large diffs are not rendered by default.

133 changes: 133 additions & 0 deletions examples/layers-add-remove.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<!DOCTYPE html>
<html ng-app="demoapp">
<head>
<script src="../bower_components/jquery/jquery.min.js"></script>
<script src="../bower_components/angular/angular.min.js"></script>
<script src="../bower_components/leaflet-dist/leaflet.js"></script>
<script src="../dist/angular-leaflet-directive.min.js"></script>
<script src="../bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="../bower_components/leaflet-dist/leaflet.css" />
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap-theme.min.css">
<script>
var app = angular.module("demoapp", ["leaflet-directive"]);
app.controller("DemoController", [ "$scope", function($scope) {
$scope.definedLayers = {
cloudmade: {
name: 'Cloudmade Tourist',
type: 'xyz',
url: 'http://{s}.tile.cloudmade.com/{key}/{styleId}/256/{z}/{x}/{y}.png',
layerParams: {
key: '007b9471b4c74da4a6ec7ff43552b16f',
styleId: 7
}
},
osm: {
name: 'OpenStreetMap',
url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
type: 'xyz'
}
};
$scope.definedOverlays = {
hillshade: {
name: 'Hillshade Europa',
type: 'wms',
url: 'http://129.206.228.72/cached/hillshade',
visible: true,
layerOptions: {
layers: 'europe_wms:hs_srtm_europa',
format: 'image/png',
opacity: 0.25,
attribution: 'Hillshade layer by GIScience http://www.osm-wms.de',
crs: L.CRS.EPSG900913
}
}
};
angular.extend($scope, {
bern: {
lat: 46.916,
lng: 7.466,
zoom: 10
},
layers: {
baselayers: {
cloudmade: $scope.definedLayers.cloudmade,
osm: $scope.definedLayers.osm
},
overlays: {
hillshade: $scope.definedOverlays.hillshade
}
}
});

$scope.toggleLayer = function(layerName) {
var baselayers = $scope.layers.baselayers;
if (baselayers.hasOwnProperty(layerName)) {
delete baselayers[layerName];
} else {
baselayers[layerName] = $scope.definedLayers[layerName];
}
};

$scope.toggleOverlay = function(overlayName) {
var overlays = $scope.layers.overlays;
if (overlays.hasOwnProperty(overlayName)) {
delete overlays[overlayName];
} else {
overlays[overlayName] = $scope.definedOverlays[overlayName];
}
};

}]);
</script>
<style>
html {
margin: 20px;
}
html,body, .container {
height: 90%;
}
.container {
display:table;
width: 100%;
margin-top: -50px;
padding: 50px 0 0 0;
-moz-box-sizing: border-box;
box-sizing: border-box;
}

.row {
height: 100%;
display: table-row;
}
.col-md-8, .col-md-4 {
display: table-cell;
height: 100%;
float: none;
}
.angular-leaflet-map {
height: 100%;
border: 1px solid #888;
}
</style>
</head>
<body ng-controller="DemoController">
<div class="container">
<div class="row">
<div class="col-md-8">
<h1>Dynamic addition/removal of layers</h1>
<div class="btn-group" data-toggle="buttons">
<button type="button" class="btn btn-default active" ng-click="toggleLayer('cloudmade')">Cloudmade Tourist Layer</button>
<button type="button" class="btn btn-default active" ng-click="toggleLayer('osm')">OpenStreetMap Layer</button>
<button type="button" class="btn btn-default active" ng-click="toggleOverlay('hillshade')">Hillshade Europe Overlay</button>
</div>
<p>Layer definition:</p>
<pre ng-bind="layers.baselayers | json"></pre>
</div>
<div class="col-md-4">
<leaflet center="bern" layers="layers"></leaflet>
</div>
</div>
</div>
</body>
</html>
Loading

0 comments on commit ac0ce4b

Please sign in to comment.