Curioso asunto resultó ser la investigación de cómo calcular la distancia entre dos coordenadas.
Se encontraron métodos por todos lados muy semejantes entre sí.
Varios de ellos tenían como error común el no pasar a radianes los valores que se utilizan con las funciones trigonométricas.
Las funciones toRad y distanceBetween que se puede ver a continuación tienen su origen en lo encontrado en este enlace: https://stackoverflow.com/questions/5260423/torad-javascript-function-throwing-error/7179026#7179026
La modificación básicamente ha sido hacer que el resultado sea devuelto en metros y no en millas.
Se han hecho pruebas y las distancias en la ciudad capital de Guatemala que salen del cálculo me ha parecido bastante cercano a la realidad.
A continuación encontrarán:// Devuelve en radianes el valor del parámetro function toRad(Value) { return Value * Math.PI / 180; } // Calcula en metros la distancia entre dos coordenadas function distanceBetween(lat1, lon1, lat2, lon2) { var R = 3958.7558657440545; // Radius of earth in Miles R = 6371 * 1000; // meters var dLat = toRad(lat2-lat1); var dLon = toRad(lon2-lon1); var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * 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; }
<!doctype html> <html lang="es"> <head> <meta charset="utf-8"> <title>Google Maps - Distancia entre coordenadas</title> <style> * { margin: 0; padding: 0;} body, html { background-color:transparent; width:100%; height:100%;} table thead tr th { font-weight: normal; } table { color:#FFF; font-size:1.2em; } #data_c { width:100%; height: auto; display:block; background-color:#333; } #map { width:100%; height:90%; display:block; background-color:#333; } #distance_c { text-align: center; font-size:1.2em; background-color:#069; } </style> </head> <body> <div id="data_c" name="data_c"> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <thead> <tr> <th width="33%">Marcador I<hr/></th> <th width="33%" style="background-color:#069;">Distancia<hr/></th> <th width="33%">Marcador II<hr/></th> </tr> </thead> <tbody> <tr> <td> <table style="margin:0px auto;"> <tr> <td><div id="marker1_lat" name="marker1_lat">a</div></td> <td>,</td> <td><div id="marker1_lng" name="marker1_lng">b</div></td> </tr> </table> </td> <td style="background-color:#069;"><div id="distance_c" name="distance_c"></div></td> <td> <table style="margin:0px auto;"> <tr> <td><div id="marker2_lat" name="marker2_lat">c</div></td> <td>,</td> <td><div id="marker2_lng" name="marker2_lng">d</div></td> </tr> </table> </td> </tr> </tbody> </table> </div> <div id="map" name="map"></div> <script type="text/javascript"> var map; var marker1; var marker2; centerLat = 14.622074373952; centerLng = -90.514445682417; // ////////////////////////////////////////////////////////////// // Funciones toRad y distanceBetween son copias casi idénticas de // lo que se encontró publicado en este enlace: // https://stackoverflow.com/questions/5260423/torad-javascript-function-throwing-error/7179026#7179026 // ////////////////////////////////////////////////////////////// // Devuelve en radianes el valor del parámetro function toRad(Value) { return Value * Math.PI / 180; } // Calcula en metros la distancia entre dos coordenadas function distanceBetween(lat1, lon1, lat2, lon2) { var R = 3958.7558657440545; // Radius of earth in Miles R = 6371 * 1000; // meters var dLat = toRad(lat2-lat1); var dLon = toRad(lon2-lon1); var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * 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; } // ////////////////////////////////////////////////////////////// // Limpia valores de contenedores de datos de latitud y longitud por marcador function coord_clearInfo(marker) { document.getElementById(marker + '_lat').innerHTML = ''; document.getElementById(marker + '_lng').innerHTML = ''; } // Actualiza latitud y longitud por marcador // y actualiza la distancia entre los dos marcadores en metros y kilómetros function coord_setPos(marker, latLng) { document.getElementById(marker + '_lat').innerHTML = latLng.lat(); document.getElementById(marker + '_lng').innerHTML = latLng.lng(); d = distanceBetween( marker1.getPosition().lat(), marker1.getPosition().lng(), marker2.getPosition().lat(), marker2.getPosition().lng() ); document.getElementById('distance_c').innerHTML = d.toFixed(2) + ' metros' + ' / ' + (d/1000).toFixed(2) + ' kilómetros'; } // Inicialización del mapa con el API de Google Maps function initAutocomplete() { // El mapa map = new google.maps.Map(document.getElementById('map'), { center: {lat: centerLat, lng: centerLng}, zoom: 10, mapTypeId: 'roadmap' }); // Marcador I marker1 = new google.maps.Marker({ map:map, draggable:true, position: {lat: centerLat, lng: centerLng}, title :'Marcador I' }); // Marcador II... "al lado" del I marker2 = new google.maps.Marker({ map:map, draggable:true, position: {lat: (centerLat + 0.1), lng: (centerLng + 0.1)}, title :'Marcador II' }); // Actualización de coordenadas de los dos marcadores coord_setPos('marker1', marker1.getPosition()); coord_setPos('marker2', marker2.getPosition()); // Asignación de eventos de inicio, durante y finalización de movimiento de marcador I google.maps.event.addListener(marker1, 'dragstart', function() { coord_clearInfo('marker1'); } ); google.maps.event.addListener(marker1, 'drag', function() { coord_setPos('marker1', marker1.getPosition()); }); google.maps.event.addListener(marker1, 'dragend', function() { coord_setPos('marker1', marker1.getPosition()); }); // Asignación de eventos de inicio, durante y finalización de movimiento de marcador II google.maps.event.addListener(marker2, 'dragstart', function() { coord_clearInfo('marker2'); } ); google.maps.event.addListener(marker2, 'drag', function() { coord_setPos('marker2', marker2.getPosition()); }); google.maps.event.addListener(marker2, 'dragend', function() { coord_setPos('marker2', marker2.getPosition()); }); } </script> <script src="https://maps.googleapis.com/maps/api/js?key=[GOOGLE MAPS KEY]&libraries=places&callback=initAutocomplete" async defer></script> </body> </html>