Initializing two leaflet maps - one rewrites another - javascript

I'm trying to put multiple leaflet maps on one page, but I have problem with two of them - the second one rewrites the first one, so first one is rendering map, and the second has just grey area.
Here is the code:
var map_a = new L.Map( "smallMap", {
fullscreenControl: false,
layers: [osmMap]
}).setView([51.005, -0.09], 14);
var map_b = new L.Map( "smallMapSecond", {
fullscreenControl: false,
layers: [osmMap]
}).setView([51.505, -0.09], 14);
I have appropriate divs called smallMap and smallMapSecond. When I Initialize only one map, it works. Where could be the problem?

Well,one of the potential problems I see here without having a jsFiddle available is that you are using the same tileLayer osmMap for both maps. Sharing TileLayers between map instances is going to cause problems. Initialize tileLayers one per map.

Related

How to solve map.addlayer not a function

I am trying to implement the leaflet-panel-layer plugin and customize the included overlay to my needs. The original code uses a geojson formatted as js and I use a basic js marker list (which I load in from a seperate document) so I am wondering what I have to change to show the markers. I already got some parts of the map working e.g. choosing between baselayers but I can´t get the overlaylayers to work how I want.
I think the loading in isn´t the problem here, its just that I cant add the markers to the map, because the follwing Error seems to have to do something with how and where the map is definined (info from other people with similar error message)
``leaflet.js:5 Uncaught TypeError: map.addLayer is not a function
at NewClass.addTo (leaflet.js:5:64472)
at URD_Regio.js:105:284``
How I load in the js files with the Markers in them:
<script src="js/URD_Regio.js"></script>
<script src="js/URD_Fernverkehr.js"></script>
How I define my markers (in the mentioned external js file) and how I group them:
var ulm_1 = L.marker([44.7892, 9.745775]);
ulm_1.bindPopup('<b>.....');
var db_regio = L.layerGroup ([ulm_1],......).addTo(map)
I have tried adding the addTo(map) command in several places but pretty much always got the same error.
My current code:
var overLayers = [
{
group: "data",
collapsed: true,
layers: [
{
active: false,
name: "Drinking Water",
layer: L.layerGroup(db_regio) //.addTo(map)?
},
Note when implementing the original code which uses a geojson formatted as js, the code works just fine.
How I define my map:
var map = L.map('map', { zoom: 6, center: L.latLng([52.3900214, 12.419982]) }), osmLayer = new L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');

What would make a Google map Ag object returned without mapDataProvider?

I'm working on an SPA project (ionic, so it's angular with ui-router) where I need to display two different maps on two different pages/controllers.
The first map is a general map (let's call it the main map)where a few locations are marked and the second one (let's call it the edit map)is a focus on a specific location where the user can edit the location by dragging the marker.
The general implementation scheme I'm using is that I'm calling a initMap method from mappingService that instanciates a google map from each controller.
$rootScope.markers = [];
this.initMap = function initMap(mapTarget, mapCenter) {
// the initMap function initialize the map it takes two arguments:
// + mapTaget which defines the html element the map is bound to.
// + mapCenter that defines the center of the map and whether to display the center
var markup = "<div id='" + mapTarget.mapId + "'></div>";
document.getElementById(mapTarget.containerId).innerHTML = markup;
var centerPos = new google.maps.LatLng(mapCenter.lat, mapCenter.lng);
$rootScope.map = new google.maps.Map(document.getElementById(mapTarget.mapId), {
center: centerPos,
zoom: 18,
disableDefaultUI: true
});
// eventually place a person marker for the user's position
if (mapCenter.display) {
console.log('placing the position marker');
$rootScope.markers[0] = new google.maps.Marker({
position: {lat: mapCenter.lat, lng: mapCenter.lng},
map: $rootScope.map,
title: 'userLocation',
icon: './img/person_icon.png'
});
}
};
The only difference is that on the main map I'm first calling a geolocate service the return a promise and I'm using the returned location coordinates to then call the mapping service:
geolocateService.getLocalPosition()
.then(function(coords) {
mappingService.initMap(
{containerId: $scope.mapContainer, mapId: $scope.mapId},
{lat: coords.lat, lng: coords.lng, display: true}
);
While on the edit map I'm calling directly the mapping service.
mappingService.initMap(
{containerId: $scope.mapContainer, mapId: $scope.mapId},
{lat: $scope.location.lat, lng: $scope.location.lng, display: false}
);
I am able to render both maps without problem and even to add markers and some event listeners.
However, I run into the problem that after some sequence of actions, for example going from the main map to the edit map two times, one of the map would suddenly become blank (white to be exactly, so it doesn't seems to be something that I could solve by resizing the map). I'm receiving the Ag object and the only difference is that I don't get the mapDataProviders property on the broken map.
When it works, I get:
Ag object when it works
While when it doesn't, I get:
Ag object when it doesn't work
The code snippet above is my last implementation attempt. I've been trying to implement those maps from a lot of different ways to no avail. Among those attempts, I tried:
totally separates both instanciation, dividing the initMap methods into an initMainMap and an initEditMap.
using one instance for both maps and replacing the DOM element> This is what you see above with the following additional method that is called when leaving the view:
this.removeMap = function removeMap(containerId) {
var container = document.getElementById(containerId);
$rootScope.markers = [];
container.innerHTML = '';
// important part:
var old_element = container;
var new_element = old_element.cloneNode(true);
old_element.parentNode.replaceChild(new_element, old_element);
delete $rootScope.map;
}
knowing that on both views I have either:
or
<div id="edit-map-container"></div>
I'm trying to understand what would make the google map API return a map without mapDataProvider (which I believe means that the map works and even starts to render except that it lacks the tiles to display).
P.S. it looks like there is a memory leak, which is apparently a well known issue.
If anyone has the answer to this, I'm a bit lost right here!

How to add layers and update layer control dynamically : leaflet

I am working with the lealflet api, where user can draw shapes to
map(image)...
Initially the layer control(handling 1 layer) is added for base map
using imageoverlay......
I have added a button of id 'newLyer' to page where click event
handles the creation of new layer.....i.e user can create new layer
and update layer control(which is now handling 2 layers)....
I have used several methods to create the layers and adding to control
but failed....
Adding new layer to layerGroup
var layerGroup = new L.LayerGroup(),
imageOverlayUrl = 'aa.jpg',
// New imageoverlay added to the layergroup
imageOverlay = new L.ImageOverlay(imageOverlayUrl, bounds).addTo(layerGroup),
// New featuregroup added to the layergroup
featureGroup = new L.FeatureGroup().addTo(layerGroup);
LayerControl where i needed to add the control(if i am correct)
var layerControl = new L.control.layers({
'Main': layerGroup,
//here i need to add new layer control
}, null, { collapsed: false }).addTo(map);
OnClick function with so far static code, this will be executed on click
$('#newLayer').click(function addNewLayer() {
// Second layergroup not added to the map yet
var layerGroupNew = new L.LayerGroup(),
imageOverlayUrlNew = 'bb.png',
// New imageoverlay added to the second layergroup
imageOverlayNew = new L.imageOverlay(imageOverlayUrlNew, bounds).addTo(layerGroup2),
// New featuregroup added to the second layergroup
featureGroupNew = new L.FeatureGroup().addTo(layerGroupNew);
});
In Short
Initially, i have one layer with its control, now onclick function
creates the new layer which will be added to the map but how i can add
this layer into layerControl....
If someone has idea about how to do this sort of thing, please do help,,,, any kind of help or reference will be appreciated....
Thanks for your time
If you look at the documentation for L.Control.Layers:
http://leafletjs.com/reference.html#control-layers
You'll see that L.Control.Layers has a addBaseLayer method:
http://leafletjs.com/reference.html#control-layers-addbaselayer
Adds a base layer (radio button entry) with the given name to the control.
Thus you can do:
layerControl.addBaseLayer(newBaseLayer, 'My New BaseLayer');
And you're good to go. As you see, you could have spared yourself the trouble of posting this question if you would have taken a look at the reference. Leaflet is very well documented. I've personally learned most that i know about Leaflet by reading the docs completely once of twice. Good luck with your project, cheers!

interact with geojson layers independently in google maps api v3

I would like to load two geojson layers to my map and be able to style them independently with different rules. I can display both my geojson files with the below code, but since they are both part of the same map.data object I have only been able to apply universal styling to both. Is there any way around this? Ultimately(longer term goal) I would also like to be able to toggle the different layers on and off with a checkbox as well (I am focusing on independent styling first so as not to overcomplicate the problem)
function initialize() {
map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 12,
center: {lat: 39.218509, lng: -94.563703}
});
map.data.loadGeoJson('https://url1');
map.data.loadGeoJson('https://url2');
map.data.setStyle(function(feature) { //styling rules here}
google.maps.event.addDomListener(window, 'load', initialize);
any help would be very much appreciated. I saw some threads that looked applicable (such as Google maps GeoJSON- toggle marker layers?) but I wasn't sure how to apply it specifically for my purposes.
So I just had to do something similar and needed to add 2 geojson files and style them differently. What you want to do is initialize the map and then add 2 different layers. Basically set the styling for both. Below is my code with notes. I actually used this function Angular in a service and returned a promise.
Set up your map options
var mapOptions = {
zoom: 4,
scrollwheel: false,
center: new google.maps.LatLng(40.00, -98),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
Set your map to a variable.
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
Initialize 2 variable that will take layers. I did state and county.
var countyLayer = new google.maps.Data();
var stateLayer = new google.maps.Data();
Then load the GeoJson files for each layer.
countyLayer.loadGeoJson('counties.json');
stateLayer.loadGeoJson('states.json');
After that set the style for each layer.
stateLayer.setStyle({
strokeColor: 'red',
strokeWeight: 5
});
countyLayer.setStyle({
strokeColor: 'black',
strokeWeight: 1
});
The last step is to set the layer to the map.
countyLayer.setMap(map);
stateLayer.setMap(map);
After this I returned a promise but you could just return the map object. Does this make sense / help answer your question?
Also, within each layer setStyle() function you can add dynamic styling through functions. Like add a function to fillColor that would change the color based on data in the GeoJson file.

customizing google maps V.3 streetview controls

I've got one instance of google maps with fully customized options in my app.The users are able to switch to street view if they want to and come back all with the same instance of the map.
Is there a way to customize streetview controls when creating the map instance, along with the other map options?
I can not see any documentation on how to do that on the main map, while if you directly instantiate a the street view on a separate dom element you can do that like this:
var panoramaOptions = {
zoomControl: false,
linksControl: false,
panControl: false
}
var panorama = new google.maps.StreetViewPanorama(document.getElementById("map_streetview"), panoramaOptions)
mymap.setStreetView(panorama)
Any hint?
You may access the streetView-property of a map(no matter if custom or default) by using the getStreetView()-method of the map.
Use the setOptions()-method of the streetView to set the options:
mymap.getStreetView().setOptions(panoramaOptions);

Categories

Resources