Create Polygon Feature: Java Script

6145
20
Jump to solution
01-09-2020 11:27 PM
Vakhtang_Zubiashvili
Occasional Contributor III

Hi guys,

I am trying to use ArcGIS API for JavaScript Sandbox this sample to add polygon feature, i also use codes taking from here https://community.esri.com/thread/224031-how-to-create-a-polygon-js-api-49?commentID=811443&et=watch... from   Robert Scheitlin, GISP,   but can not combine this two sample to add polygon and update attributes. 

Thank you for your help

Here is a code samples i use (you can see them in links too):

// ***********************************************************
      // Call FeatureLayer.applyEdits() with specified params.
      // ***********************************************************
      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;
            //selectFeature(objectId);
          }
        })
// called when sketchViewModel's create-complete event is fired.
        function addGraphic(event) {
          // Create a new graphic and set its geometry to
          // `create-complete` event geometry.
          const graphic = new Graphic({
            geometry: event.geometry,
            symbol: sketchViewModel.graphic.symbol,
            attributes: {}
          });

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>Update FeatureLayer using applyEdits() - 4.14</title>
    <link
      rel="stylesheet"
    />
    <script src="https://js.arcgis.com/4.14/"></script>
    <style>
      html,
      body,
      #viewDiv {
        padding0;
        margin0;
        height100%;
        width100%;
      }
      #formDiv {
        width100%;
      }
      .esri-item-list__scroller {
        overflow-yvisible;
      }
      .editArea-container {
        background#fff;
        line-height1.5em;
        overflowauto;
        padding12px 15px;
        width300px;
      }
      .list-heading {
        font-weightnormal;
        margin-top20px;
        margin-bottom10px;
        color#323232;
      }
      .or-wrap {
        background-color#e0e0e0;
        height1px;
        margin2em 0;
        overflowvisible;
      }
      .or-text {
        background#fff;
        line-height0;
        padding0 1em;
        positionrelative;
        bottom0.75em;
      }
      /* override default styles */
      .esri-feature-form {
        background#fff;
      }
      .esri-feature-templates {
        width256px;
      }
      .esri-feature-templates__section-header {
        displaynone;
      }
      .esri-feature-templates__section {
        box-shadownone;
      }
      .esri-feature-templates__scroller {
        max-height200px;
      }
    </style>
    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/widgets/Sketch/SketchViewModel",
        "esri/layers/FeatureLayer",
        "esri/Graphic",
        "esri/layers/GraphicsLayer",
        "esri/widgets/Expand",
        "esri/widgets/FeatureForm",
        "esri/widgets/FeatureTemplates"
      ], function(
        Map,
        MapView,
        SketchViewModel,
        FeatureLayer,
        Graphic,
        GraphicsLayer,
        Expand,
        FeatureForm,
        FeatureTemplates
      ) {
        let editFeaturehighlight;
        const featureLayer = new FeatureLayer({
          url:
          title:"ქუჩების ფენა",
          outFields: ["*"],
          popupEnabled: false,
          id: "incidentsLayer"
        });     
        // GraphicsLayer to hold graphics created via sketch view model
      const graphicsLayer = new GraphicsLayer({
        id: "tempGraphics"
      });
        const map = new Map({
          basemap: "dark-gray",
          layers: [graphicsLayerfeatureLayer]
        });
        const view = new MapView({
          container: "viewDiv",
          map: map,
          center: [44.750241.725524],
          zoom: 12
        });
        //****************************-სიმბოლოები პოლიგონისთვის-***********************
        const pointSymbol = {
        type: "simple-marker"// autocasts as new SimpleMarkerSymbol()
        style: "square",
        color: "#8A2BE2",
        size: "16px",
        outline: { // autocasts as new SimpleLineSymbol()
          color: [255255255],
          width: 3
        }
      };
      const polylineSymbol = {
        type: "simple-line"// autocasts as new SimpleLineSymbol()
        color: "#8A2BE2",
        width: "4",
        style: "dash"
      };

      const polygonSymbol = {
        type: "simple-fill"// autocasts as new SimpleFillSymbol()
        color: "red",
        style: "solid",
        outline: {
          color: "red",
          width: 1
        }
      };
        // New FeatureForm and set its layer to 'Incidents' FeatureLayer.
        // FeatureForm displays attributes of fields specified in fieldConfig.
        const featureForm = new FeatureForm({
          container: "formDiv",
          layer: featureLayer,
          fieldConfig: [
            {
              name: "Req_Code",
              label: "REQ კოდი"
            },
            {
              name: "abonentebis_raodenoba",
              label: "აბონენტების რაოდენობა"
            }
          ]
        });
        // Listen to the feature form's submit event.
        // Update feature attributes shown in the form.
        featureForm.on("submit"function() {
          if (editFeature) {
            // Grab updated attributes from the form.
            const updated = featureForm.getValues();
           // Loop through updated attributes and assign
            // the updated values to feature attributes.
            Object.keys(updated).forEach(function(name) {
              editFeature.attributes[name] = updated[name];
            });
            // Setup the applyEdits parameter with updates.
            const edits = {
              updateFeatures: [editFeature]
            };
            applyEditsToIncidents(edits);
            document.getElementById("viewDiv").style.cursor = "auto";
          }
        });
        // Check if the user clicked on the existing feature
        selectExistingFeature();
        // The FeatureTemplates widget uses the 'addTemplatesDiv'
        // element to display feature templates from incidentsLayer
        const templates = new FeatureTemplates({
          container: "addTemplatesDiv",
          layers: [featureLayer]
        });
        // Listen for when a template item is selected
        templates.on("select"function(evtTemplate) {
          // Access the template item's attributes from the event's
          // template prototype.
          attributes = evtTemplate.template.prototype.attributes;
          unselectFeature();
          document.getElementById("viewDiv").style.cursor = "crosshair";
          // With the selected template item, listen for the view's click event and create feature
          const handler = view.on("click"function(event) {
            // remove click event handler once user clicks on the view
            // to create a new feature
            handler.remove();
            event.stopPropagation();
            featureForm.feature = null;
            if (event.mapPoint) {
              point = event.mapPoint.clone();
              point.z = undefined;
              point.hasZ = false;
              // Create a new feature using one of the selected
              // template items.
              editFeature = new Graphic({
                geometry: point,
                attributes: {
                  IncidentType: attributes.IncidentType
                }
              });
              // Setup the applyEdits parameter with adds.
              const edits = {
                addFeatures: [editFeature]
              };
              applyEditsToIncidents(edits);
              document.getElementById("viewDiv").style.cursor = "auto";
            } else {
              console.error("event.mapPoint is not defined");
            }
          });
        });
        // Call FeatureLayer.applyEdits() with specified params.
        function applyEditsToIncidents(params) {
          // unselectFeature();
          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 ||
                editsResult.updateFeatureResults.length > 0
              ) {
                unselectFeature();
                let objectId;
                if (editsResult.addFeatureResults.length > 0) {
                  objectId = editsResult.addFeatureResults[0].objectId;
                } else {
                  featureForm.feature = null;
                  objectId = editsResult.updateFeatureResults[0].objectId;
                }
                selectFeature(objectId);
                if (addFeatureDiv.style.display === "block") {
                  toggleEditingDivs("none""block");
                }
              }
              // show FeatureTemplates if user deleted a feature
              else if (editsResult.deleteFeatureResults.length > 0) {
                toggleEditingDivs("block""none");
              }
            })
            .catch(function(error) {
              console.log("===============================================");
              console.error(
                "[ applyEdits ] FAILURE: ",
                error.code,
                error.name,
                error.message
              );
              console.log("error = "error);
            });
        }
        // Check if a user clicked on an incident feature.
        function selectExistingFeature() {
          view.on("click"function(event) {
            // clear previous feature selection
            unselectFeature();
            if (
              document.getElementById("viewDiv").style.cursor != "crosshair"
            ) {
              view.hitTest(event).then(function(response) {
                // If a user clicks on an incident feature, select the feature.
                if (response.results.length === 0) {
                  toggleEditingDivs("block""none");
                } else if (
                  response.results[0].graphic &&
                  response.results[0].graphic.layer.id == "incidentsLayer"
                ) {
                  if (addFeatureDiv.style.display === "block") {
                    toggleEditingDivs("none""block");
                  }
                  selectFeature(
                    response.results[0].graphic.attributes[
                      featureLayer.objectIdField
                    ]
                  );
                }
              });
            }
          });
        }
        // Highlights the clicked feature and display
        // the feature form with the incident's attributes.
        function selectFeature(objectId) {
          // query feature from the server
          featureLayer
            .queryFeatures({
              objectIds: [objectId],
              outFields: ["*"],
              returnGeometry: true
            })
            .then(function(results) {
              if (results.features.length > 0) {
                editFeature = results.features[0];
                // display the attributes of selected feature in the form
                featureForm.feature = editFeature;
                // highlight the feature on the view
                view.whenLayerView(editFeature.layer).then(function(layerView) {
                  highlight = layerView.highlight(editFeature);
                });
              }
            });
        }
        // Expand widget for the editArea div.
        const editExpand = new Expand({
          expandIconClass: "esri-icon-edit",
          expandTooltip: "Expand Edit",
          expanded: true,
          view: view,
          content: document.getElementById("editArea")
        });
        view.ui.add(editExpand"top-right");
        // input boxes for the attribute editing
        const addFeatureDiv = document.getElementById("addFeatureDiv");
        const attributeEditing = document.getElementById("featureUpdateDiv");
        // Controls visibility of addFeature or attributeEditing divs
        function toggleEditingDivs(addDivattributesDiv) {
          addFeatureDiv.style.display = addDiv;
          attributeEditing.style.display = attributesDiv;
          document.getElementById(
            "updateInstructionDiv"
          ).style.display = addDiv;
        }
        // Remove the feature highlight and remove attributes
        // from the feature form.
        function unselectFeature() {
          if (highlight) {
            highlight.remove();
          }
        }
        // Update attributes of the selected feature.
        document.getElementById("btnUpdate").onclick = function() {
          // Fires feature form's submit event.
          featureForm.submit();
        };
        // Delete the selected feature. ApplyEdits is called
        // with the selected feature to be deleted.
        document.getElementById("btnDelete").onclick = function() {
          // setup the applyEdits parameter with deletes.
          const edits = {
            deleteFeatures: [editFeature]
          };
          applyEditsToIncidents(edits);
          document.getElementById("viewDiv").style.cursor = "auto";
        };
      });
    </script>
  </head>
<body>
    <div id="editArea" class="editArea-container esri-widget--panel">
      <div id="addFeatureDiv" style="display:block;">
        <h3 class="list-heading">Report Incidents</h3>
        <ul style="font-size: 13px; padding-left: 1.5em;">
          <li>აირჩიეთ ფენა ჩამოათვალიდან</li>
          <li>დააწკაპეთ რუკაზე რომ დაამატოთ ახალი ობიექტი</li>
          <li>დაკავშირებული მონაცემების ატვირთვა</li>
          <li>დააწკაპეთ <i>მონაცემების ატვირთვა</i></li>
        </ul>
        <div id="addTemplatesDiv" style="background:#fff;"></div>
      </div>
      <div id="featureUpdateDiv" style="display:none; margin-top: 1em;">
        <h3 class="list-heading">შეიყვანეთ ინციდენტის ინფორმაცია</h3>
        <div id="attributeArea">
          <div id="formDiv"></div>
          <input
            type="button"
            class="esri-button"
            value="მონაცემების ატვირთვა"
            id="btnUpdate"   />
        </div>
        <br />
        <div id="deleteArea">
          <input
            type="button"
            class="esri-button"
            value="წაშალეთ ინციდენტი"
            id="btnDelete" />
        </div>
      </div>
      <div id="updateInstructionDiv" style="text-align:center; display:block">
        <p class="or-wrap"><span class="or-text">ან</span></p>
        <p id="selectHeader">მონიშნეთ ინციდენტი რომ წაშალოთ ან შეცვალოთ.</p>
      </div>
    </div>
    <div id="viewDiv"></div>
  </body>
</html>
0 Kudos
20 Replies
KenBuja
MVP Esteemed Contributor

It doesn't look like the ViewSketchModel has a "graphic" property (line 29). It does have a "createGraphic" property.

Vakhtang_Zubiashvili
Occasional Contributor III

Hi Ken,

Can you please explain?

I have: 

var sketchVM = new SketchViewModel({
        view,
        layer: graphicsLayer,
        pointSymbol,
        polylineSymbol,
        polygonSymbol
      });      
      // Call create method to create a polygon with Click.
       sketchVM.create("polygon", {mode: "click"});
   // Create a new feature using one of the selected
        // template items.
        editFeature = new Graphic({
            geometry: event.geometry,
            symbol: sketchVM.graphic.symbol,
            attributes: {
            IncidentType: attributes.IncidentType
          }
        });

What i have to do more?

0 Kudos
Vakhtang_Zubiashvili
Occasional Contributor III

I am sorry guys, i disturbed you, but need help. Please notice that i am working In JavaScript 4.14 not in 4.9, all codes you wrote are works for 4.9 and works great, but not for 4.14; 

Need Help people

0 Kudos
KenBuja
MVP Esteemed Contributor

In Ver 4.10, the SketchViewModel had significant breaking changes, which is why your 4.9 code won't work anymore: Changes for SketchViewModel at 4.10 | ArcGIS API for JavaScript 4.14 

Vakhtang_Zubiashvili
Occasional Contributor III

I lost Robert Scheitlin, GISP‌, Ken Buja‌, i changed  - - - - "symbol: sketchViewModel.graphic.symbol"(JS version 4.9) to "symbol: sketchViewModel.crateGraphic.symbol" (JS version 4.14) and "view" to "view:view". now it does polygon sketch, but doesn't update featureLayer. It does not show any error in console, i do not understand

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>Update FeatureLayer using applyEdits() - 4.14</title>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.14/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.14/"></script>
    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }

      #formDiv {
        width: 100%;
      }

      .esri-item-list__scroller {
        overflow-y: visible;
      }

      .editArea-container {
        background: #fff;
        line-height: 1.5em;
        overflow: auto;
        padding: 12px 15px;
        width: 300px;
      }

      .list-heading {
        font-weight: normal;
        margin-top: 20px;
        margin-bottom: 10px;
        color: #323232;
      }

      .or-wrap {
        background-color: #e0e0e0;
        height: 1px;
        margin: 2em 0;
        overflow: visible;
      }

      .or-text {
        background: #fff;
        line-height: 0;
        padding: 0 1em;
        position: relative;
        bottom: 0.75em;
      }

      /* override default styles */
      .esri-feature-form {
        background: #fff;
      }

      .esri-feature-templates {
        width: 256px;
      }

      .esri-feature-templates__section-header {
        display: none;
      }

      .esri-feature-templates__section {
        box-shadow: none;
      }

      .esri-feature-templates__scroller {
        max-height: 200px;
      }
    </style>

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/FeatureLayer",
        "esri/Graphic",
        "esri/layers/GraphicsLayer",
        "esri/widgets/Expand",
        "esri/widgets/Sketch/SketchViewModel",
        "esri/widgets/FeatureForm",
        "esri/widgets/FeatureTemplates"
      ], function(
        Map,
        MapView,   
        FeatureLayer,
        Graphic,
        GraphicsLayer,
        Expand,
        SketchViewModel,
        FeatureForm,
        FeatureTemplates
      ) {
        let editFeature, highlight;






        const featureLayer = new FeatureLayer({
          url:
            "http://localhost:6080/arcgis/rest/services/test/Request_Area/FeatureServer/0",
          title:"ქუჩების ფენა",
          outFields: ["*"],
          popupEnabled: false,
          id: "incidentsLayer"
        });
       
        // GraphicsLayer to hold graphics created via sketch view model
      const graphicsLayer = new GraphicsLayer({
        id: "tempGraphics"
      });
       

        const map = new Map({
          basemap: "dark-gray",
          layers: [featureLayer, graphicsLayer, ]
        });

        const view = new MapView({
          container: "viewDiv",
          map: map,
          center: [44.7502, 41.725524],
          zoom: 12,
          highlightOptions: {
            color: "red"
          }
        });

        //****************************-სიმბოლოები პოლიგონისთვის-***********************
        const pointSymbol = {
        type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
        style: "square",
        color: "#8A2BE2",
        size: "16px",
        outline: { // autocasts as new SimpleLineSymbol()
          color: [255, 255, 255],
          width: 3
        }
      };

      const polylineSymbol = {
        type: "simple-line", // autocasts as new SimpleLineSymbol()
        color: "#8A2BE2",
        width: "4",
        style: "dash"
      };

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

        // New FeatureForm and set its layer to 'Incidents' FeatureLayer.
        // FeatureForm displays attributes of fields specified in fieldConfig.
        const featureForm = new FeatureForm({
          container: "formDiv",
          layer: featureLayer,
        });
          
       

        // Check if the user clicked on the existing feature
       
        // The FeatureTemplates widget uses the 'addTemplatesDiv'
        // element to display feature templates from incidentsLayer
        const templates = new FeatureTemplates({
          container: "addTemplatesDiv",
          layers: [featureLayer]
        });


        var attributes;
        // Listen for when a template item is selected
        templates.on("select", function(evtTemplate) {

          var sketchVM = new SketchViewModel({
            view: view,
            layer: graphicsLayer,
            pointSymbol,
            polylineSymbol,
            polygonSymbol
          });
                  
// Call create method to create a polygon with Click.
sketchVM.create("polygon", {mode: "click"});
sketchVM.on("create-complete", addGraphic);


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

          const edits = { 
            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);
          });
        }
  });

        // Expand widget for the editArea div.
        const editExpand = new Expand({
          expandIconClass: "esri-icon-edit",
          expandTooltip: "Expand Edit",
          expanded: true,
          view: view,
          content: document.getElementById("editArea")
        });

        view.ui.add(editExpand, "top-right");
        // input boxes for the attribute editing
        const addFeatureDiv = document.getElementById("addFeatureDiv");
        const attributeEditing = document.getElementById("featureUpdateDiv");
      });
    </script>
  </head>
  <body>
    <div id="editArea" class="editArea-container esri-widget--panel">
      <div id="addFeatureDiv" style="display:block;">
        <div id="addTemplatesDiv" style="background:#fff;"></div>
      </div>
      <div id="featureUpdateDiv" style="display:none; margin-top: 1em;">
        <h3 class="list-heading">შეიყვანეთ ინციდენტის ინფორმაცია</h3>
        <div id="attributeArea">
          <div id="formDiv"></div>
          <input
            type="button"
            class="esri-button"
            value="მონაცემების ატვირთვა"
            id="btnUpdate"
          />
        </div>
        <br />
        <div id="deleteArea">
          <input
            type="button"
            class="esri-button"
            value="წაშალეთ ინციდენტი"
            id="btnDelete"
          />
        </div>
      </div>
    </div>
    <div id="viewDiv"></div>
  </body>
</html>
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Vakhtang,

  You are adding a new feature that has no attributes. Does your layer have any required fields?

Values of non nullable fields must be provided when adding new features. Date fields must have numeric values representing universal time.

0 Kudos
Vakhtang_Zubiashvili
Occasional Contributor III

Robert,

No it does not have any required fields. It has numeric, string and Date fields. When using JS 4.9 i can add feature without attributes, does it imposible in version 4.14 ?

0 Kudos
Vakhtang_Zubiashvili
Occasional Contributor III

I have removed Date field. 

For attributes i added, but still nothing

                             

 var attributes:
//////Code here;

attributes = evtTemplate.template.prototype.attributes;
//////Code here
    geometry: event.geometry, 
symbol: sketchVM.creataGraphic.symbol,
attributes: attributes

 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Vakhtang,

  You will need to check your ArcGIS Server logs to see what is failing on the server end then.

Vakhtang_Zubiashvili
Occasional Contributor III

Thanks Robert, we will get latest version of ArcGIS Server soon and i will transfer all data an after that i will try again. 

Before that, i am trying to complete another task, i wanted to start working on that after "adding new polygon feature", but i try it before new ArcGIS Server. Take a look it please and help : https://community.esri.com/message/904126-updates-graphicsgraphicslayer-to-feature-layer-use-applyed... .

Thank you. 

0 Kudos