OpenLayers3 : more than one overlay at a time?
Asked Answered
P

2

6

I'm using OpenLayers3 to integrate a map into a website. I added some features representing objects according to their position. I added an overlay containing data on that object when it is clicked on, and it is working perfectly. But, there is something I don't know how to do, and I've tried but it is not working :

Foreach object on the map, I want a kind of label displaying its name next to it - because it is impossible to distinguish them, except if the overlay is displayed. But clicking on every object is not convenient, specially on a smartphone... (sometimes, objects are very very close to each other).

I tried displaying an overlay for that. But it seems that only one overlay can be shown at a time. Do you know how to circumvent/avoid that to display more than one overlay ? Or do you have a fallback solution if it cannot be done ? I've looked at the API and the examples on OpenLayers3 website... but I haven't found something. I'm running out of ideas.

Thanks a lot.

Post scriptum : Before I'm asked for some code, I cannot post any part of code because it is for a project where I'm working, so obviously, my code is confidential. Sorry, thank you for your comprehension. But I can work on any example or idea to make it fit my code and see if it is working or not.

Phlebosclerosis answered 20/11, 2015 at 10:15 Comment(6)
By overlay you mean ol.Overlay?Clergyman
Why not showing each Icon on the map with a label, which can be set by ol.style? If so, i will post a code example for you.Maxie
@JonatasWalker : Yes, I meant ol.Overlay.Phlebosclerosis
@DominikTamm : I'd like to see your code example, if you don't mind. Thank you :)Phlebosclerosis
@LucDrt, take a look at this example: openlayers.org/en/v3.11.2/examples/vector-labels.htmlHydrophone
It's exactly what I want to do ! Thank you so much for this example. I'm going to work on it. I let you know if it works (I think it's gonna work)Phlebosclerosis
C
1

Take a look at this fiddle. I'm using this tiny css (https://github.com/chinchang/hint.css) helper. The overlays are created with this function:

function createOverlay(txt, coord) {
    var div = document.createElement('div');
    div.className = 'marker hint-address hint--always hint--left';
    div.setAttribute('data-hint', txt);

    var overlay = new ol.Overlay({
        element: div,
        offset: [-20, -40],
        position: coord,
        positioning: 'center-center'
    });
    map.addOverlay(overlay);
}
Clergyman answered 20/11, 2015 at 13:8 Comment(1)
This technique works well, I wanted to insert an HTML table so just replaced div.setAttribute with div.innerHTML = txtCoordinate
G
0

According to The Book of OpenLayers3, "An overlay allows [you] to place any kind of HTML element in map at some location."

I think you are looking for a vector layer instead. You can create a new vector layer for labels, whose source is populated with labels generated from data on the features layer. The labels layer can be styled by a style function. Adding features to the feature layer source triggers adding labels to the label layer source. The style function grabs text from a feature property and displays it. Here is how I made a label layer with labeled circles for the ends of LineStrings:

var features = new ol.Collection();
var featureSource = new ol.source.Vector({features:features});
var labels = new ol.Collection();
var labelSource = new ol.source.Vector({features:labels});

function labelStyleFunction(feature, resolution) {
  labelStyle = new ol.style.Style({
    fill: fill,
    stroke: stroke,
    image: new ol.style.Circle({
      radius: 10,
      fill: new ol.style.Fill({
      color: 'rgba(255, 255, 150, 1)'
    }),
    stroke: new ol.style.Stroke({
      color: 'rgba(255, 204, 0, 0.2)',
      width: 1
    })
  }),
  text: new ol.style.Text({
    textAlign: "Start",
    textBaseline: "Middle",
    font: 'Normal 12px Arial',
    text: feature.get("number").toString(),
    fill: fill,
    stroke: lightStroke,
    offsetX: -3,
    offsetY: 5,
    rotation: 0
    })
  })
  return[labelStyle];  // the style function returns an array
}

var featureLayer = new ol.layer.Vector({
    title: "features",  
    source: featureSource,
    style: featureStyle
});

var labelLayer = new ol.layer.Vector({
    title: "feature labels",  
    source: labelSource,
    style:  labelStyleFunction
});       

featureSource.on('addfeature', function() {
     makeLabeledCircles();
});

// make labels from data in features
function makeLabeledCircles() {
  myFeatures = featureSource.getFeatures();
  labelSource.clear();
  for (var i = 0; i < myFeatures.length; i++) {
    var geometry = myFeatures[i].getGeometry();
    coords = geometry.flatCoordinates;
    len = coords.length;
    pointCoords = [coords[len-2], coords[len-1]];
    pointFeature = new ol.Feature({
      geometry: new ol.geom.Point(pointCoords)
    });
    pointFeature.set("number", features[i].get("number"));
    labelSource.addFeature(pointFeature);
  }
}
Gally answered 28/11, 2015 at 19:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.