39

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.

Michael Schmidt
  • 9,090
  • 13
  • 56
  • 80
vaibhav shah
  • 4,939
  • 19
  • 58
  • 96

8 Answers8

57

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

Patrick D
  • 6,659
  • 3
  • 43
  • 55
33

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);
}
Stackman
  • 439
  • 4
  • 6
14

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

Michel
  • 26,600
  • 6
  • 64
  • 69
  • Could data be slightly more specific by making it `Record` vs `any`. It's likely to be key value pairs? – Greg K Oct 23 '20 at 10:30
  • Certainly. `DataMarker` is a custom object extending `L.Marker`. As such, the `data` property in it can be as specific as someone needs. – Michel Oct 23 '20 at 17:15
  • 1
    Not necessarily key-value pairs, it could be primitive values, or anything really. – Michel Oct 23 '20 at 17:17
8

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
}
Andi AR
  • 2,678
  • 2
  • 23
  • 28
  • 2
    OMG this is what I needed!! Big thanks, I was trying to pass the parameter with binding, but this worked perfectly. – Marius B Mar 16 '18 at 09:38
4

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);
geegee
  • 41
  • 2
  • This works in my regular browsers, but on Android chrome and firefox, nothing comes up. onMarkerClick takes in e, but what is e ? – Kalnode Mar 02 '18 at 18:54
  • Ok, this works: function onEachFeature(feature, layer) { layer.on('click', function (e) { onMarkerClick(e); }); } – Kalnode Mar 02 '18 at 19:03
2

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);
Dreamer64
  • 923
  • 2
  • 13
  • 30
1

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.

Nikhil VJ
  • 5,630
  • 7
  • 34
  • 55
0

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;
}
gisman
  • 41
  • 4