[GIS] Marker appears in different position when zooming

openlayers

I am using OpenLayers 4 and following the example http://openlayers.org/en/latest/examples/icon.html didn't work when I implemented. I need to place several maps from latitude and longitude coordinates.

For the moment I will leave as no zooming map, but I wish to know how to keep the mark in the same lat, lon position when zooming?

Position lost when zooming OpenLayers 4

My code:

        lat =  40.416775;
        lon = -3.703790;


        var iconFeature = new ol.Feature({
            geometry: new ol.geom.Point(ol.proj.fromLonLat([lon, lat]))
        });
        var iconStyle = new ol.style.Style({
            image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
              anchor: [0.5, 46],
              anchorXUnits: 'fraction',
              anchorYUnits: 'pixels',
              src: '/plugins/obs/gfx/marker.png'
            }))
        });
        iconFeature.setStyle(iconStyle);
        var vectorSource = new ol.source.Vector({
            features: [iconFeature]
        });
        var vectorLayer = new ol.layer.Vector({
            source: vectorSource
        });

        var map = new ol.Map({
            target: mapid,
            layers: [
              new ol.layer.Tile({
                source: new ol.source.OSM()
              }),
              vectorLayer
            ],
            view: new ol.View({
              center: ol.proj.fromLonLat([lon, lat]),
              zoom: 12,
            }),
            controls: ol.control.defaults({
               attributionOptions: {
                 collapsible: false
               }
            })
          });

Best Answer

When the marker icon is moving through the map while zooming, it is caused by a bad anchor with respect to the dimensions/shape of the image of the marker.

So you have to define a proper anchor in your ol.style.Icon object, by playing with the anchor property, or better, by understanding how it works. For instance, for a "map pointer marker" like in the OL example, you have to set the following:

          anchor: [0.5, img_height],
          anchorXUnits: 'fraction',
          anchorYUnits: 'pixels',

where img_height is the height in pixels of your image. The rationale is to set the X anchor in the middle (0.5, with unit as fraction); and for Y positioning, we take the height of the image since it should be anchored at the "arrow" of the pointer, which is a the bottom.

For a simple circle that should be exactly anchored at the center of the image, the parameters should be:

          anchor: [0.5, 0.5],
          anchorXUnits: 'fraction',
          anchorYUnits: 'fraction',

which are actually the default values ;-).

The relevant API doc is here.

Related Question