Question

I'm currently developing my first OSM project and tried to start with standard examples from the OpenLayers Examples lib, I managed to place 3 Markers on the Map and display other Layers aswell (Google Streetmap, Mapnik)

But if I go ahead and change the layer (from WSM to Mapnik for example) my Markers get reset onto spot 0,0. I don't change the projection afaik.

Is there something I'm missing?

<script defer="defer" type="text/javascript">
    var map, layer;

    function init(){
        OpenLayers.ProxyHost="/proxy/?url=";
        map = new OpenLayers.Map('map');
        layer = new OpenLayers.Layer.WMS( "OpenLayers WMS", 
            "http://vmap0.tiles.osgeo.org/wms/vmap0", {layers: 'basic'} );
        map.addLayer(layer);

        var osm = new OpenLayers.Layer.OSM();            
        var gmap = new OpenLayers.Layer.Google("Google Streets");
        map.addLayers([osm, gmap]);

        map.setCenter(new OpenLayers.LonLat(0, 0), 0);

        var markers = new OpenLayers.Layer.Markers( "Markers" );
        map.addLayer(markers);

        var size = new OpenLayers.Size(21,25);
        var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
        var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png',size,offset);
        var halfIcon = icon.clone();

        markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(10,10),icon));
        markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,45),halfIcon));

        marker = new OpenLayers.Marker(new OpenLayers.LonLat(90,10),icon.clone());
        marker.setOpacity(0.9);
        marker.events.register('mousedown', marker, function(evt) { alert(this.icon.url); OpenLayers.Event.stop(evt); });
        markers.addMarker(marker); 
        map.addControl(new OpenLayers.Control.LayerSwitcher());
        map.zoomToMaxExtent();

        halfIcon.setOpacity(0.5);
    }
</script>
Was it helpful?

Solution

This issue is related to Projection used by base layers. WMS layer is using projection of EPSG:4326. This projection consider earth as ellipsoid and contains bound in degree of -180.0000, -90.0000, 180.0000, 90.0000

While OSM and other well known maps like Google Maps, Bing Maps uses EPSG:900913 (Officially known as EPSG:3857). This is mercator projection which consider earth as sphere instead of ellipsoid and contains bounds in meter from -20037508.34 to 20037508.34.

So when you change your layer from WMS to OSM; projection changes to EPSG:900913 and in EPSG:900913, difference between points added by you is so negligible ( as they are considered as meters instead of degrees) they are projected near 0,0. (Go for full zoom to look at difference between points.)

According to me, to resolve this issue you have to transform your points through OpenLayers.LonLat.transform method when base layer is changed. You can associate "changebaselayer" event to raise event when your base layer is changed.

For more clarity I have modified jsfiddle provided by Andreas with following changes

  1. Added label displaying projection of WMS and OSM layer. (for reference only)
  2. Associated changebaselayer method with map object

    map = new OpenLayers.Map('map', {
        eventListeners: {
            "changebaselayer": mapBaseLayerChanged
        }
    });
    
  3. Added method "" in which you can write logic to change projection of marksers by calling transform method.

    function mapBaseLayerChanged(event) {
        var currentLayer = event.layer;
        alert(currentLayer.name);
        // Write code to transform each markers.
    }
    

Hope this answer helps you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top