Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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
    );
}
share|improve this question
add comment

4 Answers

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'
        })
    }
);
share|improve this answer
    
No, I have 'allOverlays' set to true, so there is no base layer and as far as I understand it shouldn't be necessary to set one... should it? –  Richard Turner May 29 '12 at 11:59
    
You are right (in theory). You could try to add an "empty" layer instead of the raster layer (just initialize it using OpenLayers.Layer())? –  atlefren May 29 '12 at 12:18
add comment
up vote 1 down vote accepted

By putting debugging breaks in the OL code and manually switching the two layers around using JS once the map was rendered I was able to see that the vector layer resolutions were being calculated incorrectly. Actually it was all a bit messy. I also realised that EPSG:3857 != EPSG:900913, which helped!

By removing numZoomLevels from the map options, and adding the following options to the vector layer, I was able to get it all working:

maxExtent: oBounds.transform(oGoogleProj, oSpheMercProj),
maxResolution: 'auto', // important, it doesn't default to auto
units: 'm'
share|improve this answer
add comment

you can check out OpenLayers.Map parameters here... there are two options which come to my mind.

  • first of all, the problem can stems from allOverlays parameter.

{Boolean} Allow the map to function with “overlays” only. Defaults to false. If true, the lowest layer in the draw order will act as the base layer. In addition, if set to true, all layers will have isBaseLayer set to false when they are added to the map. Note

If you set map.allOverlays to true, then you cannot use map.setBaseLayer or layer.setIsBaseLayer. With allOverlays true, the lowest layer in the draw layer is the base layer. So, to change the base layer, use setLayerIndex or raiseLayer to set the layer index to 0.

  • the second is that when you use bounds on your map, maybe the features on vector layer cant render in this bounds that you dont see it...

if you add your code on jsfiddle, i can look at your code there and update my answer too..

i hope it helps you...

share|improve this answer
    
Well, the vector layer features display fine if the raster layer is at the bottom (so acting as the de facto base layer), so I don't think the problem is that they're out-of-bounds. I think the issue is something to do with needing to specify a resolution, which OL will calculate from the raster layer when that's present at the bottom of the stack, but my attempts to manually set maxResolution and minResolution haven't made a difference. –  Richard Turner May 29 '12 at 12:10
add comment

I had a similar problem making a raster layer a base layer from WMS. I had to add a OSM layer as base and then hide it. I tried all sorts of isBaseLayer things before this and this was the only way I could get it to work.

Adding the WMS layer only results in an Uncaught TypeError: Cannot call method 'containsLonLat' of null

var mapLayer = new OpenLayers.Layer.OSM();
var miniscale = new OpenLayers.Layer.WMS(
                    "UKDistricts",
                    "http://localhost:8080/geoserver/wms",
                    {
                        layers: "OSOpenData:MiniScale_(no_grid)_R13",
                        transparent: true,
                        isBaseLayer: true
                    },
                    {
                        opacity: 1,
                        maxExtent: new OpenLayers.Bounds(-10, 40, 10 ,70).transform(new OpenLayers.Projection("EPSG:4326"),
                        new OpenLayers.Projection("EPSG:900913"))
                    });
map.addLayers([mapLayer, miniscale]);
mapLayer.setVisibility(false);
share|improve this answer
    
Yeah, adding a dummy raster base layer was something I wanted to avoid. –  Richard Turner Jun 1 '12 at 21:50
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.