как передать какой-то параметр в вызове геокодирования Google - PullRequest
0 голосов
/ 04 июля 2018

У меня есть массив объектов с адресами с четырьмя полями, field1 - текущее местоположение (хранилище), а остальные - информация об адресе.

Моя проблема в том, как мне убедиться, что у меня есть результат с ключом: значением (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 Geocoding Cal является асинхронным, поэтому я не могу найти способ, как сделать эту работу .

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Цикл по массиву с последующим вызовом обратного вызова в конце будет работать, но его трудно прочитать и он может вызвать некоторые проблемы, поэтому я бы использовал здесь 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 });
0 голосов
/ 04 июля 2018

Используйте Promise. Что-то вроде

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))
...