How can I add an infoTemplate to an existing Graphic instance?
I'm doing this graphic instances without infoTemplate for every point that I have:
const layerMarkers = new GraphicsLayer({id: layerId});
this.map.addLayer(layerMarkers);
// Some code
const graphic = new Graphic(point, imageSymbol, null, null );
layerMarkers.add(graphic);
Then I want to call some API when I click the graphic:
layerMarkers.on('click', function(e) {
console.log(e);
console.log(this);
//Here I can see the object, I need to do something here with it
});
What I need is to set:
infoTemplate.setTitle(result.poi.nombre);
infoTemplate.setContent(this.getTooltip(result.poi));
And then I need to update my graph object with the infoTemplate
I can't do:
const graphic = new Graphic(point, imageSymbol, null, infoTemplate);
Or I will overwrite my object.
Any tips?
Just use the setInfoTemplate method on the graphic layer to set the template after the graphics layer is already instantiated.
If you just want to show the info window when a user clicks on the graphic layer then just use the show method on the maps InfoWindow instance.
this.map.infoWindow.show(e.screenPoint,e.getInfoWindowAnchor(e.screenPoint));
after you set the content.
You can also use setFeatures which will take a deferred (that eventually returns an array of graphics)
There's a bunch of ways to do what you want depending on the order of the user interactions and whether you are getting data for the popup over the network or not.
Related
we are using OpenLayers 4.6.4 with the ol-ext extension in order to show beautiful looking clusters. That is working fine so far, but we need to link each cluster with custom informations (like putting a simple field into the cluster object) and once the cluster is clicked on the map, i want to retrieve it with the arguments delivered in the callback.
I was not able to find a simple example on putting custom fields on a cluster and retrieving them once i click them on the map.
The event i add my listener is handled by ol.interaction.SelectCluster from ol-ext
Any ideas?
You cannot change the cluster features so easily, but that's actually not necessary to get information about it.
Cluster is just a layer source which clusters (who would have guessed) an underlaying source. It creates Features, which in turn have the represented Features stored in a property features.
The ol-ext example demonstrates how to read the contained features:
var selectCluster = new ol.interaction.SelectCluster(.....);
selectCluster.getFeatures().on(['add'], function (e)
{ var c = e.element.get('features');
if (c.length==1)
{ var feature = c[0];
$(".infos").html("One feature selected...<br/>(id="+feature.get('id')+")");
}
else
{ $(".infos").text("Cluster ("+c.length+" features)");
}
})
Without any interaction, you could do this:
map.on('singleclick', function(evt) {
const feature = map.forEachFeatureAtPixel(
evt.pixel,
function(someFeature){ return someFeature; }, // stop at the very first feature
);
const containedFeatures = feature.get('features');
});
I have a page to display all markers on a single google map and use map.data.loadGeoJson to achieve this.
The markers link to their respective details page with the following:
map.data.addListener('click', function(event) {
var id = event.feature.getProperty('name');
window.location.href = 'submission-details.php?submission_id='+id;
});
(The property 'name' is a json file property and the ID for each submission).
I would like the details page to also show a map, but only with one marker relevant to that specific details page.
My json type is feature collection, so I think I need a way to target each feature from the collection, rather than just using map.data.loadGeoJson which displays them all.
Not sure where to go from here and struggled to find someone else asking the same question so any help appreciated!
UPDATE
Thanks Duncan.
I added:
map.data.loadGeoJson('../photo_share/upload/file.json', {},function() {
map.data.getFeatureById(53);
map.data.getFeatureById(53).getProperty('name');
console.log(map.data.getFeatureById(53));
console.log(map.data.getFeatureById(53).getProperty('name'));
});
google.maps.event.addDomListener(window, "load", initMap3);
And it does display in console log, but how do I now use this to only display the one marker, because it currently displays all of them still.
The google.maps.Data class has a getFeatureById method. Given you're passing that id into the submission-details.php page, you should be able to use that to get just the single feature.
You still need to use loadGeoJson, and wait until that's loaded before trying to access it; see Google Maps API: getFeatureById for feature collection not working
Update: And then to stop the whole collection displaying, maybe something like this (completely untested)?
map.data.loadGeoJson('../photo_share/upload/file.json', {}, function(features) {
// get the feature you want:
var feature = map.data.getFeatureById(53);
// hide the current set:
map.data.setMap(null);
// wipe out all the current features:
for (var i = 0; i < features.length; i++) {
map.data.remove(features[i]);
}
// add the feature you want back in:
map.data.add(feature);
// display it:
map.data.setMap(map);
});
I added some points on the map using javascript(OpenLayers3). These points' positions are fetching from sql(randomly generated). I have to create a pop-up menu about each object on the map. This pop-up includes the data information of each selected point but ı dont know how to get the data from sql using the object on the map.
Points Img
How to get data ? Img
One way to do it is to transfer ID from your sql for each object in map. You can add custom property in that way:
var pointFeature = new ol.Feature({
geometry: new ol.geom.Point([0, 0]),
id: 25
});
Next use click event to get feature and ID:
map.on('click', function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature) {
return feature;
});
if (feature) {
alert(feature.get('id'));
}
});
Here you go! All that remain is to make ajax request to your asp.net with ID as parameter.
Another way is to transfer ALL attributes from your sql on map from the beginning, so you won't need to make ajax request - you could just get properties from feature. But be careful as this solution will increase your point data greatly.
I am using a simple Mapbox layer control calling MB data layers (below).
I need to add a few more marker layers to this, but not sure how to get a mapbox ID. How can I accomplish this?
L.mapbox.accessToken = 'pk.eyJ1IjoibWFwc3RlciIsImEiOiI3RmFfME5ZIn0.73sdzUFNqSsGQzjlsnimaA';
var map = L.map('map').setView([38.8922,-77.0348], 14);
var layers = document.getElementById('menu-ui');
addLayer(L.mapbox.tileLayer('examples.map-i87786ca'), 'Base Map', 1);
addLayer(L.mapbox.tileLayer('examples.bike-lanes'), 'Bike Lanes', 2);
addLayer(L.mapbox.tileLayer('examples.bike-locations'), 'Bike Stations', 3);
function addLayer(layer, name, zIndex) {
layer
.setZIndex(zIndex)
.addTo(map);
code is from Mapbox toggling layers template
At the moment you're using their example ID and maps. You're not supposed to do that. If you would have read at the bottom of the page you posted it says:
Use this example by copying its source into your own HTML page and replacing the Map ID with one of your own from your projects.
Where "your projects" is linked to https://www.mapbox.com/projects/. When you're not logged in you get a nice dialog which asks you to login or register. Once you've done that you'll get your very own ID and you are able to create projects. When creating a project you'll get a Map ID per project. It's all pretty selfexplanatory.
EDIT: If you want to insert a separate layer with features, you've got to create a project with only a markerlayer. Save it and copy the id. You can include that in another map by using L.mapbox.featureLayer:
var mapId = 'examples.map-zr0njcqy'; // use your feature mapid
var features = L.mapbox.featureLayer(mapId); // declare featureLayer
features.on('ready', function () { // Wait untill features are loaded
addLayer(features); // add it the same your tilelayers
}
You can also use this to load external geojson files by just using an URL instead of a mapid.
See the example: https://www.mapbox.com/mapbox.js/example/v1.0.0/features-from-another-map/
And the reference: https://www.mapbox.com/mapbox.js/api/v2.1.5/l-mapbox-featurelayer/
Ok, here is my situation. I am using the leaflet map module with drupal. I have the map integrated on my website with views. I have nodes that contain content that I want to be displayed via a popup window. When I click each individual marker, the popup works exactly as I want. however, I want to be able to click an external link to be able to also open the popup. I have viewed and implemented this code from another question:
var markers = [];
var marker1 = L.marker([51.497, -0.09],{title:"marker_1"}).addTo(map).bindPopup("Marker 1");
markers.push(marker1);
var marker2 = L.marker([51.495, -0.083],{title:"marker_2"}).addTo(map).bindPopup("Marker 2");
markers.push(marker2);
var marker3 = L.marker([51.49, -0.097],{title:"marker_3"}).addTo(map).bindPopup("Marker 3");
markers.push(marker3);
function markerFunction(id){
for (var i in markers){
var markerID = markers[i].options.title;
if (markerID == id){
markers[i].openPopup();
};
}
}
$("a").click(function(){
markerFunction($(this)[0].id);
});
by user abenrob, but that doesn't work with markers generated by drupal.
My question has 2 parts, as I can see it.
1: How do I access the map inside my different block? I have set up the links from my menu block to call my function that contains the aforementioned code, and they call it correctly. However, when my Javascript needs to speak to the map, I get nothing.
Currently I have "var map = document.getElementById('leaflet-map');", but that seems to be pulling the div, not the map contained inside the div.
2: How do I access the list of markers generated by my map in drupal. Currently, as a test, I am just generating a marker manually and using the bindPopup function to bind the div containing the popup on the page, but I can't add it to the map (see part 1). Ideally I would not want to recreate the markers in javascript if they are already created in Drupal, but we don't always live in an ideal world, but it seems that if I get the map to connect, I could at least work with that.
In case anyone else stumbles across this with the same question, I figured out the first question. I accessed the map created by Drupal through the Leaflet module by utilizing the following code:
// This accesses the leaflet map created by drupal and sets the map variables so that they can be used with the functions
var map;
$(document).bind('leaflet.map', function(e, settingsLeaflet, lMap)
{
map = lMap;
});
I am still working on the second question. When I figure it out, I will add another update.
Edit: I was able to access the markers in the second question by using the following code:
var markers = {};
var markersList = [];
// This accesses the leaflet map features and pulls the marker variables so that they can be used with the functions
$(document).bind('leaflet.feature', function(e, lFeature, feature)
{
markers[feature.feature_id] = lFeature;
markersList.push(lFeature);
});
from there it was as easy as looping through the markers list, as such:
// This function takes the variable id, which is passed from the HTML call of this function. It then loops through the marker list and compares the id with the value of the title of each marker. If it finds a match, then it opens the popup bound to that specific marker.
function markerPopups(id)
{
// Loops through the markers list
for (var i = 0; i < markersList.length; i++)
{
// Sets a variable to get the title of the marker, which
var markerID = markersList[i].options.title.replace(/[^a-zA-Z0-9]/g, '_');
// Compares the variable passed through the function to the title of the marker. If there is a match, it opens the popup for that marker.
if(markerID == id)
{
markersList[i].openPopup();
}
}
}
Also, it wasn't needed to access the map once you accessed the pre-made markers, so you can ignore the first part, unless you need to use the map for anything else.