简体   繁体   中英

How to reproject layers (using GeoServer and OpenLayers) in order to overlay on the google maps

I am writing a code using OpenLayers. In this code, I want to display different layers in different zoom levels. Up until here, everything works. my problem began when I tried to add Google Maps as baselayers. My layers' projection system is not consistent with Google layers, so they should be reprojected. I tried to use Proj4js.transform method but it didn't work. My layers are in EPSG:3006(Sweden) and Google layers are in EPSG:900913. The following code results in a projected layer shifted to right. It means that the re-projection did not work properly. Please let me know what is wrong with my code.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>OpenLayers map preview</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <!-- Import OL CSS, auto import does not work with our minified OL.js build -->
    <link rel="stylesheet" type="text/css" href="http://gisl.nateko.lu.se:8088/geoserver/openlayers/theme/default/style.css">
    <!-- add here more css definition libraries-->

         <!-- Basic CSS definitions -->
    <style type="text/css">
        body {
            font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
            font-size: small;
        }
        /* Toolbar styles */
        #toolbar {
            position: relative;
            padding-bottom: 0.5em;
            display: none;
        }
        /* The map and the location bar */
        #map {
            clear: both;
            position: relative;
            width: 337px;
            height: 512px;
            border: 2px solid black;
        }            
        #wrapper {
            width: 337px;
            height: 50px;                           
        }            
        #location {
            float: right;
            font-family: Arial, Verdana, sans-serif; 
            font-size: 12px; 
            color: #483D8B;
            background-color: white;
        }            
        #scale {
            float:left;
            font-family: Arial, Verdana, sans-serif; 
            font-size: 12px; 
            color: #483D8B;
            background-color: white;
        }
        #nodelist{
            font-family: Arial, Verdana, sans-serif; 
            font-size: 14px; 
            color: #000000;
            font-style: normal;
            background-color: white;
        }
    </style>
    <!-- Import OpenLayers, reduced, wms read only version -->
    <script type="text/javascript" src="http://www.openlayers.org/api/OpenLayers.js"></script>      
    <!-- add here more js libraries -->




    <script src="http://maps.google.com/maps/api/js?v=3.2&sensor=false"></script>
    <script src ='proj4js/lib/proj4js-combined.js'></script>
    <script src ='proj4js/lib/deprecated.js'></script>

    <script defer="defer" type="text/javascript">
        var map;
        var untiled;
        var tiled;
        var pureCoverage = false;
        // pink tile avoidance
        OpenLayers.IMAGE_RELOAD_ATTEMPTS = 5;


        // make OL compute scale according to WMS spec
        OpenLayers.DOTS_PER_INCH = 25.4 / 0.28;



        function init(){



            format = 'image/png';


            var options = {
                controls: [],
                projection: new OpenLayers.Projection('EPSG:900916'),
                displayProjection: new OpenLayers.Projection('EPSG:4326'),
                maxExtent: new OpenLayers.Bounds(           
                -20037508, -20037508,20037508, 20037508.34),
                //modify parameter
                maxResolution: 5000,
                //modify parameter
                //setting zoom levels
                numZoomLevels:15,
                units: 'm',

            };
            map = new OpenLayers.Map('map', options);
            // setup tiled layer

                var gphy = new OpenLayers.Layer.Google(
                "Google Physical",
                {type: google.maps.MapTypeId.TERRAIN, numZoomLevels: 15, sphericalMercator:true}
                // used to be {type: G_PHYSICAL_MAP}
                );
                var gmap = new OpenLayers.Layer.Google(
                    "Google Streets", // the default
                    {numZoomLevels: 15, sphericalMercator:true}
                    // default type, no change needed here
                );
                var ghyb = new OpenLayers.Layer.Google(
                    "Google Hybrid",
                    {type: google.maps.MapTypeId.HYBRID, numZoomLevels: 15, sphericalMercator:true}
                    // used to be {type: G_HYBRID_MAP, numZoomLevels: 20}
                );
                var gsat = new OpenLayers.Layer.Google(
                    "Google Satellite",
                    {type: google.maps.MapTypeId.SATELLITE, 
                    numZoomLevels: 15, 
                    sphericalMercator:true

                    }
                    // used to be {type: G_SATELLITE_MAP, numZoomLevels: 22}
                );

            //add controls here
                map.addControl(new OpenLayers.Control.LayerSwitcher());
                map.addControl(new OpenLayers.Control.LayerSwitcher());
                map.addControl(new OpenLayers.Control.PanZoomBar());
                zf= new OpenLayers.Control.ZoomToMaxExtent({title:"Zoom to max extent"});
                // create a panel to locate the zoom extent button & add the panel to the map
                // use the code to create the button from ZoomToMaxExtent.js
                var panel= new OpenLayers.Control.Panel({defaultControl:zf});       
                panel.addControls([zf]);
                map.addControl(panel);
                map.addControl(new OpenLayers.Control.Navigation());
                map.addControl(new OpenLayers.Control.Scale($('scale')));
            //end add controls


            layer2 = new OpenLayers.Layer.WMS( 
                "Gr2LundKom:districts","http://gisl.nateko.lu.se:8080/geoserver/wms", 
                {
                    projection: map.displayProjection,
                    height: '600',
                    width: '800',
                    layers: 'Gr2LundKom:districts',
                    styles: '',
                    srs:'EPSG:3006',
                    format: format,
                    tiled: 'true',
                    transparent: 'true',

                }, 
                {
                    buffer: 0,
                    displayOutsideMaxExtent: true,
                    isBaseLayer: false,
                    reproject: true
                });
                Proj4js.defs["EPSG:3006"] = "+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs";
                Proj4js.defs["EPSG:4326"] = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";
                var src = new OpenLayers.Projection('EPSG:3006');
                var dst =  new OpenLayers.Projection('EPSG:4326');
                Proj4js.transform(src, dst, layer2); 
                layer2.projection=dst;                  

            layer3 = new OpenLayers.Layer.WMS( 
                "Gr2LundKom:public_buildings,other_buildings,roads_all,Public_Libraries",
                "http://gisl.nateko.lu.se:8080/geoserver/wms",
                {
                    projection: map.displayProjection,
                    height: '600',
                    width: '800',
                    layers: "Gr2LundKom:public_buildings,other_buildings,roads_all,Public_Libraries",
                    transparent: "true", 
                    styles: '',
                    srs:'EPSG:3006',
                    format: format,
                    tiled: 'true',
                    transparent: 'true'
                }, 
                {
                    buffer: 0,
                    displayOutsideMaxExtent: true,
                    isBaseLayer: false,
                    reproject: true                     
                });
                Proj4js.transform(src, dst, layer3);
                layer3.projection=dst;                  

            map.addLayers([gsat,gphy,gmap,ghyb,layer2]);
            //map.setCenter(new OpenLayers.LonLat(1335967.698, 6179172.362), 22);
            map.zoomToExtent(new OpenLayers.Bounds(         
                -20037508, -20037508,20037508, 20037508.34));

            // change the dislapy layers with the chandge of scale
            map.events.register('zoomend', this, function (event) {
            var zLevel = map.getZoom();     
                if( zLevel == 1 || zLevel == 2 || zLevel == 3  )
                {
                    layer3.setVisibility(false);
                    layer2.setVisibility(true);
                }
                if( zLevel == 4 || zLevel == 5 || zLevel == 6)
                {
                    layer2.setVisibility(false);
                    layer3.setVisibility(true);
                    map.addLayers([gsat,gphy,gmap,ghyb,layer3]);
                }

                });

        }









    </script>
    </head>     
<body onload="init()">
    Map viewer using Geoserver and MapLayers
    <br><br>


        <div id="map">
        </div>
        <br>
        <div id="wrapper">
            <div id="location">location</div>
            <br>
            <div id="scale">
            </div>
        </div>

        <br>
        <div id="nodelist" >
            --> Click on the map to get feature info
        </div>
 </body>

Well, I know it is a workaround, but I see you use geoserver, so you could convert your layers in geoserver into google mercator (you should use the code EPSG:3857, as I recall EPSG:900916 didn't work for me). I struggled with this problem too, and that was the only thing which helped me. This problem comes however only if you use wms, wfs layers you could transform easily.

And also I think that you should not try to visualize everything in EPSG:4326 but in google mercator instead.

I hope this helps.

我认为您在这里有错字,应该是EPSG:900913而不是EPSG:900916,因为它是Google用数字(900913)表示的形式

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM