Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: [PHP] Lähin karttakoordinaatti

Sivun loppuun

Petja [08.05.2012 20:04:59]

#

Olen tekemässä testimielessä pikkuprojektia, joka näyttää Berliinin U9-metrokartan ja osaa kertoa itseään lähimmän aseman hyödyntäen tietokoneissa lisääntyvään päin olevia GPS-antureita @ JS-API.

Asiaan...

function lahin_asema($coord){

//Lista metroasemista
$metrokartta = Array(
Array("Osloer Straße", "52 33 25 N 13 22 25 E"),
Array("Nauener Platz", "52 33 06 N 13 22 03 E"),
...
);

//Etsi $coord-muuttujaa lahinnä oleva aseman nimi, sijainti ja alkion ID luettelosta

return Array( $lahin_asema_nimi, $lahin_asema_coord, $alkion_id ); //Palauta tulos

}

//Funktion kutsuminen

lahin_asema("53 32 26 N 12 23 24 E");

//Pitäisi palauttaa:
//Array("Osloer Straße", "52 33 25 N 13 22 25 E", 1)

Googlea olen jo yrittänyt, mutta apua en löytänyt.
Eipä silti, ei vastaavanlaisia pahemmin tehdä.

Lebe80 [08.05.2012 20:16:26]

#

No eiköhän nuo kannattaisi muuntaa ensiksi vaikka luvuiksi, niin olisi helpompi laskea etäisyyksiä pallon pinnalla.

The Alchemist [08.05.2012 20:38:07]

#

Tässä nyt puhutaan nyt Berliinin paikallisliikenteestä, niin voitaneen unohtaa pallokoordinaatistot ja puhua ihan XY-koordinaateista tavan kartalla. Taas kerran joutuu huomauttamaan suorastaan räikeästä ihmisten hyväksikäytöstä, kun ongelmaa tai tavoitetta ei ole käytännössä millään tavoin dokumentoitu. On vain annettu randomi funktiokutsu esimerkkisyötteellä ja sanottu, että mitä sen pitää palauttaa.

"Koodatkaa mulle tämä."

jalski [08.05.2012 20:44:59]

#

Lebe80 kirjoitti:

No eiköhän nuo kannattaisi muuntaa ensiksi vaikka luvuiksi, niin olisi helpompi laskea etäisyyksiä pallon pinnalla.

Jeps... Tämän jälkeen great-circle distance ja Haversine formula voisivat olla ne hakusanat joista lähteä liikkeelle.

Lebe80 [08.05.2012 22:04:37]

#

The Alchemist kirjoitti:

Tässä nyt puhutaan nyt Berliinin paikallisliikenteestä, niin voitaneen unohtaa pallokoordinaatistot ja puhua ihan XY-koordinaateista tavan kartalla.

no kun luvut (metroasemien sijainnit) on (ilmoitettu) ihan pituus-/leveyspiirin koordinaatteina niin eikö niistä ole järkevää laskea etäisyydet juuri pallon pinnalta? Itse tein erään Lahden nähtävyysmultimediasovelluksen jossa näytettiin päätelaitteelta etäisyys kohteeseen juuri noin.


Ei tarvitse mitään omia virityksiä keksiä etäisyyksien laskentaan.

Grez [08.05.2012 23:14:49]

#

Jos kuitenkin hyvistä neuvoista huolimatta haluaa tehdä äärimmäisen yksinkertaisen joka toimii vain Berliinissä, niin kannatta laittaa joku kerroin x:ään tai y:hyn, koska Berliinissäkään leveyssekunti ei taida olla saman pituinen kuin pituussekunti.

Itse olen yleensä käyttänyt Vincentyn kaavaa, mutta toki sen ja Haversinen lisäksi on muitakin...

Petja kirjoitti:

Eipä silti, ei vastaavanlaisia pahemmin tehdä.

En ole ihan varma ymmärsinkö mitä tarkoitit. Vastaavanlaisia (koordinaattien perusteella lähimmän kohteen etsiviä sovelluksia) ainakin tehdään paljon ja netistäkin löytyy ainakin kymmentittäin esimerkkejä.

Petja [09.05.2012 15:20:25]

#

On ymmärrettävämpää käyttää itse tehtyjä x- ja y-koordinaatteja, mutta tietokoneen oman sijainnin määrittäminen näiksi menisi aivan liian hankalaksi. Jos ihan nyt vain pysytään meille ihmisille jo luoduissa karttakoordinaateissa. Sitä varten ne meille on luotu!

Lisäksi aina kaikenmaailman muuntaminen tms. vie aina enemmän aikaa ja resursseja koodin kirjoittamisen lisäksi myös sen suorittamisessa, kuten voin olettaa teidän jo tietävän.

Grez kirjoitti:

Petja kirjoitti:

Eipä silti, ei vastaavanlaisia pahemmin tehdä.

En ole ihan varma ymmärsinkö mitä tarkoitit. Vastaavanlaisia (koordinaattien perusteella lähimmän kohteen etsiviä sovelluksia) ainakin tehdään paljon ja netistäkin löytyy ainakin kymmentittäin esimerkkejä.

Ymmärsit ihan oikein, mutta eipä Google minulle mitään järkevää kertonut.
Olisi kai pitänyt käyttää paremmin valittua hakusanaa tai klikata relevantimpaa tulosta?

syyskimo [09.05.2012 16:25:57]

#

Google "geolocation distance", melko suuri läjä osumia.

Itse tehdyistä käytetyistä karttakoordinaateista, niin se on tietty makuasia mikä on selkein. Itse pökkelönä ymmärrän helpommin 2-ulotteista karttaa kuin pallokoordinaatistoa. Tosin jos "jo luotu" pallokoordinaatisto on selkseä, niin en kyllä ymmärrä mikä ongelmasi on in the first place?

Itse voit palauttaa pienehköllä alueella koordinaatit x:ksi y:ksi valitsemalla alueen keskeltä origon ja mittaat siihen pallokoordinaatiston mukaan etäisyydet => x ja y. Saman tempun kun teet käyttäjän paikkaan niin silloin voit leikkiä, että Berliini makaa 2-ulotteisella pannukakulla ja laskenta on hyvin helppoa.

Ei silti, ei tuo pallokoordinaatistokaan nyt ihan mahdotonta ole, kun vaikkapa otta puhtaan esimerkkikoodin ja lähtee siitä. Esimerkiksi ensimmäinen osuma hakusanalla "geolocation distance":

http://www.html5rocks.com/en/tutorials/geolocation/trip_meter/

Metabolix [09.05.2012 16:52:25]

#

Kulmilla laskeminen ei edellytä mitään maagista tietoa pallokoordinaatistosta, vaan yksinkertainen trigonometria ja pistetulo riittävät. Kahdesta kulmasta saa helposti sini- ja kosinifunktioilla paikkavektorin (x, y, z), kahdesta vektorista saa pistetulolla niiden välisen kulman kosinin, ja tästä taas saa kosinin käänteisfunktiolla kulman. Lopuksi kerrotaan kulma säteellä, niin saadaan kaaren pituus.

# Parametreina kulmat (luonnollisesti radiaaneina) ja pallon säde.
function matka_pallopinnalla($lat_A, $lon_A, $lat_B, $lon_B, $r = 1) {
	return $r * acos(
		cos($lat_A) * cos($lon_A) * cos($lat_B) * cos($lon_B) +
		cos($lat_A) * sin($lon_A) * cos($lat_B) * sin($lon_B) +
		sin($lat_A) * sin($lat_B)
	);
}

Grez [09.05.2012 20:37:20]

#

Edelleen kun tarkoituksena on vain löytää pistettä lähin toinen piste niin ei tarvitse edes kulmia eikä vektoreita, vaan ihan perus pythagoras riittää.

Edit: Luin Metabolixin viestin näköjään huolimattomasti kun alussa sanoi ettei tarvitse tietoa pallokoordinaatistosta niin ajattelin että siinä ei käytetä pallokoordinaatistoa.

syyskimo [09.05.2012 23:28:52]

#

Metabolix:
Maaginen ja maaginen tieto pallokoordinaatistosta: kaavasi laskee etäisyyttä _pallolla_, ikävän näköinen vrt. pythagoras. Ehkä käytin hieman väärin tuota sanaa. :)

Vastaus alkuperäiseen kyssäriin: Itse oikoisin vähän ja tekisin kuten Grez ehdottaa (en edes niinkuin itse ehdotin, koska se on aivan turhaa): eli käyttäisin noita pisteitä kuin ne olisi 2-ulotteisella pinnalla. Mutta jos asian haluaa tehdä kunnolla (eli jos kiinnostaa mikä on lähin Berliinin metroasema antarktikselta katsoen) niin käyttää raskaampaa kaavaa.

Grez [09.05.2012 23:43:12]

#

En ehdottanut sinänsä tekemään tasolla, mutta jos tasolla halutaan tehdä niin sitten voi tehdä noin.

Itse tekisin jollain todellisella kaavalla ihan senkin takia, että sitten se softa toimii sellaisenaan vaikka Helsingin metroasemille ilman että tarvii muutella maagisia numeroita.

Metabolix [09.05.2012 23:56:13]

#

syyskimo kirjoitti:

kaavasi laskee etäisyyttä _pallolla_, ikävän näköinen vrt. pythagoras.

Mikä siinä on ikävää? Minusta yksinkertainen, matemaattisesti mielekäs kaava näyttää paljon mukavammalta kuin jokin mystisiä korjauskertoimia sisältävä approksimaatio, johon sisältyy vähänkin pidemmillä matkoilla huomattava virhe ja jonka keksiminen ja kirjoittaminen vie vieläpä enemmän aikaa kuin tämän ratkaisun johtaminen. Kaavojen pituudessa ei ole olennaista eroa, ja pieni ero suoritusnopeudessa ei vaikuta näin pienellä asemamäärällä mitenkään.

Maapallo ei toki ole pyöreä, joten pallokaavakaan ei anna tarkkoja vastauksia, mutta ainakin se toimii siedettävän tarkasti ilman muutoksia missä tahansa kaupungissa.

syyskimo [10.05.2012 10:53:17]

#

Ei mielestäni tarvitse kaupungin (vaikka olisi kuinka suurkaupunki) alueella tehdä mitään mystisiä korjauksia. Ja ei tietenkään tuo kaavasi mitenkään hankala ole. Kyse nyt oli vain lähinnä siitä, että kaupungin kokoisella alueella voi leikkiä olevansa tasaisella pinnalla.

Mutta tein nyt huvin ja urheilun vuoksi testin:

Käytin palloetäisyyden laskemiseen seuraavaa kaavaa (en jostain syystä saanut Metabolixin kaavaa toimimaan - kädetin varmaan jotain parametreja):

$dLat = deg2rad($comp->n - $this->n);
$dLon = deg2rad($comp->e - $this->e);
$a = sin($dLat/2) * sin($dLat/2) +
      cos(deg2rad($this->e)) * cos(deg2rad($comp->e)) *
      sin($dLon/2) * sin($dLon/2);
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
$d = Point::$r * $c;
return $d;

2d tietysti lasketaan pythagoraksella.

Eli alla test-case, jossa ollaan inhasti Rovaniemellä, jotta saadaan vähän pallovääristymää nousemaan:

I'm at: 66.499574 N 25.706635 E
area left bottom: 66.412902 N 25.383911 E area right top: 66.616487 N 26.196899 E (to make 3d / 2d comparable)
Distance to: 66.523110 N 25.772552 E ball: 0.08407% 2d: 0.08351%
Distance to: 66.514081 N 25.711441 E ball: 0.01993% 2d: 0.01823%
Distance to: 66.502586 N 25.767746 E ball: 0.07256% 2d: 0.07301%
Distance to: 66.500943 N 25.727921 E ball: 0.02531% 2d: 0.02545%
Distance to: 66.504502 N 25.708694 E ball: 0.00693% 2d: 0.00637%
Distance to: 66.490537 N 25.760880 E ball: 0.06541% 2d: 0.06562%
Distance to: 66.484510 N 25.718307 E ball: 0.02418% 2d: 0.02274%
Distance to: 66.412902 N 25.383911 E ball: 0.39986% 2d: 0.39872%
Distance to: 66.616487 N 26.196899 E ball: 0.60026% 2d: 0.60138%

Eli tuossa lasketaan matka nurkastasta nurkkaan jota käytetään sitten pallo-etäisyydellä ja 2d-etäisyydellä suhdearvona. Tämä siis sitä varten, että voidaan suoraan verrata 2d ja 3d arvoja (en jaksanut vaivautua muuttaa 2d:tä metreiksi, kun sillä mitään väliä ole tässä esimerkissä).

Virhettähän tuossa selvästi tulee 2d:llä, mutta ei niin paljon etteikö paikoista voisi verrata mikä on lähinnä. Siis mielestäni.

Sitä en kiellä etteikö tuo oikea tapakin olisi helppo, mutta lähinnä yritin kertoa että voi härskisti mennä sieltä missä aita on matalin eikä sillä ole väliä lopputuleman kannalta.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta