Select to view content in your preferred language

Geocoding list of Addresses

702
9
01-18-2024 08:57 AM
Charan
by
New Contributor III

Hi everyone, I have created a functionality which allows users to upload an Excel file containing addresses and I'm then geocoding those addresses to get statistics within the buffer. My issue is that the order of my addresses changes when geocoding.

 

          document.getElementById("done-button").onclick = () => {
            var fileInput = document.getElementById('fileInput');
            var file = fileInput.files[0];

            if (file) {
              var reader = new FileReader();

              reader.onload = function (e) {
                var data = e.target.result;
                var workbook = XLSX.read(data, { type: 'binary' });
                var sheetName = workbook.SheetNames[0];
                var sheet = workbook.Sheets[sheetName];

                var dataArray = XLSX.utils.sheet_to_json(sheet, { header: 1 });
                list_address = dataArray.flat()
                uniqueAddressID2 = list_address
                const params=[]
                const geocode = "https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer";
                for (var i = 0; i < list_address.length; i++) {
                  //const addressinput = list_address[i]
                  params[i] = {
                    address: {
                      address: list_address[i],
                    },
                    countryCode: "CAN",
                    outSpatialReference: SpatialReference.WGS84
                  };
                }

                for (var i = 0; i < params.length; i++) {
                  locator.addressToLocations(geocode, params[i]).then((results) => {
                    if (results.length) {
                      const result = results[0];
                      const point = new Point({
                        x: result.location.x,
                        y: result.location.y,
                        spatialReference: { wkid: 4326 }
                      });
                      address_geo.push(point)
                      BatchBufferGeom(address_geo)
                    };
                  });
                
                
                };
              }
              
              reader.readAsBinaryString(file);
            } else {
              alert('Please select a file.');
            }
          }

 

 

0 Kudos
9 Replies
BlakeTerhune
MVP Regular Contributor

Is the order based on a sorting definition for a particular field or set of fields? If not, you would have to reference the original order and copy each geocode row out individually in the order you want.

0 Kudos
Charan
by
New Contributor III

@BlakeTerhune so in the second for loop (see below). The list of addresses (params) is still in order but the results change it 

for (var i = 0; i < params.length; i++) {
}

 

0 Kudos
BlakeTerhune
MVP Regular Contributor

Are you sure they're in the right order when read into list_address and params?

0 Kudos
Charan
by
New Contributor III

yup, I ran console.log on both and the order was correct

0 Kudos
JeffreyThompson2
MVP Regular Contributor

I think I know what's happening. When you send the locations to the geocoder, it returns a promise which is resolved whenever it is completed, which may or may not be in the order it was sent. So, the result list is jumbled. As for how to fix it... I don't know.

GIS Developer
City of Arlington, Texas
0 Kudos
ReneRubalcava
Frequent Contributor II

If you adjust the logic of how you are doing things a bit, you can create an array of promises and wait for them all to complete. It does require another loop to do your buffer, but this could help you maintain the order you are looking for.

const geocodePromises = params.map(
  (param) => locator.addressToLocations(...)
);

Promise.all(geocodePromises).then((results) => {
  // do something with results
});

 

Note, you can use Promise.all or Promise.allSettled. The result signatures are different, but depends on your needs.

Charan
by
New Contributor III

Hi @ReneRubalcava I used the following code, however, I'm getting an error at location.x

                const geocodePromises = params.map(
                    (param) => locator.addressToLocations(geocode, param)
                )
                Promise.all(geocodePromises).then((results) => {
                  for(var i=0; i<results.length; i++) {
                    const result= results[i]
                    const point = new Point({
                      x: result.location.x,
                      y: result.location.y,
                      spatialReference: { wkid: 4326 }
                    });
                    console.log(result)
                    address_geo.push(point)
                    BatchBufferGeom(address_geo)
                  }

Charan_0-1705691242777.png

 

 

 

0 Kudos
ReneRubalcava
Frequent Contributor II

This probably means there was not a result for that address, so you probably need to add some checks that you have a valid result.

0 Kudos
BlakeTerhune
MVP Regular Contributor

Ah, yes, good point! You would probably have to leverage the await operator.

0 Kudos