2018-4-3
这篇博客主要讲述要素的层的编辑功能,是基于FeatureLayer的applyEdit方法。由于自己目前正在学习当中,有许多不足之处请各位指出,欢迎指导学习!
主要功能是
1.将地图中的图层遍历出来放置在可编辑图层列;
2.点击对应图层可对其进行增加、修改、删除的操作;
3.增加功能具备图形添加、属性添加;
4.修改功能具备自动读取图形属性,自动生成属性字段结构、判断是否修改以及修改属性;
5.删除功能是将图形的所有信息删除;
代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="FeatureTest.aspx.cs" Inherits="GIS_FeatureTest" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.20/3.20/dijit/themes/tundra/tundra.css" /> <script type="text/javascript" src="http://localhost/arcgis_js_api/library/3.20/3.20/init.js"></script> <link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.20/3.20/esri/css/esri.css" /> <style> html, body { height: 100%; 100%; margin: 0; padding: 0; overflow:hidden; } #header { border:solid 2px #462d44; background:#fff; color:#444; -moz-border-radius: 4px; border-radius: 4px; font-family: sans-serif; font-size: 1.1em padding-left:20px; } #map { padding:1px; border:solid 2px #444; -moz-border-radius: 4px; border-radius: 4px; } #rightPane { border:none; padding: 0; 228px; } #leftPane { border:none; padding: 0; 228px; } .templatePicker { border: solid 2px #444; } </style> <script> var map; var drawToolbar; var buildslayer; var drawlayer, polylineAtt, features; var symbol, felayers = []; var landusePolygonLayer; require([ "esri/map", "esri/toolbars/draw", "esri/toolbars/edit", "esri/graphic", "esri/config", "esri/layers/FeatureLayer", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/dijit/InfoWindow", "esri/dijit/editing/TemplatePicker", "dojo/_base/Color", "dojo/_base/array", "dojo/_base/event", "dojo/_base/lang", "dojo/parser", "dijit/registry", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/form/Button", "dojo/domReady!" ], function ( Map, Draw, Edit, Graphic, esriConfig, FeatureLayer, ArcGISDynamicMapServiceLayer, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, InfoWindow, TemplatePicker, Color, arrayUtils, event, lang, parser, registry ) { parser.parse(); //esriConfig.defaults.io.proxyUrl = "/proxy/"; esriConfig.defaults.io.proxyUrl = "http://localhost/Donet/proxy.ashx"; esriConfig.defaults.io.alwaysUseProxy = false; esriConfig.defaults.geometryService = new esri.tasks.GeometryService("http://localhost:6080/arcgis/rest/services/Utilities/Geometry/GeometryServe"); var dynamicMapLayer1 = new ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/V2/BaseMap/MapServer"); map = new Map("map", { // basemap: "streets", // center: [-83.244, 42.581], zoom: 15 }); //符号可自己判断是否需要 symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLD, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLD, new Color([255, 0, 0])), new Color([0, 222, 100, 0.2])) map.addLayer(dynamicMapLayer1); //添加基础底图加载完成事件 dojo.connect(dynamicMapLayer1, "onLoad", function (layers) { //将图层遍历出来加在列表中——有个问题是图层的顺序怎么改,最主要是面图层会相互覆盖,和面覆盖线、点层? for (var i = 0; i < layers.layerInfos.length-1; i++) { var infos = layers.layerInfos; var name = infos[i].name; var id = infos[i].id; var indiv = document.createElement("div"); indiv.innerHTML = "<p><input type=button id="+name+" value="+name+" onclick=Edit("+id+") /></p>"; document.getElementById("layers").appendChild(indiv); //将要素地图服务加载进来,这里是将所有的要素图层都添加进来了,可以进行编辑处理 var url = landusePolygonLayer.url + "/" + id + ""; felayers[i] = new FeatureLayer(url, { mode: FeatureLayer.MODE_SNAPSHOT, outFields: ["*"] }); map.addLayer(felayers[i]); } }); //实例化一个绘图工具 drawToolbar = new esri.toolbars.Draw(map); //绘制完成事件 drawToolbar.on("draw-end", function (evt) { drawToolbar.deactivate(); features = evt; var content=""; for (item in polylineAtt) { content = content + "<p>" + item + ":<input type=txt id=d" + item + "></p>"; } content = content+"<input type=button id =newok onclick=create(features) value=添加 />"; map.infoWindow.setTitle("新建"); map.infoWindow.setContent(content); map.infoWindow.show(); }); }); var maphandler; function Edit(id) { //打开一个对话窗口,标题:编辑;内容包含三个操作按钮:新建、修改、删除 map.infoWindow.setTitle("编辑"); map.infoWindow.setContent("<p>选择你想要进行的操作!</p> <input type=button id =newcreate onclick=createnew(" + id + ") value=新建 /> <input type=button id =geoupdate onclick=updategeo(" + id + ") value=修改 /> <input type=button id =geodelete onclick=deletegeo(" + id + ") value=删除 />"); //要编辑的要素图层 drawlayer = felayers[id]; //要素的属性结构——这里应该改为自动的 polylineAtt = {}; for (var i = 0 ; i < felayers[id].fields.length; i++) { var item = felayers[id].fields[i].alias; polylineAtt[item] = ""; } map.infoWindow.show(); } var newattributes = []; function createnew(id) { drawToolbar.deactivate(); map.infoWindow.hide(); var geometryType = drawlayer.geometryType; //drawToolbar = new esri.toolbars.Draw(map); //选择绘制要素,并开始绘制 switch (geometryType) { case "esriGeometryPoint": drawToolbar.activate(esri.toolbars.Draw.POINT); break; case "esriGeometryPolyline": drawToolbar.activate(esri.toolbars.Draw.POLYLINE); break; case "esriGeometryPolygon": drawToolbar.activate(esri.toolbars.Draw.POLYGON); break; } } function create(features) { for (item in polylineAtt) { polylineAtt[item] = document.getElementById("d" + item).value; } map.infoWindow.hide(); map.graphics.add(features); //if(polylineAtt.name == "" ) //var newAttributes = langv.mixin({}, drawlayer.templates[0].prototype.attributes); delete polylineAtt["OBJECTID"]; delete polylineAtt["RoofType"]; var newGraphic = new esri.Graphic(features.geometry, null, polylineAtt); map.graphics.add(features); drawlayer.applyEdits([newGraphic], null, null,callback); } function callback(result) { if (result[0].success == true) { alert("添加成功!"); } else { alert("添加失败!"); } } function updategeo(id) {
if(handler){
handler.remove();
} map.infoWindow.setTitle("修改"); map.infoWindow.setContent("请点击要编辑的目标要素"); map.infoWindow.show(); handler=map.on("click", function (evt) { var content = ""; features = evt; for (item in polylineAtt) { content = content + "<p>" + item + ":<input type=txt id=d" + item + " value=" + evt.graphic.attributes[item] + "></p>"; } content = content + "<input type=button id =newok onclick=updatefe(features) value=修改 />"; map.infoWindow.setContent(content); map.infoWindow.show(); }); } function updatefe(features) { var isUpdate = false; delete polylineAtt["RoofType"]; for (item in polylineAtt) { var getvalue =document.getElementById("d" + item).value; var setvalue = features.graphic.attributes[item]; if (getvalue == setvalue) { polylineAtt[item] = setvalue; } else { polylineAtt[item] = getvalue; isUpdate = true; } } if (isUpdate) { var newGraphic = new esri.Graphic(features.geometry, null, polylineAtt); drawlayer.applyEdits(null, [newGraphic], null, function () { alert("修改成功!"); }); } else { alert("没有修改!"); } map.infoWindow.hide(); } function deletegeo(id) {
if(handler){
handler.remove();
}
map.infoWindow.setTitle("删除"); map.infoWindow.setContent("请点击要删除的目标要素"); map.infoWindow.show(); handler=map.on("click", function (evt) { polylineAtt["OBJECTID"] = evt.graphic.attributes["OBJECTID"]; var newGraphic = new esri.Graphic(evt.geometry, null, polylineAtt); drawlayer.applyEdits(null, null, [newGraphic], function () { alert("删除成功!"); }); }); } </script> </head> <body class="claro"> <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="gutters:true, design:'headline'" style=" 100%; height: 100%;"> <div data-dojo-type="dijit/layout/ContentPane" id="header" data-dojo-props="region:'top'"> Use ctrl or cmd + click on graphic to delete. Double click on graphic to edit vertices. </div> <div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div> <div id="leftPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'right'"> <div id="templatePickerDiv"> </div> <div id="layers"> </div> </div> </div> </body> </html>
其中遇到的问题有
1.在使用循环为控件input 指定onclick事件的时候参数值用 i 是传递不过去的,导致每个input的onclick事件的参数都是最后一个 i 值;而使用拼写的方式是可以将参数传递过去,很是奇怪,可能是我没有找到对应的方法吧;
2.注意的是ArcGIS api 开发中对图层的编辑一定是要使用对应的FeatureLayer图层,否则编译成功、运行也不会报错,但是编辑是无效的;
3.JSON对象添加、删除、修改和遍历;对JavaScript其实只是掌握其皮毛,还要深入学习才行;添加方式 testjson.param = " "; 或者 testjson[param]=" ";我使用的是第二种方式;删除: delete testjson[param]; 修改和添加类似,其实编译器会自动帮我们判断是添加还是修改,有就修改,没有就添加。 遍历是使用的 for - in 方式; for( item in testjson ) { testjson[item]=....; }
4.使用applyEdit进行修改和删除的时候发现其成功回调函数的参数值是空的,所以不能像添加一样对其回调参数进行判断,对了添加的回调参数中有个success值可以用其判断是否成功,当然成功回调函数本就是代表成功,但是回调参数我们还是可以了解其中的内容的,说不定什么时候会有用的不是?
5.最后一个问题,目前还没有解决,就是在地图中选择点、线的时候不太容易选中,面不用说了很好选,但是我在测试的时候发现线和点真的很难选中,没选中还会报错(这个可以优化掉);现在的想法就是选的时候难道需要添加一点范围?不过这样可能会选中多个,先试试吧,成功的话我再更新一下。