J'ai un tableau où chaque valeur de tableau est un objet { lat: ___, lng: ___ }
. Je voudrais entrer une fraction (disons 20%
(0.2
)) et obtenir la coordonnée spécifique pour cette fraction, basée sur la distance du point 0. Qu'est-ce que cela signifie que étant donné la distance d
(somme de tous les chemins individuels entre les points) , la coordonnée devrait être 1/5 de d
. Si je devais mettre la fraction à 0
cela me donnerait les premières coordonnées dans le chemin. Et si je devais mettre la fraction à 1
ça me donnerait le dernier.Obtenir la coordonnée à partir du chemin avec plusieurs points en fonction de la fraction de la distance du chemin
J'ai lu sur les coordonnées basées sur les fractions ici sur SO (Calculate point between two coordinates based on a percentage) et utilisé cette fonction dans mon algorithme.
Ce que j'ai pensé que je pourrais faire est d'ajouter tous les chemins entre chaque point pour obtenir une somme d
. Ensuite, pour chaque distance entre les points f
je vérifie pour voir si cette distance était inférieure à d
. Si true
, déduire f
de d
. Si false
, utilisez la fonction du lien ci-dessus et entrez la fraction restante d
. Je pensais que cela me donnerait la bonne coordonnée.
Cela fonctionne dans une certaine mesure, mais pour les chemins individuels avec une longue distance, il laisse des lacunes tout au long du chemin complet.
Voici le code de l'algorithme ainsi que le code de génération de cette image. Je pense que le problème se produit dans modules.fractionCoordinateArray
.
var modules = {};
modules.distance = function (lat1, lon1, lat2, lon2, km = true) {
\t var p = 0.017453292519943295, c = Math.cos;
\t var a = 0.5 - c((lat2 - lat1) * p)/2 + c(lat1 * p) * c(lat2 * p) * (1 - c((lon2 - lon1) * p))/2;
\t if (km) {
\t \t return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
\t } else {
\t \t return 12742 * Math.asin(Math.sqrt(a)) * 1000; // meters
\t }
};
modules.distanceSum = function (arr, km = true) {
\t var total = 0;
\t for (var i = 0; i < arr.length; i++) {
\t \t if (i > 0) {
\t \t \t total += modules.distance(arr[i-1].lat, arr[i-1].lng, arr[i].lat, arr[i].lng, km);
\t \t }
\t }
\t return total;
};
modules.fractionCoordinateArray = function (arr, frac = 0) {
\t var dist = modules.distanceSum(arr), fractions = [];
\t if (frac <= 0) {
\t \t return { lat: arr[0].lat, lng: arr[0].lng };
\t } else if (frac >= 1) {
\t \t return { lat: arr[arr.length-1].lat, lng: arr[arr.length-1].lng };
\t }
\t for (var i = 0; i < arr.length; i++) {
\t \t if (i > 0) {
\t \t \t var frc = modules.distance(arr[i-1].lat, arr[i-1].lng, arr[i].lat, arr[i].lng)/dist;
\t \t \t if (frac > frc) {
\t \t \t \t frac -= frc;
\t \t \t }
\t \t \t else {
\t \t \t \t return modules.fractionCoordinate(arr[i-1].lat, arr[i-1].lng, arr[i].lat, arr[i].lng, frac);
\t \t \t }
\t \t }
\t }
};
modules.fractionCoordinate = function (lat1, lng1, lat2, lng2, per) {
\t return { lat: lat1 + (lat2 - lat1) * per, lng: lng1 + (lng2 - lng1) * per };
};
/*
\t For generating the image I used this;
*/
var dst = [], path = [{lat: 12, lng: 12}, {lat: 13.75, lng: 13}, {lat: 14, lng: 17}, {lat: 59, lng: 18}]; // Example path
for (var i = 0; i < 51; i++) {
\t var crd = modules.fractionCoordinateArray(path, i/50);
\t dst.push('markers=size:tiny%7C' + crd.lat + ',' + crd.lng);
}
console.log('https://maps.googleapis.com/maps/api/staticmap?autoscale=2&size=600x300&maptype=roadmap&format=png&visual_refresh=true&' + dst.join('&'));
Je suis à la recherche de l'aide sur la façon de résoudre ce problème de la manière la plus efficace. Je vous remercie!
C'est génial, merci! J'ai mis à jour le code et l'ai mis dans un [jsFiddle] (https://jsfiddle.net/magnusburton/v1s9qLmy/) et cela fonctionne très bien. C'est juste un écart mineur dans la partie supérieure du chemin maintenant. L'esprit prend un coup d'oeil? En outre, je n'ai pas bien compris la dernière partie sur la façon d'améliorer la vitesse. J'ai ajouté une entrée de distance à chaque élément de tableau dans le violon et pour chaque élément, il augmente. Maintenant, que dois-je utiliser pour la recherche binaire? –
@MagnusBurton: Je suis content que ça marche pour vous. Il est possible que vous ayez une erreur "off-by-one" - la meilleure façon de déboguer ces erreurs est d'essayer des cas plus petits (par exemple, des tableaux de longueur 2) et de voir si vous pouvez l'isoler. En ce qui concerne la recherche binaire: S'il y a, disons, 100 arêtes, vous regardez d'abord l'entrée totale-distance-si-loin du 50e; Si c'est déjà au-dessus de votre distance cible, vous savez qu'il doit être quelque part dans les 50 premiers, alors vous regarderez alors la 25ème entrée; si c'était en dessous de votre distance cible, vous regarderiez alors le 37ème (à peu près à mi-chemin entre 25 et 50), etc. –
J'ai compris ce que j'avais fait de mal et j'ai continué à supprimer la mauvaise valeur dans ma boucle. C'est corrigé maintenant. Merci pour votre explication de la recherche binaire. Va mettre en œuvre cela maintenant parce que cela semble être une amélioration de la vitesse. –