Buffer results

8798
14
Jump to solution
02-04-2015 01:15 PM
MayJeff
Occasional Contributor

Just notice some issues on JSFiddle Edit fiddle - JSFiddle .  When I input this Parcel ID: 1931376038, and run 100 feet buffer. It shows more parcels outside the buffer ring. If I enter this parcel ID 193137602, and add this code like params.unionResults =true in order to combine buffer ring but still shows each single buffer rings.  How do you only show all parcels inside buffer ring and if search results are more than one, but only want to show one buffer ring instead of individual buffer ring around each parcels.  Thank you.

bufferRing.gifbufferRing1.gif

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

May Jeff,

  No errors. I also fixed several other things I saw in the code and updated to 3.13 API to use some of the great new stuff like geometryEngineAsync.  Here is my updates:

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <!--The viewport meta tag is used to improve the presentation and behavior of the samples
  on iOS devices-->
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Buffer</title>

  <link rel="stylesheet" href="http://js.arcgis.com/3.13/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.13/esri/css/esri.css">
  <style>
    html,
    body {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
    }
    
    #leftPane {
      color: #000;
      width: 250px;
      padding-bottom: 15px;
    }
    
    #map {
      padding: 0;
    }
    
    .details {
      font-size: 14px;
      font-weight: 600;
      padding-bottom: 20px;
    }
    
    button {
      margin: 2px;
      cursor: pointer;
    }
  </style>

  <script src="http://js.arcgis.com/3.13/"></script>
  <script>
    require([
          "esri/map",
          "esri/config",
          "esri/layers/FeatureLayer",
          "esri/tasks/query",
          "esri/symbols/SimpleLineSymbol",
          "esri/symbols/SimpleFillSymbol",
          "esri/graphic",
          "esri/graphicsUtils",
          "esri/geometry/geometryEngineAsync",
          "esri/tasks/GeometryService",
          "esri/Color",
          "dojo/on",
          "dojo/dom",
          "dijit/registry",
          "dojo/_base/array",
          "dojox/grid/DataGrid",
          "dojo/data/ItemFileReadStore",
          "dijit/form/Button",
          "dojo/parser",
          "dijit/layout/BorderContainer",
          "dijit/layout/ContentPane",
          "dojo/domReady!"
    ], function (
      Map, esriConfig, FeatureLayer, Query, SimpleLineSymbol, SimpleFillSymbol,
      Graphic, graphicsUtils, geometryEngineAsync, GeometryService,
      Color, on, dom, registry, arrayUtils, DataGrid, ItemFileReadStore, Button, parser) {
      var map, center, zoom;
      var grid, store;
      var graphic;
      var bufferGra;

      parser.parse();

      esriConfig.defaults.io.proxyUrl = "/Proxy/proxy.ashx";
      esriConfig.defaults.io.alwaysUseProxy = false;

      registry.byId("applyBufferP").on("click", applyBufferP);
      registry.byId("clearParcelGrid").on("click", clearParcelGrid);
      registry.byId("parcelSearch").on("click", queryParcels);
      registry.byId("intersectBuffer").on("click", intersectParcels);

      center = [-83.266, 42.568];
      zoom = 11;
      map = new esri.Map("map", {
        basemap: "streets",
        center: center,
        zoom: zoom
      });

      var parcelUrl = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/TaxParcelQuery/MapServer/0";
      var featureLayerParcel = new FeatureLayer(parcelUrl, {
        mode: FeatureLayer.MODE_SELECTION,
        visible: true,
        outFields: ["PARCELID", "SITEADDRESS", "OWNERNME1", "OWNERNME2", "RESYRBLT"]
      });
      var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_NULL, new SimpleLineSymbol(SimpleFillSymbol.STYLE_SOLID, new Color([100, 100, 100]), 2), new Color([0, 0, 255, 0.20]));
      featureLayerParcel.setSelectionSymbol(symbol);
      map.addLayer(featureLayerParcel);

      function queryParcels() {
        var queryParcels = new Query();
        queryParcels.where = "PARCELID LIKE '" + "%" + dom.byId("parcelText").value + "'";
        featureLayerParcel.selectFeatures(queryParcels, FeatureLayer.SELECTION_NEW, function (features, selectionMethod) {
          if (features.length > 0) {
            var parcelItems = dojo.map(features, function (feature) {
              return feature.attributes;
            });
            var parcelData = {
              identifier: "PARCELID",
              items: parcelItems
            };
            var parcelStore = new ItemFileReadStore({
              data: parcelData
            });
            var parcelGrid = registry.byId("gridP");
            parcelGrid.on("rowclick", onRowClickHandler);
            parcelGrid.setStore(parcelStore);
            map.setExtent(graphicsUtils.graphicsExtent(featureLayerParcel.getSelectedFeatures()), true);
          } else {
            alert("No Parcels found!");
          }
        });
      }

      function intersectParcels() {
        geometryEngineAsync.union(bufferGra).then(
          function (union) {
            var queryNew = new Query();
            queryNew.outFields = ["PARCELID", "SITEADDRESS", "OWNERNME1", "OWNERNME2", "RESYRBLT"];
            queryNew.spatialRelationship = Query.SPATIAL_REL_INTERSECTS;
            queryNew.geometry = union;
            queryNew.returnGeometry = true;
            featureLayerParcel.selectFeatures(queryNew, FeatureLayer.SELECTION_ADD, function (features, selectionMethod) {
              var items = dojo.map(features, function (feature) {
                return feature.attributes;
              });
              var data = {
                identifier: "PARCELID",
                items: items
              };
              var store = new ItemFileReadStore({
                data: data
              });
              var grid = registry.byId("parcelGrid");
              grid.on("rowclick", onRowClickHandler);
              grid.setStore(store);

              arrayUtils.forEach(features, function (feature) {
                graphic = new Graphic(feature.geometry, symbol);
                map.graphics.add(graphic);
              });
            });
          }
        );
        dijit.byId("dialogOne").show();
      }

      function applyBufferP() {
        var graphics = featureLayerParcel.graphics;
        var selectedGeoms = graphicsUtils.getGeometries(graphics);
        var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
            new Color([0, 0, 255, 0.65]), 2
          ),
          new Color([0, 0, 255, 0.35])
        );
        geometryEngineAsync.buffer(selectedGeoms, [100], GeometryService.UNIT_FOOT, true).then(
          function (geoms) {
            arrayUtils.forEach(geoms, function (geometry) {
              map.graphics.add(new Graphic(geometry, symbol));
            });
            bufferGra = geoms;
          }
        );
      }

      function onRowClickHandler(evt) {
        var clickedObjectf = evt.grid.getItem(evt.rowIndex).PARCELID;
        var selectedObjectf;
        var distance = 50;

        dojo.forEach(featureLayerParcel.graphics, function (graphicf) {
          if ((graphicf.attributes) && graphicf.attributes.PARCELID === clickedObjectf) {
            selectedObjectf = graphicf;
            return;
          }
        });

        if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Point') {
          var PointExtent = new esri.geometry.Extent({
            "xmin": selectedObjectf.geometry.x - distance,
            "ymin": selectedObjectf.geometry.y - distance,
            "xmax": selectedObjectf.geometry.x + distance,
            "ymax": selectedObjectf.geometry.y + distance,
            "spatialReference": {
              "wkid": 102100
            }
          });
          map.setExtent(PointExtent);
        } else if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Polygon') {
          var selectedParcel = selectedObjectf.geometry.getExtent();
          map.setExtent(selectedParcel.expand(3));
        } else if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Polyline') {
          var selectedStreetl = selectedObjectf.geometry.getExtent();
          map.setExtent(selectedStreetl.expand(3));
        }
      }

      function clearParcelGrid() {
        var newStore = new ItemFileReadStore({
          data: {
            idenitifer: "",
            items: []
          }
        });
        var grid = registry.byId("gridP");
        grid.setStore(newStore);
        document.getElementById('parcelText').value = '';
        featureLayerParcel.clearSelection();
        map.graphics.clear();
      }
    });
  </script>

  <body class="claro">
    <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'" style="width:100%;height:100%;margin:0;">
      <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'" style="height:200px;" title="Search">
        Search by Parcel #:
        <input type="text" id="parcelText" value="1931376029" />
        <br>
        <button id="parcelSearch" data-dojo-type="dijit/form/Button" type="button" data-dojo-attach-point="button">Search</button>
        <button id="clearParcelGrid" data-dojo-type="dijit/form/Button" type="button" data-dojo-attach-point="button">Clear</button>
        <button id="applyBufferP" data-dojo-type="dijit/form/Button" type="button" data-dojo-attach-point="button">Buffer</button>
        <button id="intersectBuffer" data-dojo-type="dijit/form/Button" type="button">Show Parcels Intersecting Buffer</button>
        <table data-dojo-type="dojox/grid/DataGrid" jsid="gridP" id="gridP">
          <thead>
            <tr>
              <th field="PARCELID">Parcel ID</th>
              <th field="OWNERNME1">Owner 1</th>
              <th field="OWNERNME2">Owner 2</th>
              <th field="SITEADDRESS">Address</th>
              <th field="RESYRBLT">Year Built</th>
            </tr>
          </thead>
        </table>
      </div>
      <div id="dialogOne" data-dojo-type="dijit/Dialog" title="Selected Parcels">
        <div data-dojo-type="dijit/layout/ContentPane" title="Selected Parcels">
          <table data-dojo-type="dojox/grid/DataGrid" data-dojo-id="parcelGrid" id="parcelGrid" style="width: 375px; height: 600px" data-dojo-props="rowsPerPage:'100', rowSelector:'20px'">
            <thead>
              <tr>
                <th field="PARCELID">Parcel ID</th>
                <th field="OWNERNME1">Owner 1</th>
                <th field="OWNERNME2">Owner 2</th>
                <th field="SITEADDRESS">Address</th>
                <th field="RESYRBLT">Year Built</th>
              </tr>
            </thead>
          </table>
        </div>
      </div>
      <div id="map" data-dojo-props="region:'center'" data-dojo-type="dijit/layout/ContentPane" style="border:1px solid #000;"></div>
    </div>
  </body>

View solution in original post

14 Replies
OwenEarley
Occasional Contributor III

The issue is in your doQuery() function. When you set the query geometry you are using the entire extent of the buffer graphic. This is basically a box that contains the graphic (see blue box on image).

    function doQuery() {
        var query = new Query();
        query.geometry = graphic.geometry.getExtent();

extent.png

Update your code to just use the buffer geometry:

    function doQuery() {
        var query = new Query();
        query.geometry = graphic.geometry;
0 Kudos
MayJeff
Occasional Contributor

Owen,

After I changed it to query.geometry = graphic.geometry; then I got error message. Can you help me to take a look?  Thanks.

bufferRing2.gif

0 Kudos
OwenEarley
Occasional Contributor III

The reason that this is happening is due to the complexity of the shape. For more information see: Using the proxy | Guide | ArcGIS API for JavaScript:

Requests exceed the limit on the length of the uniform resource locators (URLs) imposed by the browser. Common scenarios where you may run into URL length issues are when you use the buffer from a complex polygon as the input to a query task or if you specify a spatial reference using well-known text (WKT).

The proxy needs to be set up on the machine hosting your page. Details are in the page link above.

gs = new GeometryService("http://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");

    esriConfig.defaults.io.proxyUrl = "/proxy/"; // <- the API cannot connect to the proxy location

    esriConfig.defaults.io.alwaysUseProxy = false;

Note that this error will not occur for simple property shapes. If I search for 1931376029 in an updated version then the process works - Edit fiddle - JSFiddle

extent2.png

MayJeff
Occasional Contributor


Thanks for your reply.  So I what do need to modify it so it will select the correct parcels inside buffer ring?  Can you show me on the JS Fiddle?  Try to make it works when enter 1931376038.  Thanks for your time.

0 Kudos
OwenEarley
Occasional Contributor III

Sorry for the late reply - have been on a road trip.

If the proxy is configured then it should also work for 1931376038. Do you have a proxy set up?

0 Kudos
MayJeff
Occasional Contributor

Owne,

Thanks for replying my thread.  Finally got time to work on this issue again.  I try to use my own services to plug it in and had proxy set up.  The error message still the same if query.geometry = graphic.geometry.  On the other hand, if query.geometry = graphic.geometry.getExtent(), will get the results but like you said it only get the extent one.

The sample here, all use esri services.  Is there any way to set proxy to true?

Thanks.

0 Kudos
OwenEarley
Occasional Contributor III

If the proxy is set up then the API should automatically use it when it needs to. However, there are some settings that you can configure (from Using the proxy | Guide | ArcGIS API for JavaScript 😞

Using the proxy

In order for your application to route requests through the proxy you must add code to your application to define the location of the proxy. If all requests in your application will use the same proxy you can specify the proxy location using proxyUrl. You can also specify whether or not the proxy should always be used for communication using alwaysUseProxy

    esriConfig.defaults.io.proxyUrl = "<url_to_proxy>"
    esriConfig.defaults.io.alwaysUseProxy = false;

In the code above, esriConfig refers to the object returned by the esri/config module.

The proxyUrl setting needs to point to the proxy endpoint on the server that is hosting your page. You can also force the API to always use the proxy with the alwaysUseProxy setting.

I would start by changing to alwaysUseProxy = true. Then test your page to make sure that requests are being routed through your proxy. Tools like Fiddler can help show you what HTTP requests are being made from your machine.

MayJeff
Occasional Contributor

Owen,

Thanks for replying my thread again.  Proxy is setting as mentioned above already and also use Fiddler to check the network traffic when using my own map services & proxy.

Besides that, I also rewrite the buffer code with ESRI map services at

Edit fiddle - JSFiddle to see can get the same result when try to search by 1931376029. Looks like query geometry got some issue in this rewrite code.  Suppose to get the same answer with this jsfiddle:Edit fiddle - JSFiddle

Unfortunately, so far no luck and still got the same error message with new rewrite code (query geometry) & old code (not return correct parcels)

Thanks.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

May Jeff,

   So let me try to make this as simple as possible. I tested your fiddle code (both of them) and just changed the proxyUrl to use my own proxy  and both fiddles worked fine. This tells me that you really don't understand what you are suppose to be putting in the proxyURL. I have a proxy set up on my machine and it's url is http://gislap183/Proxy/proxy.ashx so I change the proxyUrl in your fiddles to:

esriConfig.defaults.io.proxyUrl = "/Proxy/proxy.ashx";

Because when I run your fiddle code (locally) I use the url http://gislap183/js/jeffMay9.html it knows that the proxy is at http://gislap183/Proxy/proxy.ashx and all the code runs fine. So in your code you have

esriConfig.defaults.io.proxyUrl = "/proxy/"; This likely does not point to anything valid on your setup and thus no results. You need to determine what is the actual url to your proxy and use that. If it is a .net proxy then it will likely look like mine and have *.ashx.

0 Kudos