Updates Graphics(graphicsLayer) to Feature Layer use ApplyEdits

3184
11
Jump to solution
01-24-2020 05:57 AM
Vakhtang_Zubiashvili
Occasional Contributor III

Hi all,

Robert Scheitlin, GISP‌, Ken Buja

I have web map with editable featureLayer. After click on my feature i get atrributes (using hitTest), and after click button "Query" query result displays as graphicsLayer and after another click graphic adds to graphicLayer. Idea of doing that is to merge several features in to one feature and update featreLayer after click on button.

Now after click button "Update" i want to update graphicLayer features in my featureLayer, but it does not update.

I paste full code to show how it  is done:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>GWP - მილი და სამისამართო ერთეული</title>

  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    } 
  </style>
<link rel="stylesheet" href="https://js.arcgis.com/4.14/esri/css/main.css">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://js.arcgis.com/4.14"></script>
  <script>
    require([
    "esri/Map",
        "esri/widgets/ScaleBar",
        "esri/widgets/Home",
        "esri/widgets/Compass",
        "esri/widgets/BasemapToggle",
        "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleFillSymbol",
        "esri/symbols/SimpleLineSymbol",
        "esri/renderers/UniqueValueRenderer",
        "esri/tasks/QueryTask",
        "esri/tasks/support/Query",
        "esri/widgets/BasemapToggle",
        "esri/widgets/DistanceMeasurement2D",
        "esri/widgets/AreaMeasurement2D",
        "esri/widgets/ScaleBar",
        "esri/widgets/Home",
        "esri/widgets/Compass",
        "esri/views/MapView",
        "esri/widgets/Legend",
        "esri/widgets/Expand",
        "esri/layers/GroupLayer",
        "esri/layers/MapImageLayer",
        "esri/widgets/LayerList",
        "esri/layers/FeatureLayer",
        "esri/layers/GraphicsLayer",
        "esri/widgets/Expand",
        "esri/widgets/Sketch/SketchViewModel",
        "esri/widgets/FeatureForm",
        "esri/widgets/FeatureTemplates",
        "esri/geometry/geometryEngine",
        "esri/Graphic",
        "dojo/on",
        "dojo/dom",
        "dojo/dom-construct",
        "dojo/domReady!"
    ], function(
      Map, ScaleBar, Home, Compass, BasemapToggle, SimpleMarkerSymbol, SimpleFillSymbol, SimpleLineSymbol, UniqueValueRenderer, QueryTask, Query, BasemapToggle, DistanceMeasurement2D,
        AreaMeasurement2D, ScaleBar, Home, Compass, MapView,Legend, Expand, GroupLayer, MapImageLayer,
        LayerList,
        FeatureLayer,
        GraphicsLayer,
        Expand,
        SketchViewModel,
        FeatureForm,
        FeatureTemplates,
        geometryEngine,
        Graphic,
        on, dom, domConstruct
    ) {
      let editFeature, highlight;

      var fLpolygonSymbol = {
        type: "simple-fill", // autocasts as new SimpleFillSymbol()
        color: "yellow",
        style: "solid",
        outline: {
          color: "red",
          width: 1
        }
      };

      const featureLayer = new FeatureLayer({
          url:
            "http://localhost:6080/arcgis/rest/services/test/Request_Area/FeatureServer/0",
          title:"",
          outFields: ["*"],
          popupEnabled: false,
          id: "incidentsLayer",   
          listMode: "hide",
          legendEnabled: false
        });
        // GraphicsLayer to hold graphics created via sketch view model
      const graphicsLayer = new GraphicsLayer({
        id: "tempGraphics",
        listMode: "hide"
          });
    const labelClass = {
          // autocasts as new LabelClass()
          symbol: {
            type: "text", // autocasts as new TextSymbol()
            color: "black",
            haloColor: "black",
            font: {
              // autocast as new Font()
              family: "sans-serif",
              size: 8,
              weight: "bold"
            }
          },
          labelPlacement: "center-along",
          labelExpressionInfo: {
          expression: "$feature.g_dasaxeleba_ka"
  }
      };

      var renderer = {
        type: "simple", // autocasts as new SimpleRenderer()
             symbol: {
                 type: "simple-fill", // autocasts as new SimpleFillSymbol()
                 style: "none",
              outline: {
      // makes the outlines of all features consistently light gray
      color: "grey",
      width: 0.5
     }
   }
 };
 layer2popup =  {
      title: "ქუჩა",
      content: [{
         type: "fields",
         fieldInfos: [{
           fieldName: "g_dasaxeleba_ka",
            label: "ქუჩის დასახელება",
           visible: true
         },{
          fieldName: "SE_ID_new",
            label: "SE ID new",
           visible: true
         },
         {
          fieldName: "zd_donis_ID",
            label: "ზედა ზონის ID",
           visible: true
         }]
     }]  
    }


      var layer2 = new FeatureLayer({
        url: "http://localhost:6080/arcgis/rest/services/test/Tbilisi_wyalmomarageba_vaxo/MapServer/15",
        title: "სამისამართო ერთეული",
        popupTemplate: layer2popup,
        popupEnabled: false,
        outFields: ["*"],
        labelingInfo: [labelClass],
        renderer: renderer
      });
       //saZiebo sistema
        var HWUrl =       "http://10.0.251.179:6080/arcgis/rest/services/test/Tbilisi_wyalmomarageba_vaxo/MapServer/15";
        // magistraluri arxi
        var HWLayer = new FeatureLayer({
          url: HWUrl,
          outFields: ["*"],
          visible: false
        });
           /*
        // GraphicsLayer for displaying results
        var resultsLayer = new GraphicsLayer({
          title: "ძიების რეზულტატი"   
        });
     */
      var map = new Map({
        basemap: "osm",
        layers: [layer2, featureLayer, graphicsLayer]
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        center: [44.7502, 41.725524],
          zoom: 12,
          highlightOptions: {
            color: "red"
          } 
      });
       // Double-Click-ზე Zoom შეჩერება
      view.on("double-click", function(evt) {
      evt.stopPropagation();
      console.info(evt);
      });
       // Add a basemap toggle widget to toggle between basemaps
       var toggle = new BasemapToggle({
            titleVisible: true,
            view: view,
            nextBasemap: "satellite"
          });
        // Toggle რუკისთვის
        view.ui.add(toggle, "top-left");
  // Click-ზე graphicsLayer შექმნა და მისი რუკაზე დამატება

        view.on("click", function (event) {
               // Search for graphics at the clicked location. View events can be used
                // as screen locations as they expose an x,y coordinate that conforms
               // to the ScreenPoint definition.
               view.hitTest(event).then(function (response) {
                 if (response.results.length) {
                 var graphic = response.results.filter(function (result) {
                    // check if the graphic belongs to the layer of interest
                         return result.graphic.layer === layer2;
                        })[0].graphic;

                var attributes = graphic.attributes;
                var name = attributes.g_dasaxeleba_ka;
                var SE_ID = attributes.SE_ID_new;
              }
          var queryZebna = dom.byId("query-Zebna");
          on(queryZebna, "click", function() {
            queryMagistraluri()
            .then(displayResults);
        });  
        function queryMagistraluri() {
        var query = HWLayer.createQuery();
         //query.returnGeometry = true;
         //query.outFields = ["*"]; 
         query.where = "g_dasaxeleba_ka LIKE N'%"+ name +"%'";
         query.outSpatialReference = view.spatialReference;                                                         
         return HWLayer.queryFeatures(query)
      }
        // display the query results in the view     
        function displayResults(results) {        
          console.log(results); 
          var pfeatures = results.features.map(function(graphica) {
            graphica.symbol = {
              type: "simple-fill",  // autocasts as new SimpleFillSymbol()
                 color: "orange",
                    style: "solid",
                    outline: {  // autocasts as new SimpleLineSymbol()
                    color: "black",
                       width: 1
                              }                      
            };        
            return graphica  
          });
          graphicsLayer.addMany(pfeatures);
          view.goTo(pfeatures)
        }   
      });
    });
        const btnupdate = dom.byId("button-update");
        on(btnupdate, "click", function () {
         
          // Create a new graphic and set its geometry to
          function addGraphic(event) {
          // Create a new graphic and set its geometry to
          // `create-complete` event geometry.
          const graphic = new Graphic({
            geometry: polygon,
            symbol: graphica.symbol,
            attributes: {}
          });
          graphicsLayer.add(graphic);

               const edits = { //Fire the addFeatures function using the completed graphic
              addFeatures: [graphic]
              };
              applyEdits(edits);
              console.log(graphic);
              
        };
        function applyEdits(params) {
          featureLayer.applyEdits(params).then(function(editsResult) {
            // Get the objectId of the newly added feature.
            // Call selectFeature function to highlight the new feature.
            if (editsResult.addFeatureResults.length > 0) {
              const objectId = editsResult.addFeatureResults[0].objectId;
            }
          })
          .catch(function(error) {
            console.log("===============================================");
            console.error("[ applyEdits ] FAILURE: ", error.code, error.name,
              error.message);
            console.log("error = ", error);
           });
          }
        })
 });
</script>
</head>
<body>
  <button id="query-Zebna">ძებნა</button>
  <button id="button-update">Update</button>
  <div id="viewDiv"></div>
  
</div>
 
</body>
</html>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Vakhtang,

   You are attempting to add a GraphicsLayer as the addFeatures property of the applyEdits method and that is the issue. The applyEdits addFeatures property is expecting and array of graphics.

          const edits = { //Fire the addFeatures function using the completed graphic
              addFeatures: pfeatures
          };

View solution in original post

11 Replies
RobertScheitlin__GISP
MVP Emeritus

Vakhtang,

   This portion of your code make no sense. You have a button click event function whose contents is just two other functions... But nothing calls addGraphic.

      const btnupdate = dom.byId("button-update");
      on(btnupdate, "click", function () {

        // Create a new graphic and set its geometry to
        function addGraphic(event) {
          // Create a new graphic and set its geometry to
          // `create-complete` event geometry.
          const graphic = new Graphic({
            geometry: polygon,
            symbol: graphica.symbol,
            attributes: {}
          });
          graphicsLayer.add(graphic);

          const edits = { //Fire the addFeatures function using the completed graphic
            addFeatures: [graphic]
          };
          applyEdits(edits);
          console.log(graphic);

        };

        function applyEdits(params) {
          featureLayer.applyEdits(params).then(function (editsResult) {
              // Get the objectId of the newly added feature.
              // Call selectFeature function to highlight the new feature.
              if (editsResult.addFeatureResults.length > 0) {
                const objectId = editsResult.addFeatureResults[0].objectId;
              }
            })
            .catch(function (error) {
              console.log("===============================================");
              console.error("[ applyEdits ] FAILURE: ", error.code, error.name,
                error.message);
              console.log("error = ", error);
            });
        }
      });
Vakhtang_Zubiashvili
Occasional Contributor III

Robert,

I see

I changed my code, now it applies empty attributes without geometry. 

Also if i do not mistake i already have defined  graphic here (see row 24), can i use it for update graphics layer? if so, how? 

If no: How can i call "create-complete" for addGraphic? From this Query?  "var query = HWLayer.createQuery();" tell me how please.

P.S. Sorry for my bad skills, i study JavaScript myself and sometimes it is hard to connect some portion of code to next part. Thank you for your help, i really appreciate.

view.on("click", function (event) {  
        view.hitTest(event).then(function (response) {
                 if (response.results.length) {
                 var graphic = response.results.filter(function (result) {
                    // check if the graphic belongs to the layer of interest
                         return result.graphic.layer === layer2;
                        })[0].graphic;
                var attributes = graphic.attributes;
                var name = attributes.Req_Code; }
          var queryZebna = dom.byId("query-Zebna");
          on(queryZebna, "click", function() {
            queryMagistraluri()
            .then(displayResults);});  
        function queryMagistraluri() {
        var query = HWLayer.createQuery();
         //query.returnGeometry = true;
         //query.outFields = ["*"]; 
         query.where = "Req_Code IS NULL";
         query.outSpatialReference = view.spatialReference;                                                         
         return HWLayer.queryFeatures(query)}
        // display the query results in the view     
        function displayResults(results) {        
          console.log(results); 
          var pfeatures = results.features.map(function(graphica) {  
            graphica.symbol = {
              type: "simple-fill",  // autocasts as new SimpleFillSymbol()
                 color: "cyan",
                    style: "solid",
                    outline: {  // autocasts as new SimpleLineSymbol()
                    color: "black",
                       width: 1
                              },                             
            };        
            return graphica  
          });
          graphicsLayer.addMany(pfeatures);  
          console.log(graphicsLayer)
          // Apply Edits აქ მუშაობს, მაგრამ მხოლოდ ამატებს ატრიბუტებს.
          const edits = { //Fire the addFeatures function using the completed graphic
              addFeatures: [graphicsLayer]
              };
              applyEdits(edits);
              console.log(graphic);
          view.goTo(pfeatures)
        }
          })
        })
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Vakhtang,

   You are attempting to add a GraphicsLayer as the addFeatures property of the applyEdits method and that is the issue. The applyEdits addFeatures property is expecting and array of graphics.

          const edits = { //Fire the addFeatures function using the completed graphic
              addFeatures: pfeatures
          };
Vakhtang_Zubiashvili
Occasional Contributor III

Robert, 

Thank you very much for help. 

I do not kmow if i have to open new question. but i ask here and if needed i will open new question. 

When adding new features from one to another layer using this code, one field has same name and it values adds automaticaly from source layer (Layer2) to target layer (featureLayer). So i tried to add attributes with same name to graphics (pfeatures) as it has target layer (featureLayer)(e.g.  field name "Req_Code") and add value e.g. "REQ-123", but it does not applies. in console.log it returns -, Req_Code: REQ-123".

Code: 

pfeatures = results.features.map(function(graphica) {  
            graphica.symbol = {
              type: "simple-fill",  // autocasts as new SimpleFillSymbol()
                 color: "cyan",
                    style: "solid",
                    outline: {  // autocasts as new SimpleLineSymbol()
                    color: "black",
                       width: 1
                              },                             
            };        
           
pfeatures.attributes{
Req_Code:"REQ-123"
}
console.log(pfeatures)
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Vakhtang,

  pFeatures is an Array of graphics you can not set an attribute on the whole array that way. You need to apply the attribute to one graphic.

Vakhtang_Zubiashvili
Occasional Contributor III

Robert, 

I tryied to merge graphics using geometryEngine.union, but had no result. How can i merge (dissolve, union) pfeatures array in one graphic?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

When using GeometryEngine.union make sure you are passing the geometries to it and not the graphics

0 Kudos
Vakhtang_Zubiashvili
Occasional Contributor III

Oops, you guessed right, i passed graphics. that is why i got "null" in

log.

Can you please explain how can i pass geometry or point me Sample or

something like that?

On Tue, Jan 28, 2020, 11:54 PM Robert Scheitlin, GISP <geonet@esri.com>

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Each Graphic has a geometry property.

0 Kudos