Generating leaflet map in a popup - leaflet

I'm generating the leaflet map in a popup by a click event, with the code:
mymap = L.map('mapdiv').setView([center.lat, center.long], zoom);
However, if I close the popup and click again to generate a new map, I get the error:
Map container is already initialized
How should I generate the map the second time?

You should destroy the map when the pop-up is closed. See the remove() method of L.Map. e.g.
var mymap;
popup.on('open', function(){
mymap = L.map( /* etc */ );
});
popup.on('close', function(){
mymap.remove();
});

Related

How can I pull a URL stored inside a Mapbox dataset and add it to a 'click' function on a popup?

I have a function code that pulls data from the "description" field and displays it inside a popup on mouseenter, but can someone help me figure out how to pull in the URL stored inside "linkurl" and use it to open that URL when the icon is clicked? The popup displays properly over an icon, but I can't figure out how to bring the URL in as a link on click. Here's the code I'm working with:
map.on('load', function() {
// Create a popup, but don't add it to the map yet.
var popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
// POINTS OF INTEREST
function showPopup(e) {
// Updates the cursor to a hand (interactivity)
map.getCanvas().style.cursor = 'pointer';
// Show the popup at the coordinates with some data
popup
.setLngLat(e.features[0].geometry.coordinates)
.setHTML(checkEmpty(e.features[0].properties.description))
.addTo(map);
}
function hidePopup() {
map.getCanvas().style.cursor = '';
popup.remove();
}
function checkEmpty(info) {
return (info) ? info : "No data";
}
// CHANGE: Add layer names that need to be interactive
map.on('mouseenter', 'points-of-interest-2019', showPopup);
map.on('mouseleave', 'points-of-interest-2019', hidePopup);
});
To add a link within the Popup itself, you can use Popup#setHTML in conjunction with the <a> tag define a hyperlink. For example:
// Show the popup at the coordinates with some data
var properties = e.features[0].properties;
popup
.setLngLat(e.features[0].geometry.coordinates)
.setHTML(
'<a href=\'' + properties.linkurl + '\'>'
+ checkEmpty(properties.description)
+ '</a>')
.addTo(map);
Since creating a Popup with the GL JS API automatically creates a DOM element as outlined in the source code here, there is currently not a way to make the entire Popup clickable to navigate to a particular link. You could instead use Popup#setHTML along with some minimal CSS to create a link which wraps the entire content added to the Popup, so that clicking the content of the Popup will open the link.
Alternatively, if you are using Marker instances and would like clicking on the marker itself to open a link, you could utilize the options.element parameter to specify a DOM element wrapped in a link to use as a marker. For example, consider a slight modification to this example:
var el = document.createElement('a');
el.href = 'https://www.mapbox.com/'
el.className = 'marker';
el.style.backgroundImage =
'url(https://placekitten.com/g/' +
marker.properties.iconSize.join('/') +
'/)';
el.style.width = marker.properties.iconSize[0] + 'px';
el.style.height = marker.properties.iconSize[1] + 'px';
// add marker to map
new mapboxgl.Marker(el)
.setLngLat(marker.geometry.coordinates)
.addTo(map);

How to add popup or bind popup to a point/marker in Leaflet FlowMap without breaking the 'flow' display?

I am using the following leaflet plugin:
https://github.com/jwasilgeo/Leaflet.Canvas-Flowmap-Layer
I am having issues adding a popup to the map when a user clicks on a point.
L.marker([pts[p].lat, pts[p].lng], {
icon: new L.DivIcon({
html: '<div>Test</div>'
})
}).addTo(map).bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
.openPopup();
The popup shows, but I am unable to get the actual flowmap lines to show up. Is there anyway to allow for a popup and to allow for the lines to show up underneath it?
You can use the fact that the CanvasFlowmapLayer extends L.GeoJSON
You just need to overload the method creating the marker and add your popup there ...
var oneToManyFlowmapLayer = L.canvasFlowmapLayer(geoJsonFeatureCollection, {
pointToLayer: function(geoJsonPoint, latlng) {
var marker = L.circleMarker(latlng);
return marker.bindPopup('' + latlng)
},
// et caetera
Check it out here: https://yafred.github.io/Leaflet.Canvas-Flowmap-Layer/docs/main/

Defining Leaflet map as dynamic map id (Cannot read property '_container' of undefined)

I have 2 different divs which using by leaflet as map object. I want to define my map objects into a function such as
html
<div id="mymap"></div>
<div id="mymap2"></div>
javascript
var map;
function define_map(map_id) {
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
osm = L.tileLayer(osmUrl, {
maxZoom: 7
}),
map = new L.Map(map_id, {
center: new L.LatLng(51.505, -0.04),
zoom: 7
}),
drawnItems = L.featureGroup().addTo(map);
});
define_map("mymap");
define_map("mymap2");
$(".btnmarker").on("click", function() {
console.log(map);
L.DomUtil.addClass(map._container, 'my_crosshair-cursor-enabled'); // ON THIS LINE GETTING ERROR CODE Cannot read property '_container' of undefined
selected_tool = $(this).attr("id");
});
There is no problem, my maps seems working good until accessing features of them from button click event (this button will add a marker class to a map which i clicked on it)
But i'm getting map is not defined error. map is a variable and defined on top line of page.
Thanks inadvance

Cant open popup programmatically

I have a map on which im loading the markers with geoJSON.
When the map loads i run a function buildVisibleSys which is responsible to build a list of currently visible systems on the map.
That function looks like this:
buildVisibleSys = function() {
var bounds, visibleSys;
visibleSys = [];
bounds = map.getBounds();
return systemLocations.eachLayer(function(marker) {
var link;
link = onScreenEl.appendChild(document.createElement('a'));
link.href = '#';
link.id = "marker" + marker._leaflet_id;
link.innerHTML = marker.options.title;
link.onclick = function() {
marker.openPopup();
map.panTo(marker.getLatLng());
};
});
};
map.on('load', buildVisibleSys);
In this function, for each layer im getting some data and building a html block with the names of each marker. Each of those names, associated to the link var, have a onclick event attached that will center the map on the correspondent marker. This all works except for the marker.openPopup() call i also have on that onclick event.
Any idea of what am I missing here?
I've also made a demo of the code available here:
http://jsfiddle.net/lmartins/z8wBW/
UPDATE:
Even more confusing to me is that with mouseover the same method works without a problem, that is, in the function above the following code do open the popup:
link.onmouseover = function(ev) {
marker.openPopup();
marker._icon.classList.add('is-active');
};
Change your link handler to
link.onclick = function(e) {
marker.openPopup();
map.panTo(marker.getLatLng());
e.stopPropagation();
e.preventDefault();
};
The click of the link to open the popup is bubbling down to the map and closing the popup right after it's opened.

Disable touch in bing map after map is initialized

How to disable mobile touch event after the bing map is initialized?
We can disable before initializing by below code, using MapOptions object. However I'm looking after the Bing Map is initialized.
// Set the map and view options, setting the map style to Road and
// removing the user's ability to change the map style
var mapOptions = {credentials:"Bing Maps Key",
height: 400,
width: 400,
mapTypeId: Microsoft.Maps.MapTypeId.road,
disableTouchInput : true,
};
// Initialize the map
var map = new Microsoft.Maps.Map(document.getElementById("mapDiv"), mapOptions);
Any help is highly appreciated. Thanks in advance!!!
Most of the MapOptions do work when passed into the setOptions method of the map. For instance try this: map.setOptions({disableTouchInput: true});
Note that I've only tested this in IE. If you simply want to disable panning and zooming you can do this in a number of different ways. The first is to use map options, the other is to use the viewchange event, store the original map position and keep setting the map to the same view to lock it.
Since you can't set most of the MapOptions once the map is created you can only do this by swapping out your map for a new map with the options you want. This is a very basic example, but here is an example that shows and hides the bing logo which is one of the settings that you can't change with setOptions.
function switchMapOptions(active, inactive) {
try {
var newMap = new MM.Map($(inactive)[0], options);
for (var i = 0; i < map.entities.getLength(); i++) {
var loc = map.entities.get(i).getLocation();
newMap.entities.push(new MM.Pushpin(loc));
}
newMap.setView({center: map.getCenter(), zoom: map.getZoom(), animate: false});
map.dispose();
map = newMap;
}
catch (e) {
alert(e.message);
}
}
Full code at Jsfiddle: http://jsfiddle.net/bryantlikes/zhH5g/4/