书接Arcgis api for Javascript + arcgisServer + arcSDE笔记(1)
Arcgis api for Javascript提供了一系列接口,可以在网页上实现地图加载、地理数据的展示与编辑、空间分析等功能。
本章仅介绍基本框架的搭建、数据的加载等,详细的开发文档在https://developers.arcgis.com/javascript/latest/guide/查阅。
使用arcgis api for js只需要在网页代码中写入:
<script src="https://js.arcgis.com/4.14/"></script>
(现在已经更新到4.15了)
网页会在线调取arcgis api。但如果需要离线部署,需要下载api到本地,并将其部署到服务器上。
首先从官网(https://developers.arcgis.com/javascript/latest/guide/get-api/)上下载api压缩包。
在IIS上搭建一个网站,在网站的MIME类型中注册一些条目(具体在上述网站中有介绍)。
将解压后的arcgis_js_api文件夹放入网站所在文件夹。然后,需要修改arcgis_js_api\library\4.14\init.js和arcgis_js_api\library\4.14\dojo\dojo.js两个文件
打开init.js,搜索baseUrl:”https://[HOSTNAME_AND_PATH_TO_JSAPI]dojo”,将[HOSTNAME_AND_PATH_TO_JSAPI]内容替换为服务器路径,如:
网站地址为http://localhost/ArcHelloWorld/,则将[ ]中内容改为http://localhost/ArcHelloWorld/arcgis_js_api/library/4.14/。最终效果:baseUrl:”http://localhost/ArcHelloWorld/arcgis_js_api/library/4.14/dojo”。
对dojo.js文件做同样操作。
然后就可以引用本地部署的api了。引用代码如下:
<script src="http://localhost/ArcHelloWorld/arcgis_js_api/library/4.14/dojo/dojo.js"></script>
(等价于<script src="https://js.arcgis.com/4.14/"></script>)
注意,本地api的链接必须是http或https形式的(官方推荐https),所以必须部署在服务器上。
为了界面效果,还需要引用arcgis的css文件(<link rel="stylesheet" href="https://js.arcgis.com/4.14/esri/css/main.css">),可以将其下载到本地离线使用。
以下是官方文档提供的hello world代码(只截取了<script>部分):
<script> require([ "esri/Map", "esri/views/MapView" ], function(Map, MapView) { var map = new Map({ basemap: "topo-vector" }); var view = new MapView({ container: "viewDiv", map: map, center: [-118.71511,34.09042], zoom: 11 }); }); </script>使用到arcgis api的相关代码都是放在require(["esri/Map", "esri/views/MapView"], function(Map, MapView) {……}中的,require中填写需要引用的模块,并将模块名作为function的参数,程序逻辑写在function的函数体中。
以下是添加地图的代码 :
//require("esri/layers/MapImageLayer") var mylayer = new MapImageLayer({ url: "http://localhost:6080/arcgis/rest/services/测试地图/MapServer", }); Map.add(mylayer);url为之前在arcgis server上发布的地图服务的链接,“测试地图”即是服务的名称。MapImageLayer会将整张地图加载进去,包含地图内的所有图层(如下图,左侧是layerList微件)。
注:可以使用sublayers属性加载其中部分图层。
如果想要单独加载某个矢量图层,则需要使用FeatureLayer,使用方法类似。FeatureLayer的url可以从服务器中查看。例如想加载上图中的某个矢量图层,可以在浏览器中浏览http://localhost:6080/arcgis/rest/services/测试地图/MapServer,在网页中可以查看到图层列表,每个图层都对应一个编号。
“管理范围界桩位移点”的代码为0,则使用以下代码可以单独加载这个图层:
var myFeature = new FeatureLayer({ url: "http://localhost:6080/arcgis/rest/services/测试地图/MapServer/0", });单独加载某个图层的优势在于,可以单独对图层进行配置,包括颜色、线条等符号样式,点击事件,弹出窗口等。
建议对于需要交互的矢量数据以FeatureLayer单独加载,以进行配置和编辑;对于影像、路网等底图信息以MapImageLayer加载。
注意:
如果是需要提供编辑功能的图层,则需要从FeatureServer中加载。FeatureServer即地图发布时勾选的Feature access,这种图层才能开启编辑功能。加载这种图层的方法与上文相同,将url中的MapServer改为FeatureServer即可。
Arcgis提供了相当数量的微件,可以大幅简化开发。例如上文提到的layerList微件,它可以展示地图中的图层,并控制其开闭。此外还有导航控制条、画图工具条、搜索框、量测工具等常用功能。
具体的内容可以在https://developers.arcgis.com/javascript/latest/api-reference/中查看。
以下介绍了一些常用微件。
自动显示图层列表,以下是显示图例的例子。
var layerList = new LayerList({ view: view, listItemCreatedFunction: function (event) { const item = event.item; if (item.layer.type != "group") { // don't show legend twice item.panel = { content: "legend", open: false,//默认不展开 }; } } }); view.ui.add(layerList, "bottom-left");搜索框用于搜索地图中的要素,默认数据源是arcgis自带的地理编码服务器(没什么用,可以关掉),可以针对每个图层自定义搜索数据源和搜索规则。
var searchWidget = new Search({ view: view, locationEnabled:false,//使用本地位置,没什么用 includeDefaultSources:false, sources: [{ layer: Jihua2019Layer, searchFields: ["OBJECTID","Layer"], outFields: ["*"], displayField: "OBJECTID", exactMatch: false, suggestionsEnabled:true, suggestionTemplate: "{OBJECTID}, {Layer}", 、 // 注意:只有使用10.3的 地理编码服务,才能使用suggestions,而该服务必须具有suggest capability loaded或支持分页的10.3要素图层,i.e.supportsPagination = true。 name: "搜索2019年新城计划出让地块", placeholder: "ID或名称" }, { layer: CunliangLayer, searchFields: ["汇总标"], displayField: "汇总标", exactMatch: false, outFields: ["汇总标", "ID", "规划用"], name: "搜索新城存量用地", placeholder: "" }, { layer: roadLayer, searchFields: ["ID"], displayField: "ID", exactMatch: false, outFields: [ "ID"], name: "道路", placeholder: "" },] });可以对所有可编辑图层进行编辑,包括图形和其属性。可编辑图层需要来自FeatureServer。
var editor = new Editor({ view: view }); view.ui.add(editor, "top-right");可以把一个微件的ui收缩成一个小图标,使界面简洁,很有用。
//layerlist放进expand里 const llExpand = new Expand({ view: view, content: layerList, expanded: false }); view.ui.add(llExpand, "bottom-left");