Opis problemu:
Stworzyć stronę z mapą googla na której po zaznaczeniu miejsca lub wybraniu go z pola podpowiedzi rysujemy okrąg o zadanej przez użytkownika średnicy (w kilometrach) a następnie wyświetlamy w odpowiednich miejscach markery z informacjami z bazy danych.Zastosowane technologie:
Google Maps API - javascript, do tego jQuery, php do komunikacji z bazą danych, wykorzystałem JSON-a do podania informacji z PHP do javascriptu. Do tego był jeszcze skrypt perlowy do rozkodowywania danych, ale to inna historia.Potyczka!
Nie jestem jakimś wielkim web designerem, więc nie specjalnie przejmowałem się bajerami na stronie, szablonami ani niczym podobnym. Ważne było wyświetlanie informacji, więc sama mapa zajmuje dobre 3/4 miejsca. Na górze wrzuciłem textfielda do wpisywania adresu do którego podpiąłem autocomplete od googla, oraz formę do wpisywania długości i szerokości geograficznych z palca. Jest tam jeszcze elegancki suwak do wyboru długości promienia okręgu, z jQueryUI.No to od początku. Dane które miałem do wyświetlenia były dosyć specyficzne - depesze meteorologiczne SYNOP. Wygląda to to mniej więcej tak:
AAXX 02019 17061 05/82 /1110 10081 20068 39435 40042 55004 60002 8/000Kilka dni wcześniej pisałem do tego skrypt perlowy który rozkodowywał tą depeszę, ale nie będę się w to teraz zagłębiał.
W bazie mam osobną tabelę na raporty, a osobną tabelę na stację z których raporty są. W stacjach mam ich współrzędne geograficzne także większego problemu nie było.
Żeby wyświetlić dane z zadanego okręgu stwierdziłem, że najlepiej z bazy wyjąć depesze z kwadratu opisanego na tym okręgu, a później zastosować proste równanie okręgu.
d=(x-a)2+(y-b)2Gdzie środek okręgu jest w punkcie (x,y) a punkt mamy w punkcie (a,b).
d<r2
No ale oczywiście zapomniałem, że przecież współrzędne geograficzne nijak się mają do szkolnego układu współrzędnych.
Jeszcze większy problem pojawił się przy szukaniu kwadratu opartego na okręgu. Jakkolwiek długość geograficzna ma stałą wartość w kilometrach, tak szerokość zmienia się w zależności od długości. Trzeba było kombinować i udało mi się znaleźć TO. Trzeba było to przepisać na php-a i gotowa funkcja do znajdowania długości i szerokości geograficznej punktu w zadanej odległości i kierunku od innego wygląda tak:
function toRad($arg){
return $arg*pi()/180;
}
function toDeg($arg)
{
return $arg*180/pi();
}
function getLatLon($side,$dist,$lat,$lng)
{
$dist=$dist/6371;
$side=toRad($side);
$lat1=toRad($lat);
$lng1=toRad($lng);
$lat2=asin(sin($lat1)*cos($dist)
+cos($lat1)*sin($dist)*cos($side));
$lng2=$lng1 + atan2(sin($side)*sin($dist)*cos($lat1)
,cos($dist)-sin($lat1)*sin($lat2));
$result = array(toDeg($lat2),toDeg($lng2));
return $result;
}
Teraz po dostaniu współrzędnych punktu wywoływałem getLatLon z różnymi parametrami $side: 0 dla punktu na północ od środka, 90 na wschód itd. Zapytanie do bazy było już proste do stworzenia i nie będę się tu w to wgłębiał. Trzeba tylko napomknąć co z tej bazy wyłowiłem. Miałem id stacji, długość i szerokość geograficzną i treść raportu.
Potem musiałem to wrzucić do pliku zakodowanego JSON-em. Zdecydowałem się na tablicę w takim formacie:
$tablica = array(station_ID=>array(array(raporty_danej_stacji),dlugosc,szerokosc))Jak widać tablice wielowymiarowe się przydają i muszę przyznać, że w php-ie robi się takie rzeczy na prawdę wygodnie. Ale wychodzi tutaj kolejny problem, może być wiele raportów z tej samej stacji, a ja chciałbym je wyświetlić wszystkie w jednym markerze. Można to załatwić pewnie SQL-em ale ja zdecydowałem się na prosty warunek przy wrzucaniu danych z bazy do tablicy.
while($row=$statement->fetch()){
if(array_key_exists($row['STATION_ID'],$resultArray)){
$resultArray[$row['STATION_ID']]["content"]
[count($resultArray[$row['STATION_ID']]["content"])]=
$row['CONTENT'];
}
else{
$resultArray[$row['STATION_ID']]=array(
"content"=>array(0=>$row['CONTENT']),
"lat"=>$row['STATION_LAT'],
"lng"=>$row['STATION_LONG']);
}
}
Jak widać po ifie mamy wstrętnego jednolinijkowca - zrobiłem to w ten sposób żeby zachować wewnętrzną tablicę z contentem jako pełnoprawną asocjacyjną - było to potrzebne ze względu na kodowanie JSON. Chociaż teraz pewnie zrobiłbym to inaczej bo nie jestem specjalnie z tego zadowolony.Ze strony php zostało już tylko zakodowanie i zapisanie pliku. Robi się to w jednej linijce (po otworzeniu pliku oczywiście):
fwrite($OUT,json_encode($resultArray));
Tyle na dzisiaj. W następnej części przejdziemy do javascript i samych google maps.
Zapraszam!
Brak komentarzy:
Prześlij komentarz