PC SOFT

FOROS PROFESIONALES
WINDEVWEBDEV y WINDEV Mobile

Inicio → WINDEV 2025 → Resultat calcul distance différent entre tableur et WinDev
Resultat calcul distance différent entre tableur et WinDev
Iniciado por Ambroise, 15,jun. 2020 10:38 - 27 respuestas
Miembro registrado
112 mensajes
Publicado el 15,junio 2020 - 10:38
Bonjour,

Je souhaite calculer la distance entre 2 points dont j'ai les coordonnées géographiques SANS UTILISER D'API GOOGLE (exigence de ma hierarchie)

J'ai un point Cercle de coordonnées LongitudeCercle et LatitudeCercle en degres decimaux
un point de coordonnées LongitudePoint et LatitudePoint en degres décimaux.

Je commence par convertir mes valeurs en radian par la formule
LongCercle=(ValPi* LongitudeCercle)/180
... idem pour les autres valeurs

J'ai trouvé une formule sur internet qui est dans mon tableur D=ACOS(SIN(RADIANS(LongCercle))*SIN(RADIANS(LongPoint))+COS(RADIANS(LongCercle))*COS(RADIANS(LongPoint))*COS(RADIANS(LatCercle-LatPoint)))*6378,137

Ma transformation en WD donne :

xDistance=ArcCosinus((Sinus(LongCercle)*Sinus(LongPoint))+(Cosinus(LongCercle)*Cosinus(LongPoint)*Cosinus(LatCercle-LatPoint)))*6378137

Or, je trouve des valeurs très différentes suivant mes tests.
Sur géoportail, la distance mesurée est de 891m
sur Calc, la formule me renvoie 883 m (acceptable pour mon cas)
en WD, la formule me renvoie 1342 m ... soit 50% d'erreur

Ou me suis je planté ?

Merci de vos lumières.
Cordialement
Miembro registrado
334 mensajes
Publicado el 15,junio 2020 - 11:43
Ambroise a écrit :
> Je souhaite calculer la distance entre 2 points dont j'ai les coordonnées géographiques SANS UTILISER D'API GOOGLE (exigence de ma hierarchie)

Tout a fait d'accord avec elle, en se qui me concerne !

Pour la différence, peut-être que la différence provient du fait que dans ta formule Windev, il y manque la fonction RADIANS ?

--
———————————————————————————————————
Ce qui se conçoit bien se code clairement et se débogue facilement...

- Pastiche d’une citation de Nicolas Boileau -
Miembro registrado
356 mensajes
Publicado el 15,junio 2020 - 12:26
Bonjour,

Sauf changement dans les versions récentes les formules trigonométriques de Windev utilisent des angles en degrés.

Tiens nous au courant.

--
Francis MOREL
http://www.SoftProtect.fr
Publicado el 15,junio 2020 - 12:49
manque une virgule dans la partie windev?
6378137 au lieu de 6378,137
Miembro registrado
1.173 mensajes
Publicado el 15,junio 2020 - 13:43
bonjour,
Quels les types des variables utilisées (réel, numérique) ?

--
Thierry TILLIER
Développeur Windev-Webdev
Formation Windev : https://coursdinfo.teachable.com/
Formation bureautique : https://coursdinfo.net
Miembro registrado
112 mensajes
Publicado el 15,junio 2020 - 14:37
Merci à tous pour vous intéresser à mon problème.

Francis MOREL a écrit :
> Sauf changement dans les versions récentes les formules trigonométriques de Windev utilisent des angles en degrés.

J'ai bien vu que je devais utiliser non pas des degrés décimaux dans mes calculs mais des radians.
C'est pour cela que je commence à convertir l'ensemble des coordonnées en radian via la formule :
LongCercle=(ValPI* LongitudeCercle)/180
LatCercle=(ValPI* LatitudeCercle)/180
LongPoint=(ValPI* LongitudePoint)/180
LatPoint=(ValPI* LatitudePoint)/180


THIERRY TILLIER
Quels les types des variables utilisées (réel, numérique) ?


Je me suis souvenu qu'il existait un problème en ce sens au niveau de la précision des types numériques. C'est pour cela que j'utilise des champs et des variables en type numérique.
J'ai aussi tenté avec des types monétaires mais même résultat }:(
Miembro registrado
112 mensajes
Publicado el 15,junio 2020 - 14:41
Jopab a écrit :
manque une virgule dans la partie windev?
6378137 au lieu de 6378,137

Oui j'ai vu mais cela doit me faire une erreur d'un facteur 1000 (exprimer ma distance en mètres ou en kilomètres) mais pas ajouter 50% de ma distance....
Miembro registrado
1.173 mensajes
Publicado el 15,junio 2020 - 14:55
pour les numériques vous pouvez tenter 2 choses
1 - Définir les variables en spécifiant la partie entière et la partie décimale
LongCercle est numérique(9,9)
2 - ajouter le préfixe 0n sur les valeurs fixes

par défaut, les nombres affectés directement à une variable du type numérique sont convertis en réel.

--
Thierry TILLIER
Développeur Windev-Webdev
Formation Windev : https://coursdinfo.teachable.com/
Formation bureautique : https://coursdinfo.net
Miembro registrado
112 mensajes
Publicado el 15,junio 2020 - 15:34
Merci THIERRY TILLIER pour continuer à chercher une solution à mon problème...

1 - Définir les variables en spécifiant la partie entière et la partie décimale
LongCercle est numérique(9,9)
2 - ajouter le préfixe 0n sur les valeurs fixes


J'ai tenté par désespoir le tout pour le tout....
LongCercle est un numérique(2,15)=(ValPI*SAI_LongitudeCercle)/180
LatCercle est un numérique(2,15)=(ValPI*SAI_LatitudeCercle)/180
LongPoint est un numérique(2,15)=(ValPI*SAI_LongitudePoint)/180
LatPoint est un numérique(2,15)=(ValPI*SAI_LatitudePoint)/180
Trace (LongCercle+" = "+Conversion(SAI_LongitudeCercle,"degré","radian"))
Trace (LatCercle+" = "+Conversion(SAI_LatitudeCercle,"degré","radian"))
Trace (LongPoint+" = "+Conversion(SAI_LongitudePoint,"degré","radian"))
Trace (LatPoint+" = "+Conversion(SAI_LatitudePoint,"degré","radian"))


J’obtiens les valeurs suivantes dans le TRACES :
0.855709904231346 = 0.8557099042314
0.035508950524627 = 0.03550895052463
0.855723249018807 = 0.8557232490188
0.035298643585749 = 0.03529864358575


Donc ma conversion fonctionne et ne donne pas une approximation énorme... Cependant, j'ai toujours une réponse retournée de 1350m environ au lies des 890m ;(
Miembro registrado
1.173 mensajes
Publicado el 15,junio 2020 - 16:15
Attention, le SAI_LongitudeCercle (et les autres) doit avoir un masque de saisie qui correspond aux numériques ->numérique(2,15)
Est-bien le cas ?
même question concernant la procédure Conversion.

--
Thierry TILLIER
Développeur Windev-Webdev
Formation Windev : https://coursdinfo.teachable.com/
Formation bureautique : https://coursdinfo.net
Miembro registrado
356 mensajes
Publicado el 15,junio 2020 - 17:21
Re,

> J'ai bien vu que je devais utiliser non pas des degrés décimaux dans mes calculs mais des radians.

En fait c'est tout à fait l'inverse Windev UTILISE DES DEGRÉS pour toutes les formules trigo.
Voir l'aide par exemple pour Cosinus
https://doc.pcsoft.fr/fr-FR/?3050062&3050062
L'angle est bien spécifié en degrés décimaux.

Et de ce fait les ArcCosinus et équivalents sont aussi en degrés et doivent donc être convertis en radians pour être utilisés dans ta formule.

Et a moins que tu ne veuilles une super précision les variables en réels (voir en réel sur 8) sont largement suffisantes.

--
Francis MOREL
http://www.SoftProtect.fr
Miembro registrado
86 mensajes
Publicado el 15,junio 2020 - 17:46
Tu peux toujours essayer ceci


PROCÉDURE Get_Distance(Latitude1,Longitude1,Latitude2,Longitude2)

TempO is real
Rad is real

Rad = 0n57.2957795130823

TempO = Sin(Latitude1/Rad) * Sin(Latitude2/Rad) + Cos(Latitude1/Rad) * Cos(Latitude2/Rad) * Cos(Longitude2/Rad - Longitude1/Rad)

IF TempO > 1 THEN
TempO = 1
ELSE IF TempO < -1 THEN
TempO = -1
END

RENVOYER (0n6372.795477598 * ArcCos(TempO) )

--
Benoit Neve
Miembro registrado
112 mensajes
Publicado el 16,junio 2020 - 07:56
Bonjour et merci B. Neve pour ta procédure.

Hélas, elle me renvoie le même ordre de grandeur avec 50% de plus que la distance mesurée (également 1,340 km et non les 900m attendus).
Miembro registrado
356 mensajes
Publicado el 16,junio 2020 - 09:29
Bonjour Ambroise,

En appliquant mes remarques ci-dessus et avec les valeurs récupérées dans ton post de 15h34 (converties en degrés)
soit
LongCercle est un reel = 49.028957 // degrés
LatCercle est un reel = 2.03451 // degrés
LongPoint est un reel = 49.02933 // degrés
LatPoint est un reel = 2.02246 // degrés

j'obtiens 884m.

A+

--
Francis MOREL
http://www.SoftProtect.fr
Miembro registrado
112 mensajes
Publicado el 16,junio 2020 - 11:03
Bon alors visiblement, j'ai un schmilblick quelque part.

J'ai bien vu que les coordonnées doivent être en DEGRES ...
Voici mon code...

LongCercle est un réel = 49.028957 // degrés
LatCercle est un réel = 2.03451 // degrés
LongPoint est un réel = 49.02933 // degrés
LatPoint est un réel = 2.02246 // degrés

Temp0 is real // Pour tester
Temp1 is real // Pour tester
Rad is real

Rad = 0n57.2957795130823

Temp0 = Sin(LatPoint/Rad) * Sin(LatCercle/Rad) + Cos(LatPoint/Rad) * Cos(LatCercle/Rad) * Cos(LongCercle/Rad - LongPoint/Rad)
Temp1 = Sinus(LatPoint) * Sinus(LatCercle) + Cosinus(LatPoint) * Cosinus(LatCercle) * Cosinus(LongCercle - LongPoint)

IF Temp0 > 1 THEN
Temp0 = 1
ELSE IF Temp0 < -1 THEN
Temp0 = -1
END
IF Temp1 > 1 THEN
Temp1 = 1
ELSE IF Temp1 < -1 THEN
Temp1 = -1
END

D0= (0n6372.795477598 * ArcCosinus(Temp0) )
D1= (0n6372.795477598 * ArcCosinus(Temp1) )
MoiMême=MoiMême+D0+"ou "+D1


Et lors de l'execution j'obtiens dans mon champ libelle :
1.340931 ou 76.82892


Je craque car je ne vois pas où se trouve mon erreur... les degres, les radians, les formules ...........

Francis MOREL, si tu peux m'envoyer ton code car là je n en peux plus de perdre du temps sur ça.

D'avance merci
Miembro registrado
356 mensajes
Publicado el 16,junio 2020 - 12:23
Re,

Comme je te disais les fonction trigo de Windev utilisent les degrés, donc ArcCosinus renvoi des degrés qu'il convient de convertir en radians en divisant par 57.295.
Le code correspondant est alors
LongCercle est un réel = 49.02857 // degrés
LatCercle est un réel = 2.03451
LongPoint est un réel = 49.02933
LatPoint est un réel = 2.02246
xDistance est un réel

xDistance=ArcCosinus((Sinus(LongCercle)*Sinus(LongPoint))+(Cosinus(LongCercle)*Cosinus(LongPoint)*Cosinus(LatCercle-LatPoint)))*6378137/57.295

Trace(xDistance)

A+

--
Francis MOREL
http://www.SoftProtect.fr
Miembro registrado
112 mensajes
Publicado el 16,junio 2020 - 13:34
:merci

Un énorme MERCI !!!!

J'avais tenté de convertir partour de degres en radian.... sauf à la fin

Super, je peux continuer ma cartographie.

ENCORE MERCI A TOUS !!!!
Miembro registrado
86 mensajes
Publicado el 16,junio 2020 - 16:33
Pffff... On cherche comme des boeufs.
Ceci n'utilise PAS les API Google

pos1 est une géoPosition
pos1..Latitude = 1.442951
pos1..Longitude = 43.604363

pos2 est une géoPosition
pos2..Latitude = 2.505874
pos2..Longitude = 50.458744

InfoConstruit("La distance séparant les deux positions est de %1 mètres.", géoDistance(pos1, pos2))

https://doc.pcsoft.fr/?1000019211&name=geodistance_fonction

--
Benoit Neve
Miembro registrado
1.173 mensajes
Publicado el 16,junio 2020 - 16:41
B. Neve
Et oui, on nous l'avait montré dans un TechTour me semble-t-il.
...
ça nous a quand même permis de voir que Francis touche sa bille en Trigo :D

--
Thierry TILLIER
Développeur Windev-Webdev
Formation Windev : https://coursdinfo.teachable.com/
Formation bureautique : https://coursdinfo.net
Miembro registrado
356 mensajes
Publicado el 17,junio 2020 - 10:59
Bonjour,

Au passage merci Thierry pour le compliment :merci: :merci:

Toutefois il reste un léger problème avec cette fonction (que je ne connaissais pas, merci Benoit :D)
Avec les données de Ambroise geodistance() donne 1335.1167 m alors que Google Maps donne 879.57 et la formule d'Ambroise corrigée 883.59
Chercher l'erreur !! ;( ;(

Avec d'autre données les résultats sont similaires différences notables entre Maps et geodistance.
Je n'ose pas imaginer que développeurs de WD ont fait une erreur de radians/dégrés :o

A suivre.

--
Francis MOREL
http://www.SoftProtect.fr
Miembro registrado
499 mensajes
Publicado el 17,junio 2020 - 12:09
Bonjour Francis,

Je crois qu'il s'agit d'une simple confusion entre latitude et longitude. Sur votre le cité plus haut:
LongCercle est un réel = 49.02857 // degrés
LatCercle est un réel = 2.03451
LongPoint est un réel = 49.02933
LatPoint est un réel = 2.02246


Ces coordonnées (2.03451° Nord, 49.02857° Est) donnent un point situé en plein océan indien, à l'est de la Somalie, là où l'inverse (49.02857° Nord, 2.03451° Est) donne un point situé au Nord-Ouest de Paris, ce qui me semble un peu plus correct. ;)
Miembro registrado
356 mensajes
Publicado el 17,junio 2020 - 12:35
Re,

Ouf, j'aime mieux ça

Bien vu Benjamin :merci:

J'ai copié bêtement les valeurs et le code d'Ambroise sans m'apercevoir de l'inversion.
Comme quoi on peut "toucher sa bille en trigo" mais pas en géographie :D

Merci encore de cette correction.

A+

--
Francis MOREL
http://www.SoftProtect.fr
Miembro registrado
112 mensajes
Publicado el 17,junio 2020 - 13:38
Oups, comme quoi on peut " ne toucher sa bille ni en trigo, ni en géo" ;(
Miembro registrado
213 mensajes
Publicado el 17,junio 2020 - 15:48
Bonjour,

Peu importe la bille en trigo ou la boussole en géo, un sujet des plus intéressants.

Je retiens le géoPosition de B. Neve, déjà ajouté à mes raccourcis fonctions.
Un code final révisé d'Ambroise serait intéressant, ne serait-ce que pour la postérité.

Bon dev.

Serge

--
-----
Parfois, la logique est implacable...
Miembro registrado
91 mensajes
Publicado el 18,junio 2020 - 09:34
bonjour,

Et question peut-être stupide, mais comment calculer un point à 1 km (puis faire un cercle autour de ce point) ?
merci pour ces recherches et codes.

A+

Eric
Miembro registrado
112 mensajes
Publicado el 18,junio 2020 - 10:19
Bonjour,
Je me suis TRES GRANDEMENT inspiré du projet OSM disponible sur le site de depot PCSOFT.
J'ai modifié la procédure Affiche-carte pour lui passer un booleen a vrai si je veux un cercle. Ensuite, j'insère le code suivant dans la constitution du fichier html (procedure initcarte()) :
sTmpHTM=sTmpHTM+[
var IconFoyer = L.icon({
iconUrl: 'https://www.association-sauvy.fr/leaflet/marker-icon-red.png', // Pour avoir un marqueur rouge ou autre site pas encore trouvé!!!
iconSize: [38, 55], // size of the icon
iconAnchor: [4, 62], // point of the icon which will correspond to marker's location
popupAnchor: [10, -55] // point from which the popup should open relative to the iconAnchor
});
]
POUR TOUT stCurCercle de tabCur_Cercle
sTmpHTM=sTmpHTM+"L.marker(["+stCurCercle.rLatitude+", "+stCurCercle.rLongitude+"],{icon: IconFoyer})"
sTmpHTM=sTmpHTM+[

.bindPopup('<b>Foyer</b>')
.addTo(mymap);

]

sTmpHTM=sTmpHTM+"var circle = L.circle(["+stCurCercle.rLatitude+","+stCurCercle.rLongitude+"],{"
sTmpHTM=sTmpHTM+[

color:'red',
fillcolor:'#f03',
fillOpacity: 0.3,

]
sTmpHTM=sTmpHTM+"radius: "+nRayon // La taille du rayon du cercle en mètres
sTmpHTM=sTmpHTM+[

})
.addTo(mymap);
]


Je mettrai dès que tout fonctionne mon script sur le site de dépot.

Pour le calcul des distances, j'utilise comme préconisé la fonction geodistance()

Esperant avoir repondu aux attentes.
Bonne journée
Miembro registrado
91 mensajes
Publicado el 18,junio 2020 - 12:32
Merci pour la réponse, jevais étudier cela tranquille.

il faudrait aussi la definition de stCurCercle et de tabCur_Cercle, ainsi que l'explication de leur mise à jour.

Merci bcp.

a+
Eric
Miembro registrado
112 mensajes
Publicado el 18,junio 2020 - 14:47
J ai fait la meme chose que stCutPoint et tabCurPoint du projet OSM24....
Je pense que mon code pourrait être simplifié mais tant que ca fonctionne, on verra plus tard quand l'ensemble du projet sera fonctionnnel.

Pour le moment encore quelques bugs et de l'exploitation de résultats à coder.... donc ca v attendre.