如何在 google 地理编码调用中传递一些参数

how to pass some parameter within the google geocoding call

我有一个包含四个字段的地址的对象数组,字段 1 是当前位置(商店),其余是地址信息。

我的问题是如何确保最后得到 key:value (store:cords) 的结果,以便我知道哪个商店有哪些电线。

这是我到目前为止编写的代码:

var NodeGeocoder = require('node-geocoder')
const csv=require('csvtojson')
const csvFilePath='location.csv'
csv({noheader:true})
.fromFile(csvFilePath)
.then((jsonObj)=>{
    convertAddressesToCoords(jsonObj, function(coords){
        console.log('converting finished.');
        console.log(coords.length);
        console.log(coords);
    });
});

function convertAddressesToCoords(addresses, callback) {
    var coords = [];
    var options = {
      provider: 'google',
      httpAdapter: 'https', 
      apiKey: 'xxxxxxxxxxxxxxxxxxxxxxxx', 
      formatter: null        
    };

    var geocoder = NodeGeocoder(options);

    for(var i = 0; i < addresses.length; i++) {
        currAddress = addresses[i].field2 + ' ' + addresses[i].field3 + ' ' + addresses[i].field4;
        geocoder.geocode(currAddress, function(err, results) {
                coords.push(results);
                    if(coords.length == addresses.length) {
                        if( typeof callback == 'function' ) {
                            callback(coords);
                        }
                    }
        });
    }
}

当前代码工作正常,我可以为每个地址获取坐标,但问题是最后我不知道哪个商店有哪个坐标,因为 google 地理编码 cal 是异步的,所以我找不到如何使这项工作的方式。

使用承诺。像

function convertAddressesToCoords(addresses, callback) {
  var coords = [];
  var options = {
    provider: 'google',
    httpAdapter: 'https', 
    apiKey: 'xxxxxxxxxxxxxxxxxxxxxxxx', 
    formatter: null        
  };

  var geocoder = NodeGeocoder(options);
  return Promise.all(
    adresses.map(
      (address)=>new Promise((resolve,reject)=>{
        geocoder.geocode(addresses[i].field2 + 
           ' ' + addresses[i].field3 + 
           ' ' + addresses[i].field4, 
           function(err, results) {
             if (err) {
               return reject(err);
             }
             return resolve(results);
           }
        );
      })
    )
  );
}

然后就可以像

一样使用了
csv({noheader:true})
.fromFile(csvFilePath)
.then((jsonObj)=>convertAddressesToCoords(addresses))
.then((coords)=>console.log(coords))

遍历一个数组然后在最后调用回调是可行的,但它难以阅读并且会导致一些问题,因此我会在这里使用 Promises:

const getCoords = geocoder => address => new Promise((resolve, reject) => {
   address = [address.field2, address.field3, address.field4].join(" ");
   geocoder.geocode(address, function(err, coords) {
      if(err) reject(err) else resolve({ address, coords });
   });
});

所以现在要得到某个坐标,你可以这样做:

getCoords(NodeGeocoder(options))({field2: "Unknown Location"})
  .then(({ address, coords }) => console.log(adress + " is at " + coords));

现在从您的 csv 中获取信息也很容易:

csv({noheader:true})
.fromFile(csvFilePath)
.then(data => Promise.all(data.map(getCoords(NodeGeocoder(options)))
.then(positions => {
  //...
 })

并且 positions 现在是一个坐标/地址对数组。


如果您想使用您的代码,只需添加

const currAddress = addresses[i].field2 + ' ' + addresses[i].field3 + ' ' + addresses[i].field4;

把它保存在闭包中,然后你可以把它推到结果中:

coords.push({ coords: results, address: currAddress });