JS API: sourceCountry in Geocoder has no effect

6002
13
Jump to solution
08-20-2014 01:36 PM
JamesSampica
New Contributor

Using this sample...

ArcGIS API for JavaScript Sandbox

change the geocoder as follows...

 

    geocoder = new Geocoder({

          autoComplete: true,

          map: map ,

          arcgisGeocoder: {

                    sourceCountry: "USA"

                }

    }, "search");

 

typing anything into the geocoder still causes it to match addresses from other countries.

 

Is there a workaround for this?

0 Kudos
1 Solution

Accepted Solutions
KellyHutchins
Esri Frequent Contributor

James,

Looks like a bug. We'll work on getting this fixed for a future release but in the meantime you can work-around the issue using setRequestPreCallback to add the country code to the request. Here's an example:

<!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>ArcGIS API for JavaScript | Simple Geocoding</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">

    <style>

      html, body, #map {

        height:100%;

        width:100%;

        margin:0;

        padding:0;

      }

      #search {

        display: block;

        position: absolute;

        z-index: 2;

        top: 20px;

        left: 74px;

      }

    </style>

    <script src="http://js.arcgis.com/3.10/"></script>

    <script>

      var map, geocoder;

      require([

        "esri/map", "esri/dijit/Geocoder", "esri/request", "dojo/domReady!"

      ], function(Map, Geocoder, esriRequest) {

        map = new Map("map",{

          basemap: "gray",

          center: [-120.435, 46.159], // lon, lat

          zoom: 7

        });

        esriRequest.setRequestPreCallback(function(ioArgs){

 

          if(ioArgs.url === "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates"){

            ioArgs.content.CountryCode = "US";

          console.log(ioArgs);

          }

          return ioArgs;

        });

        geocoder = new Geocoder({

          map: map,

          arcgisGeocoder:{

            sourceCountry: "US"

          }

        }, "search");

        geocoder.startup();

      });

    </script>

  </head>

  <body>

    <div id="search"></div>

    <div id="map"></div>

  </body>

</html>

View solution in original post

13 Replies
RiyasDeen
Occasional Contributor III

try this work around.

  • On map load event call query any feature layer where you can get shape of the USA country boundary.
  • Get extent of the shape as arcgisGeocoder.searchExtent this will restrict geocode
  • Set autoNavigate: false property to false.
  • Attach to find-results event.
geocoder.on("find-results", function (response)

        {

          response.results.results[0].feature.symbol = new SimpleMarkerSymbol("circle", 20, null, new Color([255, 0, 0, 0.25]))

          map.graphics.add(response.results.results[0].feature);

          materAt(response.results.results[0].feature.geometry);

        })

  • Use GeometryTask to check if returned geometry is within US boundary identified in step 1.
  • Discard the one's not within US boundary.

I have not implemented this workaround anywhere, hopefully this should work for you.

0 Kudos
RiyasDeen
Occasional Contributor III

line 8 in above snippet should be map.centerAt(response.results.results[0].feature.geometry);

0 Kudos
KellyHutchins
Esri Frequent Contributor

James,

Looks like a bug. We'll work on getting this fixed for a future release but in the meantime you can work-around the issue using setRequestPreCallback to add the country code to the request. Here's an example:

<!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>ArcGIS API for JavaScript | Simple Geocoding</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">

    <style>

      html, body, #map {

        height:100%;

        width:100%;

        margin:0;

        padding:0;

      }

      #search {

        display: block;

        position: absolute;

        z-index: 2;

        top: 20px;

        left: 74px;

      }

    </style>

    <script src="http://js.arcgis.com/3.10/"></script>

    <script>

      var map, geocoder;

      require([

        "esri/map", "esri/dijit/Geocoder", "esri/request", "dojo/domReady!"

      ], function(Map, Geocoder, esriRequest) {

        map = new Map("map",{

          basemap: "gray",

          center: [-120.435, 46.159], // lon, lat

          zoom: 7

        });

        esriRequest.setRequestPreCallback(function(ioArgs){

 

          if(ioArgs.url === "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates"){

            ioArgs.content.CountryCode = "US";

          console.log(ioArgs);

          }

          return ioArgs;

        });

        geocoder = new Geocoder({

          map: map,

          arcgisGeocoder:{

            sourceCountry: "US"

          }

        }, "search");

        geocoder.startup();

      });

    </script>

  </head>

  <body>

    <div id="search"></div>

    <div id="map"></div>

  </body>

</html>

Noah-Sager
Esri Regular Contributor

I found that setting the country suffix helps:

geocoder = new Geocoder({

          autoComplete: true,

          map: map ,

          arcgisGeocoder: {

                sourceCountry: "USA",

                suffix: "United States",

          }

}, "search");

When the geocoder dijit has the auto-complete property set to true the geocoder calls the suggest operation in REST. The suggest operation accepts 4 parameters, the search text, a starting location, a distance from the starting location, and a category. Thus it is not possible to limit the autocomplete suggestions using a source country or a search extent. The only way to limit results is via a starting location and a search distance, or a filtering category. Please refer your customer to the documentation here:

https://developers.arcgis.com/rest/geocode/api-reference/geocoding-suggest.htm

The searchExtent and sourceCountry parameters can help narrow results in the find and findAddressCandidates rest operations. The documentation for these can be found here:

https://developers.arcgis.com/rest/geocode/api-reference/geocoding-find.htm

When autocomplete is enabled each time a character is typed into the geocoder input text box the suggest operation is called which returns suggestions for the user. When the user presses enter the findAddressCandidates operation is called which returns potential matches. The address with the highest candidate score is displayed on the map.

Hope this helps!

-Noah

TracySchloss
Frequent Contributor

I can't believe how confusing this is.  It doesn't look to me like the esriRequest for the preCallback is doing anything, or at least nothing to fix the issue of suggested matches outside the US. 

I'd also like to see this work for a ZIP code search.  When you try that, you see some conflicting feedback.  For example, 65043.  If I just enter that, I get a whole bunch of suggested locations in Brazil.  But if I click the find icon, I am properly taken to the location I expect in central Missouri.  The users are going to LOVE that. 

I tried adding a suffix of Missouri, but that just gives additional confusing results. 

Is this part of the bug?

0 Kudos
KellyHutchins
Esri Frequent Contributor

Tracy,

You shouldn't need to use the workaround with setRequestPreCallback if you are using version 3.11 of the ArcGIS API for JavaScript. For the issue you are seeing with inconsistent search results can you post a code sample that shows the problem along with the input you used?

0 Kudos
TracySchloss
Frequent Contributor

Yes, I'm using version 3.11.  The versions of the API change so fast, it's hard to keep track of the threads that might relate to an older version.  I'm trying to figure out what's going on behind the scenes. Shouldn't this work for ZIP codes?  I've been using Locator this whole time, because I feel like I get less flaky results compared to the Geocoder dijit.  Working with state-wide data, users want to be able to enter a ZIP to get to a particular part of the state.   In my example, 65043, it returns just a set of codes for Brazil:

65043.png

If I then click to search, it does take me to the right location in central MO, not Brazil. 

65043_2.png

If I try the same search again, this time I get the match in the list of choices along with all those Brazil codes.  Why?  I started out centered on the state in the first place, so I would think that extent and the sourceCountry would be enough to limit to US ZIP codes.

65043_3.png

Here is my code.  It's basically the example from Geocoder widget | Guide | ArcGIS API for JavaScript

<!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>Geocode Dijit</title>
    <link rel="stylesheet" href="http://js.arcgis.com/3.11/esri/css/esri.css">
    <style>
      html, body, #map {
        height:100%;
        width:100%;
        margin:0;
        padding:0;
      }
      #search {
        display: block;
        position: absolute;
        z-index: 2;
        top: 20px;
        left: 74px;
      }
    </style>
    <script type="text/javascript">
var djConfig = {
  parseOnLoad: false
};
</script>
    <script src="http://js.arcgis.com/3.11/"></script>
    <script>
      var map, geocoder;
    require(["dojo/parser","esri/map", "esri/dijit/Geocoder", "esri/layers/GraphicsLayer","esri/graphic",
    "esri/symbols/SimpleMarkerSymbol","esri/InfoTemplate","dojo/_base/Color", "dojo/_base/array", "dojo/dom",
    "esri/request", "dojo/domReady!"
  ], function(
    parser,Map,Geocoder,GraphicsLayer,Graphic,SimpleMarkerSymbol,InfoTemplate,Color,arrayUtils,dom,esriRequest
        ) {
     parser.parse();


          var symbol = new SimpleMarkerSymbol();
          symbol.setStyle(SimpleMarkerSymbol.STYLE_CIRCLE); 
          symbol.setColor(new Color([255,128,0,0.75]));  
        // create the map
        map = new Map("map",{
          basemap: "topo",
      center: [-92.593, 38.5],
      zoom: 7,
        });
        // create the geocoder
        var geocoder =  new Geocoder({
          autoComplete: true,
          map: map,
          arcgisGeocoder: {
            placeholder: "Find a place",
          sourceCountry:"US",
          } 
        }, dom.byId("search"));
        geocoder.startup();
        geocoder.focus();
        geocoder.on("select", showLocation);
        
        function showLocation(evt) {
          map.graphics.clear();
          var point = evt.result.feature.geometry;
          var graphic = new Graphic(point, symbol);
          map.graphics.add(graphic);


       //   map.infoWindow.setTitle("Search Result");
          map.infoWindow.setContent(evt.result.name);
          map.infoWindow.show(evt.result.feature.geometry);
        }


       geocoder.on('clear', function (evt){
          map.graphics.clear();
          map.infoWindow.hide();
         });
        });


    </script>
  </head>
  <body>
    <div id="search"></div>
    <div id="map"></div>
  </body>
</html>
0 Kudos
KellyHutchins
Esri Frequent Contributor

Tracy,

It looks like the inconsistency you are experiencing is because the suggest operation doesn't currently support the search extent or source country. So the results you get in the list can be outside the specified search area. However at the next release of ArcGIS Online (due out very soon) support will be added for searchExtent. Once this update happens if you specify a searchExtent the suggest results will  honor that extent too. So you could restrict your search to just Missouri. 

0 Kudos
Noah-Sager
Esri Regular Contributor

To add my 2 cents to Kelly's statement, it looks possible to add a suffix parameter to the Geocoder widget constructor.

// create the geocoder  
        var geocoder =  new Geocoder({  
          autoComplete: true,  
          map: map,  
          arcgisGeocoder: {  
            placeholder: "Find a place",  
            sourceCountry:"US",  
            suffix:",Missouri, USA"
          }   
        }, dom.byId("search"));

65043.png

-Noah

0 Kudos