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,不过最近工作很忙各种出差,搁置了一段时间了,欢迎交流。

posted @ 2015-12-18 10:44  coIorZ  阅读(14878)  评论(1编辑  收藏  举报