@Pe_Bo - Ideálně udělat funkce vracející jednu hodnotu - nevím jestli SQLite zvládne jako výsledek pole. Pokud to umí a uděláš k tomu pak příklad tak klidně udělej dvě fce co budou vracet pole.
distance(lat_start, lon_start, lat_end, lon_end) - vrací vzdálenost mezi body - jednotky nechám na autorovi, každopádně klidně nechat vyšší přesnost, nezaokrouhlovat výsledek
azimut_start(lat_start, lon_start, lat_end, lon_end) - výchozí azimut, hodnota ideálně ve stupních mezi 0 a 360 - nezaokrouhlovat
azimut_end(lat_start, lon_start, lat_end, lon_end) - koncový azimut, hodnota ideálně ve stupních mezi 0 a 360 - nezaokrouhlovat
project_lat(lat, lon, azimut_start, distance) - projekce bodu - latitude - hodnota ideálně ve stupních mezi -180 a 180 - nezaokrouhlovat
project_lon(lat, lon, azimut_start, distance) - projekce bodu - longitude - hodnota ideálně ve stupních mezi -180 a 180 - nezaokrouhlovat
A jako teaser. Vincentyho metoda v aplikaci nad GG db a GC4PCQB
WITH/* --360°challenge CZ */ params AS (
SELECT id,
7 cnt,/* počet Vincentyho iterací - lambdaDiff by mělo být <1E-12 */
49.74375 x1,
15.33863333 y1,/* CZ N 49° 44.625 E 015° 20.318 - 49.74375 15.33863333 */
x x2,
y y2,
6378.137 a,
6356.752314245 b/* Semi-major axis a = 6378137.0 metres
Semi-minor axis b ≈ 6356752.314245 metres
Inverse flattening 1/f = 298.257223563
kontrola výpočtu provedena https://www.ngs.noaa.gov/cgi-bin/Inv_Fwd/inverse2.prl
http://www.movable-type.co.uk/scripts/latlong-vincenty.html */
FROM geocache/* WHERE cachestatus<>2-- <> 0 */
WHERE country = 'Czech Republic'
),
iteration (
id,
cnt,
a,
b,
f,
x1,
y1,
x2,
y2,
fi1,
lambda1,
fi2,
lambda2,
L,
tanU1,
tanU2,
cosU1,
cosU2,
sinU1,
sinU2,
lambda,
sinSigma,
cosSigma,
sigma,
sinAlfa,
cosSqAlfa,
cos2SigmaM,
C,
lambdaIter,
lambdaDiff
)
AS (
SELECT id,
1 cnt,
a,
b,
( (a - b) / a) f,
x1,
y1,
x2,
y2,
(x1 * PI() / 180) fi1,/* fí latitude */
(y1 * PI() / 180) lambda1,/* lambda longitude */
(x2 * PI() / 180) fi2,
(y2 * PI() / 180) lambda2,
( (y2 * PI() / 180) - (y1 * PI() / 180) ) L,
(1 - ( (a - b) / a) ) * tan( (x1 * PI() / 180) ) tanU1,
(1 - ( (a - b) / a) ) * tan( (x2 * PI() / 180) ) tanU2,
1 / (sqrt(1 + ( (1 - ( (a - b) / a) ) * tan( (x1 * PI() / 180) ) ) * ( (1 - ( (a - b) / a) ) * tan( (x1 * PI() / 180) ) ) ) ) cosU1,
1 / (sqrt(1 + ( (1 - ( (a - b) / a) ) * tan( (x2 * PI() / 180) ) ) * ( (1 - ( (a - b) / a) ) * tan( (x2 * PI() / 180) ) ) ) ) cosU2,
( (1 - ( (a - b) / a) ) * tan( (x1 * PI() / 180) ) ) * (1 / (sqrt(1 + ( (1 - ( (a - b) / a) ) * tan( (x1 * PI() / 180) ) ) * ( (1 - ( (a - b) / a) ) * tan( (x1 * PI() / 180) ) ) ) ) ) sinU1,
( (1 - ( (a - b) / a) ) * tan( (x2 * PI() / 180) ) ) * (1 / (sqrt(1 + ( (1 - ( (a - b) / a) ) * tan( (x2 * PI() / 180) ) ) * ( (1 - ( (a - b) / a) ) * tan( (x2 * PI() / 180) ) ) ) ) ) sinU2,
( (y2 * PI() / 180) - (y1 * PI() / 180) ) lambda,
0 sinSigma,
0 cosSigma,
0 sigma,
0 sinAlfa,
0 cosSqAlfa,
0 cos2SigmaM,
0 C,
( (y2 * PI() / 180) - (y1 * PI() / 180) ) lambdaIter,
0 lambdaDiff
FROM params
UNION ALL
SELECT id,
cnt + 1 cnt,
a,
b,
f,
x1,
y1,
x2,
y2,
fi1,
lambda1,
fi2,
lambda2,
L,
tanU1,
tanU2,
cosU1,
cosU2,
sinU1,
sinU2,
lambdaIter lambda,
(sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) sinSigma,
(sinU1 * sinU2 + cosU1 * cosU2 * cos(lambdaIter) ) cosSigma,
(atan2( (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ), (sinU1 * sinU2 + cosU1 * cosU2 * cos(lambdaIter) ) ) ) sigma,
(cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ) sinAlfa,
(1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) cosSqAlfa,
(CASE/* osetreni pokud se pocita czdalenost na rovniku -> deleni nulou */ WHEN (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) = 0 THEN 0 ELSE ( (sinU1 * sinU2 + cosU1 * cosU2 * cos(lambdaIter) ) - 2 * ( (sinU1 * sinU2) / (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) ) ) END) cos2SigmaM,
f / 16 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) * (4 + f * (4 - 3 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) ) ) C,
(L + (1 - (f / 16 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) * (4 + f * (4 - 3 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) ) ) ) ) * f * (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ) * ( (atan2( (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ), (sinU1 * sinU2 + cosU1 * cosU2 * cos(lambdaIter) ) ) ) + (f / 16 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) * (4 + f * (4 - 3 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) ) ) ) * (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) * ( (CASE/* osetreni pokud se pocita czdalenost na rovniku -> deleni nulou */ WHEN (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) = 0 THEN 0 ELSE ( (sinU1 * sinU2 + cosU1 * cosU2 * cos(lambdaIter) ) - 2 * ( (sinU1 * sinU2) / (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) ) ) END) + (f / 16 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) * (4 + f * (4 - 3 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) ) ) ) * (sinU1 * sinU2 + cosU1 * cosU2 * cos(lambdaIter) ) * ( -1 + 2 * power( (CASE/* osetreni pokud se pocita czdalenost na rovniku -> deleni nulou */ WHEN (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) = 0 THEN 0 ELSE ( (sinU1 * sinU2 + cosU1 * cosU2 * cos(lambdaIter) ) - 2 * ( (sinU1 * sinU2) / (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) ) ) END), 2) ) ) ) ) lambdaIter,
(L + (1 - (f / 16 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) * (4 + f * (4 - 3 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) ) ) ) ) * f * (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ) * ( (atan2( (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ), (sinU1 * sinU2 + cosU1 * cosU2 * cos(lambdaIter) ) ) ) + (f / 16 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) * (4 + f * (4 - 3 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) ) ) ) * (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) * ( (CASE/* osetreni pokud se pocita czdalenost na rovniku -> deleni nulou */ WHEN (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) = 0 THEN 0 ELSE ( (sinU1 * sinU2 + cosU1 * cosU2 * cos(lambdaIter) ) - 2 * ( (sinU1 * sinU2) / (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) ) ) END) + (f / 16 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) * (4 + f * (4 - 3 * (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) ) ) ) * (sinU1 * sinU2 + cosU1 * cosU2 * cos(lambdaIter) ) * ( -1 + 2 * power( (CASE/* osetreni pokud se pocita czdalenost na rovniku -> deleni nulou */ WHEN (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) = 0 THEN 0 ELSE ( (sinU1 * sinU2 + cosU1 * cosU2 * cos(lambdaIter) ) - 2 * ( (sinU1 * sinU2) / (1 - power( (cosU1 * cosU2 * sin(lambdaIter) / (sqrt(power( (cosU2 * sin(lambdaIter) ), 2) + power( (cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ), 2) ) ) ), 2) ) ) ) END), 2) ) ) ) ) - lambda lambdaDiff
FROM iteration
WHERE cnt < (
SELECT DISTINCT cnt
FROM params
)
),
vincenty AS (
SELECT id,
x1,
y1,
x2,
y2,
distance,
bearing,
floor(bearing) bearing_int,
bearing_fin/* hodnota je ve směru DO cílového bodu - pro zpětný nutno připočíst 180st */,
lambdaDiff
FROM (
SELECT *,
(cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) uSq,
(1 + ( (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) / 16384) * (4096 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * ( -768 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * (320 - 175 * (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) ) ) ) ) bigA,
( ( (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) / 1024) * (256 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * ( -128 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * (74 - 47 * (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) ) ) ) ) bigB,
( ( ( (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) / 1024) * (256 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * ( -128 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * (74 - 47 * (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) ) ) ) ) * sinSigma * (cos2SigmaM + ( ( ( (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) / 1024) * (256 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * ( -128 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * (74 - 47 * (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) ) ) ) ) / 4) * (cosSigma * ( -1 + 2 * power(cos2SigmaM, 2) ) - ( ( ( (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) / 1024) * (256 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * ( -128 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * (74 - 47 * (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) ) ) ) ) / 6) * cos2SigmaM * ( -3 + 4 * power(sinSigma, 2) ) * ( -3 + 4 * power(cos2SigmaM, 2) ) ) ) ) deltaSigma,
b * (1 + ( (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) / 16384) * (4096 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * ( -768 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * (320 - 175 * (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) ) ) ) ) * (sigma - ( ( ( (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) / 1024) * (256 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * ( -128 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * (74 - 47 * (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) ) ) ) ) * sinSigma * (cos2SigmaM + ( ( ( (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) / 1024) * (256 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * ( -128 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * (74 - 47 * (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) ) ) ) ) / 4) * (cosSigma * ( -1 + 2 * power(cos2SigmaM, 2) ) - ( ( ( (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) / 1024) * (256 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * ( -128 + (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) * (74 - 47 * (cosSqAlfa * ( (power(a, 2) - power(b, 2) ) / power(b, 2) ) ) ) ) ) ) / 6) * cos2SigmaM * ( -3 + 4 * power(sinSigma, 2) ) * ( -3 + 4 * power(cos2SigmaM, 2) ) ) ) ) ) distance,
CASE WHEN (180 / PI() * atan2(cosU2 * sin(lambdaIter), cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ) ) < 0 THEN 360 + (180 / PI() * atan2(cosU2 * sin(lambdaIter), cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ) ) ELSE (180 / PI() * atan2(cosU2 * sin(lambdaIter), cosU1 * sinU2 - sinU1 * cosU2 * cos(lambdaIter) ) ) END bearing,
CASE WHEN (180 / PI() * atan2(cosU1 * sin(lambdaIter), -sinU1 * cosU2 + cosU1 * sinU2 * cos(lambdaIter) ) ) < 0 THEN 360 + (180 / PI() * atan2(cosU1 * sin(lambdaIter), -sinU1 * cosU2 + cosU1 * sinU2 * cos(lambdaIter) ) ) ELSE (180 / PI() * atan2(cosU1 * sin(lambdaIter), -sinU1 * cosU2 + cosU1 * sinU2 * cos(lambdaIter) ) ) END bearing_fin
FROM iteration
WHERE cnt = (
SELECT DISTINCT cnt
FROM params
)
)
),
loop (
cnt
)
AS (
SELECT 0 cnt
UNION ALL
SELECT cnt + 1/* čítač */
FROM loop
WHERE cnt < 359
),
found_sector AS (
SELECT l.cnt
FROM (
SELECT *
FROM loop
)
l
LEFT JOIN
(
SELECT DISTINCT bearing_int
FROM (
SELECT *
FROM geocache g
WHERE dtfound <> 0 AND
country = 'Czech Republic'
)
g
LEFT JOIN
vincenty v ON g.id = v.id
)
f ON l.cnt = f.bearing_int
WHERE f.bearing_int IS NULL
)
SELECT g.id,
g.name,
v.bearing_int,
v.distance
FROM (
SELECT *
FROM geocache g
WHERE dtfound = 0 AND
cachestatus <> 2 AND
country = 'Czech Republic'
)
g
LEFT JOIN
vincenty v ON g.id = v.id
JOIN
found_sector s ON s.cnt = v.bearing_int
ORDER BY v.distance,
v.bearing_int,
g.id;