I am creating a Leaflet Map Widget using Preact and webpack.
I have 3 buttons with a single map. Below images shows what I implemented.
when click one single button, the map will show some locations. Like wise other buttons also have each locations. First I clicked "Cemeteries" button, Its fine. locations are displaying on the map. But after that I click "Funeral Homes" button, still have the "cemeteries" locations also. When I click "crematoria" button, same problem, "cemeteries", "Funeral Homes" and "crematoria" locations are displaying together.
What I want is, when I click a one single button, map will show only the each button's locations and when I click another button, previous clicked button locations need to remove.
In my componentDidMount() I created the map.
this.state.map = createMap('mapid').setView([51.505, -0.09], 13);
let urlll = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?';
this.state.map.addLayer(tileLayer(
urlll,
{attribution: 'Map data © OpenStreetMap contributors, Imagery © Mapbox',
maxZoom: 18,
id: 'MY_MAPBOX_ID',
tileSize: 512,
zoomOffset: -1,
accessToken: 'MY_ACCESS_TOKEN'
})
)
After that I create 3 methods for button click events. This is a one method
handleMapCemeteries (e) {
e.preventDefault();
var locationsdemo = [
["LOCATION_1", 11.8166, 13.0942],
["LOCATION_2", 87.9804, 76.9189],
["LOCATION_3", 10.7202, 45.5621],
["LOCATION_4", 11.3889, 11.6277],
["LOCATION_5", 10.5929, 43.6325]
];
let marketIcon = icon({
iconUrl: markerIcon,
iconRetinaUrl: markerIcon,
iconAnchor: [5, 25],
popupAnchor: [10, -44],
iconSize: [25, 35],
});
for (var i = 0; i < locationsdemo.length; i++) {
markeDemo = marker([locationsdemo[i][1], locationsdemo[i][2]], {
icon: marketIcon,
draggable: true,
title: 'Hover Text',
}).bindPopup(locationsdemo[i][0]).addTo(this.state.map);
}
}
Is anyone know how to remove markers when button click?
Instead of adding the markers to the map (.addTo(this.state.map);) add them to a LayerGroup / FeatureGroup (make sure the group is a global variable and only initialized once):
var fg = L.featureGroup().addTo(this.state.map);
...
marker. ... .addTo(fg);
and then you can remove all markers:
fg.clearLayers();
Related
I want to get a popup marker(by image) on my map every time I double click on the screen. Every time I try to copy other's code, it won't work. Can someone help plz?THE MARKER NEEDS TO BE AN IMAGE!
I try to copy other's code, but it won't work. I'm still new in this line of work, so I don't know really how to do it on my own.
var map = L.map('map', {
layers: [
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
'attribution': 'Map data © OpenStreetMap contributors'
})
],
center: [0, 0],
zoom: 0
});
map.on('dblclick',(e)=>{
L.marker(e.latlng).addTo(map).bindPopup('Hello World').openPopup()
})
Demo: https://plnkr.co/edit/u7QL15wYzLprVwhP
Custom icons: https://leafletjs.com/examples/custom-icons/
var greenIcon = L.icon({
iconUrl: 'https://leafletjs.com/examples/custom-icons/leaf-green.png',
iconSize: [38, 95], // size of the icon
iconAnchor: [22, 94],
});
L.marker([51.5, -0.09], {icon: greenIcon}).addTo(map);
Hello everyone I have some problems its about the current positionmarker in my leaflet its supposed to update every 3 second and it does but it everytime it puts a new "position" marker on the map and the old one stays how can i fix this?
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: '© Leaflet 2021',
tileSize: 512,
zoomOffset: -1,
id: 'mapbox/streets-v11',
accessToken: '######'
}).addTo(map);
var greenIcon = L.icon({
iconUrl: 'person.png',
iconSize: [35, 35], // size of the icon // the same for the shadow
popupAnchor: [0, -20] // point from which the popup should open relative to the iconAnchor
});
// placeholders for the L.marker and L.circle representing user's current position and accuracy
var current_position, current_accuracy;
function onLocationFound(e) {
var radius = e.accuracy / 2;
var marker;
L.marker(e.latlng, {icon: greenIcon}).addTo(map)
}
// wrap map.locate in a function
function locate() {
map.locate({setView: true, maxZoom: 15});
}
map.on('locationfound', onLocationFound);
// call locate every 3 seconds... forever
setInterval(locate, 3000);
An efficient way to fix this is to keep a reference to the marker you create, so that you can update its position rather than creating a new marker each time you get a location update. The reference needs to be held in a variable that is outside your callback function, but in scope when the callback is created.
For instance, your callback can check whether the marker already exists, and either create it and attach it to the map object for easy re-use, or just update its coordinates if it is already there:
function onLocationFound(e) {
var radius = e.accuracy / 2;
if (map._here_marker) {
// Update the marker if it already exists.
map._here_marker.setLatLng(e.latlng);
} else {
// Create a new marker and add it to the map
map._here_marker = L.marker(e.latlng, {icon: greenIcon}).addTo(map);
}
}
Having this reference will also let you edit the marker from other functions, e.g. to change the icon or popup, hide it from view, etc.
You can do it, for example, in the following way.
Add an ID (customId) to the marker:
const marker = L.marker([lng, lat], {
id: customId
});
And when you add a new marker remove the existing one with the code below:
map.eachLayer(function(layer) {
if (layer.options && layer.options.pane === "markerPane") {
if (layer.options.id !== customId) {
map.removeLayer(layer);
}
}
});
This question already has answers here:
How to display Leaflet markers near the 180° meridian?
(4 answers)
Closed 2 years ago.
not exactly sure how to word this, but when i place a leaflet marker that is east of the (i believe) 64 lat mark it goes on a map to the left. i want to make it so all the markers go on the same map.
image on what i'm talking about:
i want to make it so the markers to the left go to the latitude and longitude marks they need to be at where every other marker is. you can see i draw an arrow to show where that is
what i have tried:
i can't find anything so i tried setting worldCopyJump to false. i then tried true and it did not fix this.
thanks!
(oh and if i zoom into the area it should be at it does not appear.)
code:
HTML:
<div id="mapid" style="width: 100%; height: 950px;"></div>
JS
var mymap = L.map('mapid', {worldCopyJump: true}).setView([51.505, -0.09], 3);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=api_key', {
/*maxZoom: 7,*/
attribution: 'Map data © OpenStreetMap contributors, ' +
'Imagery © Mapbox',
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
//set following lines to false
}).addTo(mymap);
var presentIcon = L.icon({
iconUrl: 'giftmarker.png',
iconSize: [38, 60], // size of the icon
iconAnchor: [12, 57], // point of the icon which will correspond to marker's location
});
L.marker([65.585848, -171.011122], {icon: presentIcon}).addTo(mymap);
L.marker x60 times
You need to add 360 to the Lng of the wrong placed markers.
So the marker should look like: L.marker([65.585848, 188.988878], {icon: presentIcon}).addTo(mymap);
With this code you can chage all existing markers. I take the break at -149 lng to swap the markers to the other side:
map.eachLayer((layer) => {
if (layer instanceof L.Marker) {
if (layer.getLatLng().lng <= -149) {
var latlng = layer.getLatLng();
latlng.lng = latlng.lng + 360;
layer.setLatLng(latlng);
}
}
});
I need to create a circle around a point where a user clicks. How would I do this? Every tutorial shows extracting a circle from a geojson source and not creating one. Need to be able to edit the radius as well.
Did you try something yourself? Following the mapbox examples you should be able to get an idea of how to build something like that.
You would need to do 3 things:
Create a source that holds the data
Create a layer of type "circle" for displaying the data as circles
On every click of the user, extract the "latitude, longitude" and add a point to your data list. Then display all of those points as a circle on the map.
This is an example of how I would have coded that: https://jsfiddle.net/andi_lo/495t0dx2/
Hope that helps you out
mapboxgl.accessToken = '####';
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/light-v9', //stylesheet location
center: [-74.50, 40], // starting position
zoom: 9 // starting zoom
});
map.on('load', () => {
const points = turf.featureCollection([]);
// add data source to hold our data we want to display
map.addSource('circleData', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [],
},
});
// add a layer that displays the data
map.addLayer({
id: 'data',
type: 'circle',
source: 'circleData',
paint: {
'circle-color': '#00b7bf',
'circle-radius': 8,
'circle-stroke-width': 1,
'circle-stroke-color': '#333',
},
});
// on user click, extract the latitude / longitude, update our data source and display it on our map
map.on('click', (clickEvent) => {
const lngLat = new Array(clickEvent.lngLat.lng, clickEvent.lngLat.lat);
points.features.push(turf.point(lngLat));
map.getSource('circleData').setData(points);
});
});
#map {
height: 500px;
}
<div id="map"></div>
I am using leaflet plugin to show the marker. When I click on the current marker the icon should change the current marker only.
Again when I click on another marker change that marker to new icon and keep all other marker icon original.
Like I have 2 marker Icon
1- original Icon which I am setting when showing the marker on map
2- new marker - I want this marker icon should be set when click on marker.Only current Marker Icon should be changed and keep all other Icon Original Icon.
you can try this.
When you click the marker1, its icon will change to the one you set.
let marker1 = L.marker([e.latitude, e.longitude], { icon: greenIcon }).on('click', ()=>{
marker1.setIcon(redIcon)
}).addTo(map)
Do you have a marker layer? If yes you could first create a new icon
var customIcon = L.Icon.extend({
options: {
iconSize: [40.4, 44],
iconAnchor: [20, 43],
popupAnchor: [0, -51]
}
});
var myCustomIcon = new CustomIcon({ iconUrl: '../images/marker.png' });
After that you should get clicked marker's index inside the Layer and update the icon like this:
markersLayer[markersIndex].setIcon(myCustomIcon);