Unterschied zwischen OpenLayers.Layer.OSM und OpenLayers.Layer.XYZ

Hi,

ich habe hier ein Problem mit dem Positionieren von Markern (POIs) in einem XYZ-Layer, die im OSM-Layer an der richtigen Stelle angezeigt werden.

Ich habe hier beide Varianten:


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
    <link rel="stylesheet" href="style.css" type="text/css" />

    <script src="../lib/OpenLayers.js"></script>
    <script type="text/javascript">
        var map = null;

        function init() {
            var geographic = new OpenLayers.Projection("EPSG:4326");

            map = new OpenLayers.Map('map', {
                projection: geographic,
                displayProjection: geographic,
            });

            var layer_tiles = new OpenLayers.Layer.OSM("XYZ-Layer", "http://tile.openstreetmap.org/${z}/${x}/${y}.png");
            map.addLayer(layer_tiles);

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

            // http://maps.google.com/maps?f=q&source=s_q&hl=de&geocode=&q=+-5.615055%C2%B0,+120.457567%C2%B0&sll=37.0625,-95.677068&sspn=34.259599,79.013672&ie=UTF8&ll=-5.614966,120.457417&spn=0.002627,0.004823&t=h&z=18
            var lonlat_center = new OpenLayers.LonLat(120.457567, -5.615055).transform(geographic, map.getProjectionObject());

            var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png');
            layer_markers.addMarker(new OpenLayers.Marker(lonlat_center, icon));

            map.setCenter(lonlat_center, 15);
        }
    </script>
  </head>
  <body onload="init()">
    <div id="map" class="smallmap"></div>
  </body>
</html>

bzw.


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
    <link rel="stylesheet" href="style.css" type="text/css" />

    <script src="../lib/OpenLayers.js"></script>
    <script type="text/javascript">
        var map = null;

        function init() {
            var geographic = new OpenLayers.Projection("EPSG:4326");

            map = new OpenLayers.Map('map', {
                projection: geographic,
                displayProjection: geographic,
                maxExtent: new OpenLayers.Bounds(-180, -180, 180, 180), // !!! Warum?
            });

            var layer_tiles = new OpenLayers.Layer.XYZ("XYZ-Layer", "http://tile.openstreetmap.org/${z}/${x}/${y}.png");
            map.addLayer(layer_tiles);

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

            // http://maps.google.com/maps?f=q&source=s_q&hl=de&geocode=&q=+-5.615055%C2%B0,+120.457567%C2%B0&sll=37.0625,-95.677068&sspn=34.259599,79.013672&ie=UTF8&ll=-5.614966,120.457417&spn=0.002627,0.004823&t=h&z=18
            var lonlat_center = new OpenLayers.LonLat(120.457567, -5.615055).transform(geographic, map.getProjectionObject());

            var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png');
            layer_markers.addMarker(new OpenLayers.Marker(lonlat_center, icon));

            map.setCenter(lonlat_center, 15);
        }
    </script>
  </head>
  <body onload="init()">
    <div id="map" class="smallmap"></div>
  </body>
</html>

Damit die Tiles im XYZ-Layer richtig angezeigt werden, musste ich maxExtent: new OpenLayers.Bounds(-180, -180, 180, 180) als Parameter angeben. Das ist der einzige Unterschied der 2 Dateien neben OSM bzw. XYZ.

Ich habe mir lib\OpenLayers\Layer\XYZ.js angeschaut, kann aber nichts verdächtiges finden.

Hat jemand eine Idee?

Coach

Ich kann es dir leider nicht sagen. Da ich aber auch gerade mit Markern und Popups am wirbeln bin kann ich dir einfach mal die Seite empfehlen, da der Markers Layer veraltet ist und bei mir nur Probleme machte:
http://docs.openlayers.org/library/overlays.html

Der Layer hat ja auch eine eigene Projektion und maxextend, maxscale… Wenn Du einen Layer.XYZ anlegst, hat der keine defaultprojektion, sondern nimmt die aus der Karte. Layer.OSM dagegen hat den besonderen Fall, dass er Mercator als Projektion und die ganze Welt als maxextend hat.

Im Quellcode findest Du die Defaultwerte für Layer.OSM um die Zeile 85 rum (“sphericalMercator: true”) und das dazugehörige Setzen des maxextend ab der Zeile 56 (“if (… this.sphericalMercator)”).

Grüße,
Max

der sich eigentlich eher wundert, warum im zweiten Beispiel der Marker trotzdem an der passenden Stelle sitzt. Meiner Meinung nach arbeitest Du da auf Mercator-Kacheln, mogelst dem OL aber vor, das sei EPSG:4326… Das merkt niemand, bis einer einen Marker setzt.
Vielleicht liegts auch daran, dass Du als Grenze 90° nördlich vom Nordpol angibst (-180,-90,180,90 wäre ja korrekt für EPSG4326)… Aber wenns passt… :wink:

Edit: Schau mal genau, vermutlich passts nicht… Ich denke, Dein Marker mit XYZ sollte in N-S-Richtung verschoben sein, allerdings nur ein bisschen, weil Du Glücklicher so nah am Äquator sitzt. Der Fehler sollte in höheren Breiten deutlicher sein.

Hi,

@!i!: Ich hatte ursprünglich das Problem bei OpenLayers.Layer.Vector und nur für das Forum die Markers benutzt.

@maxbe: Danke. Ich hatte das mit dem sphericalMercator auch im Quellcode entdeckt, aber dann natürlich bei der Map anstatt dem Layer gesetzt. Darum hat’s natürlich nicht geklappt. Jetzt funktionierts. Super. Nochmals danke.

Coach