I have the following HTML-JavaScript code and I have problems re-projecting the vector layer (WFS) from EPSG:27700 (British National Grid) to EPSG:900913 (Google Maps).
I managed to project the WMS layer but I have difficulties with the WFS.
With what I have read so far, to perform this re-projection 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)
Code is the following:
<html>
<head>
<style>
html,body {
height: 99%;
width: 99%;
}
#map {
width: 80%;
height: 80%;
border: 1px solid black;
}
</style>
<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&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>
</head>
<body onload="init()">
<h1 id="title">OpenLayers: Google Layer Example</h1>
<div id="map" </div>
<div id="coordinates"></div>
</body>
</html>
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 a lot 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 don't need to use proxy.
--> For conversion between projection systems (e.g. from EPSG:27700 to EPSG:900913) you don't 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 won't be able to see the layer on the screen.