Reputation: 83
I am displaying custom markers with an image icon and displaying the number of markers based on the zooming level. How do I add a popup window to each of these markers?
This is the code I used to plot all the markers.
map.on('load', function () {
// add a clustered GeoJSON source for a sample set of earthquakes
map.addSource('earthquakes', {
"type": "geojson",
"data": "https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson",
"cluster": true,
"clusterRadius": 80
});
map.addLayer({
"id": "cluster",
"type": "symbol",
"source": "earthquakes",
"filter": ["!=", "cluster", true]
});
// objects for caching and keeping track of HTML marker objects (for performance)
var markers = {};
var markersOnScreen = {};
function updateMarkers(){
var newMarkers = {};
var features = map.querySourceFeatures( 'earthquakes' );
for ( var i = 0; i < features.length; i++ ) {
var coords = features[ i ].geometry.coordinates;
var props = features[ i ].properties;
if (!props.cluster) continue;
var id = props.cluster_id;
var marker = markers[id];
if (!marker) {
var el = new Image();
el.src = 'icon.png';
el.classList.add( 'mapMarker' );
el.dataset.type = props.type; // you can use custom data if you have assigned it in the GeoJSON data
marker = markers[id] = new mapboxgl.Marker({element: el}).setLngLat(coords);
}
newMarkers[id] = marker;
if (!markersOnScreen[id])
marker.addTo(map);
}
// for every marker we've added previously, remove those that are no longer visible
for (id in markersOnScreen) {
if (!newMarkers[id])
markersOnScreen[id].remove();
}
markersOnScreen = newMarkers;
}
// after the GeoJSON data is loaded, update markers on the screen and do so on every map move/moveend
map.on('data', function (e) {
if (e.sourceId !== 'earthquakes' || !e.isSourceLoaded) return;
map.on('move', updateMarkers);
map.on('moveend', updateMarkers);
updateMarkers();
});
});
I tried this but does not help.
map.on('click', 'states-layer', function (e) {
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML(e.features[0].properties.name)
.addTo(map);
});
// Change the cursor to a pointer when the mouse is over the states layer.
map.on('mouseenter', 'states-layer', function () {
map.getCanvas().style.cursor = 'pointer';
});
// Change it back to a pointer when it leaves.
map.on('mouseleave', 'states-layer', function () {
map.getCanvas().style.cursor = '';
});
Also tried marker.popup() function. Any help is greatly appreciated.
Thanks, Adheesh
Upvotes: 0
Views: 2334
Reputation: 21
Try not to create markers. Instead make a layer for single points in the map. You can add an icon to the layer so it looks like a marker. It works like this:
First you should add layer for points unclustered.
Example with an icon:
map.loadImage('https://imageURL', function(error, image) {
if (error) throw error;
map.addImage('IMAGE-NAME', image);
map.addLayer({
id: "unclustered-point",
type: "symbol",
source: "earthquakes",
filter: ["!", ["has", "point_count"]],
layout: {
"icon-image": 'IMAGE-NAME',
"icon-size":1,
}
});
Example without an icon:
map.addLayer({
id: "unclustered-point",
type: "circle",
source: "earthquakes",
filter: ["!", ["has", "point_count"]],
});
Then add a click event:
map.on('click', 'unclustered-point', function (e) {
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML(e.features[0].properties.description)
.addTo(map);
});
Remember to put your code inside of map.on("load"...) function
map.on('load', function()
{
//put your code here
}
I think for this to work you would have to not use yours markers code.
Upvotes: 1