App inventor 2 en español
Cómo programar los teléfonos móviles con Android.
Curso de App inventor 2 en español - Juan Antonio Villalpando
-- Tutorial de iniciación de App Inventor 2 en español --
Volver al índice del tutorial
___________________________
169P.- Calcula distancia terrestre mediante JavaScript.
p169P_javascript_distancia.aia
- En mis tutoriales de App Inventor hemos visto distintas formas para calcular la distancia geométrica entre dos puntos terrestres mediante Haversine:
15D_procedimientos.htm
- ahora vamos a calcular esa distancia con un código de JavaScript.
- Mediante Thaddeus Vicenty se puede calcular la distancia con una precisión de milímetros.
https://www.movable-type.co.uk/scripts/latlong-vincenty.html
Vincenty's solution for the distance between points on an ellipsoidal earth model is accurate to within 0.5 mm distance (!), 0.000015? bearing, on the ellipsoid being used. Calculations based on a spherical earth model, such as the (much simpler) Haversine , are accurate to around 0.3% - which is still good enough for many (most?) purposes, of course.
- Introduciremos longitud y latitud del punto inicial y del final, en grados.
- El código es simplemente un copia, pega y estudia de aquí:
- https://gist.github.com/mathiasbynens/354587
- Simplemente hay que conocer la entrada y salida de datos de la función calculadora.
- Nosotros introduciremos unos puntos de la siguente forma: 36.525:-6.181:-99,177:19.334
- Qué serán la latitud y longitud de los dos puntos entre los que queremos calcular la distancia.
- La función que calcula la distancia en el código JavaScript es:
function distVincenty(lat1, lon1, lat2, lon2) { }
_________________
- Diseño.
- Subimos el archivo distancia_vicenty.htm
_________________
- Bloques.
_________________
- Archivo distancia_vicenty.htm
distancia_vicenty.htm |
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head><body>
<script>
datos = window.AppInventor.getWebViewString() ; // Obtiene los datos.
datos = datos + ":" ;
coordenada = datos.split(":");
long1 = coordenada[0];
lati1 = coordenada[1];
long2 = coordenada[2];
lati2 = coordenada[3];
window.AppInventor.setWebViewString(distVincenty(long1,lati1,long2,lati2)); // Devuelve el resultado.
//////////////////////////// CODIGO VICENTY //////////////////////////////////////////////////////////////////////////////////////////
/*!
* JavaScript function to calculate the geodetic distance between two points specified by latitude/longitude using the
* Vincenty inverse formula for ellipsoids.
*
* Original scripts by Chris Veness
* Taken from http://movable-type.co.uk/scripts/latlong-vincenty.html and optimized / cleaned up by Mathias Bynens
* Based on the Vincenty direct formula by T. Vincenty, "Direct and Inverse Solutions of Geodesics on the Ellipsoid
* with application of nested equations", Survey Review, vol XXII no 176, 1975
* @param {Number} lat1, lon1: first point in decimal degrees
* @param {Number} lat2, lon2: second point in decimal degrees
* @returns {Number} distance in metres between points
*/
function toRad(n) {
return n * Math.PI / 180;
};
function distVincenty(lat1, lon1, lat2, lon2) {
var a = 6378137,
b = 6356752.3142,
f = 1 / 298.257223563, // WGS-84 ellipsoid params
L = toRad(lon2-lon1),
U1 = Math.atan((1 - f) * Math.tan(toRad(lat1))),
U2 = Math.atan((1 - f) * Math.tan(toRad(lat2))),
sinU1 = Math.sin(U1),
cosU1 = Math.cos(U1),
sinU2 = Math.sin(U2),
cosU2 = Math.cos(U2),
lambda = L,
lambdaP,
iterLimit = 100;
do {
var sinLambda = Math.sin(lambda),
cosLambda = Math.cos(lambda),
sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda));
if (0 === sinSigma) {
return 0; // co-incident points
};
var cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda,
sigma = Math.atan2(sinSigma, cosSigma),
sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma,
cosSqAlpha = 1 - sinAlpha * sinAlpha,
cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha,
C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
if (isNaN(cos2SigmaM)) {
cos2SigmaM = 0; // equatorial line: cosSqAlpha = 0 (§6)
};
lambdaP = lambda;
lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
} while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0);
if (!iterLimit) {
return NaN; // formula failed to converge
};
var uSq = cosSqAlpha * (a * a - b * b) / (b * b),
A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))),
B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))),
deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))),
s = b * A * (sigma - deltaSigma);
return s.toFixed(3); // round to 1mm precision
};
</script>
</body></html>
|
_________________
- Comentarios.
- Los datos llegan mediante:
window.AppInventor.getWebViewString();
- Los datos retornan mediante:
window.AppInventor.setWebViewString
--------------------------------------------------------------------------------------------------
- Llegada de datos:
datos = window.AppInventor.getWebViewString() ; // Obtiene los datos.
datos = datos + ":" ;
- Los datos llegan: datos = 36.525:-6.181:-99,177:19.334
- La orden split, corta los datos por ":"
coordenada = datos.split(":");
long1 = coordenada[0];
lati1 = coordenada[1];
long2 = coordenada[2];
lati2 = coordenada[3];
- Se realiza la función distVicenty:
function distVincenty(lat1, lon1, lat2, lon2) { }
- Retorna el resultado de la función y vuelve a App Inventor mediante:
window.AppInventor.setWebViewString(distVincenty(long1,lati1,long2,lati2)); // Devuelve el resultado.
_________________
- Propuesta.
- Comprobar:
http://www.movable-type.co.uk/scripts/latlong.html
- Ver: 15D_procedimientos.htm
__________________________________
|