UNPKG

mohsen-angular-leaflet-directive

Version:

angular-leaflet-directive - An AngularJS directive to easily interact with Leaflet maps

157 lines (128 loc) 5.96 kB
angular.module('leaflet-directive').directive('lfPaths', function(leafletLogger, $q, leafletData, leafletMapDefaults, leafletHelpers, leafletPathsHelpers, leafletPathEvents) { return { restrict: 'A', scope: false, replace: false, require: ['leaflet', '?lfLayers'], link: function(scope, element, attrs, controller) { var mapController = controller[0]; var isDefined = leafletHelpers.isDefined; var isString = leafletHelpers.isString; var leafletScope = mapController.getLeafletScope(); var paths = leafletScope.paths; var createPath = leafletPathsHelpers.createPath; var bindPathEvents = leafletPathEvents.bindPathEvents; var setPathOptions = leafletPathsHelpers.setPathOptions; mapController.getMap().then(function(map) { var defaults = leafletMapDefaults.getDefaults(attrs.id); var getLayers; // If the layers attribute is used, we must wait until the layers are created if (isDefined(controller[1])) { getLayers = controller[1].getLayers; } else { getLayers = function() { var deferred = $q.defer(); deferred.resolve(); return deferred.promise; }; } if (!isDefined(paths)) { return; } getLayers().then(function(layers) { var leafletPaths = {}; leafletData.setPaths(leafletPaths, attrs.id); // Should we watch for every specific marker on the map? var shouldWatch = (!isDefined(attrs.watchPaths) || attrs.watchPaths === 'true'); // Function for listening every single path once created var watchPathFn = function(leafletPath, name) { var clearWatch = leafletScope.$watch('paths["' + name + '"]', function(pathData, old) { if (!isDefined(pathData)) { if (isDefined(old.layer)) { for (var i in layers.overlays) { var overlay = layers.overlays[i]; overlay.removeLayer(leafletPath); } } map.removeLayer(leafletPath); clearWatch(); return; } setPathOptions(leafletPath, pathData.type, pathData); }, true); }; leafletScope.$watchCollection('paths', function(newPaths) { // Delete paths (by name) from the array for (var name in leafletPaths) { if (!isDefined(newPaths[name])) { map.removeLayer(leafletPaths[name]); delete leafletPaths[name]; } } // Create the new paths for (var newName in newPaths) { if (newName.search('\\$') === 0) { continue; } if (newName.search('-') !== -1) { leafletLogger.error('The path name "' + newName + '" is not valid. It must not include "-" and a number.', 'paths'); continue; } if (!isDefined(leafletPaths[newName])) { var pathData = newPaths[newName]; var newPath = createPath(newName, newPaths[newName], defaults); // bind popup if defined if (isDefined(newPath) && isDefined(pathData.message)) { newPath.bindPopup(pathData.message, pathData.popupOptions); } // Show label if defined if (leafletHelpers.LabelPlugin.isLoaded() && isDefined(pathData.label) && isDefined(pathData.label.message)) { newPath.bindLabel(pathData.label.message, pathData.label.options); } // Check if the marker should be added to a layer if (isDefined(pathData) && isDefined(pathData.layer)) { if (!isString(pathData.layer)) { leafletLogger.error('A layername must be a string', 'paths'); continue; } if (!isDefined(layers)) { leafletLogger.error('You must add layers to the directive if the markers are going to use this functionality', 'paths'); continue; } if (!isDefined(layers.overlays) || !isDefined(layers.overlays[pathData.layer])) { leafletLogger.error('A path can only be added to a layer of type "group"', 'paths'); continue; } var layerGroup = layers.overlays[pathData.layer]; if (!(layerGroup instanceof L.LayerGroup || layerGroup instanceof L.FeatureGroup)) { leafletLogger.error('Adding a path to an overlay needs a overlay of the type "group" or "featureGroup"', 'paths'); continue; } // Listen for changes on the new path leafletPaths[newName] = newPath; // The path goes to a correct layer group, so first of all we add it layerGroup.addLayer(newPath); if (shouldWatch) { watchPathFn(newPath, newName); } else { setPathOptions(newPath, pathData.type, pathData); } } else if (isDefined(newPath)) { // Listen for changes on the new path leafletPaths[newName] = newPath; map.addLayer(newPath); if (shouldWatch) { watchPathFn(newPath, newName); } else { setPathOptions(newPath, pathData.type, pathData); } } bindPathEvents(attrs.id, newPath, newName, pathData, leafletScope); } } }); }); }); }, }; });