ArcGIS API for JavaScript应用开发

ArcGIS API for JavaScript 应用开发简介javascript

1、开发环境准备css

     ArcGIS API for JavaScript 提供在线版API,4.x 是 ArcGIS API for JavaScript 的新一代版本,实现了2D和3D应用的彻底集成,3.x是一个2D版本,编程思路差别仍是比较大的。开发调试过程当中,最好进行本地化部署。ArcGIS JavaScript API能够从Esri官网获取,须要先注册一个Esri全球帐户。SDK本地化部署指在本地Web Server上的部署,在API文件夹arcgis_js_api\library\3.18\install_win.html中有官方的部署文档,基本过程以下:html

  • 复制 \arcgis_js_api\library 全部文件夹到你的Web server上,例如:复制到默认网站C:\Inetpub\wwwroot\arcgis_js_api\library下,java

  • 本地化配置,打开C:\Inetpub\wwwroot\arcgis_js_api\library\3.16\3.16\init.js 查找 [HOSTNAME_AND_PATH_TO_JSAPI],替换为 本地server路径" <myserver>/arcgis_js_api/library/3.18/3.18/ ",如" 127.0.0.1/arcgis_js_api/library/3.18/3.18 "。打开C:\Inetpub\wwwroot\arcgis_js_api\library\3.18\3.18\dojo\dojo.js 查找[HOSTNAME_AND_PATH_TO_JSAPI],替换为 "<myserver>/arcgis_js_api/library/3.18/3.18/"例如"127.0.0.1/arcgis_js_api/library/3.18/3.18"git

脚本中使用本地化SDK时(版本以3.16为例),嵌入以下语句。数据库

    ...编程

<link rel="stylesheet" href="http://127.0.0.1/arcgis_js_api/library/3.16/3.16/dijit/themes/claro/claro.css"/>api

<link rel="stylesheet" type="text/css" href="http://127.0.0.1/arcgis_js_api/library/3.16/3.16/esri/css/esri.css" />浏览器

<script type= "text/javascript" src= "http://127.0.0.1/arcgis_js_api/library/3.16/3.16/init.js" ></script>服务器

    ...

使用在线API时 ,即所谓Content Delivery Network (CDN),对应要素替换为:

     <link rel="stylesheet" href="https://js.arcgis.com/3.18/dijit/themes/claro/claro.css"/>

     <link rel="stylesheet" type="text/css" href="https://js.arcgis.com/3.18/esri/css/esri.css" />

     https://js.arcgis.com/3.18

2、打开地图

      一个最基本的打开地图的应用脚本,使用由ERSI提供的缺省数据,以及CDN的API(在线API):

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

    <title>第一个地图应用</title>

    <link rel="stylesheet" href="https://js.arcgis.com/3.18/dijit/themes/claro/claro.css"/>

    <link rel="stylesheet" type="text/css" href="https://js.arcgis.com/3.18/esri/css/esri.css" />

    <style>

           html, body ,#map{ height: 100%; width: 100%; margin: 0; padding: 0; }

    </style>

<script type="text/javascript" src="https://js.arcgis.com/3.18" ></script>

<script>

  //Dojo模块,使用在线缺省数据。

        require(["esri/map", "dojo/domReady!"], function (Map) {

            //初始化<div id="map" ></div>的map容器

            var map = new Map("map", {

                center: [-118, 34.5],

                zoom: 8,

                basemap: "topo"

            });

        });

     </script>

</head>

<body>

      <div id="map" >

      </div>

  </body>

</html>

脚本运行效果如图所示:

打开地图的核心代码是:

       ....

var map = new Map("map", {

                center: [-118, 34.5],

                zoom: 8,

                basemap: "topo"

            });

       ....

这段代码至关于建立了一个地图容器,定位在center处,显示在第8级。3.18的Map对象能够认为是一个view+doc的对象,在4.0后,就将Map和View分开了,一个负责数据管理,一个负责显示及控制。ESRI在网上为basemap提供的缺省选项包括”topo”,"satellite", "hybrid", "topo", "gray", "oceans", "osm", "national-geographic"等几类。去掉basemap就是打开一个白图。

如从打开一个空白地图开始,逐个打开图层并加入地图,就能够完成地图的调用了,相似以下代码:

...

var map,tiled_layers;

//建立map

map = new Map("map", {

          center: [-96.541, 38.351],

          zoom: 14,

         slider: false

 });

//根据图层服务的URL地址,或图层文件的URL地址打开图层

tiled_layers= new ArcGISTiledMapServiceLayer("图层服务所在的URL",{打开选项,可全用缺省});

//加入地图

    map.addLayer(tiled_layers);

    ...

     固然,前提是这些图层的都是预先配准好的,显示风格也有了较好的缺省设置,不然的话,就得对他们的显示属性进行设置。经常使用的的图层对象主要有如下几种:

...

GraphicsLayer,通常矢量地图,通常用来处理业务数据;

FeatureLayer,矢量地图,由Arcgis维护的矢量地图数据

ArcGISTiledMapServiceLayer 通过切片缓冲过的地图,背景地图通常用这种方式;

ArcGISDynamicMapLayer, 从mdx文档发布出来的矢量图

MapImageLayer,经地理编码的影像,可与地图一块叠加;

WMSLayer, 符合OGC Web Map Services (WMS)的服务提供的Map图层. ;

WFSLayer ,符合 OGC Web Feature Services (WFS)要求的服务提供的矢量图层. ;

CSVLayer,利用服务器上的CSV file (.csv, .txt)产生的图层。

KMLLayer,利用服务器上的(.kml, .kmz).产生的图层。(.kml, .kmz);

GeoRSSLayer,利用服务器上的GeoRSS文件产生的图层。

...

显然,这些图层能够来自不一样服务。对于arcgis for server发布出来的地图,在服务上右键选中property能够看服务地址:例如为http://localhost/arcgis/services/zy/MapServer,但实际引用方法为:http://localhost/ArcGIS/rest/services/zy/MapServer,能够将该地址复制到浏览器地址查看是否正确

图层对象里实际上能够包含多个图层,每一个图层的在特定地图比例尺范围内的可见性通常在发布时就设置好了(就应该设置好),要注意这一点。

 

3、在地图上绘制图形

     自绘制图形即Graphic对象,通常都建立在GraphicLayer,每一个Map至少缺省带一个GraphicLayer,能够建立多个,以实现分层管理,但在某个具体的业务中,将业务数据组织在一个图层中是有便利的,虽然从系统的角度不可取。Graphic 对象实际上包括一个 geometry,一个 symbol和一组属性(或一个infoTemplate),经常使用的geometry对象主要有Point、Polyline、Polygon等,用于肯定Graphic的位置;经常使用的符号对象有SimpleMarkerSymbol、SimpleLineSymbol、SimpleFillSymbol、TextSymbol等,用于肯定图形对象的显示方式。属性主要是有关图形的其余语义信息,如长度、名称、隶属关系等。

  所以,想在地图背景上绘制图形,主要有如下几步:

  //使用dojo加载绘制模块

....

  require([

        "esri/map",

        "esri/graphic",

        "esri/geometry/Point",

        "esri/geometry/Polyline",

        "esri/geometry/Polygon",

        "esri/symbols/SimpleLineSymbol",

        "esri/symbols/SimpleFillSymbol",

        "esri/symbols/TextSymbol",

        "dojo/parser",

      "dojo/on",

        "dojo/domReady!"

      ], function(

        Map, Graphic,

        Point, Polyline, Polygon,

        SimpleLineSymbol, SimpleFillSymbol, TextSymbol,

        parser,on

      ) {

   ...

    });

//读入几何数据,以下读入一个箭头绘制的多边形数据,不一样的对象读入数据的要求各不相同。

//你能够想象你是从数据库中读入的,反正不是ArcGIS直接支持的类型。

...

var arrow = new Polygon({

            "rings": [

              [

                [9862211, 6617856],

                [8922952, 5522055],

                [8922952, 5991684],

                [6105178, 5991684],

                [6105178, 7087485],

                [8922952, 7087485],

                [8922952, 7557114],

                [9862211, 6617856]

              ]

            ],

            "spatialReference": {

              "wkid": 102100

            }

          });

...

//建立符号对象,这里比较偷懒,全用缺省值,

//本质上,你能够根据数据的不一样取值进行设置,从而实现应用数据须要的可视化效果

//固然,符号对象能够重用给多个图形对象。

...

var polygonSymbol = new SimpleFillSymbol();

...

//最后建立图形对象并加入GraphicLayer图层

...

map.graphics.add(new Graphic(arrow, polygonSymbol));

...

下面的代码是一步建立点的geometry对象、符号属性,以及根据infoTemplate赋予属性的例子,前提时数据你都准备好了。

   ...

var myPoint = {"geometry":{"x":-104.4140625,"y":69.2578125,

       "spatialReference":{"wkid":4326}},"attributes":{"XCoord":-104.4140625,

       "YCoord":69.2578125,"Plant":"Mesa Mint"},"symbol":{"color":[255,0,0,128],

       "size":12,"angle":0,"xoffset":0,"yoffset":0,"type":"esriSMS",

       "style":"esriSMSSquare","outline":{"color":[0,0,0,255],"width":1,

       "type":"esriSLS","style":"esriSLSSolid"}},

       "infoTemplate":{"title":"Vernal Pool Locations","content":"Latitude: ${YCoord} <br/>

        Longitude: ${XCoord} <br/> Plant Name:${Plant}"}

   };

   var gra = new Graphic(myPoint);

...

如下是一段最基础的在地图背景上显示自定义图形的所有代码:

<!DOCTYPE html>

<html>

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">

    <title>Edit Tools</title>

    <link rel="stylesheet" href="https://js.arcgis.com/3.18/dijit/themes/nihilo/nihilo.css">

    <link rel="stylesheet" href="https://js.arcgis.com/3.18/esri/css/esri.css">

    <style>

        html, body, #map {

            height: 100%;

            margin: 0;

            padding: 0;

        }

    </style>

    <script src="https://js.arcgis.com/3.18/"></script>

    <script>

      var map;

      require([

        "esri/map",

        "esri/graphic",

        "esri/geometry/Point",

        "esri/geometry/Polyline",

        "esri/geometry/Polygon",

        "esri/symbols/SimpleLineSymbol",

        "esri/symbols/SimpleFillSymbol",

        "esri/symbols/TextSymbol",

        "dojo/parser",

        "dojo/on",

        "dojo/domReady!"

      ], function(

        Map, Graphic,

        Point, Polyline, Polygon,

        SimpleLineSymbol, SimpleFillSymbol, TextSymbol,

        parser,on

      ) {

        parser.parse();

 //打开地图

        map = new Map("map", {

          basemap: "streets",

          center: [3.955, 59.338],

          zoom: 3

        });

    //用addGraphics函数关联load事件,以便在加载地图时完成图形建立

     map.on("load", addGraphics);

     //建立自绘制图形

        function addGraphics() {

          //建立图形符号对象

          var polygonSymbol = new SimpleFillSymbol();

          var polylineSymbol = new SimpleLineSymbol();

          var text = new TextSymbol("Editable Text");

          text.font.setSize("20pt");

       //建立Geometry

          var polyline = new Polyline({

            "paths":[

              [

                [-12484306,7244028],

                [-7318386,10061803],

                [-3013453,10727111]

              ]

            ],"spatialReference":{

              "wkid":102100

            }

          });

          var polygon = new Polygon({

            "rings": [

              [

                [-4226661, 8496372],

                [-3835304, 8731187],

                [-2269873, 9005137],

                [-1213208, 8613780],

                [-1017529, 8065879],

                [-1213208, 7478843],

                [-2230738, 6891806],

                [-2935181, 6735263],

                [-3522218, 6891806],

                [-3952711, 7165757],

                [-4265797, 7283164],

                [-4304933, 7635386],

                [-4304933, 7674521],

                [-4226661, 8496372]

              ]

            ],

            "spatialReference": {

              "wkid": 102100

            }

          });

          var arrow = new Polygon({

            "rings": [

              [

                [9862211, 6617856],

                [8922952, 5522055],

                [8922952, 5991684],

                [6105178, 5991684],

                [6105178, 7087485],

                [8922952, 7087485],

                [8922952, 7557114],

                [9862211, 6617856]

              ]

            ],

            "spatialReference": {

              "wkid": 102100

            }

          });

          var triangle = new Polygon({

            "rings": [

              [

                [2426417, 8535508],

                [4304933, 12292541],

                [6183449, 8535508],

                [2426417, 8535508]

              ]

            ],

            "spatialReference": {

              "wkid": 102100

            }

          });

          var point = new Point(-40, 35);

       //建立图形对象并加入图层

          map.graphics.add(new Graphic(polyline, polylineSymbol));

          map.graphics.add(new Graphic(polygon, polygonSymbol));

          map.graphics.add(new Graphic(arrow, polygonSymbol));

          map.graphics.add(new Graphic(triangle, polygonSymbol));

          map.graphics.add(new Graphic(point, text));

        }       

      });

    </script>

</head>

<body>

    <div id="map"></div>

</body>

</html>

运行效果以下图所示:

    固然,若是咱们的应用数据所有由Arcgis维护,在地图上显示本身的应用信息就和显示地图同样简单,经常使用FeatureLayer图层对象进行此类数据的管理。

 

4、处理事件和消息

    (1)地图有关的事件

    和Map有关的事件,经常使用的主要有”load \unload \layer-add \layer-remove \click\dbl-click、mouse-down \mouse-move \mouse-up \ key-down \key-up”等,前面已经接触到很多次”load”事件的应用了。下面是鼠标在地图上单击事件的例子,功能很简单,就是单击后弹出对话框显示处单击的屏幕位置坐标和地理位置坐标:

    ...

     map.on( "click", myClickHandler);

     ...

     function myClickHandler(evt) {

        alert("User clicked at " +

        evt.screenPoint.x + ", " + evt.screenPoint.y +

            " on the screen. The map coordinate at this point is " +

            evt.mapPoint.x + ", " + evt.mapPoint.y

        );

    }

         ...

    (2)特定Layer有关的事件

    特别是GraphicLayer等用户放置业务数据的图层,经常使用的主要有 \click\dbl-click\mouse-over \ graphic-add \graphic-remove\graphic-draw等,前三个通常用来查询图上目标,后两个一般用于数据变化后是否保存图形等处理,graphic-draw则用来控制显示的刷新,这里的刷新除非是图上数据变化致使应用据数须要从新导入,致使显示可能须要自行变化,才须要处理,不然,通常arcgis都给你作好了,不需费心。

      ...

//open图层

var incidentLayer = new FeatureLayer(

"https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0", {

          mode: FeatureLayer.MODE_ONDEMAND,

          outFields: ["*"],

          id: "incidentLayer"

        });

incidentLayer.setSelectionSymbol(

          new SimpleMarkerSymbol().setColor(new Color("red"))

 );

map.addLayers([incidentLayer]);

...

//设置图层目标单击事件处理程序

//这里是事件关联与处理程序定义在一块儿的作法。

incidentLayer.on("click", function(evt) {

            graphicAttributes = evt.graphic.attributes;

            title = graphicAttributes.req_type;

            content = "<b>Date Reported: </b>" + graphicAttributes.req_date

                    + "<br><b>Address: </b>" + graphicAttributes.address

                    + "<br><b>District: </b>" + graphicAttributes.district;

            relatedQuery.objectIds = [graphicAttributes.objectid];

         

            incidentLayer.queryRelatedFeatures(relatedQuery, function(relatedRecords) {

              var fset = relatedRecords[graphicAttributes.objectid];

              var count = (fset) ? fset.features.length : 0;

              content = content + "<br><hr><br><i><span id='numPeople'>" + count +

                    "</span> people think this is important.</i>";

        content = content + "<br><br><img style='cursor:pointer' src='images/thumbsup.jpeg'  οnclick='voteOnIncident(" + graphicAttributes.objectid + ");'>";

              map.infoWindow.setTitle(title);

              map.infoWindow.setContent(content);

              map.infoWindow.show(evt.screenPoint, map.getInfoWindowAnchor(evt.screenPoint));

            });

          });

   }

     ....

    (3)图形绘制事件

图形最重要的事件消息处理,是在图形的绘制编辑中。在交互输入中,esri/toolbars/draw提供有关绘制动做处理函数, esri/toolbars/Edit 提供目标图形编辑处理函数,这两个包提供的事件和编辑能力是极为重要的,要重点掌握。

处理绘制动做事件的过程主要是:

...

//引入Draw模块

require([ "esri/Darw", ... ], function(Draw, ... ){

   var tb;

   ...

   tb = new Draw(map);

   //关联draw-end事件处理对象

   tb.on("draw-end", addGraphic);

   //选中激活绘图工具

   tb.activate(point); //画点

   ...

   //定义绘制结束事件处理函数

  //将数据存入GraphicaLayer中。

   function addGraphic(evt) {

                //deactivate the toolbar and clear existing graphics

                tb.deactivate();

                map.enableMapNavigation();

                // figure out which symbol to use

                var symbol;

                if (evt.geometry.type === "point" || evt.geometry.type === "multipoint") {

                     symbol = markerSymbol;

                } else if (evt.geometry.type === "line" || evt.geometry.type === "polyline") {

                     symbol = lineSymbol;

                }

                else {

                    symbol = fillSymbol;

                }

                //建立图形对象加到地图缺省的GraphicLayer中

                //实际上,应在本身的服务器上建立一个

                //可保存的GraphicLayer

                map.graphics.add(new Graphic(evt.geometry, symbol));

}

...

});

绘制工具最经常使用的绘制动做包括这些类型,point、multipoint、line、polyline、freehandpolyline、triangle、rectangle、circle、ellipse、polygon、freehandpolygon、arrow等。

(4)图形编辑事件

处理编辑动做的主要过程是:

 ....

require([ "esri/toolbars/edit", "dojo/_base/event", "dojo/parser",...],

        function ( Edit, event, parser,... ) {

...

//建立编辑工具

var editTb = new Edit(map);

...

//单击选中目标时激活编辑工具

map.graphics.on("click", function (evt) {

    //检查没有处于绘图状态

    if (!drawediting) {

        event.stop(evt);

        //设置编辑工具能够具有的编辑动做类型

        var tool = 0;

        tool = tool | Edit.MOVE | Edit.EDIT_VERTICES | Edit.SCALE | Edit.EDIT_TEXT;

        editTb.activate(tool, evt.graphic);

    }

 });

 //当单击非目标上时,取消编辑工具

  map.on("click", function (evt) {

        if (!drawediting)

              editTb.deactivate();

});

....

    上述过程,已经基本可以完成绝大多数图形编辑的工做,若是在编辑完成后还须要进一步作工做,则须要经过监视Layer的事件进行相关的进一步处置,如保存数据等。

 

世界读书日

关于Dojo的基本知识:

    ArcGIS API for JavaScript 是基于Dojo开发的, Dojo包括按钮、格网、树、图表和其余的界面组件,并主要由3部分组成:

(1)Core-核心包;

(2)Dijit-主题界面组件;

(3)DojoX-各类扩展组件,如图表等。   

ArcGIS API for JavaScript 彻底支持利用异步模块定义(Asynchronous Module Definition,AMD)风格的代码建立JavaScript 对象和模块。因为使用Dojo对Javascript的部分能力进行了封装,所以,要理解其原理,必须理解如下几个Dojo命令,这都属于Dojo的core部分,因为Dojo也在不断发展,需注意现行版本与之前的区别。

     (1)dojo.require: 相似 <script> 标签,用于从特定包中导入JS脚本到当前脚本页。

...

// legacy

dojo.require("esri.map");

// AMD

require(["esri/map", ... ], function(Map, ... ){ ... });

...

所以,若是在后续脚本中用到API的对象或方法等,都应用require先申明一下,如:

    ....

    require([

        "esri/map",

        "esri/tasks/GeometryService",

        "esri/layers/ArcGISTiledMapServiceLayer",

        "esri/layers/FeatureLayer",

        "esri/Color",

        "esri/symbols/SimpleMarkerSymbol",

        "esri/symbols/SimpleLineSymbol",

        "esri/dijit/editing/Editor",

        "esri/dijit/editing/TemplatePicker",

        "esri/config",

        "dojo/i18n!esri/nls/jsapi",

        "dojo/_base/array", "dojo/parser", "dojo/keys",

        "dijit/layout/BorderContainer", "dijit/layout/ContentPane",

        "dojo/domReady!"

      ], function(

         Map, GeometryService,

         ArcGISTiledMapServiceLayer, FeatureLayer,

         Color, SimpleMarkerSymbol, SimpleLineSymbol,

         Editor, TemplatePicker,

         esriConfig, jsapiBundle,

         arrayUtils, parser, keys

       ) {

      //代码区

   });

     (2)dojo.ready (or dojo.addOnLoad): 相似 <body οnlοad="">标签. 它帮助注册页面加载时初始化的脚本模块。

...

// legacy

dojo.ready(init);

// AMD

require(["dojo/ready"], function(ready){

   ready(function(){

    // This function won't run until the DOM has loaded and other modules that register have run.

   });

});

...

     (3)dojo.connect: 相似DOM组件的JavaScript 函数Element.addEventListener和Element.attachEvent。 主要用于登记页面中或页面特定组件的事件、消息处理函数。

       ...

// legacy

dojo.connect(myMap, "onLoad", myLoadHandler);

// AMD

require(["esri/map", "dojo/on"], function(Map, on) {

  // ...

  on(myMap, "load", callback);

});

...

    (4)dojo.byId: 相似 JavaScript 函数document.getElementById(id),主要用于经过id得到页面中对象id

 ...  

dojo.byId("myInputField").value = myMap.id;

...

欢迎留言......

请你们关注公众号动态!

请你们关注公众号动态!

请你们关注公众号动态!