Как запустить функцию для каждого элемента в массивах - PullRequest
0 голосов
/ 18 апреля 2019

Я хочу, чтобы div отображался в зависимости от расстояния. Для этого я получаю местоположение пользователя и координаты места, где должен появиться div, и я добиваюсь успеха, чтобы это произошло. Моя проблема сейчас в том, что будут разные места, где я хочу, чтобы это было доступно, поэтому мне нужно найти способ зацикливаться и постоянно проверять, где находится человек, и посмотреть, близко ли это к расстоянию от моих координат.

- Получение местоположения человека

if (navigator.geolocation){
    navigator.geolocation.watchPosition(showPosition)
}

- Функция для работы с div появляется

function showPosition(position){

  let locationLatitude = []
  let locationsLongitude = []

  //AJAX CALL TO GET THE POSITION OF THE PLACES AND PUSHING THEM TO THE ARRAYS
  let success = function(res){
    let locations = res.locations

    for (var i=0; i<locations.length; i++){
      locationLatitude.push(locations[i]['place_latitude'])
      locationsLongitude.push(locations[i]['place_longitude'])
    }
  }

   $.ajax({
      type: 'GET',
      url: '/api/locations',
      crossDomain: true,
      dataType: 'json',
      async: false,
      success : success,
  });

  // LOOP TO GET ALL COORDIANTES FROM PLACES (LAT,LONG)
  var locationLatitudeLength = locationLatitude.length
  var locationsLongitudeLength = locationsLongitude.length
  let startPosLat
  let startPosLong

  for(var i=0; i<locationLatitudeLength; i++){

    for(var j=0; j<locationsLongitudeLength; j++){
      startPosLat = locationLatitude[i]
      startPosLong = locationsLongitude[j]

      userlocationLatitude = position.coords.latitude
      userlocationLongitude = position.coords.longitude

     //PASS VALUES OF COORDINATES TO THE FUNCTION
     let distance = calculateDistance(startPosLat, startPosLong, userlocationLatitude, userlocationLongitude)

      }

  }

   if(distance < .05){
      $('.div-image').attr('src', 'pic2.jpg')
   }else if(distance > .05){
      $('.div-image').attr('src', 'pic.jpg')
   }


    //function to calculate the distance between two points of coordinates 
    function calculateDistance(lat1, lon1, lat2, lon2) {
        var R = 6371; // km
        var dLat = (lat2-lat1).toRad();
        var dLon = (lon2-lon1).toRad();
        var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
                Math.sin(dLon/2) * Math.sin(dLon/2);
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        var d = R * c;
        return d;
    }
      Number.prototype.toRad = function() {
        return this * Math.PI / 180;
    }
}

проблема в том, что он не распознает координаты, поступающие из цикла.

У каждого есть рекомендация, как заставить функцию запускаться для каждой координаты в цикле, чтобы проверить, там я или нет.

Ответы [ 3 ]

3 голосов
/ 18 апреля 2019

Похоже, что двойной цикл, проходящий через координаты, не ждет ответа от ajax (я предполагаю, что все координаты необходимы перед обработкой). Поскольку вызов ajax является асинхронным, местоположения не будут заполняться, пока сервер не ответит; однако цикл, проходящий через массив местоположений, начнет выполняться сразу после того, как начальный запрос сделан к серверу и, что наиболее важно, до того, как местоположения будут заполнены.

Попробуйте перенести большую часть своей функции в функцию успеха.

function showPosition(position){

  let locationLatitude = []
  let locationsLongitude = []

  //AJAX CALL TO GET THE POSITION OF THE PLACES AND PUSHING THEM TO THE ARRAYS
  let success = function(res){
    let locations = res.locations

    for (var i=0; i<locations.length; i++){
      locationLatitude.push(locations[i]['place_latitude'])
      locationsLongitude.push(locations[i]['place_longitude'])
    }

    // LOOP TO GET ALL COORDIANTES FROM PLACES (LAT,LONG)
    var locationLatitudeLength = locationLatitude.length
    var locationsLongitudeLength = locationsLongitude.length
    let startPosLat
    let startPosLong

    for(var i=0; i<locationLatitudeLength; i++){

      for(var j=0; j<locationsLongitudeLength; j++){
        startPosLat = locationLatitude[i]
        startPosLong = locationsLongitude[j]

        userlocationLatitude = position.coords.latitude
        userlocationLongitude = position.coords.longitude

        //PASS VALUES OF COORDINATES TO THE FUNCTION
        let distance = calculateDistance(startPosLat, startPosLong, userlocationLatitude, userlocationLongitude)
      }
    }

    if(distance < .05){
        $('.div-image').attr('src', 'pic2.jpg')
    }else if(distance > .05){
        $('.div-image').attr('src', 'pic.jpg')
    }
  }

   $.ajax({
      type: 'GET',
      url: '/api/locations',
      crossDomain: true,
      dataType: 'json',
      async: false,
      success : success,
  });

  //function to calculate the distance between two points of coordinates 
  function calculateDistance(lat1, lon1, lat2, lon2) {
      var R = 6371; // km
      var dLat = (lat2-lat1).toRad();
      var dLon = (lon2-lon1).toRad();
      var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
              Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
              Math.sin(dLon/2) * Math.sin(dLon/2);
      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      var d = R * c;
      return d;
  }

  Number.prototype.toRad = function() {
    return this * Math.PI / 180;
  }
}```
1 голос
/ 18 апреля 2019

Я думаю, ваш алгоритм может быть немного упрощен. В частности, разделение широты и долготы на отдельные массивы и последующее использование вложенных циклов for для их объединения представляется ненужным. Вот предложение, которое пропускает эти шаги.

Обратите внимание, что это полностью не проверено, но оно может помочь вам в правильном направлении.

Следует также отметить возможность использования for...of вместо традиционных циклов for, использование distance в той же области, в которой оно объявлено, и готовность к ситуации, когда distance == .05.

function showPosition(position){
  const userlocationLatitude = position.coords.latitude;
  const userlocationLongitude = position.coords.longitude;
  let success = function(res){
    for(let location of res.locations){
      let startPosLat = location['place_latitude'],
          startPosLng = location['place_longitude'],
          distance = calculateDistance(startPosLat, startPosLong, userlocationLatitude, userlocationLongitude);
      if(distance < .05){ $('.div-image').attr('src', 'pic2.jpg'); }
      else{ $('.div-image').attr('src', 'pic.jpg'); }  
    }
  }
  $.ajax({ type: 'GET', url: '/api/locations', crossDomain: true, dataType: 'json', async: false, success : success });

  //function to calculate the distance between two points of coordinates 
  function calculateDistance(lat1, lon1, lat2, lon2) {
      var R = 6371, dLat = (lat2-lat1).toRad(), dLon = (lon2-lon1).toRad(),
          a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * Math.sin(dLon/2) * Math.sin(dLon/2),
          c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      return R * c;
  }
  Number.prototype.toRad = function() { return this * Math.PI / 180; }
}
1 голос
/ 18 апреля 2019

Сначала я бы предложил использовать массив массивов для хранения координат, чтобы ваши широта и долгота были привязаны рядом друг с другом.Я привел несколько основных примеров зацикливания, предполагая, что checkFunction - это то, что вы определяете для обработки проверок координат.

Вы можете использовать vanilla JS для зацикливания следующим образом:

for (var i in myArray) {
   checkFunction(myArray[i]);
}

Или вы можете использоватьJQuery для цикла, как это:

$(myArray).each(function(index, value) {
    checkFunction(value);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...