Multiple Custom Geocoders in Web Map

4265
2
Jump to solution
03-23-2015 09:21 AM
LisCollins
Occasional Contributor

Hi there,

I need help with adding multiple custom geocoders to my web map that's based on the Public Information Template.

Problem:

I can get one of my custom geocoders to display on the map. But getting both of them to display as an option for users to select in a drop down has been a struggle.

I have tried creating a variable called "myGeocoders" that lists both geocoders and putting it in the options object below, but the map still only displayed one geocoder.  In the code below, I tried listing both geocoders separately along with the ESRI geocoder to see if it will show, and it still only displayed one geocoder. Same if I take out the ESRI geocoder.

Code below:

 _createGeocoderOptions: function() {
            var hasEsri = false, esriIdx, geocoders = lang.clone(this.config.helperServices.geocode);
            // default options
               
               var myGeocoders = [{
          url: "http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_CompositeLocator/GeocodeServer",
          name: "MD_CompositeLocator",
          "singleLineFieldName": "SingleLine"
          },{
          url: "http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_ParcelAccountNumberLocator/GeocodeServer",
          name: "MD_ParcelAccountNumberLocator",
          "singleLineFieldName": "Single Line Input"
        }];
               
               
            var options = {
                map: this.map,
                autoNavigate: true,
                autoComplete: true,
                arcgisGeocoder: false,
                geocoders: null,
            };
            //only use geocoders with a url defined
            geocoders = array.filter(geocoders, function (geocoder) {
                if (geocoder.url) {
                    return true;
                }
                else{
                    return false;
                }
            });
            // at least 1 geocoder defined
            if(geocoders.length){
                // each geocoder
            array.forEach(geocoders, lang.hitch(this, function(geocoder) {
                   // if esri geocoder
                    if (geocoder.url && geocoder.url.indexOf(".arcgis.com/arcgis/rest/services/World/GeocodeServer") > -1) {
                        hasEsri = true;
                        geocoder.name = "Esri World Geocoder";
                        geocoder.outFields = "Match_addr, stAddr, City";
                        geocoder.singleLineFieldName = "Single Line";
                        geocoder.esri = true;
                        geocoder.placefinding = true;
                        geocoder.placeholder = this.config.i18n.general.find;
                    }  
                         
                         //if not esri geocoder
                            if (geocoder.url && geocoder.url.indexOf("http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_CompositeLocator/GeocodeServer") > -2) {
                        hasEsri = false;
                        geocoder.name = "MD_CompositeLocator";
                        geocoder.outFields = "Street, City, State, ZIP";
                        geocoder.singleLineFieldName = "SingleLine";
                        geocoder.esri = false;
                        geocoder.placefinding = true;
                        geocoder.placeholder = "Find a Place";
                              
                    }     
                         
                         //if not esri geocoder
                            if (geocoder.url && geocoder.url.indexOf("http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_ParcelAccountNumberLocator/GeocodeServer") > -1) {
                        hasEsri = false;
                        geocoder.name = "MD_ParcelAccountNumberLocator";
                        geocoder.outFields = "*";
                        geocoder.singleLineFieldName = "Single Line Input";
                        geocoder.esri = false;
                        geocoder.placefinding = true;
                        geocoder.placeholder = "Find a Parcel Point Account ID";
                              
                    }     
                         
                         
                
                    })) ;        
                    
                    
                //only use geocoders with a singleLineFieldName that allow placefinding unless its custom
                geocoders = array.filter(geocoders, function (geocoder) {
                    if (geocoder.name && geocoder.name === "Custom") {
                        return (esriLang.isDefined(geocoder.singleLineFieldName));
                    } else {
                        return (esriLang.isDefined(geocoder.singleLineFieldName) && esriLang.isDefined(geocoder.placefinding) && geocoder.placefinding);
                    }
                });
                // if we have an esri geocoder
                if (hasEsri) {
                    for (var i = 0; i < geocoders.length; i++) {
                        if (esriLang.isDefined(geocoders.esri) && geocoders.esri === true) {
                            esriIdx = i;
                            break;
                        }
                    }
                }
                // set autoComplete
                options.autoComplete = true;
                // set esri options
                if (hasEsri) {
                    options.minCharacters = 0;
                    options.maxLocations = 5;
                    options.searchDelay = 100;
                }
                //If the World geocoder is primary enable auto complete 
                if (hasEsri && esriIdx === 0) {
                    options.arcgisGeocoder = geocoders.splice(0, 1)[0]; //geocoders[0];
                    if (geocoders.length > 0) {
                        options.geocoders = geocoders;
                    }
                } else {
                    options.arcgisGeocoder = false;
                    options.geocoders = geocoders;
                }
            }
            return options;
        },
        // create geocoder widgets
        _createGeocoders: function () {
               //add geocoder result layer
            var resultsLayer = new esri.layers.GraphicsLayer({ id: "resultsLayer" });   //geocoder symbol code
            this.map.addLayer(resultsLayer);
          
            // get options
            var createdOptions = this._createGeocoderOptions();
            // desktop geocoder options
            var desktopOptions = lang.mixin({}, createdOptions, {
                theme: this.css.desktopGeocoderTheme
            });
            // mobile geocoder options
            var mobileOptions = lang.mixin({}, createdOptions, {
                theme: this.css.mobileGeocoderTheme
            });
            // desktop size geocoder
            this._geocoder = new Geocoder(desktopOptions, dom.byId("geocoderSearch"));
            ;
               this._geocoder.startup();
               
               
                 //add feature to map                                          //geocoder symbol
            function addFeatureToMap(geometry) {
                resultsLayer.clear();
                var pictureMarkerSymbol = new PictureMarkerSymbol({ "angle": 0, "xoffset": 2, "yoffset": 8, "type": "esriPMS", "url": "http://static.arcgis.com/images/Symbols/Basic/RedStickpin.png", "contentType": "image/png", "width": 24, "height": 24 });
                resultsLayer.add(new Graphic(geometry, pictureMarkerSymbol));
            }
               
               
               //zoom to level 19 after press geocoder - MIO
               on(this._geocoder, 'select', lang.hitch(this, function (response) {
           console.log("set zoom function");
             console.log(this.map);
                    this.map.setZoom(19);
                              
            }));
               
            // geocoder results
            on(this._geocoder, 'find-results', lang.hitch(this, function (response) {
                if (!response.results || !response.results.results || !response.results.results.length) {
                    alert(this.config.i18n.general.noSearchResult);
                } else {                                                //geocoder symbol results
                    addFeatureToMap(response.results.results[0].feature.geometry); 
                         if (history.pushState) {
                                   //browser supported.
                                        //refresh the URL with the geocoder result
                                          console.log("Push state is supported. Geocoder result: ");
                              console.log(this._geocoder.value);
                              window.history.pushState(null,null,"?address=" + this._geocoder.value);
                                   } 
                              
                              
                }
            }));
          
               
               
            // mobile sized geocoder
            this._mobileGeocoder = new Geocoder(mobileOptions, dom.byId("geocoderMobile"));
            this._mobileGeocoder.startup();
            // geocoder results
            on(this._mobileGeocoder, 'find-results', lang.hitch(this, function (response) {
                if (!response.results || !response.results.results || !response.results.results.length) {
                    alert(this.config.i18n.general.noSearchResult);
                } else {    //geocoder symbol results and all below until keep geocoder values in sync
                    addFeatureToMap(response.results.results[0].feature.geometry);
                                   //refresh the URL with the geocoder result
                              if (history.pushState) {
                                   //browser supported.
                                        //refresh the URL with the geocoder result
                                          console.log("Push state is supported. Geocoder result: ");
                              console.log(this._geocoder.value);
                              window.history.pushState(null,null,"?address=" + this._geocoder.value);
                                   }
                         }
                this._hideMobileGeocoder();
            }));
               
                      on(this._geocoder, 'clear', lang.hitch(this, function () {
                resultsLayer.clear();
            }));                                               //rest of geocoder symbol result

            on(this._mobileGeocoder, 'clear', lang.hitch(this, function () {
                resultsLayer.clear();
            }));                                                //rest of geocoder symbol result
               
            // keep geocoder values in sync
            this._geocoder.watch("value", lang.hitch(this, function () {
                var value = arguments[2];
                this._mobileGeocoder.set("value", value);
            }));
            // keep geocoder values in sync
            this._mobileGeocoder.watch("value", lang.hitch(this, function () {
                var value = arguments[2];
                this._geocoder.set("value", value);
            }));
            // geocoder nodes
            this._mobileGeocoderIconNode = dom.byId("mobileGeocoderIcon");
            this._mobileSearchNode = dom.byId("mobileSearch");
            this._mobileGeocoderIconContainerNode = dom.byId("mobileGeocoderIconContainer");
            // mobile geocoder toggle 
            if (this._mobileGeocoderIconNode) {
                on(this._mobileGeocoderIconNode, "click", lang.hitch(this, function () {
                    if (domStyle.get(this._mobileSearchNode, "display") === "none") {
                        this._showMobileGeocoder();
                    } else {
                        this._hideMobileGeocoder();
                    }
                }));
            }
            var closeMobileGeocoderNode = dom.byId("btnCloseGeocoder");
            if(closeMobileGeocoderNode){
                // cancel mobile geocoder
                on(closeMobileGeocoderNode, "click", lang.hitch(this, function () {
                    this._hideMobileGeocoder();
                }));
            }
        },

Background Info:

Level: newbie JS developer.

Using ESRI JavaScript API - ESRI's Public information web map template: Esri/public-information-map-template-js · GitHub

This code was added to the main.js file in the _init: function ().

Any tips?

Thanks.


           
   

0 Kudos
1 Solution

Accepted Solutions
KellyHutchins
Esri Frequent Contributor

Instead of defining your geocoders in the main.js file try adding them to defaults. js instead. If you open defaults.js in a text editor you'll see there's a section for helper services and it contains a place where you can define one or more geocode services. Here's an example of customizing it for your services:

 "geocode": [{
      "url": "http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_CompositeLocator/GeocodeServer",
      "singleLineFieldName": "SingleLine",
      "name": "MD_CompositeLocator",
      "placefinding":true,
      "placeholder": "Find a place"
    },{
      "url":"http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_ParcelAccountNumberLocator/GeocodeServer",
      "singleLineFieldName": "SingleLine",
      "name": "MD_ParcelAccountNumberLocator",
      "placefinding":true,
      "placeholder": "Find a Parcel Point Account ID"
      }]

After defining your services open the templateConfig.js file and set the queryForOrg option to false so that it doesn't query ArcGIS Online for helper services and uses the ones you've defined in default. js.

View solution in original post

0 Kudos
2 Replies
KellyHutchins
Esri Frequent Contributor

Instead of defining your geocoders in the main.js file try adding them to defaults. js instead. If you open defaults.js in a text editor you'll see there's a section for helper services and it contains a place where you can define one or more geocode services. Here's an example of customizing it for your services:

 "geocode": [{
      "url": "http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_CompositeLocator/GeocodeServer",
      "singleLineFieldName": "SingleLine",
      "name": "MD_CompositeLocator",
      "placefinding":true,
      "placeholder": "Find a place"
    },{
      "url":"http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_ParcelAccountNumberLocator/GeocodeServer",
      "singleLineFieldName": "SingleLine",
      "name": "MD_ParcelAccountNumberLocator",
      "placefinding":true,
      "placeholder": "Find a Parcel Point Account ID"
      }]

After defining your services open the templateConfig.js file and set the queryForOrg option to false so that it doesn't query ArcGIS Online for helper services and uses the ones you've defined in default. js.

0 Kudos
LisCollins
Occasional Contributor

So simple! Wow. Thanks!

0 Kudos