Geometry Service Question

4181
27
Jump to solution
01-09-2017 05:22 PM
LloydBronn
Occasional Contributor II

I've set up a blank map where I click on any point and a popup displays the lat/lon coordinates and a link to a geoprocessing service. Right now I'm using this example to get everything working. Eventually I'll make my own geoprocessing tool that returns custom charts based on the lat/lon coordinates from the click event. When I click the link in the popup, it just says "calculating" and never returns a population. Chrome creates a debug text file with a bunch of errors. I'm pretty sure this happens because I haven't specified a geometry service in my script. 

<!DOCTYPE html>
<html>  
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Forecast Analysis</title>
    <link rel="stylesheet" href="http://js.arcgis.com/3.19/dijit/themes/claro/claro.css">
    <link rel="stylesheet" type="text/css" href="http://js.arcgis.com/3.19/esri/css/esri.css">
    <style>
      html, body, .container, #map {
            height: 700px;
            width: 100%;
            margin: 0;
            padding: 0;
            margin: 0;
            font-family: "arial";
        }          
       .esriScalebar {
        padding: 20px 20px;
      }
       
       #HomeButton {
      position: absolute;
      top: 95px;
      left: 20px;
      z-index: 50;
    }
       
          
          .esriPopup .titleButton.maximize {
        display: none;

      }
       .esriPopup .sizer {
          position: relative;
          width: 150px;
          z-index: 1;
          }     
                    
          .esriPopup .contentPane {
        text-align: left;
          
      }
          
       
       #search {
         display: block;
         position: absolute;
         z-index: 2;
         top: 20px;
         left: 75px;
      }
       
       .esriPopup .actionsPane .zoomTo{     
       display: none; 
       }  
     
 
    </style>
    <script src="http://js.arcgis.com/3.19/"></script>
    <script>
      var map;

      require([
         "esri/config",
        "esri/map",
          "esri/arcgis/utils",
        "esri/tasks/Geoprocessor",
        "esri/tasks/GeometryService",
        "esri/tasks/BufferParameters",
          "esri/graphic",
          "esri/geometry/webMercatorUtils",
          "esri/SpatialReference",
        "esri/tasks/FeatureSet",
        "esri/symbols/SimpleFillSymbol",
          "esri/dijit/Popup",
        "esri/dijit/PopupTemplate",
          "esri/InfoTemplate",
          "esri/layers/FeatureLayer",
          "esri/symbols/SimpleMarkerSymbol",
          "esri/symbols/SimpleLineSymbol",
          "esri/dijit/BasemapGallery",
          "esri/dijit/HomeButton",
          "esri/dijit/Search",
          "dojo/dom-construct",
        "esri/Color",
          "dojo/dom",
          "dojo/dom-attr",
          "dojo/query",
          "dojo/on",           
          "dojo/parser",
          "dijit/layout/BorderContainer",
        "dijit/layout/ContentPane",
          "dijit/TitlePane",
        "dojo/domReady!"
      ], function (
        esriConfig, Map,  arcgisUtils, Geoprocessor, GeometryService,
        BufferParameters, Graphic, webMercatorUtils,  SpatialReference,
        FeatureSet, SimpleFillSymbol, Popup, PopupTemplate, 
          InfoTemplate, FeatureLayer, SimpleMarkerSymbol,
          SimpleLineSymbol, BasemapGallery, HomeButton, Search, domConstruct, 
          Color, dom, domAttr, query, on, parser
      ) {
          parser.parse();

            map = new Map("map", {
            basemap: "gray",
               center: [10, 40],
               maxZoom: 18,
            minZoom: 3
          });
            
            var home = new HomeButton({
          map: map
         }, "HomeButton");
         home.startup();
           
           var search = new Search({
            map: map,
               showInfoWindowOnSelect: false,
               enableLabel: false,
               enableHighlight: false
         }, "search");
         search.startup();
            
           var popupOptions = {
            markerSymbol: new SimpleMarkerSymbol("circle", 32, null,
              new Color([0, 0, 0, 0.25])),
            marginLeft: "20",
            marginTop: "20"
          };
          
      
            
            var basemapGallery = new BasemapGallery({
             showArcGISBasemaps: true,
             map: map
           }, "basemapGallery");
           basemapGallery.startup();
            
            basemapGallery.on('load',function(){  
          basemapGallery.remove('basemap_2');  
          basemapGallery.remove('basemap_4');
          basemapGallery.remove('basemap_5'); 
          basemapGallery.remove('basemap_0'); 
          basemapGallery.remove('basemap_1');
          basemapGallery.remove('basemap_11');
     }); 
       
          basemapGallery.on("selection-change",function(){
           var tp = dijit.byId("TitlePane");
         if(tp != null){tp.toggle();}
         });
       
           basemapGallery.on("error", function(msg) {
            console.log("basemap gallery error:  ", msg);
          });
       
         basemapGallery.on("load", function(msg) {
        for (b=0;b<map.basemapLayerIds.length;b++){
          var lyr = map.getLayer(map.basemapLayerIds[b]);
          if(lyr._isRefLayer){
            refLayerId = lyr.id;
          }
        }
      });
       
       map.on("load", function() {
          //after map loads, connect to listen to mouse move & drag events
          map.on("mouse-move", showCoordinates);
          map.on("mouse-drag", showCoordinates);
        });

        function showCoordinates(evt) {
          //the map is in web mercator but display coordinates in geographic (lat, long)
          var mp = webMercatorUtils.webMercatorToGeographic(evt.mapPoint);
          //display mouse coordinates
          dom.byId("info").innerHTML = "Longitude: " + mp.x.toFixed(3) + "    " + "Latitude: " + mp.y.toFixed(3);
        };
               
          map.on("click", function(evt){
            var mp = webMercatorUtils.webMercatorToGeographic(evt.mapPoint);
            var x = mp.x.toFixed(3);
            var y = mp.y.toFixed(3);
          map.graphics.clear();
          var graphic = new Graphic(evt.mapPoint);

          map.graphics.add(graphic);
          map.infoWindow.setFeatures([graphic]);

          map.infoWindow.setContent("Longitude: " + x.toString() + " <br>Latitude: " + y.toString());
          map.infoWindow.show(evt.mapPoint)
        });

          var link = domConstruct.create("a",{
                "class": "action", 
                "id": "statsLink",
                "innerHTML": "Population", //text that appears in the popup for the link 
                "href": "javascript: void(0);"
              }, query(".actionList", map.infoWindow.domNode)[0]);
          on(link, "click", calculatePopulation);
            
            window.gp = new Geoprocessor("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Population_World/GPServ...");
            
            function calculatePopulation(evt){
            //display a message so user knows something is happening
            domAttr.set(dom.byId("statsLink"), "innerHTML", "Calculating...");

            //Get the feature associated with the displayed popup and use it as 
            //input to the geoprocessing task. The geoprocessing task will calculate 
            //population statistics for the area within the specified buffer distance. 
            var feature = window.map.infoWindow.getSelectedFeature();
            
            var param = new BufferParameters();
            param.geometries = [webMercatorUtils.webMercatorToGeographic(feature.geometry)];

            param.distances = [10]; //buffer distance
            param.unit = GeometryService.UNIT_KILOMETER;
            param.bufferSpatialReference = new SpatialReference({"wkid": 4326});
            param.outSpatialReference = new SpatialReference({"wkid": 102100});
            param.geodesic = true;

            config.defaults.geometryService.buffer(param, function(geometries){

              var graphic = new Graphic(geometries[0]);
              graphic.setSymbol(new SimpleFillSymbol().setColor(new Color([0,255,255,0.25])));

              window.map.graphics.add(graphic);
 
              //Use the buffered geometry as input to the GP task 
              var featureSet = new FeatureSet();
              featureSet.geometryType = "esriGeometryPolygon";
              featureSet.features = [graphic];
              var taskParams = {
                "inputPoly": featureSet
              };
              window.gp.execute(taskParams, gpResultAvailable, gpFailure);


            });
          }

          function gpResultAvailable(results, messages){
            domAttr.set(dom.byId("statsLink"),"innerHTML", "Population");
            //clear any existing features displayed in the popup 
            window.map.infoWindow.clearFeatures();

            //display the query results 
            var content = "";
            if(results.length > 0){
              content = "Population = " + results[0].value.features[0].attributes.SUM;
            }else{
              content = "No Results Found";
            }
            window.map.infoWindow.setContent(content);
          }
          function gpFailure(error){
            domAttr.set(dom.byId("statsLink"),"innerHTML", "Population");

            var details = domConstruct.create("div", {
              "innerHTML": "Population = " + error
            }, query(".break", window.map.infoWindow.domNode)[0],"after" );
            console.error("Error occurred: ", error);
          }

        
          
     
     });
    </script>
  </head>

  <body class="claro">
  
    <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'"
         style="width: 100%; height: 100%; margin: 0;">
           
      <div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'">
       
       <div id="search"></div>
             
             <span id="info" style="font-family:arial;position:absolute;left:15px; bottom:30px; background-color:lightgray; opacity: 0.70; z-index:50;"></span>
             
             <div id="HomeButton"></div>
             
          <div style="position:absolute; left:15px; bottom:60px; z-Index:999;">
          
     <div data-dojo-type="dijit/TitlePane" id = "TitlePane" style="font-family:arial;background-color:lightgray"
             data-dojo-props="title:'Switch Basemap', closable:true, open:false">
                
            <div id="basemapGallery"></div>
               
               
             </div>
          </div>   
      </div>
    </div>
  </body>

</html>

If I follow the GP tool in popup example and I add a geometry service from my company ArcGIS server or this ESRI sample server, my popup disappears, as does my lat/lon tracker. The popup and lat/lon tracker incorporate webmercator utils to convert XY to lat/lon. I'm not sure how to proceed.  

config.defaults.geometryService = new GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
config.defaults.io.proxyUrl = "/proxy/";
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

   Your issue is that you have "esri/config" var'd as esriConfig and then you are trying to use config.defaults.... instead of esriConfig.defaults....

Use:

            esriConfig.defaults.geometryService = new GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
            esriConfig.defaults.io.proxyUrl = "/proxy/proxy.ashx";

and 

esriConfig.defaults.geometryService.buffer(param, function(geometries) {

View solution in original post

27 Replies
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

   Your issue is that you have "esri/config" var'd as esriConfig and then you are trying to use config.defaults.... instead of esriConfig.defaults....

Use:

            esriConfig.defaults.geometryService = new GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
            esriConfig.defaults.io.proxyUrl = "/proxy/proxy.ashx";

and 

esriConfig.defaults.geometryService.buffer(param, function(geometries) {
LloydBronn
Occasional Contributor II

Oh duh, thanks! 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

   You need to start checking your browser web console. You will see errors there that will tell you what is going wrong. In this case it is likely your proxy. On my end it works without issue.

LloydBronn
Occasional Contributor II

I'm using the above proxy: esriConfig.defaults.io.proxyUrl = "/proxy/proxy.ashx";

It says "Uncaught TypeError: Cannot read property 'getSelectedFeature' of undefined
at HTMLAnchorElement.calculatePopulation "

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

   So is /proxy/proxy.ashx the correct location and file name from your proxy? Do you have "http://sampleserver1.arcgisonline.com" setup in your proxy.config file?

0 Kudos
LloydBronn
Occasional Contributor II

I just copied those two lines from above:

esriConfig.defaults.geometryService = new GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
esriConfig.defaults.io.proxyUrl = "/proxy/proxy.ashx";

Do I need a proxy config file if I'm using ESRI's geometry service? I haven't used a geometry service or a proxy before. 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

   There is a reason that the esri sample has those line (they are needed). You will need to install and setup a proxy for this to work.

0 Kudos
LloydBronn
Occasional Contributor II

Thanks for your help Robert.

I set up the proxy using .Net 4.5 on the IIS server and enabled directory browsing. The lines in the script are now:

esriConfig.defaults.geometryService = new GeometryService("http://<ourserver>/arcgis/rest/services/Utilities/Geometry/GeometryServer");
esriConfig.defaults.io.proxyUrl = "http://<ourserver>/DotNet/proxy.ashx";
esriConfig.defaults.io.alwaysUseProxy = false; ‍‍‍

I confirmed that I can navigate to the proxy.ashx file URL through a web browser, but I get this error:

{error: {code: 400,message:"This proxy does not support empty parameters."}}

I'm still getting the same error as before when I try to calculate population in the popup:

"Uncaught TypeError: Cannot read property 'getSelectedFeature' of undefined
at HTMLAnchorElement.calculatePopulation "

I've set up the proxy config file:

<?xml version="1.0" encoding="utf-8" ?>
<ProxyConfig allowedReferers="*"
             mustMatch="true">
    <serverUrls>  
          <serverUrl url="http://<ourserver>/arcgis/rest"
                       username ="usernamen"
                       password ="password"
                   matchAll="true"/>
    </serverUrls>
</ProxyConfig>

<!-- See https://github.com/Esri/resource-proxy for more information -->

Are there other steps I need to take to configure the proxy? 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

  Have you done a ping test on your proxy?

http://[yourmachine]/DotNet/proxy.ashx?ping

Have you seen this blog?

Setting up a Proxy | Support Services Blog 

Or this JS API help topic?

Using the proxy | Guide | ArcGIS API for JavaScript 3.19

You will need to have http://sampleserver1.arcgisonline.com as one of the serverUrls in your proxy.config

0 Kudos