Marc Marc - 7 months ago 497
Javascript Question

how to add markers with OpenLayers 3

I'm trying to add makers on a

OpenLayers 3
map.

The only example I have found is this one in the
OpenLayers
example list.

But the example uses ol.Style.Icon instead of something like OpenLayers.Marker in
OpenLayers 2
.

First Question

The only difference would be that you have to set the image Url which is not a big deal but I'm wondering if it's the only way to add a marker?

Also
OpenLayers 3
doesn't seem to come with marker images so it would make sense if there's no other way than
ol.Style.Icon


Second Question

It would be really nice if someone could give me an example of a function to add markers or icons after the map is loaded.

From what I understand in the example, they create a layer for the icon

var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([-72.0704, 46.678], 'EPSG:4326', 'EPSG:3857')),
name: 'Null Island',
population: 4000,
rainfall: 500
});


var iconStyle = new ol.style.Style({
image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: 'data/icon.png'
}))
});

iconFeature.setStyle(iconStyle);

var vectorSource = new ol.source.Vector({
features: [iconFeature]
});

var vectorLayer = new ol.layer.Vector({
source: vectorSource
});


Then they set the icon layer when they initialize the map

var map = new ol.Map({
layers: [new ol.layer.Tile({ source: new ol.source.OSM() }), vectorLayer],
target: document.getElementById('map'),
view: new ol.View2D({
center: [0, 0],
zoom: 3
})
});


If I want to add many markers, do I have to create 1 layer for each marker?

How could I add many markers to a layer? I can't figure out how this part would look
like

var vectorSource = new ol.source.Vector({
features: [iconFeature]
});

var vectorLayer = new ol.layer.Vector({
source: vectorSource
});


Thank you

Answer

Q1. Markers are considered deprecated in OpenLayers 2, though this isn't very obvious from the documentation. Instead, you should use an OpenLayers.Feature.Vector with an externalGraphic set to some image source in its style. This notion has been carried over to OpenLayers 3, so there is no marker class and it is done as in the example you cited.

Q2. The ol.source.Vector takes an array of features, note the line, features: [iconFeature], so you would create an array of icon features and add features to that, eg:

var iconFeatures=[];

var iconFeature = new ol.Feature({
  geometry: new ol.geom.Point(ol.proj.transform([-72.0704, 46.678], 'EPSG:4326',     
  'EPSG:3857')),
  name: 'Null Island',
  population: 4000,
  rainfall: 500
});

var iconFeature1 = new ol.Feature({
  geometry: new ol.geom.Point(ol.proj.transform([-73.1234, 45.678], 'EPSG:4326',     
  'EPSG:3857')),
  name: 'Null Island Two',
  population: 4001,
  rainfall: 501
});

iconFeatures.push(iconFeature);
iconFeatures.push(iconFeature1);

var vectorSource = new ol.source.Vector({
  features: iconFeatures //add an array of features
});

var iconStyle = new ol.style.Style({
  image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
    anchor: [0.5, 46],
    anchorXUnits: 'fraction',
    anchorYUnits: 'pixels',
    opacity: 0.75,
    src: 'data/icon.png'
  }))
});


var vectorLayer = new ol.layer.Vector({
  source: vectorSource,
  style: iconStyle
});

Obviously, this could be more elegantly handled by putting all of the ol.Feature creation inside a loop based on some data source, but I hope this demonstrates the approach. Note, also, that you can apply a style to the ol.layer.Vector so that it will be applied to all features being added to the layer, rather than having to set the style on individual features, assuming you want them to be the same, obviously.

EDIT: That answer doesn't seem to work. Here is an updated fiddle that works by adding the features (icons) to the empty vector source in a loop, using vectorSource.addFeature and then adds the whole lot to the layer vector afterwards. I will wait and see if this works for you, before updating my original answer.