[GIS] OpenLayers (allOverlays): Vector layer not rendered without raster layer beneath it

openlayers-2rastervectorwfs

This is another newbie question. I'm trying to create a map using OpenLayers that comprises only of vector layers from a WFS server. However, I'm thwarted because my vector layer won't render unless it has a raster layer beneath it. I surmise this is because OpenLayers is deriving some setting(s) (resolution? minExtent?) from the raster layer that it's unable to do from the vector one, but I'm just guessing and I don't know what those settings are.

The code below works beautifully, displaying both layers. If I remove the line to add the raster layer to the map, or add it after I've added the vector layer, the map displays nothing (calling oMap.zoomToMaxExtent() still shows nothing).

What am I missing?

function initMap() {
    var oRasterLayer,
        oVectorLayer,
        oBounds,
        oSpatialProj,
        oSphericalMercatorProj;

    // Use MapBox dark theme for UI controls
    OpenLayers.ImgPath = "http://js.mapbox.com/theme/dark/";

    oSpatialProj           = new OpenLayers.Projection("EPSG:4326");
    oSphericalMercatorProj = new OpenLayers.Projection("EPSG:3857");

    oBounds = new OpenLayers.Bounds(-11, 49.6, 4, 62.6).transform(
        oSpatialProj,
        oSphericalMercatorProj
    );

    oMap = new OpenLayers.Map(
        sMapDivId,
        {
            numZoomLevels    : 10,
            maxExtent        : oBounds,
            restrictedExtent : oBounds,
            allOverlays      : true
        }
    );
    oMap.addControl(new OpenLayers.Control.LayerSwitcher());

    oRasterLayer = new OpenLayers.Layer.XYZ(
        'Land',
        sTilesUrl.replace(/\${layer}/, 'land'),
        {
            projection        : oSphericalMercatorProj,
            wrapDateLine      : true,
            sphericalMercator : true
        }
    );

    /* Add a postcode area selection layer. This is a vector layer, working
    directly with data from PostGIS. */
    oVectorLayer = new OpenLayers.Layer.Vector(
        'Selection',
        {
            projection        : oSphericalMercatorProj,
            wrapDateLine      : true,
            sphericalMercator : true,
            strategies        : [new OpenLayers.Strategy.BBOX()],
            protocol          : new OpenLayers.Protocol.WFS({
                url          : '/wfs',
                featureType  : 'areas',
                featureNS    : "http://gis.mediatel.co.uk",
                geometryName : 'wkb_geometry',
                srsName      : 'EPSG:3857'
            })
        }
    );

    // SWAP THESE TWO LINES, OR COMMENT-OUT THE RASTER ONE, TO BREAK THE MAP:
    oMap.addLayer(oRasterLayer);
    oMap.addLayer(oVectorLayer);

    oSelectControl = new OpenLayers.Control.SelectFeature(
        oVectorLayer,
        {
            clickout    : true,
            toggle      : true,
            multiple    : true,
            hover       : false,
            toggleKey   : 'ctrlKey',
            multipleKey : 'shiftKey',
            box         : false
        }
    );
    oMap.addControl(oSelectControl);

    oMap.setCenter( // Near London
        new OpenLayers.LonLat(0, 51.5).transform(
            oSpatialProj,
            oSphericalMercatorProj
        ),
        9
    );
}

Best Answer

This is because a vector layer isn't treated as a base layer by default.

Try setting the "isBaseLayer" property of your vectorLayer to true:

oVectorLayer = new OpenLayers.Layer.Vector(
    'Selection',
    {
        isBaseLayer       : true,
        projection        : oSphericalMercatorProj,
        wrapDateLine      : true,
        sphericalMercator : true,
        strategies        : [new OpenLayers.Strategy.BBOX()],
        protocol          : new OpenLayers.Protocol.WFS({
            url          : '/wfs',
            featureType  : 'areas',
            featureNS    : "http://gis.mediatel.co.uk",
            geometryName : 'wkb_geometry',
            srsName      : 'EPSG:3857'
        })
    }
);