Rendering text from geojson

10,313 views
Skip to first unread message

Tom Chance

unread,
May 19, 2012, 4:30:41 AM5/19/12
to Leaflet
Hello there,

Could anyone suggest a trick to render labels for polygons in a
geojson file?

I have a geojson file will polygons, each of which carries a 'name'
attribute. I would like to render these in the centre of each polygon,
or as a fallback have them appear as a tooltip when the mouse waves
over them. I don't want to use popups as I have a second geojson file
overlayed that triggers popups.

Leaflet doesn't seem to support this, but maybe somebody with better
javascript skills could suggest a way to do this?

Tom

FunkMonkey33

unread,
May 21, 2012, 8:21:39 PM5/21/12
to Leaflet
Without editing the Leaflet source code, your only option really is to
use popups. What I would do is define a popup that looks different
than your other layer's popup. You can then attach it to the mouse
hover-type events.

If you were going to edit the source code, you could perhaps extend
the Polygon class to create, say, a LabeledPolygon, and define the
text using an SVG text object. Still working on extending Leaflet
classes, so I'm of no help here, but I know it's do-able.

Aaron

Tom Chance

unread,
May 22, 2012, 5:00:45 AM5/22/12
to Leaflet
Thanks, I'll try to find an opportunity to look into extending the
class. Does anyone have any examples I could study to see how to do it
properly?

Tom

Adrian Jones

unread,
May 22, 2012, 2:18:13 PM5/22/12
to leafl...@googlegroups.com
No need to edit leaflet source. Just extend using this:

L.LabelOverlay = L.Class.extend({
        initialize: function(/*LatLng*/ latLng, /*String*/ label, options) {
            this._latlng = latLng;
            this._label = label;
            L.Util.setOptions(this, options);
    },
    options: {
            offset: new L.Point(0, 2)
    },
    onAdd: function(map) {
            this._map = map;
            if (!this._container) {
                    this._initLayout();
            }
            map.getPanes().overlayPane.appendChild(this._container);
            this._container.innerHTML = this._label;
            map.on('viewreset', this._reset, this);
            this._reset();
    },
    onRemove: function(map) {
            map.getPanes().overlayPane.removeChild(this._container);
            map.off('viewreset', this._reset, this);
    },
    _reset: function() {
            var pos = this._map.latLngToLayerPoint(this._latlng);
            var op = new L.Point(pos.x + this.options.offset.x, pos.y - this.options.offset.y);
            L.DomUtil.setPosition(this._container, op);
    },
    _initLayout: function() {
            this._container = L.DomUtil.create('div', 'leaflet-label-overlay');
    }
});


//Use something like this to display the labels

var labelLocation = new L.LatLng(Lat,Lng);
var labelTitle = new L.LabelOverlay(labelLocation, label);
map.addLayer(labelTitle);

Tom Chance

unread,
May 26, 2012, 5:20:07 AM5/26/12
to Leaflet
Thanks, I gave that a whirl but it seems to break when I initialise
"new L.LabelOverlay". I'm not sure why.

Also, I presume if I use the getbounds() method on the polygon I could
then calculate a center point to place the text?

Tom

Mathias Lin

unread,
Jul 30, 2013, 7:27:47 AM7/30/13
to leafl...@googlegroups.com, adrian...@gmail.com
Hi Adrian,

thanks for the code sample.

It works almost fine, but seems to have a bug when placing multiple labels.

var labelLocation = new L.LatLng(Lat,Lng);
var labelTitle = new L.LabelOverlay(labelLocation, 'labelX');
map.addLayer(labelTitle);

var labelLocation2 = new L.LatLng(Lat,Lng);
var labelTitle2 = new L.LabelOverlay(labelLocation2, 'labelY');
map.addLayer(labelTitle2);



labelTitle2 has a different (wrong) location (off a bit from the lat/lng I pass as parameter) if placed on the map after labelTitle.
And then strangely, labelTitle2 has a different (=it's correct) position when I comment out the first labelTitle code, so it seems that there is some relationship between the labels, regarding their positions.

Mathias Lin

unread,
Jul 30, 2013, 7:43:28 AM7/30/13
to leafl...@googlegroups.com, adrian...@gmail.com
Hi Adrian,

to clarify once more: duplicating the same code (with the same lat/lng) places the marker at different positions:


    var labelLocation = new L.LatLng(51.329219337279405, 10.454119349999928);
    var labelTitle = new L.LabelOverlay(labelLocation, 'GERMANY');
    map.addLayer(labelTitle);

    var labelLocation = new L.LatLng(51.329219337279405, 10.454119349999928);
    var labelTitle = new L.LabelOverlay(labelLocation, 'GERMANY');
    map.addLayer(labelTitle);


Mathias Lin

unread,
Jul 30, 2013, 9:31:17 AM7/30/13
to leafl...@googlegroups.com, adrian...@gmail.com
I found a solution to the problem, it seems that it was somehow related to the line-height (default leaflet style).

Applying the following style positions multiple labels correctly:

    .leaflet-label-overlay {
        line-height:0px;
        margin-top: 9px;
        position: absolute;

jhpoo...@gmail.com

unread,
Jul 28, 2015, 2:36:52 PM7/28/15
to Leaflet, adrian...@gmail.com, mathias...@gmail.com
Dear all,

I saw the complete code on http://stackoverflow.com/a/17964638/1257804, thanks!

I was wondering, how can I change the text style (font-size, font) and for example catch a click event?

Thanks in advance, Jelmer
Reply all
Reply to author
Forward
0 new messages