arcgis api for javascript (1) 基本的地图显示及spatialReference
折腾arcgis api for javascript有两个星期了,也算是过关斩将,有所收获,在此记录下心得。
准备工作
官方网站https://developers.arcgis.com/javascript/
jsapi包可以下载下来也可以使用在线的
<link rel="stylesheet" href="https://js.arcgis.com/3.15/esri/css/esri.css"> <script src="https://js.arcgis.com/3.15/"></script>
如果想使用本地的,需要简单的部署一下,搜索arcgis api for javascript 本地化部署,这里不多说了。
地图服务这里使用官方的http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer,推荐自己装arcgis server后发布自己的服务,折腾一下总是好的。
地图显示
require([ 'esri/map', 'esri/geometry/Extent','esri/layers/ArcGISTiledMapServiceLayer', 'esri/layers/ArcGISDynamicMapServiceLayer', ], function ( Map, Extent, ArcGISTiledMapServiceLayer, ArcGISDynamicMapServiceLayer, ) { //地图服务地址 var BASE_SERVER = 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer', //地图对象 map;
function createMap(data) { //这里extent指定了map初始化时的显示范围,extent里除了xmin,xmax,ymin,ymax还有个重要属性spatialReference,即在此时确定了map的坐标系 //extent不是必选参数,创建map时除了容器ID是必需的,其它参数都是可选的
map = new Map('mapDiv', {extent: new Extent(data.initialExtent)}); //这是我们的底图,如果不是瓦片数据地图,就new ArcGISDynamicMapServiceLayer var layer = new ArcGISTiledMapServiceLayer(BASE_SERVER);
//map成功加载第一张地图时触发 dojo.connect(map, 'onLoad', function(map) {
//继续加载别的地图
var layer2 = new ArcGISDynamicMapServiceLayer(SERVER2);
//设置只显示哪些图层
layer2.setVisibleLayers([0, 1]);
map.addLayer(layer2);
//给map注册事件等等
//......
});
//加载图层 map.addLayer(layer); } //获取地图服务的json数据,在本文这个例子里没有什么特别作用,不要也可以 $.get(BASEMAP_SERVER, { f: 'json' }, createMap, 'jsonp'); });
地图的显示还是相当简单的,本文的重点在于谈谈我对spatialReference的理解
spatialReference(sr)
简单的说,代表坐标系。我们知道,有地理坐标系统(lon, lat)和投影坐标系统(x, y)之分,根据所取参数不同,又细分为形形色色的坐标系。 我们在应用里会调用多个地图服务,它们很有可能采用不同的坐标系,即spatialReference.wkid值不同,但最终它们都得正确的落在同一个map上。也就是layer要重新投影转换以使它的sr同map的sr保持一致。有些layer可以自动转换,有些需要我们用代码控制转换,有些则无法转换。见下图(引用自http://help.arcgis.com/en/webapi/silverlight/apiref/ESRI.ArcGIS.Client~ESRI.ArcGIS.Client.Map~SpatialReference.html)
那么我们的map的sr是怎么确定的呢。创建map时可以指定extent同时也确定了sr;如果创建map时不指定sr,则map的sr等于加载到map上的第一个layer的sr。map的sr一旦确定就无法改变(如果你需要动态的改变sr,只有创建新的map实例去加载新sr的layer,再替换掉旧的map)。这也是为什么我们通常要先加载Tiled,再加载Dynamic。
手动转换也不复杂,jsapi提供了这样一个对象
require(["esri/geometry/webMercatorUtils"], function(webMercatorUtils) { /* code goes here */ });
它提供geographic和webMercator之间的相互转换,具体可以去官网api了解。
贴一小段代码
var paths = this.getPaths(obj.coords), sr = this.map.spatialReference, line, polyline; if (!paths) return; //paths里面是一串用经纬度表示的点,属于地理坐标系 line = new Polyline({ paths: paths, spatialReference: sr }); //判断sr是否是投影坐标系统 if (sr.isWebMercator()) //表示当前map不是地理坐标系统,那我们就需要转换line了,告诉它line里面的114,30...这些点其实是lon,lat而不是x,y,否则就飞到海里去了 line = webMercatorUtils.geographicToWebMercator(line); polyline = new Graphic(line, symbolLine); this.map.graphics.add(polyline); this.map.setExtent(line.getExtent().expand(1));
希望对大家有帮助,如有错误,请务必指正~
PS. 感觉有好久没有写博客了,期间在自学Node和折腾github,https://github.com/coiorz,不过最近工作很忙各种出差,搁置了一段时间了,欢迎交流。