OpenLayers: OSM als Basemap und Layer von Geoserver darüber -aber wie?

Hallo liebe Community!

Ich bin OpenLayers Neuling und habe ein kleines Problem:

Ich würde gerne die OSM als Hintergrundkarte nehmen und darüber einen Layer vom Geoserver geben.
Leider klappt das nicht wirklich. Das Map-Fenster bleibt weiß.

Was muss ich denn am Code ändern?

Vielen Dank für eure Hilfe!
LG,
Alex


var tiled
      function init() {
      var basemap = new OpenLayers.Map("map");
      
        var mapnik         = new OpenLayers.Layer.OSM();
        var fromProjection = new OpenLayers.Projection("EPSG:4326");   // Transform from WGS 1984
        var toProjection   = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
        var position       = new OpenLayers.LonLat(16.084787,47.724691).transform( fromProjection, toProjection);
        var zoom           = 14;
        
  
           tiled = new OpenLayers.Layer.WMS(
                    "GISnk:nkPOIs1 - Tiled", "http://localhost:8080/geoserver/GISnk/wms",
                    {
                        LAYERS: 'GISnk:nkPOIs1',
                        STYLES: '',
                        format: format,
                        tiled: true,
                        tilesOrigin : map.maxExtent.left + ',' + map.maxExtent.bottom
                    },
                    {
                        buffer: 0,
                        displayOutsideMaxExtent: true,
                        isBaseLayer: false,
                        yx : {'EPSG:900913' : false}
                    } 
                );
 

        basemap.addLayer(mapnik, tiled);
        basemap.setCenter(position, zoom );
      }




Funktioniert denn Deine OSM-Hintergrundkarte alleine? Dein Codeschnipsel hat in der ersten Zeile ein “var tiled” - kein Semikolon am Zeilenende, keine Wertzuweisung dahinter? Die Funktion “init” wird auch aufgerufen (z.B. via ‘’)? Dein “Map-Fenster” hat auch die ID “map”, sowie eine Höhen- und Breitenangabe (also nicht 0x0 Pixel)?

Danke für die rasche Antwort!

Ja, nur die OSM alleine funktioniert:

      function init() {
      var basemap = new OpenLayers.Map("map");
      
        var mapnik         = new OpenLayers.Layer.OSM();
        var fromProjection = new OpenLayers.Projection("EPSG:4326");   // Transform from WGS 1984
        var toProjection   = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
        var position       = new OpenLayers.LonLat(16.084787,47.724691).transform( fromProjection, toProjection);
        var zoom           = 14;
        
  
        


        basemap.addLayer(mapnik);
        basemap.setCenter(position, zoom );
      }


und die init Funktion wird im HTML Bereich auch aufgerufen:

    <link rel="stylesheet" href="style.css" type="text/css">

    <style type="text/css">
      html, body, #map {
          width: 100%;
          height: 100%;
          margin: 0;
      }

            #text {
                position: absolute;
                top: 1em;
                right: 1em;
                width: auto;
                z-index: 20000;
                background-color: white;
                padding: 0 0.5em 0.5em 0.5em;
            }
            
             #logo {
                float:right;
           
            }
    </style>
    <script src="http://openlayers.org/api/OpenLayers.js"></script>

  </head>
  <body onload="init();">
    <div id="map"></div>

Der aktualisierte JS Code:



      function init() {
      var basemap = new OpenLayers.Map("map");
      
        var mapnik         = new OpenLayers.Layer.OSM();
        var fromProjection = new OpenLayers.Projection("EPSG:4326");   // Transform from WGS 1984
        var toProjection   = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
        var position       = new OpenLayers.LonLat(16.084787,47.724691).transform( fromProjection, toProjection);
        var zoom           = 14;
        
  
        
 var tiled = new OpenLayers.Layer.WMS(
                    "GISnk:nkPOIs1 - Tiled", "http://localhost:8080/geoserver/GISnk/wms",
                    {
                        LAYERS: 'GISnk:nkPOIs1',
                        STYLES: '',
                        format: format,
                        tiled: true,
                        tilesOrigin : map.maxExtent.left + ',' + map.maxExtent.bottom
                    },
                    {
                        buffer: 0,
                        displayOutsideMaxExtent: true,
                        isBaseLayer: false,
                        yx : {'EPSG:900913' : false}
                    } 
                );


        basemap.addLayer(mapnik, tiled);
        basemap.setCenter(position, zoom );
      }




Ich kenne mich mit Geoserver nicht aus, aber meine Zugriffe auf wms scheitern oft daran, dass der wms-Server kein EPSG 900913 kann.

Ich würde einfach mal den Debugger des Browsers aufmachen, sehen, welche URL die Bilder haben, die vom WMS abgeholt werden und schauen, ob der eine Fehlermeldung ausgibt, wenn man nur diese URL in den Browser eingibt.

Die Variable “format” kommt mir auch komisch vor. Da gehört das Bildformat, also sowas wie “image/png” oder “svg” rein und ich sehe nicht, wo du das definiert hast, aber ich habe natürlich auch nur Stücke der Seite.

Grüße, Max

Der Zugriff auf den WMS funktioniert mit QGIS gut.
Auch wenn ich nur den WMS Layer alleine im OL lade funktioniert es. Leider schaffe ich es nicht OSM als Hintergrundkarte hinzuzufügen.

Hier der gesamte Code:

<html>
  <head>
    <title>Geoportal</title>
    <link rel="stylesheet" href="style.css" type="text/css">

    <style type="text/css">
      html, body, #map {
          width: 100%;
          height: 100%;
          margin: 0;
      }

            #text {
                position: absolute;
                top: 1em;
                right: 1em;
                width: auto;
                z-index: 20000;
                background-color: white;
                padding: 0 0.5em 0.5em 0.5em;
            }
            
             #logo {
                float:right;
           
            }
    </style>
    
  <script src="http://localhost:8080/geoserver/openlayers/OpenLayers.js" type="text/javascript">
        </script>
        <script defer="defer" type="text/javascript">
            var map;
            var untiled;
            var tiled;
            var pureCoverage = false;
            // pink tile avoidance
            OpenLayers.IMAGE_RELOAD_ATTEMPTS = 5;
            // make OL compute scale according to WMS spec
            OpenLayers.DOTS_PER_INCH = 25.4 / 0.28;
        
            function init(){
                // if this is just a coverage or a group of them, disable a few items,
                // and default to jpeg format
                format = 'image/png';
            
                var bounds = new OpenLayers.Bounds(
                    601109.4892999977, 422893.79740000144,
                    610631.181400001, 432588.51139999926
                );
                var options = {
                    controls: [],
                    maxExtent: bounds,
                    maxResolution: 37.8699765624915,
                    projection: "EPSG:900913",
                    units: 'm'
                };
                map = new OpenLayers.Map('map', options);
            
                // setup tiled layer
                tiled = new OpenLayers.Layer.WMS(
                    "GISnk:nkPOIs1 - Tiled", "http://localhost:8080/geoserver/GISnk/wms",
                    {
                        LAYERS: 'GISnk:nkPOIs1',
                        STYLES: '',
                        format: format,
                        tiled: true,
                        tilesOrigin : map.maxExtent.left + ',' + map.maxExtent.bottom
                    },
                    {
                        buffer: 0,
                        displayOutsideMaxExtent: true,
                        isBaseLayer: true,
                        yx : {'EPSG:900913' : true}
                    } 
                );
            
        
                map.addLayers([tiled]);

                // build up all controls
                map.addControl(new OpenLayers.Control.PanZoomBar({
                    position: new OpenLayers.Pixel(2, 15)
                }));
                map.addControl(new OpenLayers.Control.Navigation());
                map.addControl(new OpenLayers.Control.Scale($('scale')));
                map.addControl(new OpenLayers.Control.MousePosition({element: $('location')}));
                map.zoomToExtent(bounds);
                
               
                
                // support GetFeatureInfo
                map.events.register('click', map, function (e) {
                    document.getElementById('nodelist').innerHTML = "Loading... please wait...";
                    var params = {
                        REQUEST: "GetFeatureInfo",
                        EXCEPTIONS: "application/vnd.ogc.se_xml",
                        BBOX: map.getExtent().toBBOX(),
                        SERVICE: "WMS",
                        INFO_FORMAT: 'text/html',
                        QUERY_LAYERS: map.layers[0].params.LAYERS,
                        FEATURE_COUNT: 50,
                        Layers: 'GISnk:nkPOIs1',
                        WIDTH: map.size.w,
                        HEIGHT: map.size.h,
                        format: format,
                        styles: map.layers[0].params.STYLES,
                        srs: map.layers[0].params.SRS};
                    
                    // handle the wms 1.3 vs wms 1.1 madness
                    if(map.layers[0].params.VERSION == "1.3.0") {
                        params.version = "1.3.0";
                        params.j = parseInt(e.xy.x);
                        params.i = parseInt(e.xy.y);
                    } else {
                        params.version = "1.1.1";
                        params.x = parseInt(e.xy.x);
                        params.y = parseInt(e.xy.y);
                    }
                        
                 
                });
            }
            
          
        </script>

  </head>
  <body onload="init();">
    <div id="map"></div>
      <div id="text">
        
        <div id="logo">
            
            <img src="nklogokl.png" alt="Logo">
            
        </div>
              <h1 id="title">NK</h1>

              <div id="tags">
                GIS, Geoportal
              </div>

              <p id="shortdesc">
                Test Test TEst 
            </p>

            <div id="docs">
                <p>Test Test </p>
                <p>Test Link
                <a href="www.test.gv.at" target="_blank">www.test.gv.at</a> 
                Test.</p>
            </div>
      </div>
  </body>
</html>

Ich auch nicht. Weil 1. fehlt der Mapnik-Layer und 2. ist kein OpenLayers eingebunden.

Das ganz grosse Problem sehe ich aber in den Koordinaten… 601109, 422893 ist bei Mercatorprojektion 600km rechts vom Nullmeridian und 422km nördlich vom Äquator, irgendwo in Afrika. Ist das wirklich EPSG 900913? Für mich riecht das eher nach österreichischem Bundesmeldenetz… (auch wegen dem Hinweis auf …gv.at).

Vielleicht noch zur Erklärung, warum sowas ohne OSM-Layer gut gehen kann:

OpenLayers ist recht einfach gestrickt, was den Umgang mit WMSen angeht. Wenn man seinem OL sagt, dass man Mercatorprojektion möchte und in dieser Projektion den Ausschnitt (600000,200000,700000,300000) sehen möchte, dann fordert es diesen Ausschnitt beim WMS an.

Wenn man einem WMS keine Projektion sagt (das tust du nicht, weil sonst stünde da ein “projection:” bei deinem Layer “tiled”), dann liefert der in seiner Default-Projektion den Ausschnitt (600000,200000,700000,300000) aus.

OL stellt das dar was kommt und alle sind glücklich. OL meint, es hätte Mercator vor sich und glaubt sich in Afrika, der WMS meint, er hätte BMN ausgeliefert und stellt Österreich dar (mal unterstellt, die Vermutung BMN stimmt). Weil beides rechtwinklige Koordinatensysteme sind, merkt das niemand.

Probleme stellen sich erst ein, wenn man einen zweiten Layer dazunimmt, der was anderes als Default-Projektion hat. Oder wenn man mit OL irgendwelchen Umrechnungen macht. Z.B. einen Marker plaziert, oder einen Maßstab dazu darstellt oder eine GPX/KML-Datei drüberlegt…

Was sagt den QGIS zum Thema Projektion? Das kann sich die ja die SRS vom WMS holen und verrrät vielleicht, welche Projektion verwendet wird…

Ich glaube maxbe du hattest recht. Die Daten waren im BMN, ich hab sie jetzt in EPSG 90013 transformiert (hoffe ich jedenfalls).
(Das obige Beispiel war nur als demo, dass es mit nur einem Layer funktioniert.)

Hier der aktuelle Code:

<!DOCTYPE HTML>
<html>
  <head>
    <title>Geoportal</title>
    <link rel="stylesheet" href="style.css" type="text/css">

    <style type="text/css">
      html, body, #map {
          width: 100%;
          height: 100%;
          margin: 0;
      }

            #text {
                position: absolute;
                top: 1em;
                right: 1em;
                width: auto;
                z-index: 20000;
                background-color: white;
                padding: 0 0.5em 0.5em 0.5em;
            }
            
             #logo {
                float:right;
           
            }
    </style>
    
  <script src="http://www.openlayers.org/api/OpenLayers.js" type="text/javascript">
        </script>
        <script defer="defer" type="text/javascript">
            var map;
            var untiled;
            var tiled;
            var pureCoverage = false;
            // pink tile avoidance
            OpenLayers.IMAGE_RELOAD_ATTEMPTS = 5;
            // make OL compute scale according to WMS spec
            OpenLayers.DOTS_PER_INCH = 25.4 / 0.28;
        
            function init(){
                // if this is just a coverage or a group of them, disable a few items,
                // and default to jpeg format
                format = 'image/png';
            
     var bounds = new OpenLayers.Bounds(
                    1784389.363499999, 6058681.3517,
                    1794735.6761999987, 6066740.533
                );
                var options = {
                    controls: [],
                    maxExtent: bounds,
                    maxResolution: 40.41528398437367,
                    projection: "EPSG:900913",
                    units: 'm'
                };
                
                map = new OpenLayers.Map('map', options);
            
                // setup tiled layer
                 tiled = new OpenLayers.Layer.WMS(
                    "GISnk:nkpoi900913 - Tiled", "http://localhost:8080/geoserver/GISnk/wms",
                    {
                        LAYERS: 'GISnk:nkpoi900913',
                        STYLES: '',
                        format: format,
                        tiled: true,
                        tilesOrigin : map.maxExtent.left + ',' + map.maxExtent.bottom
                    },
                    {
                        buffer: 0,
                        displayOutsideMaxExtent: true,
                        isBaseLayer: false,
                        yx : {'EPSG:900913' : false}
                    } 
                );
            
                osm = new OpenLayers.Layer.OSM();
            
                map.addLayers(tiled, osm);

                // build up all controls
                map.addControl(new OpenLayers.Control.PanZoomBar({
                    position: new OpenLayers.Pixel(2, 15)
                }));
                map.addControl(new OpenLayers.Control.Navigation());
                map.addControl(new OpenLayers.Control.Scale($('scale')));
                map.addControl(new OpenLayers.Control.MousePosition({element: $('location')}));
                map.zoomToExtent(bounds);
                
               
                
                // support GetFeatureInfo
                map.events.register('click', map, function (e) {
                    document.getElementById('nodelist').innerHTML = "Loading... please wait...";
                    var params = {
                        REQUEST: "GetFeatureInfo",
                        EXCEPTIONS: "application/vnd.ogc.se_xml",
                        BBOX: map.getExtent().toBBOX(),
                        SERVICE: "WMS",
                        INFO_FORMAT: 'text/html',
                        QUERY_LAYERS: map.layers[0].params.LAYERS,
                        FEATURE_COUNT: 50,
                        Layers: 'GISnk:nkPOIs1',
                        WIDTH: map.size.w,
                        HEIGHT: map.size.h,
                        format: format,
                        styles: map.layers[0].params.STYLES,
                        srs: map.layers[0].params.SRS};
                    
                    // handle the wms 1.3 vs wms 1.1 madness
                    if(map.layers[0].params.VERSION == "1.3.0") {
                        params.version = "1.3.0";
                        params.j = parseInt(e.xy.x);
                        params.i = parseInt(e.xy.y);
                    } else {
                        params.version = "1.1.1";
                        params.x = parseInt(e.xy.x);
                        params.y = parseInt(e.xy.y);
                    }
                        
                 
                });
            }
            
          
        </script>

  </head>
  <body onload="init();">
    <div id="map"></div>
      <div id="text">
        
        <div id="logo">
            
            <img src="nklogokl.png" alt="Logo">
            
        </div>
              <h1 id="title">Geoportal</h1>

              <div id="tags">
                GIS, Geoportal
              </div>

              <p id="shortdesc">
                Test Test TEst 
            </p>

            <div id="docs">
                <p>Test Test </p>
                <p>Test Link
                <a href="www.test.gv.at" target="_blank">www.test.gv.at</a> 
                Test.</p>
            </div>
      </div>
  </body>
</html>

QGIS sagt beim WMS anfordern, dass es ein EPSG900913 ist. Auch wenn ich einen OSM Layer in QGIS hinzufüge passt der Standort überein.

Leider gehts noch immer nicht.

Kann der

map.addLayers(tiled, osm);

Code fehlerhaft sein? Wenn ich ihn aus der Layer-Vorschau vom Geoserver kopiere sind die Layer noch in eckigen Klammern. (Geht aber auch nicht)
:roll_eyes:

Oh, mit eckige Klammern scheint es jetzt besser zu gehen:
Man sieht den OSM Layer laden, der wird aber dann vom POI Layer überdeckt.

transparent: true

hat aber nicht geholfen.

hmmm, ich hab keine Ahnung, wie man beim Geoserver die Transparenz einschaltet, bei Mapserver ist das auch vom “format” abhängig, aber das könnte was exotisches sein…

Bis du das gelöst hast, kannst ja den Layer halb durchsichtig machen

displayOutsideMaxExtent: true,
isBaseLayer: false,
opacity: 0.5,                                   <---- Neu
yx : {'EPSG:900913' : false}

dann hast schon mal Freude an ein bisschen übereinander liegenden Layern :wink:

Ja, das schaut schon mal besser aus. Morgen schau ich wie ich den Geoserver dazu bringe das WMS transparent dazustellen.
Danke Maxbe!