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.
Related
I have a leaflet map that is populated with markers when GPS devices POST their lat and long on random intervals.
The issue is I have to manually drag the map to follow the marker as it receives updates and moves around the map.
Hours later and much research effort:
I implemented a half solution using a button which snaps to the markers current position, but again I have to click the button every time it moves to keep the marker in sight.
onclick="mymap.fitBounds(gotomarker1.getBounds());"
Is there a way I could click the marker itself which will then keep the marker in the center of the map as it receives lat and log updates and moves around? *ideally not a button as there could be many markers and I wouldn't want a page full of buttons.
I have tried applying an on.click function that loops the gotomarker1 code above but I cant stop it once its started, this is an issue as there is more than one marker that I may want to follow or not follow (to clarify I only want to follow one marker at a time).
the way i have solved a similar problem is to store the marker that is being followed into a variable
onclick="selectedMarker = myMarker"
Whenever you receive location updates simply focus the map on the selectedMarker
// update all locations
// ...
// focus selected marker
mymap.fitBounds(selectedMarker.getBounds());
#Nejc Jaminiks logic in his answer helped me work out what I needed to do.
When a marker is created I have this code appended to the marker in real time:
.on('click', focus);
I then have a function to detect when the marker is clicked and loop through setting the view to the marker until the marker (or another marker) is clicked then it will stop following it.
var focusenabled = true;
interval = null;
function focus(e) {
if (focusenabled) {
var i = 0;
interval = setInterval(function () {
mymap.setView(e.target.getLatLng());
console.log("focus active");
}, 2000);
focusenabled = false;
document.getElementById("footer").style.backgroundColor='red';
document.getElementById("footer").style.color='white';
} else {
clearInterval(interval);
document.getElementById("footer").style.backgroundColor='#222';
document.getElementById("footer").style.color='#222';
focusenabled = true;
}
};
I use the code below to change the footer div to red and text to white when a marker is being followed:
document.getElementById("footer").style.backgroundColor='red';
document.getElementById("footer").style.color='white';
And then when a marker is not being followed the footer div returns to the background color which effectivley hides it :)
document.getElementById("footer").style.backgroundColor='#222';
document.getElementById("footer").style.color='#222';
I'm using Leaflet and Leaflet PM and their polyline tool to create a polyline. Everything works fine when clicking and adding new points to the map. This data I then use to store away somewhere else and do some other stuff with it. The thing is.
I am going to have a function to be able to press the 'e' key and 'd' key to add points to the map using DOM Eventlisteners. This is because I need to change floor elevation. And if I use the mouse for that on the same location as a previously added point it closes the polyline. Also there it works great. I use mouseover on the map, store the lat long, and then on keydown I use my workingLayer to addLatLng(latlng). It saves the latitudes and longitudes, it draws the line. But there are no vertexes added as when I'm clicking. And I need the vertexadded function to be able to add my other meta-data to it. I'm also gonna use those vertexes to customize later on.
I've been spending the whole day on this and I really need some help now, can't find anything about it.
I also tried adding a marker directly to the layer but that didn't work.
All in all. Everything works fine when I'm clicking to make the polyline. But when programmatically call the layer.addLatLng(latlng); won't add the vertex. Only the latlng and where it is, as shown in the images. Therefore pm:vertexadded is never called.
What am I missing?
An example from my code:
lmap.on('pm:drawstart', function(e){
//Layer is now the workingLayer
let layer = e.workingLayer;
//Will hold coordinates from map
let pointFromMouse;
lmap.addEventListener('mousemove', function(e){
//Assigning current position lat/long
pointFromMouse = e.latlng;
})
document.addEventListener('keydown', function(e){
if(e.keyCode == '69'){
//When pressing 'e', adds it to the polyline
layer.addLatLng(pointFromMouse);
//I also tried setLatLngs(); and redraw(); no sucess
}
})
layer.on('pm:vertexadded', function(e){
//Here I'm calling some other stuff. I stuff another array along
//with other meta-data, other than lat/long.
})
})
Image1: How it looks when I'm clicking(Everything works fine, vertexes are added).
Image2: How it looks when I'm adding a point pressing the key. No vertextes are added, Therefore pm:vertexadded is never called.
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.
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.
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);
}