[GIS] OpenLayers: Showing a WFS overlay on top of Google Maps

google mapsopenlayers-2overlaypointwfs

I have found similar questions asked previously, but I still fail to get a simple WFS point layer to work using OpenLayers and Google Maps. The original code I used was based on WFS polygon layers I have done previously, I then re-created a page based on the OpenGeo Introduction and other sources, all without success.

The WFS side of things seems fine — I can see the WFS traffic and it contains co-ordinates in the target space. But I can't see anything rendered at all. Even adding a feature via code doesn't get rendered, in the example code below the feature in the program does display if added to the "vectorLayer", but not if added to the "wfsLayer".

On the risk of appearing stupid: what is wrong with this code?

<html>
  <head>
    <title>OpenLayers: Google Layer Example</title>
    <link rel="stylesheet" href="http://openlayers.org/api/theme/default/style.css" type="text/css" />
    <link rel="stylesheet" href="http://openlayers.org/dev/examples/style.css" type="text/css" />
    <script src="http://maps.google.com/maps/api/js?v=3.3&amp;sensor=false" type="text/javascript"></script>
    <script src="http://openlayers.org/api/OpenLayers.js"></script>
    <script type="text/javascript">
      var map;

      function init() {
        map = new OpenLayers.Map("map");
        var gmap = new OpenLayers.Layer.Google(
            "Google Streets",
            {numZoomLevels: 20}
        );
        map.addLayer(gmap);

        var wfsLayer = new OpenLayers.Layer.Vector("WFS", {
            strategies: [new OpenLayers.Strategy.BBOX()],
            protocol: new OpenLayers.Protocol.WFS({
                        url:  "/geoserver/XXX/wfs",
                        featureType: "XXX",
                        featureNS: "XXX",
                        geometryName: "location",
                        srsName: "EPSG:900913",
                        version: "1.1.0"                    
                })
        });
        map.addLayer(wfsLayer);

        var vectorLayer = new OpenLayers.Layer.Vector("Overlay");
        var feature = new OpenLayers.Feature.Vector(
             new OpenLayers.Geometry.Point(12885085, -3806132),
             {some:'data'},
             {externalGraphic: 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Button_Icon_Red.svg/300px-Button_Icon_Red.svg.png', graphicHeight: 20, graphicWidth: 20});
        // wfsLayer.addFeatures(feature); // does not work
        vectorLayer.addFeatures(feature); // works
        map.addLayer(vectorLayer);<gml:Point srsDimension="2" srsName="http://www.opengis.net/gml/srs/epsg.xml#900913"><gml:pos>1.2884006544922689E7 -3801543.4695909135</gml:pos></gml:Point>

        map.setCenter(new OpenLayers.LonLat(12885085, -3806132), 12);         
      }
    </script>
  </head>

  <body onload="init()">
    <div id="map" class="smallmap"></div>
  </body>
</html>

Note that I replaced some values with "XXX" as to not disclose the client project. As I said: the WFS traffic looks fine, so I assume these values are not relevant for the question. Points in the WFS come through like this:

<gml:Point srsDimension="2" srsName="http://www.opengis.net/gml/srs/epsg.xml#900913">
    <gml:pos>1.2884006544922689E7 -3801543.4695909135</gml:pos>
</gml:Point>

which seems fine for the spherical Mercator projection around the target location.

Best Answer

I think the problem is in your map initialization code. It's for a single layer map. The multi-layer map initialization code in the OpenLayers example from the OpenGeo Stack intro looks like this:

var map;

// Avoid pink error tiles
OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;
OpenLayers.Util.onImageLoadErrorColor = "transparent";

function init(){
  // Map is in mercator this time, so over-ride the default
  // options that assume lat/lon.
  var options = {
      projection: new OpenLayers.Projection("EPSG:900913"),
      displayProjection: new OpenLayers.Projection("EPSG:4326"),
      units: "m",
      numZoomLevels: 20,
      maxResolution: 156543.0339,
      maxExtent: new OpenLayers.Bounds(-20037508, -20037508,
                                              20037508, 20037508.34)
  };
  // Create the map object
  map = new OpenLayers.Map('map', options);

Another possible problem would be the featurePrefix. You might need to set it according to the value you set in:

url:  "/geoserver/XXX/wfs",

It should be the value of XXX if I'm not mistaken. Another possibility is that the value in geometryName might be set incorrectly. It is "the_geom" in Geoserver by default, unless of course, you changed it.