Přejít na obsah


Fotka

Vincenty SQL

geoget

  • Pokud chcete vložit odpověď, přihlašte se
45 odpovědí na toto téma

#1 tarmara

tarmara

    Air-cooled

  • Members
  • PipPipPip
  • 974 příspěvků(y)

Publikováno 31 říjen 2017 - 12:24

Už se to tu kdysi řešilo, ale čas plyne a mě se konečně podařilo Vincentyho metodu přepsat do SQL. S klauzulí WITH už není problém v rámci jednoho dotazu iterovat. Čísla které mi dotaz vrací sedí na kontrolní formulář National Geodetic Survey při NOAA - čímžto si dovolím tvrdit, že mi dotaz kalkuluje čísla správná. 

 

Začal jsem tedy tvořit dotaz, který by mi vrátil chybějící kešky pro doplnění statorového modulu FindsByBearingChallenge - můj výsledek se oproti statorovému rozchází asi o 5 sektorů (337 vs. 342). Můžete říct, že ta přesnost je zběsilá (v azimutech se lišíme v desetinách, ve vzdálenostech jsou to nízké jednotky metrů, případně centimetry), ale matematika je krásná v tom, že by se výsledky kalkulované stejnou metodou lišit neměly a pokud ano, tak velmi málo (na 4 nebo 5 desetinném místě). Toto je pak způsobené zaokrouhlováním a různou interpretací des. čísel v počítačových programech. 

 

Takže "stay tuned", jsem v kontaktu s Gordem a HaLuMa a zjišťuju proč se výpočty liší - první moje podezření je na nedostatečný počet iterací Vincentyho metody v proceduře GG, která ji počítá. Kdysi se pro výpočet VM končilo s iterací kvůli výpočetní složitosti při průběžné diferenci kolem 10^-12, dnes se dá jít až na hranici datového typu při počítačové kalkulaci - mě to v SQLite končí při rozdílu 10^-19 - i tak se počet iterací pohybuje mezi sedmi a osmi. Vycházím ze znalosti inverzní procedury ProjectPoint, která počítá Vincentyho metodou projekci bodu. Tyto procedury autor převzal z již hotového řešení a z pochopitelných důvodů (viz. níže) se nezabýval její přesnou funkčností. 

 

Pokud chcete vidět jak vypadá jeden z použitých vzorečků (vůbec se nedivím, že to autor nekontroloval, to by pozdrželo vývoj GG asi o dva roky - z toho půl roční pobyt v psychiatrické ozdravovně...):

 (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) ) ) ) * ( (atan( (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

Samotný kód uveřejním jakmile bude dotestováno a rekonciliováno na Stator, kterýžto pokládám za prubířský kámen a měl by vracet co nejpřesnější výsledky. Pak zase sepíšu nějaký pěkný článek na blog.


  • 5

#2 gord

gord

    Advanced Member

  • Members
  • PipPipPip
  • 10 143 příspěvků(y)

Publikováno 31 říjen 2017 - 12:36

Tohle cpat do SQL bych nemel odvahu :-) Dekuji za tvoji vyzkumnou cinnost.


  • 0

MHD/PID vybranych mest CR jako POI (diskuse)
GeoGet:
- Combine - automatizace opakovanych cinnosti (diskuse, dávky)

Stator - statistiky y GeoGetu (diskuse)

- Spoiler - uložení spoilerů do GPS jako POI (diskuse)

- Náhrada GJ legálními postupy

 


#3 tarmara

tarmara

    Air-cooled

  • Members
  • PipPipPip
  • 974 příspěvků(y)

Publikováno 31 říjen 2017 - 12:55

  1. pokud se vám rozchází výsledky a víte že postup výpočtu je stejný, tak si zkontrolujte že máte stejné vstupní hodnoty - rozdíl 0,001' (něco jiného na https://www.geocachi...gs/homelocation a něco jiného ve Statoru - naivně jsem doufal, že si to GG bere přes API z webu - možná i jo, možná jsem si to měnil na webu a neaktualizoval v GG) - teď už hodnoty sedí jak prdel na hrnec (konkrétně u úhlu se lišíme na 7. desetinném místě stupňů (což je méně než 0,001') a ve vzdálenosti o 3mm (na 137km :))).
  2. vypadá to na přehozený výchozí a konečný azimut - na geoidu nejdete nejkratší cestou z jednoho do druhého bodu pod stále stejným azimutem (protože to není koule a elipsoid, takže nejdete po kružnici ale po elipse) a oni se ty dva úhly liší celkem minimálně. Sám jsem udělal stejnou chybu, ale při kontrole na etalon z NGS jsem na ni přišel. Připravím nějaké důkazní materiály a dám autorům vědět.

Tento příspěvek byl upraven od tarmara: 31 říjen 2017 - 14:47

  • 1

#4 tarmara

tarmara

    Air-cooled

  • Members
  • PipPipPip
  • 974 příspěvků(y)

Publikováno 31 říjen 2017 - 15:34

Rekonciliace na Stator dokončena. Stator je samozřejmě správně, chybka byla opět na interface mezi židlí a klávesnicí. Goniometrické funkce nebyly nikdy mou silnou stránkou, arkus tangens líně se plížící mezi -1/2Pí a 1/2Pí - takže zbývá jen dořešit problém s body vzdálenými víc jak cca 10000km (implementace pak vrací zápornou vzdálenost a nějaké nesmyslné úhly). V naší česká kotlině pár takových keší je, jinak by se toto issue nemělo projevit , ale když už na tom makám, tak ať je to pořádně.


  • 2

#5 HaLuMa

HaLuMa

    Autor Geogetu

  • Members
  • PipPipPip
  • 14 531 příspěvků(y)

Publikováno 31 říjen 2017 - 15:53

Tak jsem se v tom uz ztratil, a uz vubec nevim, kdo ma co blbe. :unsure:


  • 0

#6 tarmara

tarmara

    Air-cooled

  • Members
  • PipPipPip
  • 974 příspěvků(y)

Publikováno 31 říjen 2017 - 16:31

Tak i záporná vzdálenost vyřešena! Než používat atan funkci, je lepší vzít atan2


  • 1

#7 tarmara

tarmara

    Air-cooled

  • Members
  • PipPipPip
  • 974 příspěvků(y)

Publikováno 31 říjen 2017 - 16:35

Tak jsem se v tom uz ztratil, a uz vubec nevim, kdo ma co blbe. :unsure:

Blbě jsem to měl já, Stator i GG to počítá správně. Jen mi chvilku trvalo, než jsem na to přišel, kde mám chyby. Každopádně díky HaLuMa i Gord za pomoc a vlastně i za dodání "správných" dat, na kterých jsem mohl zkoušet a vyvíjet. V tuto chvíli už mám hotovo, čísla vrací dotaz správně (= tak jak jsou ve Statoru a GG, kde jsou v pořádku).


  • 0

#8 kiReGPS

kiReGPS

    Advanced Member

  • Members
  • PipPipPip
  • 2 345 příspěvků(y)

Publikováno 31 říjen 2017 - 17:31

Iterace v SQL. Hmmm, tak to už je fakt vyšší dívčí. Velká poklona a palec nahoru...
  • 0

#9 HaLuMa

HaLuMa

    Autor Geogetu

  • Members
  • PipPipPip
  • 14 531 příspěvků(y)

Publikováno 31 říjen 2017 - 18:03

Nikdy bych nerekl, ze takovehle magie je Sqlite vubec schopen. Ze by v tom mel prsty dnesni Halloween? ;)


  • 0

#10 tarmara

tarmara

    Air-cooled

  • Members
  • PipPipPip
  • 974 příspěvků(y)

Publikováno 31 říjen 2017 - 21:32

žádná magie, ale už od SQL:1999 - viz https://en.wikipedia...able_expression - dají se s tím dělat psí kusy, ale občas je ta implementace značně nevyzpytatelná - např. * nevypíše všechny sloupce, pokud v poddotazu byla už * použita...ale dá se na ně explicitně odkázat....prostě taková past vedle pasti. To už se ale dostáváme do IT zákoutí kam se běžný kačer jen tak nepodívá.... kdybych byl sadista, tak udělám nějakou pěknou D5 mysterku....


  • 0

#11 kiReGPS

kiReGPS

    Advanced Member

  • Members
  • PipPipPip
  • 2 345 příspěvků(y)

Publikováno 31 říjen 2017 - 21:42

WITH RECURSIVE... No jo, je to tam. A už od roku 1999 ;)
  • 0

#12 Pe_Bo

Pe_Bo

    Advanced Member

  • Members
  • PipPipPip
  • 613 příspěvků(y)

Publikováno 01 listopad 2017 - 5:44

A nebylo by lepší udělat dll jako extension?


  • 0

#13 dejwy

dejwy

    dejwy

  • Members
  • PipPipPip
  • 1 223 příspěvků(y)

Publikováno 01 listopad 2017 - 7:10

A nebylo by lepší udělat dll jako extension?


??
  • 0

#14 Pe_Bo

Pe_Bo

    Advanced Member

  • Members
  • PipPipPip
  • 613 příspěvků(y)

Publikováno 01 listopad 2017 - 7:32

Viz https://sqlite.org/loadext.html

 

Ale není to tak hackerské...  :)


  • 0

#15 HaLuMa

HaLuMa

    Autor Geogetu

  • Members
  • PipPipPip
  • 14 531 příspěvků(y)

Publikováno 01 listopad 2017 - 8:29

žádná magie, ale už od SQL:1999 - viz https://en.wikipedia...able_expression - dají se s tím dělat psí kusy,

 

Mne neprekvapuje, ze je to v SQL jako takovem. Mne prekvapuje, ze se s tim dokaze poprat  tak minimalisticky engine jako SQLite. Preci jen, je staveny na trochu jine pouziti.


  • 0

#16 tarmara

tarmara

    Air-cooled

  • Members
  • PipPipPip
  • 974 příspěvků(y)

Publikováno 01 listopad 2017 - 9:02

Viz https://sqlite.org/loadext.html

 

Ale není to tak hackerské...  :)

 

Pokud jsi schopen knihovnu napsat, budu jedině rád. Potřebnou dokumentaci najdeš zde. Já ji nikde nenašel a psát knihovny neumím. Už teď používám dvě knihovny na rozšíření funkčnosti SQLite, tak bych připojoval další. Navíc by to pro jisté use case asi bylo rychlejší a uživatelsky přívětivější než čisté SQL. 

 

Mne neprekvapuje, ze je to v SQL jako takovem. Mne prekvapuje, ze se s tim dokaze poprat  tak minimalisticky engine jako SQLite. Preci jen, je staveny na trochu jine pouziti.

 

Buďme rádi, že implementaci SQL jazyka zmákne i při svém minimalismu. I když nějaké omezení má. Já například nedávno narazil právě na absenci podpory FULL OUTER a RIGHT JOINU.


Tento příspěvek byl upraven od tarmara: 01 listopad 2017 - 10:12

  • 0

#17 kiReGPS

kiReGPS

    Advanced Member

  • Members
  • PipPipPip
  • 2 345 příspěvků(y)

Publikováno 01 listopad 2017 - 11:45

Pokud jsi schopen knihovnu napsat, budu jedině rád. Potřebnou dokumentaci najdeš zde. Já ji nikde nenašel a psát knihovny neumím. Už teď používám dvě knihovny na rozšíření funkčnosti SQLite, tak bych připojoval další. Navíc by to pro jisté use case asi bylo rychlejší a uživatelsky přívětivější než čisté SQL.


Tady jsem něco našel: https://iads.symvion...errainFuncs.pdf


  • 0

#18 tarmara

tarmara

    Air-cooled

  • Members
  • PipPipPip
  • 974 příspěvků(y)

Publikováno 01 listopad 2017 - 12:04

Tady jsem něco našel: https://iads.symvion...errainFuncs.pdf

 

Zkoušel jsem to PDF přilinkovat a nic... :)

Tohle už jsem četl před 2 lety, problem je v tom, že je to knihovna ze specializovaného SW, nikde jsem ji nenašel jako binární soubor. A ani jsem nikde nenašel ten SW ke stažení (i ilegálně). Pokud by se mezi kačery našel letecký inženýr používající tenhle telemetrický SW (nebo co je to zač), tak by mohl tu knihovnu vyextrahovat....


  • 1

#19 Pe_Bo

Pe_Bo

    Advanced Member

  • Members
  • PipPipPip
  • 613 příspěvků(y)

Publikováno 01 listopad 2017 - 12:07

A potřebuješ to mimo Geoget nebo jen v něm? Totiž jak jsem pochopil, Geoget implementaci Vincentyho algoritmu obsahuje, tak by stačilo udělat jen wrapper do SQLite engine. Beztak už dnes má minimálně extension pro kompresi/dekompresi.

 

Jinak příklad takového extension přikládám. Tedy tento obsahuje výpočet jen na kouli. Pokud máš ověřený algoritmus v C, tak ho snadno zahrnu.

 

PS: Přípona souboru má být .cpp

 

Přiložený soubor (y)


  • 1

#20 tarmara

tarmara

    Air-cooled

  • Members
  • PipPipPip
  • 974 příspěvků(y)

Publikováno 01 listopad 2017 - 12:27

O tom, že GG VM obsahuje vím, mám i pascalovské zdrojáky přímo od HaLuMy. Ale já si rád hraju s databází bez dostupných funkcionalit GG. V externím SQLite prohlížeči jen nad DB3 souborem. De/kompresní znám, mám a používám. Cčkový zdroják VM metody nemám, mám jen ten pascal a tady je javascript a asi i java (dole)


  • 0





Také označené jedním nebo více z těchto klíčových slov:geoget

1 uživatel(ů) prochází toto téma

0 uživatelů, 1 návštěvníků 0 anonymních uživatelů

Reklama