how to add markers with OpenLayers 3
Asked Answered
B

4

67

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 but is it 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

Balata answered 19/6, 2014 at 20:35 Comment(2)
For performance avoid adding features one by one, use bulk add vectorSource.addFeatures(features);Insipid
the link to the example youve found is dead.Radon
S
87

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.

Siana answered 19/6, 2014 at 21:59 Comment(15)
Thank you! This is exactly what I need. I couldn't figure it out with the documentation.Balata
You are welcome. The documentation is a bit sparse still, but to be fair, they are still working on the code :DSiana
Thanks for catching that typo -- one of many reasons to use jsfiddle.Siana
No problem. Unfortunately, I have a Uncaught TypeError: undefined is not a function exception in the ol.js line 50 when I use an array of features.Balata
Is that in the compressed ol.js? I have looked at the source code and it looks fine. I had better try and get to the bottom of this.Siana
I managed to load the uncompressed js and the exception is in event.js at the line 283. src is not definedBalata
I have put a jsfiddle in the answer which does work, by using a loop to load the icons. jsfiddle.net/6RS2z/1 I hope this works for you. I'm still not sure why adding the array directly doesn't work, but don't have time to debug today. You could add icons with different styles after the map has loaded using addFeature too, as you originally asked.Siana
Thank you for taking the time to make a jsfiddle. It works like a charm. I don't know why the previous solution doesn't work. The API documentation says that features takes an Array.<ol.Feature>. I will have to take a look to make sure that I understand.Balata
I am also bemused, but I am still learning OL3, and the Google closure stuff takes some getting used to. I am glad you have a working solution, at least.Siana
The jsfiddle doesnt produce a resultEyestrain
@PhilipRego. What result are you expecting? I have just tried it, to see if the underlying OL lib had changed, as happened a few times in beta, and I still see a bunch of random markers.Siana
I didn't see anything. I didn't know I needed an account to be able to see the result.Eyestrain
same here, blank page with Uncaught TypeError: undefined is not a functionUpland
The fiddle by @JohnBarça (ty for the fiddle) didnt work anymore because the urls to the openlayer library en icon don't exist anymore. Here is an updated version jsfiddle.net/6RS2z/352Kletter
@Alexander. Thanks for pointing that out. I have updated the original fiddle.Siana
M
14

there's a good tutorial at: http://openlayersbook.github.io

not tested but may helpful

var features = [];

//iterate through array...
for( var i = 0 ; i < data.length ; i++){
    var item = data[i];                                     //get item
    var type = item.type;                                   //get type
    var longitude = item.longitude;                         //coordinates
    var latitude = item.latitude;
    /*....
    * now get your specific icon...('..../ic_customMarker.png')
    * by e.g. switch case...
    */
    var iconPath = getIconPath(type);

    //create Feature... with coordinates
    var iconFeature = new ol.Feature({
        geometry: new ol.geom.Point(ol.proj.transform([longitude, latitude], 'EPSG:4326',     
        'EPSG:3857'))
    });

    //create style for your feature...
    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: iconPath
        }))
    });

    iconFeature.setStyle(iconStyle);
    features.push(iconFeature);
    //next item...
}

/*
* create vector source
* you could set the style for all features in your vectoreSource as well
*/
var vectorSource = new ol.source.Vector({
    features: features      //add an array of features
    //,style: iconStyle     //to set the style for all your features...
});

var vectorLayer = new ol.layer.Vector({
    source: vectorSource
});
map.addLayer(vectorLayer);
Mccallum answered 26/4, 2016 at 10:59 Comment(1)
Thanks!!! map.addLayer() was what i was missing! i was trying to just push the layer into map.layers, that doesn't work.Labarbera
E
1
var exampleLoc = ol.proj.transform(
    [131.044922, -25.363882], 'EPSG:4326', 'EPSG:3857');

var map = new ol.Map({
  target: 'map',
  renderer: 'canvas',
  view: new ol.View2D({
    projection: 'EPSG:3857',
    zoom: 3,
    center: exampleLoc
  }),
  layers: [
    new ol.layer.Tile({source: new ol.source.MapQuest({layer: 'osm'})})
  ]
});

map.addOverlay(new ol.Overlay({
  position: exampleLoc,
  element: $('<img src="resources/img/marker-blue.png">')
      .css({marginTop: '-200%', marginLeft: '-50%', cursor: 'pointer'})
      .tooltip({title: 'Hello, world!', trigger: 'click'})
}));

map.on('postcompose', function(evt) {
  evt.vectorContext.setFillStrokeStyle(
      new ol.style.Fill({color: 'rgba(255, 0, 0, .1)'}),
      new ol.style.Stroke({color: 'rgba(255, 0, 0, .8)', width: 3}));
  evt.vectorContext.drawCircleGeometry(
      new ol.geom.Circle(exampleLoc, 400000));
});

var exampleKml = new ol.layer.Vector({
  source: new ol.source.KML({
    projection: 'EPSG:3857',
    url: 'data/example.kml'
  })
});
map.addLayer(exampleKml);
Evolutionary answered 29/10, 2015 at 11:13 Comment(0)
B
0

We just finished updating our website NUFOSMATIC from ol2 to ol6. Both the ol2 and ol3 code is on the site. This includes Matt Walker's ol-layerswitcher https://github.com/walkermatt replacing the missing ol2 layerswitcher. We actually updated three map applications; HEATMAP replaces the Patrick Wied (http://www.patrick-wied.at) ol2 heatmap with the native ol6 heatmap.

Only took 6 days. Wonder why we waited this long... oh, yeah, we have day jobs...

Brierroot answered 10/1, 2021 at 0:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.