I'm using openlayers 3 on a simple html page, to display a map with an overviewmap.
I would like to know if it is possible to trigger events on openlayers overviewmaps, like we can do on openlayers maps.
Indeed I have features displayed on the overviewmap (not on the map) and I'd like to be able to select them.
I can't see anything in the API related with that.
Thank you by advance
Finally, i was able to do it like this (getOverviewMap() has to be called on the overviewMap element) :
var overviewMapControl = new ol.control.OverviewMap({
// Parameters for my overviewMap
});
var map = new ol.Map({
controls: ol.control.defaults().extend([
overviewMapControl
]),
// ... other parameters
});
and the event triggered :
overviewMapControl.getOverviewMap().on('click', function(evt) {
overviewMapControl.getOverviewMap().forEachFeatureAtPixel(evt.pixel,
function(feature, layer) {
console.log(feature.getProperties());
});
});
Related
So, I want the user to be able to draw a freehand polygon on click of a button. I have it implemented in plain JS and now want to use it in vue (using vue-cli).
I am using this plugin for vue: https://github.com/xkjyeah/vue-google-maps/blob/vue2/API.md
Here is the code I am using:
var self = this;
// calls another method which disables map controls
self.disableMap();
// below line is fine
console.log(self.$refs.map.$mapObject);
// event handler is being called
self.$refs.map.$mapObject.addListener('mousedown', function() {
// the below line results in undefined
console.log(self.$refs.$polylineObject);
let poly = new(self.$refs.map.$polylineObject)({
map: self.$refs.map,
clickable: false
});
})
Any help greatly appreciated.
Recently I asked about referencing the data of an existing GeoJSON Leaflet object. My Leaflet map consists of data coming in a stream to my GeoJSON Leaflet object. User inputs can change a filter for the GeoJSON data, so to make the filter apply to both the existing and new data I am keeping track of my data in an array called myFeatures. Whenever the filters change or an item in myFeatures changes, I do the following:
myGeoJson.clearLayers();
myGeoJson.addData(myFeatures);
This is working to make my map update according to the newly updated feature data or the changes in the filter.
I am applying pop-ups to the GeoJSON object when I initialize my GeoJSON object:
var myGeoJson = L.geoJson(myFeatures, {
style: function(feature) {
...
},
pointToLayer: function(feature, latlng) {
return L.circleMarker(latlng, geojsonMarkerOptions);
},
filter: function(feature, layer) {
...
},
onEachFeature: function(feature, layer) {
if (feature.properties && feature.properties.popupContent) {
layer.bindPopup(feature.properties.popupContent);
}
}
});
When I click on an individual feature, the pop-up appears. However, the pop-up dismisses pretty quickly, thanks to clearLayers and addData being called. :(
Is there some kind of way to stop the pop-up dismissing in this situation?
Or - better question - is there a way to modifying existing data in a GeoJSON object or remove some (not all) data from a GeoJSON object?
To provide some context, my GeoJSON shows circle markers for each feature. The circle markers are colored based on a property of the feature. The property can actually change over time, so the marker's styling needs to be updated. A marker also times out after a while and needs to be removed from the map, but the other markers need to stay on the map.
There are for sure better ways to do that, but if you don't want to modify your code architecture too much, you could just create your popups in a specific layer, which you won't clear when you add your new data.
To give you an idea (markers play below the role of myGeoJson in your example):
var popup_id = {};
var popup_layer = new L.layerGroup();
var markers = new L.layerGroup();
$.each(testData, function(index, p) {
var marker = L.marker(L.latLng(p.lat, p.lon));
markers.addLayer(marker);
popup = new L.popup({offset: new L.Point(0, -30)});
popup.setLatLng(L.latLng(p.lat, p.lon));
popup.setContent(p.text);
popup_id[p.id] = popup;
marker.on('click', function() {
popup_id[p.id].openPopup();
popup_layer.addLayer(popup_id[p.id]);
markers.clearLayers();
})
});
popup_layer.addTo(map);
markers.addTo(map);
You also keep track of all your popups in a dictionary popup_id.
Since you haven't provided us with a JSfiddle it is a bit difficult to find the perfect answer for your case, but I hope that the popup layer (also here in my fiddle) gives you a good direction.
I need to add click event to Google Map markers, I'm using cordova in my app. Any way recommended in the documentation is not working... unless I make the marker draggable (then it works like gold) and I can't do that. I found that it was an issue a long, long time ago in 2011...
I think something had to be done with that since 2011. Do you have any idea?
Working piece of code below:
var position = new google.maps.LatLng(coords.lat, coords.lng);
var markerOptions = angular.extend({
map: map,
position: position,
title: name,
draggable: true
}, DrawingOptions.marker);
var googleMarker = new google.maps.Marker(markerOptions);
var marker = {
Id: id,
Type: type,
marker: googleMarker,
circle: new google.maps.Circle(circleOptions),
};
marker.marker.addListener('click', function () {
addInfoModal();
});
I also tried to make a function adding listener, but it won't work. I was also thinking about not-so-graceful solution - making marker draggable, but actually preventing action while dragging, but this isn't working and it looks bad in code.
Have you heard of something helpful in this case?
Seem your function is not right.
try without function simply adding the listener this way :
google.maps.event.addListener(googleMarker, 'click', function (event) {
alert('click');
});
I am currently developing a map-based application and need a way to get notified when Leaflet is pulling tiles from the TileProvider (which, in my case, is MapBox). I read the Leaflet documentation, especially the part with the TileLayer. Currently, I am using the following code to attach a tileload handler:
map.eachLayer(function (layer) {
layer.on('tileload', function(e) {
console.log(e);
});
});
Is there a better way to get the TileLayer of the current map? One problem with this approach is that I hook the handler to all layers (although only TileLayers will raise events, it is unclean to hook it too all layers). Or can I attach the handler directly to the map instance somehow?
Update
I initialize the map with the following MapBox code snippet:
map = L.mapbox.map( element, '...', mapOptions );
This automatically creates a TileLayer (and several other layers), attaches them to the map object and returns this object for later use.
Why not use tileload event directly on the tile layer, like this:
//create a variable to store the tilelayer
var osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
//add the tileload event directly to that variable
osm.on('tileload', function (e) {
console.log(e);
});
If you've got a lot of L.mapbox.TileLayer instances and you don't want to add the eventhandler manually to each instance like Alexandru Pufan suggests in his answer you could still use a loop and Object's instanceof method:
map.eachLayer(function (layer) {
if (layer instanceof L.mapbox.TileLayer) {
layer.on('tileload', function(e) {
console.log(e);
});
}
});
After reading your comment on Alexandru's answer i'm guessing you only have one layer, then it would be best to add it manually to the instance, which is possible with L.mapbox.TileLayer like this:
var layer = L.mapbox.tileLayer(YOUR MAP ID);
layer.on('tileload', function(e) {
console.log(e);
});
var map = L.mapbox.map('mapbox', null, {
'center': [0, 0],
'zoom': 0,
'layers': [layer]
});
While developing this solution, I learned that API V2 was being deprecated. I've since begun work on a version utilizing API V3. This work-in-progress can be found at My New Map. Special thanks are due to David Marland at Hammerspace for accelerating this conversion for me.
I'm down to 3 remaining issues..the first of which I will address in this post.
I am unable to trigger the infowindows I have defined:
google.maps.event.addListener(polyline, 'click', function(event) {
if (polyline.Contains(event.latLng)) {
infowindowInside.open(map,polyline);
} else {
infowindowOutside.open(map,polyline);
}
});
I am attaching them to a polygon..not a marker. The polygon is written:
var path = [
new google.maps.LatLng(35.950079, -84.104977),
new google.maps.LatLng(35.950774, -84.049702),
new google.maps.LatLng(35.946883, -84.047813),
new google.maps.LatLng(35.945354, -84.045067),
new google.maps.LatLng(35.940907, -84.042149),
new google.maps.LatLng(35.930483, -84.037857),
new google.maps.LatLng(35.939656, -84.037857),
new google.maps.LatLng(35.928120, -84.076309),
new google.maps.LatLng(35.938822, -84.066868),
new google.maps.LatLng(35.950079, -84.104977)];
var polyline = new google.maps.Polygon({path:path, strokeColor: "#FF0000", strokeOpacity: 1.0, strokeWeight: 2, clickable:false});
polyline.setMap(map);
I appreciate any guidance you can provide.
Thank you.
** UPDATED *****
I've now modified the code to:
google.maps.event.addListener(polyline, 'click', function(event) {
if (polyline.ContainsLocation(event.latLng, polyline)) {
window.alert('inside');//infowindowInside.open(map,polyline);
} else {
window.alert('outside');//infowindowOutside.open(map,polyline);
}
});
However..still no trigger.
Possibly because Polygon doesn't have a "contains" function. You should look at using the Google Maps API Geometry Library, which has a containsLocation function.
Google maps api v3 does not allow you to add infowindows to polylines or polygons. The solution around this is to grab the lat/lng coordinates of the mouseclick and attach the info window (where the user clicked his/her mouse) to the map like:
google.maps.event.addListener(polyline, 'click', function(event) {
if (polyline.Contains(event.latLng)) {
infowindowInside.open(map);
} else {
infowindowOutside.open(map);
}
});
(note how there isn't a second argument in the .open() method)
otherwise you can figure out the lat/lng of either the center of your polygon or one of its corners and attach the infowindow there (but to the map)
that will allow you to display your infowindow while making it appear as tho it is attached to the polygon.
Edit: Also -- as mano marks had stated about .Contains -- I am not sure if that method exists or not either, so that block of code you have may still not work even after removing the second argument from the .open() method. you may have to take a different approach to your logic if that's the case, but attaching the marker to the map instead of your polygon or polyline will solve your main issue.