getting/setting unique id to a leafletjs circlemarker - javascript

I have a map with several markers on it. I construct these markers with this piece of code:
var markers = {},
lbl = 'unique';
markers[lbl] = L.circleMarker(ll,
{ radius: 8,
fillColor: '#ff0000',
color: '#00ff00',
weight: 0,
opacity: 1,
fillOpacity: 0.9,
className: 'svgMarker'
})
.bindLabel('This is '+lbl)
.addTo(markerLayer)
.addTo(map)
.on('click', clickHandler);;
Within the clickHandler I want to load some stuff depending on which marker I clicked. To distinguish them, I have a lbl (label)var which holds the unique alphanumeric ID of the marker.
function clickHandler(event){
//- zoom to the marker
map.setView(ev.latlng, 16);
//- Load the marker dependent stuff.
// how can I pass the unique label to this function?
}
Is there a way to pass the unique id with the mouse event or is there an other way to give a 'property' to the marker which I can read out in the clickHandler?

just add a property to your marker (just javascript stuff) ... you can get it back with context 'this' in the event handler
var marker = L.marker([48.8588589,2.3470599]);
marker.id = 'unique_id';
marker.addTo(map);
marker.on('click', clickHandler);
function clickHandler(event) {
console.log(this.id);
}

Related

Google Maps GeoComplete with GeoJson

I am struggling to get Google Maps to show me the data stored in a GeoJSON object. If I use a click event on the polygon it works first time. Code below:
// Get the GeoJSON file from the server
HTTP.get(Meteor.absoluteUrl("/geo.json"), function(err,result) {
GoogleMaps.maps.fibreMap.instance.data.loadGeoJson("/geo.json");
});
// Add style and colouring to the map
GoogleMaps.maps.fibreMap.instance.data.setStyle(function(feature) {
// Get the Fibrehood Status
var status = feature.getProperty('status');
// Add colour accoring to status
if (status == "live") {
opacity = 0.65;
} else if (status == "build") {
opacity = 0.4;
} else if (status == "register_i") {
opacity = 0.2;
}
// Return the correct styling
return ({
fillColor: '#ec008c',
strokeColor: '#ec008c',
strokeOpacity: 0.35,
strokeWeight: 0,
fillOpacity: opacity
});
});
GoogleMaps.maps.fibreMap.instance.data.addListener('click', function(event) {
var hood = event.feature.getProperty('name');
var status = event.feature.getProperty('status');
console.log(hood + " : " + status);
});
However, when trying to use GeoComplete to drop a pin on an address, it does not run. I know that this should be triggered with some sort of event, like a marker dropping on the map or a Dom Element changing, but I cannot figure it out.
Does anyone have any insight into how to trigger events from the DOM or dropping a marker onto the map? I am a bit of a noob and would really appreciate any help.
Thanks
Mike
Does anyone have any insight into how to trigger events from the DOM or dropping a marker onto the map?
Sure, there is. Google Maps JS API has a well-documented example of working with map events and map markers.
In this example a marker will drop on the map where you clicked using the 'click event'.
// This event listener calls addMarker() when the map is clicked.
google.maps.event.addListener(map, 'click', function(event) {
addMarker(event.latLng, map);
});
// Add a marker at the center of the map.
addMarker(bangalore, map);
}
// Adds a marker to the map.
function addMarker(location, map) {
// Add the marker at the clicked location, and add the next-available label
// from the array of alphabetical characters.
var marker = new google.maps.Marker({
position: location,
label: labels[labelIndex++ % labels.length],
map: map
});
}
Full demo is here.
Here's a link to a sample for Listening to DOM Events:
https://developers.google.com/maps/documentation/javascript/examples/event-domListener

Google maps : Finding polygon by Id

Hi I have a polygon below :
var polygon = new google.maps.Polygon({
paths: coords,
id : 123,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 1,
fillColor: '#FF0000',
fillOpacity: 0.35
});
polygon.setMap(globalMap);
I attached an id property to it so i can refer to it later on, the problem is. How do I find that same polygon and trigger an event? like a change color or something?
function changePolygonColor(){
//refer to the polygon with id 123 (this is my question)
//change its color
polygon.fillColor = '#00FF00';
}
Many thanks!
From what I understand, you want to trigger an event after finding the polygon with a specific id.
Now, one thing you can do is just add an event listener to the polygon and refer to the polygon using the this context. You can then trigger the change of colour accordingly (for example):
google.maps.event.addListener(polygon, 'click', function (event) {
alert(this.id);
//Once you have the id here, you can trigger the color change
});
In your case however, if you don't want to trigger the color change on a specific even listener that can be added to the polygon. You could simply store the polygons in a polygon array and loop through them in your specific function that changes the colors. So you could try something like this (untested):
var polygonArray = []; //Have a global array of polygon elements
polygonArray.push(polygon); //Push your polygons as you create them into this polygon array
...
function changePolygonColor(){
//refer to the polygon with id 123 (this is my question)
//Loop through the polygon array
for (var i = 0; i < polygonArray.length; i++) {
if(polygonArray[i].id == 123) //Or whatever that you require
{
//change its color
polygon[i].fillColor = '#00FF00';
}
}
}
You might also want to check some other SO Posts on a similar issue. Hope this gets you started in the right direction.

Infowindows without markers with the Google Maps JavaScript API

I am using the Google Maps JavaScript API to create a heatmap layer. I would like to add mouseover events to 100+ locations on the map that will display an infowindow. This would get pretty cluttered if I used markers for every event, so I was hoping to find a way to eliminate markers altogether (although I did throw together an ugly mess of a solution in which a button will show/hide those markers). My first thought was to use the LatLngBounds. As a simple example:
var infowindow = new google.maps.InfoWindow(
{ content: "some info",
size: new google.maps.Size(50,50)
});
var southWest = new google.maps.LatLng(-31.203405,125.244141);
var northEast = new google.maps.LatLng(-25.363882,131.044922);
var loc = new google.maps.LatLngBounds(southWest,northEast);
google.maps.event.addListener(loc, 'mouseover', function() {
infowindow.open(map);
});
google.maps.event.addListener(loc, 'mouseout', function() {
infowindow.close();
});
For whatever reason, though, the mouseover event never seems to happen. Is there a problem with the code? Is there a better way to do this than by using LatLngBounds?
First of all, you should make a new rectangle with your bounds:
var southWest = new google.maps.LatLng(-31.203405,125.244141);
var northEast = new google.maps.LatLng(-25.363882,131.044922);
var loc = new google.maps.LatLngBounds(southWest,northEast);
var rectangle = new google.maps.Rectangle({
bounds: loc,
editable: false,
draggable: false,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
rectangle.setMap(map);
And then just use an event listener on that rectangle
google.maps.event.addListener(rectangle, 'mouseover', openInfoWindow);
function openInfoWindow(event) {
var ne = rectangle.getBounds().getNorthEast();
var sw = rectangle.getBounds().getSouthWest();
var content = 'Infowindow content';
// Set the info window's content and position.
infoWindow.setContent(contentString);
infoWindow.setPosition(ne);
infoWindow.open(map);
}

how to pass data with marker in leaflet js

I am using leaflet js with openstreetmap in my project.
I have multiple circlemarkers at same place in my map.
I want to store some Id in that circlemarkers so that I can Identify that which data should be refereed when circlemarker is clicked.
My circlemarker is
var myMarker = L.circleMarker(myPoint, { title: 'unselected', radius: 20 });
myMarker.addTo(map);
Here I am using title for other purpose that's why I cant use it.
Can any one tell me some way to do this.
It sounds like you would like to add new functionality (functions, properties, etc) to an existing class. It would make sense to use object-oriented principals for this. For this purpose, I'd recommend you extending the CircleMarker class to add those properties.
customCircleMarker = L.CircleMarker.extend({
options: {
someCustomProperty: 'Custom data!',
anotherCustomProperty: 'More data!'
}
});
Now when you create your circle marker, create an instance of your extended object instead.
var myMarker = new customCircleMarker(myPoint, {
title: 'unselected',
radius: 20,
someCustomProperty: 'Adding custom data to this marker!',
anotherCustomProperty: 'More custom data to this marker!'
});
myMarker.addTo(map);
Now you can get the properties like you would any other option from the marker. This is just a simple case of extending, and you can do more as needed, such as adding other properties or functions to the object.
JSFiddle example: JSFiddle
With the current version of leaflet (0.8-dev) you can just set your custom properties on the marker object itself, without having to create a custom marker class...
function map() {
return L.map('leaflet-canvas',
{
maxZoom: 10,
minZoom: 0,
crs: L.CRS.Simple
});
}
var map = map().setView([0, 0], 10).on('click', onMapClick);
function onMapClick(e) {
var marker = L.circleMarker(e.latlng, {draggable:true});
marker.myCustomID = Math.floor((Math.random() * 100) + 1);
marker.on('click', onMarkerClick);
map.addLayer(marker);
// 'click' the new marker to show the ID when marker created
marker.fireEvent('click');
}
function onMarkerClick(e) {
alert(e.target.myCustomID);
}
Here is a TypeScript friendly way:
DataMarker.ts
import * as L from 'leaflet';
export class DataMarker extends L.Marker {
data: any;
constructor(latLng: L.LatLngExpression, data: any, options?: L.MarkerOptions) {
super(latLng, options);
this.setData(data);
}
getData() {
return this.data;
}
setData(data: any) {
this.data = data;
}
}
SomeOtherFile.ts
import { DataMarker } from './DataMarker';
const marker = new DataMarker([ lat, lng ], anyData, markerOptions);
--
Note 1: I decided not to merge the marker options with the data property
Note 2: Adjust the type of data if you need something more specific
marker is basically javascript object rite.
Below snippet solve my case simply.
var marker = new L.marker([13.0102, 80.2157]).addTo(mymap).on('mouseover', onClick);
marker.key = "marker-1";
var marker2 =new L.marker([13.0101, 80.2157]).addTo(mymap).on('mouseover', onClick);
marker2.key = "marker-2";
function onClick(e) {
alert(this.key); // i can expect my keys here
}
just to complete the picture , to create a handler which will respond to a mouse click on a marker and provide access the new options
function onMarkerClick(e) {
console.log("You clicked the marker " + e.target.options.someCustomProperty);
console.log("You clicked the marker " + e.target.options.anotherCustomProperty);
}
marker.on('click', onMarkerClick);
Try this Uniquely identifying Leaflet Markers , its working for me.
//Handle marker click
var onMarkerClick = function(e){
alert("You clicked on marker with customId: " +this.options.myCustomId);
}
//Create marker with custom attribute
var marker = L.marker([36.83711,-2.464459], {myCustomId: "abc123"});
marker.on('click', onMarkerClick);
I would recommend to structure in your data for your markers in the standard GeoJSON format, which makes it compatible for direct saving as shapefile, etc.
var myMarker = L.circleMarker(myPoint, { title: 'unselected', radius: 20 });
myMarker.properties.id = your_Id;
myMarker.addTo(map);
To retrieve the stored information and do things with it or pass it on to other parts of your program, showing a sample onclick function:
myMarker.on('click',markerOnClick);
function markerOnClick(e) {
my_ID = e.layer.properties.id;
console.log(my_ID, e.latlng);
// do whatever you want with my_ID
}
It took me a while to find out the e.layer.properties way to access the clicked marker's properties, so hope this helps someone. Most other examples only focused on yielding the lat-long of the marker, e.latlng.
Note that you can use this same code even with a whole layer / group of markers. The function will work on each individual marker.
I have a easy solution. options property in each circleMarker is the good place to store custom value.
var myMarker = L.circleMarker(myPoint, { custom_id: 'gisman', radius: 20 });
myMarker.addTo(map);
You can easily retrive the value in options.
function markerOnClick(e) {
var id = e.options.custom_id;
}

Google map: Add click listener to each polygon

I am working on a webapplication.
I have a google map, where I add polygons from an array. I loop through that array and add the polygons to the map. I also need to add an event listener to the polygon click and alert the position of the polygon
This is what I'm doing
map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions);
//Loop on the polygonArray
for (var i = 0; i < polygonArray.length; i++) {
//Add the polygon
var p = new google.maps.Polygon({
paths: polygonArray[i],
strokeWeight: 0,
fillColor: '#FF0000',
fillOpacity: 0.6,
indexID: i
});
p.setMap(map);
//Add the click listener
google.maps.event.addListener(p, 'click', function (event) {
//alert the index of the polygon
alert(p.indexID);
});
}
Problem
The polygons are all drawing correctly. However the problem is that when I try to click on a polygon it always shows the last index. it is like it is only clicking on the last polygon added. I think when I add a new listener it overrides the old one. How can I add a listener for each polygon added in order to alert the correct index?
Thanks
It's the normal behavior.
There is two solutions that I can think of :
1) I am sure you can find back the polygon from the context (I didn't test it):
google.maps.event.addListener(polygon, 'click', function (event) {
alert(this.indexID);
});
2) You could also use some closures:
var addListenersOnPolygon = function(polygon) {
google.maps.event.addListener(polygon, 'click', function (event) {
alert(polygon.indexID);
});
}
map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions);
//Loop on the polygonArray
for (var i = 0; i < polygonArray.length; i++) {
//Add the polygon
var p = new google.maps.Polygon({
paths: polygonArray[i],
strokeWeight: 0,
fillColor: '#FF0000',
fillOpacity: 0.6,
indexID: i
});
p.setMap(map);
addListenersOnPolygon(p);
}
Move the code block inside the for-loop.
//Add the click listener
google.maps.event.addListener(p, 'click', function (event) {
//alert the index of the polygon
alert(p.indexID);
});
OR
You add this to for-loop,
p.addListener('click', clickSelection);
and do this
function clickSelection(){
alert("Clicked");
}

Categories

Resources