Skip to main content
2 of 3
appended answer 8302 as supplemental
Ian Turton
  • 83.2k
  • 6
  • 89
  • 189

Reproject a vector layer (EPSG:27700) using WFS onto a googlemaps background (EPSG:900913)

I have the following HTML-javascript code and i have problems reprojecting the vector layer (WFS) from EPSG:27700 (British National Grid) to EPSG:900913 (googlemaps).

I managed to project the WMS layer but i have difficulties with the WFS.

With what i have read so far, to perform this reprojection you need "GeoJSON" and "Proj4js". There is no much documentation and examples using these 2 features.

One more thing to add is that using the existing WFS coding i managed to project the "tasmanian" layers that already exist in Geoserver. But these are on a different projecting system (EPSG:4326)

Any help would be much appreciated.

George

Code is the following:

html,body { height: 99%; width: 99%; } #map { width: 80%; height: 80%; border: 1px solid black; }
<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://openlayers.org/api/OpenLayers.js"></script>
    <script src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js"></script>
<script src="http://maps.google.com/maps/api/js?v=3.2&amp;sensor=false"></script>
    <script src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2 mkt=en-us"></script>
    <script src="http://developers.cloudmade.com/attachments/download/58/cloudmade.js"></script>

<script src="http://proj4js.org/lib/proj4js-compressed.js"></script>

<script type="text/javascript">

    Proj4js.defs["EPSG:900913"] = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs";
    Proj4js.defs["EPSG:27700"] = "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs";
    Proj4js.defs["EPSG:4326"] = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";

  function init() {

    //set up projections

    // World Geodetic System 1984 projection
            var WGS84 = new OpenLayers.Projection("EPSG:4326");

            // WGS84 Google Mercator projection
    var WGS84_google_mercator = new OpenLayers.Projection("EPSG:900913");

    // OS British National Grid
    var os = new OpenLayers.Projection("EPSG:27700");

            //Initialize the map
            var map = new OpenLayers.Map ("map", {
                    controls:[
                            //allows the user pan ability
                            new OpenLayers.Control.Navigation(),
                            //displays the pan/zoom tools
                            new OpenLayers.Control.PanZoomBar(),
                            //displays a layer switcher
                            new OpenLayers.Control.LayerSwitcher(),

                    ],
                            projection: WGS84_google_mercator,
                        displayProjection: WGS84
            } );

            //base layers
            var openstreetmap = new OpenLayers.Layer.OSM();

            var cloudmade = new OpenLayers.Layer.CloudMade("CloudMade", {
                key: 'BC9A493B41014CAABB98F0471D759707'}
            );

            var google_maps = new OpenLayers.Layer.Google("Google Maps", {
        numZoomLevels: 20}
    );
            var google_satellite = new OpenLayers.Layer.Google("Google Satellite", 
                    {
                    type: google.maps.MapTypeId.SATELLITE,
                    'sphericalMercator': true,
                    buffer:0,
                    numZoomLevels: 20}
            );
            var bing_shaded = new OpenLayers.Layer.VirtualEarth("Bing Maps", 
            {
                     type: VEMapStyle.Shaded,
                    'sphericalMercator': true,
                     numZoomLevels: 20}
            );
    var bing_hybrid = new OpenLayers.Layer.VirtualEarth("Bing Satellite", {
        type: VEMapStyle.Hybrid,
               'sphericalMercator': true,
        numZoomLevels: 20}
        );
    var bing_aerial = new OpenLayers.Layer.VirtualEarth("Bing Aerial", {
        type: VEMapStyle.Aerial,
                    'sphericalMercator': true,
        numZoomLevels: 20}
        );

            // WMS Layers for the projection of the shapefiles
            var layer1 = new OpenLayers.Layer.WMS( "National Parks",
                        "http://localhost:8080/geoserver/wms",
                      {
                        srs: 'EPSG:4326',
                            layers: 'National_Parks',
                            transparent: 'true',
                            format: 'image/png',
                            buffer:0
                      },
                      {
                            'singleTile': true, 'ratio': 1, 'opacity': 0.75, 'isBaseLayer': false, 'wrapDateLine': false,'transitionEffect':'resize', displayInLayerSwitcher : true, 'alwaysInRange': true, 'displayOutsideMaxExtent':true
                      }
                      );

            // WFS Layers for the projection of the shapefiles
            var wfslayer = new OpenLayers.Layer.Vector("National Parks in GB",
            {
            strategies: [new OpenLayers.Strategy.BBOX()],
            protocol: new OpenLayers.Protocol.WFS({
          url:  "http://localhost:8080/geoserver/wfs",
                      //featureType: "tasmania_state_boundaries",
                      featureType: "National_Parks",
                      //featureNS: "http://www.openplans.org/topp",
                      featureNS: "http://opengeo.org/protec_are",
                      version: "1.1.0",
          srsName: "EPSG:900913",
          })
                    });

                            //transformation between coordinate systems (27700 to 900913)
                            var format = new OpenLayers.Format.GeoJSON({
                            'internalProjection': new OpenLayers.Projection("EPSG:900913"),
                            'externalProjection': new OpenLayers.Projection("EPSG:27700")
                            });


                            var newfeatures = format.write(wfslayer.features);
                            var newlayer = new OpenLayers.Layer.Vector("newlayer");
                        newlayer.addFeatures(format.read(newfeatures));


            // Display the layers on the map
            map.addLayers([openstreetmap, cloudmade, google_maps, google_satellite,bing_shaded, bing_hybrid, bing_aerial, layer1, newlayer]);

            var mapextent = new OpenLayers.Bounds(-16.08,49.06,6.76,58.74).transform(map.displayProjection, map.baseLayer.projection);
    map.zoomToExtent(mapextent);

    }

</script>
OpenLayers: Google Layer Example

Thanks a lot for the information guys.

Senthil i made the changes that you suggested and i managed to get the layer on the screen.

As quite lots of people might have the same problem i would like to summarise some important things.

--> If the web page(HTML) containing the map (comment from 'iant') that you are creating exists on the same server as WFS/Geoserver (e.g when you use the same PC) then you dont need to use proxy.

--> For conversion between projection systems (e.g. from EPSG:27700 to EPSG:900913) you dont need Proj4Js or GeoJson. WFS Version 1.1.0 will do the trick.

--> Do not run the HTML web page as a file by double clicking on it (e.g file:///E:/GISWork/GISApplication/Geoserver-2.0.3/data_dir/www/GIS.html) but run it through the server (e.g http://localhost:8080/geoserver/www/GIS.html) otherwise you wont be able to see the layer on the screen.

G

Geo
  • 133
  • 4
  • 10