Openlayers 3 feature label position relative to size of feature?
Asked Answered
C

2

7

I have several layers on an OL map which contain outlines, background colours and labels for the same sized features, so you can show or hide one or more of the layers. Two of these layers are just labels... the style contains no fill or stroke. One label should sit above the other in the center center of the feature but OL seems to spread them vertically further away or closer together relative to the height of the feature polygon, like this:

enter image description here

I have tried setting an offsetY: 15 in the text style block of the lower label, adding a line break before the lower label and setting textBaseline:'top' on the lower label and textBaseline:'bottom' on the top (that was a last ditch attempt!) but they are always spread differently!

Here's my style block for the upper label:

    function fields_label_style() {
        return [
            new ol.style.Style({
                    fill: new ol.style.Fill({
                        color: 'rgba(255,255,255,0)'
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'rgba(255,255,255,0)',
                        width: 1
                    }),
                    text: new ol.style.Text({
                        font: '13px Calibri,sans-serif',
                        fill: new ol.style.Fill({ color: '#ffffff' }),
                        stroke: new ol.style.Stroke({
                            color: '#000000', width: 2
                        }),
                        // get the text from the feature - `this` is ol.Feature
                        // and show only under certain resolution
                        text: map.getView().getZoom() > 14 ? this.get('description') : ''
                    })
                })
        ];
    }

And for the lower label:

    function cropping_label_style() {
        return [
            new ol.style.Style({
                    fill: new ol.style.Fill({
                        color: 'rgba(255,255,255,0)'
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'rgba(255,255,255,0)',
                        width: 1
                    }),
                    text: new ol.style.Text({
                        font: '13px Calibri,sans-serif',
                        fill: new ol.style.Fill({ color: '#ffffff' }),
                        stroke: new ol.style.Stroke({
                            color: '#000000', width: 2
                        }),
                        // get the text from the feature - `this` is ol.Feature
                        // and show only under certain resolution
                        text: map.getView().getZoom() > 14 ? this.get('description') : '',
                        offsetY: 15
                    })
                })
        ];
    }

Both definitely have the same polygon outline. No question. I can only think that perhaps OpenLayers is treating the offset as a percentage rather than the pixels as is stated in the documentation:

enter image description here

Compromise answered 14/9, 2016 at 20:23 Comment(1)
Seems like it is in pixels from what I can tell: tinyurl.com/hxpj6hn shows an example that works with pixels. Try returning an array of styles with one text style in each array. Same result?Falconer
C
1

Due to some complicated loops in my code I overlooked that there was a slight discrepancy between polygon boundaries on some of the fields, meaning their labels were displayed in slightly different places. Now I have made all the polygon boundaries the same the label do indeed line up correctly with the offsetY behaving as expected. My apologies.

Compromise answered 22/9, 2016 at 11:5 Comment(0)
F
0

More of a workaround than an answer because I see nothing wrong with your approach but does this produce the same result?

[
new ol.style.Style({
    fill: new ol.style.Fill({
        color: 'rgba(255,255,255,0)'
    }),
    stroke: new ol.style.Stroke({
        color: 'rgba(255,255,255,0)',
        width: 1
    })
}),

new ol.style.Style({
    text: new ol.style.Text({
        font: '13px Calibri,sans-serif',
        fill: new ol.style.Fill({
            color: '#ffffff'
        }),
        stroke: new ol.style.Stroke({
            color: '#000000',
            width: 2
        }),
        // get the text from the feature - `this` is ol.Feature
        // and show only under certain resolution
        text: map.getView().getZoom() > 14 ? this.get('description') : ''
    })
}),

new ol.style.Style({
    text: new ol.style.Text({
        font: '13px Calibri,sans-serif',
        fill: new ol.style.Fill({
            color: '#ffffff'
        }),
        stroke: new ol.style.Stroke({
            color: '#000000',
            width: 2
        }),
        // get the text from the feature - `this` is ol.Feature
        // and show only under certain resolution
        text: map.getView().getZoom() > 14 ? this.get('description') : '',
        offsetY: 15
    })
})]
Falconer answered 17/9, 2016 at 22:41 Comment(3)
I'm not quite sure how you are suggesting I implement this?Compromise
I was suggesting you put both text styles on a single layer instead of having two layers with identical geometry.Falconer
Ah I see... I can't as I have to be able to toggle their visibility independantly.Compromise

© 2022 - 2024 — McMap. All rights reserved.