1
votes

Comment exécuter la fonction pour chaque élément sur des tableaux

Je souhaite faire apparaître un div en fonction de la distance. Pour cela, j'obtiens l'emplacement de l'utilisateur et les coordonnées de l'endroit où le div est censé apparaître et je réussis à y parvenir. Mon problème maintenant, c'est qu'il y aura différents endroits où je veux que cela soit disponible, donc je dois trouver un moyen de faire une boucle et de vérifier constamment où se trouve la personne et de voir si elle est proche de la distance de mes coordonnées.

- Obtenir la localisation de la personne

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;
    }
}

- La fonction pour travailler div apparaissant

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

le problème avec ceci est que il ne reconnaît pas les coordonnées provenant de la boucle.

N'importe qui a une recommandation sur la façon de faire exécuter la fonction pour chaque coordonnée de la boucle pour vérifier si j'y suis ou non.


0 commentaires

3 Réponses :


1
votes

Je suggérerais d'abord d'utiliser un tableau de tableaux pour stocker les coordonnées afin que votre latitude et votre longitude soient référencées près l'une de l'autre. J'ai donné quelques exemples de base de boucle, en supposant que checkFunction est quelque chose que vous définissez pour gérer les vérifications de coordonnées.

Vous pouvez utiliser vanilla JS pour effectuer une boucle comme ceci:

$(myArray).each(function(index, value) {
    checkFunction(value);
});

Ou vous pouvez utiliser JQuery pour faire une boucle comme ceci:

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


4 commentaires

Nous devons utiliser for ... of pour gérer l'itération dans les tableaux, tandis que for ... in gère les propriétés d'un objet.


Non? Je ne dis pas pour ... de ne fonctionnera pas, mais je dirai que pour ... cela fonctionne. Je l'utilise quotidiennement. jsfiddle.net/9hL42cuk


Vous avez raison, je ne devrais pas dire que nous «devons» faire quoi que ce soit de la sorte. La plupart du temps, une boucle sur les propriétés énumérables d'un tableau équivaut à une boucle sur ses propriétés itérables. Cela nécessite juste quelques hypothèses raisonnables (comme que votre tableau n'aura pas de clés non définies, personne n'essaiera d'utiliser la déstructuration dans la boucle et Array.prototype n'a pas de propriétés personnalisées dans la portée actuelle.) C'est recommandé utiliser pour ... de pour des raisons de vérification des bizarreries.


Maintenant que je ne savais jamais, mais je suis aussi assez strict sur la façon dont je structure les données (c'est-à-dire ne pas imbriquer les choses de manière étrange). Je travaille principalement avec des API que j'ai écrites moi-même.



3
votes

Il semble que la double boucle passant par les coordonnées n'attend pas la réponse de l'ajax (je suppose que toutes les coordonnées sont nécessaires avant le traitement). Puisque l'appel ajax est asynchrone, les emplacements ne seront pas renseignés tant que le serveur n'aura pas répondu; cependant, la boucle passant par le tableau des emplacements commencera à s'exécuter immédiatement après la demande initiale adressée au serveur et, surtout, avant que les emplacements ne soient remplis.

Essayez de déplacer une majorité de votre fonction dans la fonction de réussite. p>

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;
  }
}```


0 commentaires

1
votes

Je pense que votre algorithme pourrait être un peu simplifié. En particulier, diviser les latitudes et longitudes en tableaux séparés, puis utiliser plus tard des boucles for imbriquées pour les réunir semble inutile. Voici une suggestion qui saute ces étapes.

Notez que cela n'a pas du tout été testé, mais cela pourrait vous aider à progresser sur la bonne voie.

D'autres choses à noter sont la possibilité d'utiliser pour. ..of au lieu des boucles for traditionnelles, en utilisant distance dans la même portée dans laquelle il est déclaré, et en étant prêt pour la situation où 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 commentaires

Merci beaucoup, cela m'a aidé et maintenant ma fonction fonctionne avec toutes les coordonnées !! :)