ArcGIS API For JavaScript 开发(五)要素图层的编辑

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.最后一个问题,目前还没有解决,就是在地图中选择点、线的时候不太容易选中,面不用说了很好选,但是我在测试的时候发现线和点真的很难选中,没选中还会报错(这个可以优化掉);现在的想法就是选的时候难道需要添加一点范围?不过这样可能会选中多个,先试试吧,成功的话我再更新一下。

原文地址:https://www.cnblogs.com/CreateFree/p/8705848.html