百度地圖、高德地圖、Google地圖等座標提取與轉換

一、地理座標系與投影座標系javascript

地理座標系也就是球面座標系,是將本不是橢球體的地球進行橢球體化,從而造成球面座標體系,國際標準的地理座標系就是WGS-84座標系;css

只不過各個國家爲了反映該國家所在區域地球的真實形狀,採用不一樣的數學模型對地球進行橢球體化,因此就有個Beijing5四、Xian80座標系。java

投影座標系是爲平面座標,是將地理座標根據必定的投影規則投影到平面,造成的平面直角座標系,好比高斯-克呂格投影,墨卡託投影等。web

 

二、WGS-84座標系算法

WGS-84座標是地理座標系,也就是GPS座標,通常用國際標準的GPS記錄儀記錄下來的座標,都是GPS的座標。可是在中國爲了保密,任何一個地圖產品都不容許使用GPS座標。GPS座標以度分秒形式表示經緯度,好比google earth上採集到的是39°31'20.51,那麼應該這樣換算,31分就是31/60度,20.51秒就是20.51/3600度,結果就是39+ 31/60 + 20.51/3600 度。api

 

三、GCJ-02座標系  與 百度 bd-09座標系dom

GCJ-02座標系又名「火星座標系」,是我國國測局首創的座標體系,由WGS-84加密而成,在國內,必須至少使用GCJ-02座標系,或者使用在GCJ-02加密後再進行加密的座標系,如百度座標系。高德和Google在國內都是使用GCJ-02座標系,能夠說,GCJ-02是國內最普遍使用的座標系。ide

百度座標系是在GCJ-02座標系的基礎上再次加密偏移後造成的座標系,只適用於百度地圖。(固然,百度地圖api接口提供了google座標轉百度座標、原始座標轉百度座標的接口,網上也有一些轉換算法,我的建議仍是用百度地圖api比較準確)工具

 

 

四、WGS84 Web Mercator  座標系測試

咱們在作開發的時候,尤爲是web地圖開發,兩種座標系相當重要 WGS84(WKID:4326) 和 WGS84 Web Mercator (WKID:102113) 。WGS84 Web Mercator 是目前在線地圖(平面)採用的通用座標系,屬於投影座標系。

 

五、測試

測試方法:

①使用arcgis api for javascript 調用 Google衛星地圖服務;

②在①的基礎上調用arcgis api for javascript 繪製折現的工具,在衛星影像圖中辨識並繪製一條道路,將其座標點經緯度(這裏輸出的應該是GCJ-02火星座標系吧?我不肯定,有知道的望留言!)輸出到控制檯;

使用高德地圖API將②獲取到的座標點集繪製成折線,比較從Google地圖中獲取到的點集座標在高德地圖中是否有誤差?

 

使用百度地圖API將②獲取到的座標點集繪製成折線,比較從Google地圖中獲取到的點集座標在百度地圖中是否有誤差?

 

Google地圖相關代碼:

@using Drision.Framework.Mvc;
@{
    ViewBag.Title = "Google地圖";

    <link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_v39_sdk/arcgis_js_api/library/3.9/3.9/js/dojo/dijit/themes/tundra/tundra.css" />
    <link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_v39_sdk/arcgis_js_api/library/3.9/3.9/js/esri/css/esri.css" />
    <script type="text/javascript" src="http://localhost/arcgis_js_v39_sdk/arcgis_js_api/library/3.9/3.9/init.js"></script>
}

<style>
    /*地圖樣式調整*/
    .esriPopup .titlePane {
        padding-left: 0px;
    }

    .esriPopup .actionsPane .zoomTo {
        display: none;
    }

    .esriPopup .titleButton.maximize {
        display: none;
    }

    .esriPopup .titleButton.close {
        display: none;
    }
</style>

<style>
    @@media(min-width: 768px) {
        .container {
            max-width: 100%;
        }
    }

    @@media(min-width: 992px) {
        .container {
            max-width: 100%;
        }
    }

    @@media(min-width: 1200px) {
        .container {
            max-width: 100%;
        }
    }

    @@media(min-width: 1600px) {
        .container {
            max-width: 100%;
        }
    }
</style>

<style>
    /* ===========懸浮菜單欄===========*/
    #controls {
        /*background: #fff;*/
        /*border: 1px solid #9e9fa1;*/
        /*box-shadow: 0 5px 4px rgba(0,0,0,.15);*/
        color: #7c8196;
        font-family: sans-serif;
        height: 40px;
        top: 3.8em;
        position: absolute;
        width: auto;
        z-index: 40;
        border-radius: 4px;
        padding: 0.1em 0.3em 0 0.3em;
        right: 1em !important;
    }
</style>


<div style="padding: 1px;">
    <div id="mapDiv" style="min-width: 1260px; min-height: 860px;"></div>

    <div id="controls">
        <button class="btn btn-info" id="polyline">繪製折線</button>
        <button class="btn btn-danger" id="remove">清除</button>
        <button class="btn btn-danger" id="quxiao">取消繪製</button>
    </div>
</div>


<script>
    dojo.require("esri/map",
        "dojo/dom",
        "dojo/on",
        "dojo/colors",

        "esri/layers/ArcGISTiledMapServiceLayer",
        "esri/layers/GraphicsLayer",
        "esri/geometry/Point",
        "esri/geometry/Polygon",
        "esri/SpatialReference",
        "esri/toolbars/draw",
        "esri/graphic",

        "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleLineSymbol",
        "esri/symbols/SimpleFillSymbol",
        "esri/symbols/PictureMarkerSymbol",

         "dojo/parser",
         "dijit/registry",
         "dijit/layout/BorderContainer",
         "dijit/layout/ContentPane",
         "dijit/form/Button",
         "dijit/WidgetSet",

         "dojo/domReady!");

    function init(Map, dom, on, Color,
            ArcGISTiledMapServiceLayer,
            GraphicsLayer,
            Point, Polygon, SpatialReference,
            SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, PictureMarkerSymbol,
            Draw, Graphic, parser, registry
            ) {

        loadGoogLyr();
        var map = new esri.Map("mapDiv", {
            logo: false,
            //basemap: "streets",
            center: [120.6168, 31.42],
            slider: false,
            zoom: 9,
            showLabels: true,
        });
        map.addLayer(new GoogleMapLayer());
        map.addLayer(new GoogleMapAnooLayer());

        //***************************   如下爲自定義圖層   *********************************

        //======== 地圖中添加繪製層 =======
        var gl = new esri.layers.GraphicsLayer({ id: "bound" });
        map.addLayer(gl);

        //======== 添加道路線 =======
        var line = new esri.geometry.Polyline({
            "paths": [[
                        [120.50459959285944, 31.235715080384875],
                        [120.51335432308402, 31.23696268129648],
                        [120.517130873377, 31.2373296196055],
                        [120.51961996334282, 31.237843330843624],
                        [120.5306062914678, 31.238430425980763],
                        [120.53300955074512, 31.23850381261634],
                        [120.5356703020879, 31.23909090364859],
                        [120.54219343441213, 31.24077877004094],
                        [120.54511167782032, 31.24107230894344],
                        [120.54725744503222, 31.242099687918223],
                        [120.54923155086718, 31.24584218824886],
                        [120.5501756884404, 31.24679613520138],
                        [120.55172064083301, 31.24760331355749],
                        [120.55618383663376, 31.248997514466723],
                        [120.55953123348435, 31.250024807227433],
                        [120.56287863033494, 31.25090533498366],
                        [120.56399442928513, 31.25149234892578],
                        [120.56759931820115, 31.255234477009502],
                        [120.5724916674443, 31.25662856523398],
                        [120.57540991085249, 31.2572155435902],
                        [120.57892896908001, 31.259269939092558],
                        [120.58304884212689, 31.26227808040296],
                        [120.58708288448528, 31.263231861286453],
                        [120.60639478939247, 31.26557958854718],
                        [120.61523535030554, 31.26668006559397],
                        [120.62845327633093, 31.267193617156938],
                        [120.63540556209752, 31.267487073938],
                        [120.63961126583287, 31.26763380198627],
                        [120.64261533992953, 31.26763380198627],
                        [120.64510442989535, 31.267927257398295],
                        [120.64931013363069, 31.26844080217318],
                        [120.65008260982698, 31.268587528738323],
                        [120.65008260982698, 31.268587528738323]
            ]],
            "spatialReference": { "wkid": 4326 }    //這裏我將繪製道路提取出來的座標點集又放入Google地圖,可是用的是 wkid 4326(WGS-84座標系)
        });                          //有點混亂,照理講這個座標應該是 GCJ-02火星座標系的,爲何用4326才能正常顯示?若是我用GPS設備提取的座標值呢? var lineSymbol = new esri.symbol.CartographicLineSymbol(
          esri.symbol.CartographicLineSymbol.STYLE_SOLID,
          new dojo.Color("#0000FF"), 2,
          esri.symbol.CartographicLineSymbol.CAP_ROUND,
          esri.symbol.CartographicLineSymbol.JOIN_MITER, 5
        );
        var polyline = new esri.Graphic(line, lineSymbol);

        gl.add(polyline);


        ////==============  如下爲繪製線操做  ======================
        var draw = new esri.toolbars.Draw(map);
        //定義圖形樣式
        draw.markerSymbol = new esri.symbol.SimpleMarkerSymbol();
        draw.lineSymbol = new esri.symbol.SimpleLineSymbol(
            esri.symbol.SimpleLineSymbol.STYLE_DASH,
            new dojo.Color([255, 0, 0]), 3
            );
        draw.fillSymbol = new esri.symbol.SimpleFillSymbol();


        $("#controls button").click(function () {
            var tool = null;
            switch (this.id) {
                case "point": tool = "POINT"; break;
                case "polyline": tool = "POLYLINE"; break;
                case "polygon": tool = "POLYGON"; break;
                case "circle": tool = "CIRCLE"; break;
                case "rectangle": tool = "RECTANGLE"; break;
                case "quxiao": draw.deactivate(); break;
                case "remove": map.graphics.clear(); break;
            }
            if (tool !== null) {
                draw.activate(esri.toolbars.Draw[tool]);   //激活對應的繪製工具
            }
        });

        draw.on("draw-complete", drawEndEvent);
        function drawEndEvent(evt) {
            //添加圖形到地圖
            var symbol;
            if (evt.geometry.type === "point" || evt.geometry.type === "multipoint") {
                symbol = draw.markerSymbol;
            } else if (evt.geometry.type === "line" || evt.geometry.type === "polyline") {
                symbol = draw.lineSymbol;
            }
            else {
                symbol = draw.fillSymbol;
            }
            map.graphics.add(new esri.Graphic(evt.geometry, symbol))

            //將經緯度座標點集輸出到控制檯(這裏輸出的是火星座標系的經緯度?)
            var output = "";
            for (var i = 0; i < evt.geographicGeometry.paths[0].length; i++) {
                output += "[" + evt.geographicGeometry.paths[0][i][0] + "," + evt.geographicGeometry.paths[0][i][1] + "],\r\n";
            }
            console.log(output);
        }
    }


    function loadGoogLyr() {

        //遙感影像圖
        dojo.declare("GoogleMapLayer", esri.layers.TiledMapServiceLayer, { // create WMTSLayer by extending esri.layers.TiledMapServiceLayer
            constructor: function () {
                this.spatialReference = new esri.SpatialReference({
                    wkid: 102113
                });
                this.initialExtent = new esri.geometry.Extent(-20037508.342787, -20037508.342787, 20037508.342787, 20037508.342787, this.spatialReference);
                this.fullExtent = new esri.geometry.Extent(-20037508.342787, -20037508.342787, 20037508.342787, 20037508.342787, this.spatialReference);
                //
                this.tileInfo = new esri.layers.TileInfo({
                    "dpi": "90.71428571427429",
                    "format": "image/png",
                    "compressionQuality": 0,
                    "spatialReference": {
                        "wkid": "3857"
                    },
                    "rows": 256,
                    "cols": 256,
                    "origin": {
                        "x": -20037508.342787,
                        "y": 20037508.342787
                    },

                    // Scales in DPI 96
                    "lods": [{
                        "level": 0, "scale": 591657527.591555, "resolution": 156543.033928
                    }, {
                        "level": 1, "scale": 295828763.795777, "resolution": 78271.5169639999
                    }, {
                        "level": 2, "scale": 147914381.897889, "resolution": 39135.7584820001
                    }, {
                        "level": 3, "scale": 73957190.948944, "resolution": 19567.8792409999
                    }, {
                        "level": 4, "scale": 36978595.474472, "resolution": 9783.93962049996
                    }, {
                        "level": 5, "scale": 18489297.737236, "resolution": 4891.96981024998
                    }, {
                        "level": 6, "scale": 9244648.868618, "resolution": 2445.98490512499
                    }, {
                        "level": 7, "scale": 4622324.434309, "resolution": 1222.99245256249
                    }, {
                        "level": 8, "scale": 2311162.217155, "resolution": 611.49622628138
                    }, {
                        "level": 9, "scale": 1155581.108577, "resolution": 305.748113140558
                    }, {
                        "level": 10, "scale": 577790.554289, "resolution": 152.874056570411
                    }, {
                        "level": 11, "scale": 288895.277144, "resolution": 76.4370282850732
                    }, {
                        "level": 12, "scale": 144447.638572, "resolution": 38.2185141425366
                    }, {
                        "level": 13, "scale": 72223.819286, "resolution": 19.1092570712683
                    }, {
                        "level": 14, "scale": 36111.909643, "resolution": 9.55462853563415
                    }, {
                        "level": 15, "scale": 18055.954822, "resolution": 4.77731426794937
                    }, {
                        "level": 16, "scale": 9027.977411, "resolution": 2.38865713397468
                    }, {
                        "level": 17, "scale": 4513.988705, "resolution": 1.19432856685505
                    }, {
                        "level": 18, "scale": 2256.994353, "resolution": 0.597164283559817
                    }, {
                        "level": 19, "scale": 1128.497176, "resolution": 0.298582141647617
                    }]
                });
                this.loaded = true;
                this.onLoad(this);
            },
            getTileUrl: function (level, row, col) {
                return "http://mt" + (col % 4) + ".google.cn/vt/lyrs=s@112&hl=zh-CN&gl=cn&" + "x=" + col + "&" + "y=" + row + "&" + "z=" + level + "&s=";
            }
        });

        //標註矢量圖
        dojo.declare("GoogleMapAnooLayer", esri.layers.TiledMapServiceLayer, { // create WMTSLayer by extending esri.layers.TiledMapServiceLayer
            constructor: function () {
                this.spatialReference = new esri.SpatialReference({
                    wkid: 102113
                });
                this.initialExtent = new esri.geometry.Extent(-20037508.342787, -20037508.342787, 20037508.342787, 20037508.342787, this.spatialReference);
                this.fullExtent = new esri.geometry.Extent(-20037508.342787, -20037508.342787, 20037508.342787, 20037508.342787, this.spatialReference);
                //
                this.tileInfo = new esri.layers.TileInfo({
                    "dpi": "90.71428571427429",
                    "format": "image/png",
                    "compressionQuality": 0,
                    "spatialReference": {
                        "wkid": "3857"
                    },
                    "rows": 256,
                    "cols": 256,
                    "origin": {
                        "x": -20037508.342787,
                        "y": 20037508.342787
                    },

                    // Scales in DPI 96
                    "lods": [{
                        "level": 0, "scale": 591657527.591555, "resolution": 156543.033928
                    }, {
                        "level": 1, "scale": 295828763.795777, "resolution": 78271.5169639999
                    }, {
                        "level": 2, "scale": 147914381.897889, "resolution": 39135.7584820001
                    }, {
                        "level": 3, "scale": 73957190.948944, "resolution": 19567.8792409999
                    }, {
                        "level": 4, "scale": 36978595.474472, "resolution": 9783.93962049996
                    }, {
                        "level": 5, "scale": 18489297.737236, "resolution": 4891.96981024998
                    }, {
                        "level": 6, "scale": 9244648.868618, "resolution": 2445.98490512499
                    }, {
                        "level": 7, "scale": 4622324.434309, "resolution": 1222.99245256249
                    }, {
                        "level": 8, "scale": 2311162.217155, "resolution": 611.49622628138
                    }, {
                        "level": 9, "scale": 1155581.108577, "resolution": 305.748113140558
                    }, {
                        "level": 10, "scale": 577790.554289, "resolution": 152.874056570411
                    }, {
                        "level": 11, "scale": 288895.277144, "resolution": 76.4370282850732
                    }, {
                        "level": 12, "scale": 144447.638572, "resolution": 38.2185141425366
                    }, {
                        "level": 13, "scale": 72223.819286, "resolution": 19.1092570712683
                    }, {
                        "level": 14, "scale": 36111.909643, "resolution": 9.55462853563415
                    }, {
                        "level": 15, "scale": 18055.954822, "resolution": 4.77731426794937
                    }, {
                        "level": 16, "scale": 9027.977411, "resolution": 2.38865713397468
                    }, {
                        "level": 17, "scale": 4513.988705, "resolution": 1.19432856685505
                    }, {
                        "level": 18, "scale": 2256.994353, "resolution": 0.597164283559817
                    }, {
                        "level": 19, "scale": 1128.497176, "resolution": 0.298582141647617
                    }]
                });
                this.loaded = true;
                this.onLoad(this);
            },
            getTileUrl: function (level, row, col) {
                return "http://mt" + (col % 4) + ".google.cn/vt/lyrs=h@177000000&hl=zh-CN&gl=cn&" + "x=" + col + "&" + "y=" + row + "&" + "z=" + level + "&s=";
            }
        });
    }

    dojo.ready(init);
</script>

實現效果:

高德地圖相關代碼:

@{
    ViewBag.Title = "高德地圖";
    
    <script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.1&key= xxx(這裏是key) &plugin=AMap.Geocoder,AMap.ToolBar"></script>
}
<style>
    /* ===========懸浮菜單欄===========*/
    #controls {
        /*background: #fff;*/
        /*border: 1px solid #9e9fa1;*/
        /*box-shadow: 0 5px 4px rgba(0,0,0,.15);*/
        color: #7c8196;
        font-family: sans-serif;
        height: 40px;
        top: 3.8em;
        position: absolute;
        width: auto;
        z-index: 40;
        border-radius: 4px;
        padding: 0.1em 0.3em 0 0.3em;
        right: 1em !important;
    }
</style>

<div style="padding: 1px; width: 100%; height: 100%;">
    <div id="container" style="width:100%; height:100%;"></div>

    <div id="controls">
        <button class="btn btn-info" id="RemotePhoto">衛星顯示</button>
        <button class="btn btn-info" id="RoadGrid">路網顯示</button>
    </div>
</div>



<script>
    var map = new AMap.Map('container', {
        resizeEnable: true,
        center: [120.6168, 31.42],
        //layers: [new AMap.TileLayer.Satellite()],  //衛星圖
        zoom: 9
    });


    var roadNetLayer = new AMap.TileLayer.RoadNet({ zIndex: 12 }); //實例化路網圖層
    roadNetLayer.setMap(map); //在map中添加路網圖層
    var satellLayer = new AMap.TileLayer.Satellite({ zIndex: 11 }); //實例化衛星圖
    satellLayer.setMap(map); //在map中添加衛星圖

    var showRemote = true;
    var showRoad = true;
    $("#RemotePhoto").click(function () {
        if (showRemote == true) {
            $(this).removeClass("btn-info").addClass("btn-danger");
            showRemote = false;

            satellLayer.hide();
        }
        else {
            $(this).removeClass("btn-danger").addClass("btn-info");
            showRemote = true;

            satellLayer.show();
        }
    });

    $("#RoadGrid").click(function () {
        if (showRoad == true) {
            $(this).removeClass("btn-info").addClass("btn-danger");
            showRoad = false;

            roadNetLayer.hide();
        }
        else {
            $(this).removeClass("btn-danger").addClass("btn-info");
            showRoad = true;

            roadNetLayer.show();
        }
    });


    var lineArr = [
[120.50459959285944, 31.235715080384875],
[120.51335432308402, 31.23696268129648],
[120.517130873377, 31.2373296196055],
[120.51961996334282, 31.237843330843624],
[120.5306062914678, 31.238430425980763],
[120.53300955074512, 31.23850381261634],
[120.5356703020879, 31.23909090364859],
[120.54219343441213, 31.24077877004094],
[120.54511167782032, 31.24107230894344],
[120.54725744503222, 31.242099687918223],
[120.54923155086718, 31.24584218824886],
[120.5501756884404, 31.24679613520138],
[120.55172064083301, 31.24760331355749],
[120.55618383663376, 31.248997514466723],
[120.55953123348435, 31.250024807227433],
[120.56287863033494, 31.25090533498366],
[120.56399442928513, 31.25149234892578],
[120.56759931820115, 31.255234477009502],
[120.5724916674443, 31.25662856523398],
[120.57540991085249, 31.2572155435902],
[120.57892896908001, 31.259269939092558],
[120.58304884212689, 31.26227808040296],
[120.58708288448528, 31.263231861286453],
[120.60639478939247, 31.26557958854718],
[120.61523535030554, 31.26668006559397],
[120.62845327633093, 31.267193617156938],
[120.63540556209752, 31.267487073938],
[120.63961126583287, 31.26763380198627],
[120.64261533992953, 31.26763380198627],
[120.64510442989535, 31.267927257398295],
[120.64931013363069, 31.26844080217318],
[120.65008260982698, 31.268587528738323],
[120.65008260982698, 31.268587528738323]
    ];
    var polyline = new AMap.Polyline({
        path: lineArr,          //設置線覆蓋物路徑
        strokeColor: "#ff0000", //線顏色
        strokeOpacity: 1,       //線透明度
        strokeWeight: 3,        //線寬
        strokeStyle: "dash",   //線樣式 實線:solid
        strokeDasharray: [10, 5] //補充線樣式
    });
    polyline.setMap(map);

</script>

實現效果(無誤差):

 

使用百度地圖api 的效果(有誤差),我只輸入了部分座標點集:

相關文章
相關標籤/搜索