arcgis-api-for-js-之參考系統的轉換
1. 前言
對於簡單的參考系統的轉換,例如從地理座標系統到 Web 墨卡託投影座標系統,可以直接使用 "esri/geometry/webMercatorUtils"
模組中的功能函式即可,對於複雜的參考系統的轉換,可以呼叫伺服器的幾何物件服務(esri/tasks/GeometryService
),幾何物件服務的 project
方法可用於實現投影或者投影轉換。
下面通過程式碼來展示如何使用上面的兩種方法準換,以及我們定義的公式來計算不同參考系統的座標。
2. 實現思路
首先我們通過使用者滑鼠點選地圖時發生的事件中的引數mapPoint
得到使用者點選地圖的地理位置的座標,然後通過 webMercatorUtils
geographicToWebMercator
方法計算該地理座標通過投影后的座標,同時呼叫我們自己的計算公式來計算投影座標,最後呼叫幾何物件服務的 project
方法,向伺服器提交投影計算請求,要求轉換的投影由第2個引數指定。當該方法執行完畢後,將呼叫 project
方法中指定的回撥函式,這裡的回撥函式將3種方法得到的投影座標分別顯示在右側的資訊框中。
3. 程式碼如下
var map,gsvs;
require(["esri/geometry/Extent", "esri/map", "esri/layers/ArcGISTiledMapServiceLayer" ,
"esri/SpatialReference", "esri/tasks/GeometryService", "esri/geometry/webMercatorUtils", "esri/geometry/Point",
"dojo/domReady!"],
function (Extent, Map, ArcGISTiledMapServiceLayer, SpatialReference, GeometryService, webMercatorUtils, Point) {
map = new esri.Map("mapDiv");
var layer = new ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer");
map.addLayer(layer);
map.setExtent(
// 設定顯示範圍
new Extent(-144.13, 7.98, -52.76, 68.89,
// 設定地理座標系為WGS84
new SpatialReference({ wkid: 4326 })));
// 呼叫伺服器的幾何物件服務
// 表示GeometryService的ArcGIS Server REST資源的URL https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer。有關構建URL的更多資訊,請參閱ArcGIS Services目錄
gsvc = new GeometryService("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
map.on("click", projectToWebMercator);
function projectToWebMercator(evt) {
map.graphics.clear();
var point = evt.mapPoint;
var outSR = new SpatialReference({ wkid: 102113 });
// 利用webMercatorUtils模組轉換座標
var wm = webMercatorUtils.geographicToWebMercator(point);
// 利用我們自己的計算方法轉換座標
var we = toWebMercator(point);
// 利用伺服器的幾何物件服務進行轉換
gsvc.project([point], outSR, function (projectedPoints) {
pt = projectedPoints[0];
var desc1 = "通過服務得到的座標:<br/>" + pt.x.toFixed(3) + ";" + pt.y.toFixed(3);
var desc2 = "功能函式計算的座標:<br/>" + wm.x.toFixed(3) + ";" + wm.y.toFixed(3);
var desc3 = "自己函式計算的座標:<br/>" + we.x.toFixed(3) + ";" + we.y.toFixed(3);
document.getElementById("spatialReference").innerHTML = desc1 + "<br/>" + desc2 + "<br/>" + desc3;
});
}
function toWebMercator(pt) {
var num = pt.x * 0.017453292519943295;
var x = 6378137.0 * num;
var a = pt.y * 0.017453292519943295;
var y = 3189068.5 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
return new Point({ "x": x, "y": y, "spatialReference": { "wkid": 102113 } });
}
});
4. 程式碼解析
首先我們通過 map 物件的setExtent
方法進行設定顯示的範圍以及投影座標,為下面程式碼:
map.setExtent(
// 設定顯示範圍
new Extent(-144.13, 7.98, -52.76, 68.89,
// 設定地理座標系為WGS84
new SpatialReference({ wkid: 4326 })));
然後建立一個GeometryService
物件。其中 URL 是必需的引數。表示GeometryService的ArcGIS Server REST資源的URL
https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer。有關構建URL的更多資訊,可以檢視ArcGIS Services目錄。
然後給地圖新增 click 事件,並執行 projectToWebMercator
函式,projectToWebMercator
函式中,首先利用事件引數的 mapPoint
得到使用者在地圖點選位置的地理座標,然後建立一個SpatialReference
空間參考物件,需要我們前面所介紹的 ID ,然後進行座標轉換,程式碼如下:
function projectToWebMercator(evt) {
// 清除地圖中的所有圖形
map.graphics.clear();
// 得到使用者在地圖點選位置的地理座標
var point = evt.mapPoint;
var outSR = new SpatialReference({ wkid: 102113 });
// 利用webMercatorUtils模組轉換座標
var wm = webMercatorUtils.geographicToWebMercator(point);
// 利用我們自己的計算方法轉換座標
var we = toWebMercator(point);
// 利用伺服器的幾何物件服務進行轉換
gsvc.project([point], outSR, function (projectedPoints) {
pt = projectedPoints[0];
var desc1 = "通過服務得到的座標:<br/>" + pt.x.toFixed(3) + ";" + pt.y.toFixed(3);
var desc2 = "功能函式計算的座標:<br/>" + wm.x.toFixed(3) + ";" + wm.y.toFixed(3);
var desc3 = "自己函式計算的座標:<br/>" + we.x.toFixed(3) + ";" + we.y.toFixed(3);
document.getElementById("spatialReference").innerHTML = desc1 + "<br/>" + desc2 + "<br/>" + desc3;
});
}
其中利用webMercatorUtils
模組轉換座標呼叫他的geographicToWebMercator
方法, 將幾何體從地理單位轉換為Web墨卡託單位。需要傳入的引數為,需要轉換的座標。
利用伺服器的幾何物件服務進行轉換時,呼叫幾何物件服務的 project
方法,向伺服器提交投影計算請求,其中 project
方法的原型為project(params, callback?, errback?)
,第一個引數為投影引數,可以設定需要轉換的點的陣列,以及轉換的座標,第二個為方法完成後呼叫的函式,第三個引數為執行錯誤時返回的資訊。我們在回撥函式中將計算的結果顯示在右側的 div 中。
最後就是我們自己函式計算的座標,程式碼:
return new Point({ "x": x, "y": y, "spatialReference": { "wkid": 102113 } });
其中 Point
類的建構函式如下:
require([
"esri/geometry/Point", "esri/SpatialReference", ...
], function(Point, SpatialReference, ... ) {
new Point(-118.15, 33.80, new SpatialReference({ wkid: 4326 }));
...
});
我們把計算後的值然後通過 Point
類的建構函式中將地圖單位中一個點的X座標、地圖單位中一個點的Y座標。以及幾何的空間參考。返回一個新的Point物件顯示在右側的轉換資訊中。
- 其中
toFixed(3)
把數字轉換為字串,結果的小數點後有指定位數的數字。