HTML Link to a Leaflet / Mapbox marker - javascript

I use Mapbox for a dynamic map on a website. It works really well except, I have a sidebar which list the pins with a little more description and an image. I want to make it so when I click on that sidebar, it would fire the click event of that marker on the map.
I used to do this all the time with Google Maps but now I'm stuck because even in the case that I can keep the instance of the marker, I cannot fire the click on it for some reason. It simply does nothing (maybe I need to re-bind the click event on it but I don't know how with mapbox)
I've encountered a few questions about this on Google and SO but none bring a real answer to that question except "keep the instance" which isn't always possible in some cases.
So basically I have a jQuery click event like this:
var marker = {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [lng, lat]
},
properties: {}
};
if (isPin) {
marker.properties = pinStyles.pin;
} else if (isWinery) {
marker.properties = pinStyles.winery;
} else {
marker.properties = pinStyles.user;
}
marker.properties.title = locationName;
marker.properties.description = pin.description;
var markerObject = L.mapbox.markerLayer(marker);
// Add to cluster
markers.addLayer(markerObject);
$('#marker_list a.marker_item:last').click(function() {
var geoJson = markerObject.getGeoJSON();
markerObject.fire('click'); // does nothing (openPopup makes "Uncaught TypeError: Object [object Object] has no method 'openPopup' " so I guess I'm not doing it right)
});
And I have this (click event for mapbox marker):
map.markerLayer.on('click', function(e) {
map.setView(e.layer.getLatLng(), map.getZoom());
});
Anyone has an idea about wether 1) fix the non-firing event OR 2) make an HTML link fire a mapbox marker click event OR .openPopup?
Thanks and have a nice day!

MapBox's marker layer is a collection of Leaflet markers. You can create an href to a function that look for a particular marker based on it's layer id.
map.markerLayer.getLayers() returns an array of layer objects that contain both a _leaflet_id and the method togglePopup.
Try matching your href call to the leaflet id and then fire map.markerLayer.getLayers()[i].togglePopup()
Let me know if this helps.

Related

Laravel Livewire set is Removing Map Marker

I am using Laravel 8 with Livewire and am displaying a Mapbox map in my page.
When I click on the map, I am getting the coordinates of the click and placing a marker on the point where clicked. All working well up to this point.
What I am then trying to do is emit the coordinates to the Livewire component ready for saving along with other form details. However, when I click the map, the marker quickly appears then disappears; although the coordinates are emitted correctly and stored.
map.on('click', function(e){
var coord = e.lngLat;
updateCoords(coord);
addMarker(coord);
});
function addMarker(coord) {
if(newMarker != undefined) {
newMarker.remove();
}
newMarker = new mapboxgl.Marker()
.setLngLat([coord.lng, coord.lat])
.addTo(map);
}
function updateCoords(coord) {
#this.set('latitude', coord.lat);
#this.set('longitude', coord.lng);
}
I've tried emitting with a listener and using #this.set, both have the same effect.
The component isn't doing anything special at the moment, but I can see that the coordinates are being passed correctly. Just the issue being that the map marker disappears from the map.
Any ideas?
Found out that it is just a case of adding
wire:ignore
to the map div.
<div id="my-map" wire:ignore></div>
I found the answer from here: Livewire Github.
When Livewire updates it replaces the DOM and removes the changes; in my case, removing the map marker.

Running function on Mapbox click marker // Displaying SVGs in position relative to Mapbox coordinates

I'm creating an interactive website prototype for a travel-booking site, using mapbox for the first time. I've done a lot of searching through the mapbox site and elsewhere but there's here's a couple things I just can't figure out:
First problem: when a marker on the map is clicked, a js function should be run to reveal the pane on the right
I already have this code from mapbox that opens an individual popup on each marker on click (I'll remove these popups later):
// When a click event occurs near a place, open a popup at the location of
// the feature, with description HTML from its properties.
map.on('click', function (e) {
var features = map.queryRenderedFeatures(e.point, { layers: ['places'] });
if (!features.length) {
return;
}
var feature = features[0];
// Populate the popup and set its coordinates
// based on the feature found.
var popup = new mapboxgl.Popup()
.setLngLat(feature.geometry.coordinates)
.setHTML(feature.properties.description)
.addTo(map);
});
Based on how the clicking is handled in that example, I was hoping something along the line of this would work:
feature.on('click', function (e) {
**Insert code to display the pane here**
});
But that does not work. It's harder to figure these things out when you're using an api you're not familiar with. So I need to know how I would do that.
The second problem: When the user clicks to look at popular trips through the city, a js function will run run to show svgs over the map (from an Illustrator mockup)
The issue here is that I need the svg to display at certain coordinates of the map, not just a position in the screen. This, I have no idea where to start.
Any help is appreciated, thanks !
I didn't really understand your "first problem", but for the second problem, you can add an image at a given lat/lon using a Marker. See this example.
var el = document.createElement('div');
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';
el.addEventListener('click', function() {
window.alert(marker.properties.message);
});
// add marker to map
new mapboxgl.Marker(el, {offset: [-marker.properties.iconSize[0] / 2, -marker.properties.iconSize[1] / 2]})
.setLngLat(marker.geometry.coordinates)
.addTo(map);
Edit
I see from your comment you want the image to remain at the same scale with the map, when it zooms in and out. You want an Image source, not a marker.
https://www.mapbox.com/mapbox-gl-js/example/image-on-a-map/
"overlay": {
"type": "image",
"url": "https://www.mapbox.com/mapbox-gl-js/assets/radar.gif",
"coordinates": [
[-80.425, 46.437],
[-71.516, 46.437],
[-71.516, 37.936],
[-80.425, 37.936]
]
}
It probably doesn't support SVG, however.

How to reference a google map marker by it's id and activate it's click event using javascript?

I am dealing with Google Maps here and javascript. I have an existing marker on my Google map and I can click on it and it displays a div. If I click it again, the div disappears. I gave this marker a specific, unique id.
There is also a Polygon on the map. I want when the user clicks on the polygon that the click event is activate for a marker that I will reference by the marker's id.
Is this possible? If so, let's say that the id of the marker is U123. How would I do this?
Here is the code I use to add an event to the polygon click:
google.maps.event.addListener(assetPolygons[polygon_count],'click', function (event) {new google.maps.event.trigger('U123', 'click');});
U123 is the name of the marker id. The above is not working.
var marker = new google.maps.Marker(markerOptions);
marker.setValues({id: 1}); // v3
marker.metadata = {type: "point", id: 1}; //v2 or v3
I guess the better way to do this is to store your marker in a global var and then do
$(".something").click(function(){
new google.maps.event.trigger( marker, 'click' );
// Here marker is a global var so accessible everywhere.
});
Two seconds in google found How to trigger the onclick event of a marker on a Google Maps V3?
The only difference in the function that was stated to work, wich is:
google.maps.event.trigger(markers[i], 'click');
and yours that i can see is the new, try removing it
I built a function that loops through the assetMarkers array that stores each marker. This works:
function ClickMarker(u) {
for (i=0;i<assetMarkers.length;i++) {
if (assetMarkers[i].id == u) {
google.maps.event.trigger(assetMarkers[i], 'click');
i = assetMarkers.length;
}
}
}
In the above function, the variable u is the id of the marker in the array assetMarkers (which is the array storing the map markers). When I create the marker, I set the id using marker.setValues({id: 'U123'}); where U123 is the id of the marker.
I have to loop through the assetMarkers array to find the one I am looking for.
I was hoping, the equivalent of document.getElementById(u) would exist in Google Maps so that I would not have to loop through the array. It would be great, Google API guys, if we programmers could do something like this:
google.maps.event.trigger(google.maps.getElementById(u), 'click');
Thanks for everyone's input! It was very helpful as I am a newbie to Google Maps.

Google Maps API markers and zoom

I'm relativ new to the Google Maps API.
My situation: Website with an fullscreen Google map as background.
First problem: If the user scrolls down, or zooms out too much, there is an gray background. Is it possible to limit the max zoom-out, and that he can't scroll out? Or maybe repeat the map vertical (with markers).
If it's possible to set the max zoom-out and lock him within the map, how could I dynamically calculate the max zoom-out releated to the screen-resolution?
Second problem: Is it possible to add custom javascript to a marker?
Example: I create 5 markers, each one should hold an custom value (ID from the database). On click my own function should be called with the custom value as parameter and do some stuff.
Edit: This is what I mean with grey: (vertical "end" of google maps)
Map object have propert maxZoom, set it when map created
yes it is possible, you can add click events, change popups open, and since it is javascript you can add any additional data just as simple as markr.MyData = 'something interesting'
I am not sure what gray part you mean? I can't see gray parts with max and min zoom in google maps
Okay. Got it finally working! :)
Fixing grey area (handles also zooming):
function setBounds() {
google_allowedBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(-85.000, -122.591),
new google.maps.LatLng(85.000, -122.333));
google_lastCenter = google_map.getCenter();
google_lastZoom = google_map.getZoom();
google.maps.event.addListener(google_map, "bounds_changed", function () {
checkBounds();
});
google.maps.event.addListener(google_map, 'center_changed', function () {
checkBounds();
});
}
function checkBounds() {
if (google_allowedBounds.getNorthEast().lat() > google_map.getBounds().getNorthEast().lat()) {
if(google_allowedBounds.getSouthWest().lat() < google_map.getBounds().getSouthWest().lat()) {
google_lastCenter = google_map.getCenter();
google_lastZoom = google_map.getZoom();
return true;
}
}
google_map.panTo(google_lastCenter);
google_map.setZoom(google_lastZoom);
return false;
}
Marker click handler:
google_listener = google.maps.event.addListener(marker, 'click', markerHandler);
function markerHandler(event) {
window.console.log(this);
}

how to get a location click event in ModestMaps / Wax

I have my nice map loading from MapBox but now I need to get a click event from Wax / ModestMaps. The following code only triggers the callback on page load:
var mapbg, interaction;
var urlBase = 'http://a.tiles.mapbox.com/v3/mteran.house';
// Build baselayer background
wax.tilejson(urlBase + '.jsonp', function(tilejson) {
map = new MM.Map('mymap-bg',
new wax.mm.connector(tilejson));
map.setCenterZoom(new MM.Location(
tilejson.center[1], // latitude
tilejson.center[0]), // longitude
tilejson.center[2]); // zoom level
map.addCallback("drawn", function (map) {
mapbg.setCenterZoom(map.getCenter(), map.getZoom());
});
wax.mm.zoomer(map, tilejson).appendTo(map.parent);
map.setZoomRange(tilejson.minzoom, tilejson.maxzoom);
wax.mm.interaction()
.map(map)
.tilejson(tilejson);
var house = new MM.Location(map.getCenter());
house.on('click', alert(map.getCenter()));
});
What kind of click event are you trying to get? The map you're using has no TileMill interaction enabled, so I'm assuming that's not the objective. If you're trying to get a click event anywhere on the map and figure out if it's on the 'house area', here's your code expanded to make that happen.
The 'close enough' will be necessary, since points are points as far as maps go; latitude/longitude locations are infinitely small and it's very hard to click them.

Categories