Moduł Gmaps – mapy Google

Kohana serii 3.0 standardowo nie posiada modułu gmaps. Guillermin stworzył taki moduł u umieścił na githubie. Jednakże jest on do Ko3.0

Postanowiłem więc zaktualizować moduł dodając kilka rzeczy. Standardowo dzięki modułowi możemy tylko wyszukać dane na temat jakiejś miejscowości. Dzięki mojej modyfikacji można również wygenerować statyczną mapę i mapę js, dzięki której zaznaczymy markerem punkt i zapiszemy w bazie współrzędne.

Wersję dla KO3.1 zawierającą moje zmiany można pobrać z linku Gmaps module (488)

Co zrobić aby wyświetlić jakąś mapę lub wyznaczyć geolokalizację?

1. Pobieramy plik i rozpakowujemy do katalogu /modules/

2. Jeśli chcemy zmieniać coś w konfigu np. język geolokalizacji powinniśmy skopiować /modules/gmaps/config/gmaps.php do /application/config/gmaps.php
W ten sposób jako plik konfiguracyjny będzie brany ten z folderu /application, jeżeli nie będziemy nic zmieniać, pomijamy ten krok.

3. W /application/bootstrap.php w sekcji modules dodajemy dodatkowy moduł

Kohana::modules(array(
'gmaps' => MODPATH.'gmaps', // Google Maps

Od tej pory możemy używać modułu gmaps.

Z czym to się je?

Zacznijmy od wyszukania lokalizacji. Funkcja do tego służąca to geo_request(). Funkcja ta zwraca (o ile znajdzie) obiekt, który zawiera dane takie jak kraj, powiat czy współrzędne. Spróbujmy wywołać następujący kod:

$gmaps=Gmaps::instance();
$search=$gmaps->geo_request('dębica');
if($search)echo Debug::vars($search); 
else 'Nic nie znaleziono';

zwróci poniższy kod:

object stdClass(5) {
    public id => string(2) "p1"
    public address => string(21) "Gmina Dębica, Poland"
    public AddressDetails => object stdClass(2) {
        public Accuracy => integer 4
        public Country => object stdClass(3) {
            public AdministrativeArea => object stdClass(2) {
                public AdministrativeAreaName => string(12) "Podkarpackie"
                public SubAdministrativeArea => object stdClass(2) {
                    public Locality => object stdClass(1) {
                        public LocalityName => string(7) "Dębica"
                    }
                    public SubAdministrativeAreaName => string(8) "dębicki"
                }
            }
            public CountryName => string(6) "Polska"
            public CountryNameCode => string(2) "PL"
        }
    }
    public ExtendedData => object stdClass(1) {
        public LatLonBox => object stdClass(4) {
            public north => float 50.0802912
            public south => float 50.0229751
            public east => float 21.4757261
            public west => float 21.3476667
        }
    }
    public Point => object stdClass(1) {
        public coordinates => array(3) (
            0 => float 21.4116964
            1 => float 50.0516417
            2 => integer 0
        )
    }
}

Znajduje się tu zatem sporo informacji na temat znalezionego miasta. Zwróćmy uwagę na obiekt Point klasy stdClass, zawiera on tablicę coordinates w której znajdują się szerokość geograficzna (latitude) – drugi element tablicy i długość geograficzna (longitude) – pierwszy element tablicy. Na podstawie tych dwóch parametrów możemy załadować mapę, a także wyznaczyć markerem punkt. Aby przypisać do zmiennych $lat i $lng współrzędne wyszukanego miasta wykonujemy:

$lat=$search->Point->coordinates[1];
$lng=$search->Point->coordinates[0];

Statyczna mapa
Gdy mamy współrzędne, możemy załadować mapę. Mapa statyczna to obrazek img z url’em do mapy. Aby przesłać do widoku url do mapy, na której zaznaczony jest marker wykonujemy funkcję staticmap()

$this->template->staticmap=$gmaps->staticmap(array('color:green', $lat, $lng),'298x300',14,'roadmap');

Pierwszy element funkcji to tablica zawierająca marker (markery) w którym znajdują się opcje i współrzędne (2 ostatnie el. tablicy), drugi to rozmiary obrazka, później wymiary mapy, przybliżenie i typ mapy.

Aby wyświetlić mapę, umieszczamy w widoku następujący obrazek

<img src="<?php echo $staticmap?>" alt="gmaps" />

Możemy dodać także literę np. A oznaczającą marker

$this->template->staticmap=$gmaps->staticmap(array('color:green','label:A', $lat, $lng),'298x300',14,'roadmap');

Jest także możliwość dodania kilku markerów, wystarczy jako pierwszy element przesłać tablicę asocjacyjną (zawierającą kilka tablic)

array(array($lat1,$lng1),array($lat2,$lng2))

Przy podaniu kilku markerów należy zwrócić uwagę, aby rozmiar obrazka przy danym zbliżeniu, objął obydwa punkty.

Mapa js – dynamiczna
Funkcja jsmap() zwraca string zawierający kod java script, który jest odpowiedzialny za umieszczenie mapy o pewnych właściwościach w znaczniku html o id=”map-canvas”. Przyjrzyjmy się deklaracji tej funkcji

public function jsmap($lat, $lng, $zoom, $maptype, $marker = NULL, $dragable = NULL, $title = NULL, $info = NULL, $getvalue = NULL){

Przyjmuje ona kilka parametrów i tak

  1. $lat - szerokość geograficzna
  2. $lng - długość geograficzna
  3. $zoom - przybliżenie (max zależy od położenia, od 0 do np. 22) Zalecam użycie 14 jeśli chcemy odczytać ulice
  4. $maptype - typ mapy [ROADMAP, SATELLITE, HYBRID, TERRAIN]
  5. $marker - należy podać TRUE jeśli na mapie ma być zaznaczony marker
  6. $dragable - TRUE jeśli marker można przestawiać
  7. $title - tytuł markera
  8. $info - box zawierający informacje o markerze
  9. $getvalue - jeśli TRUE do id #lat i #lng do atrybutu value przypisze aktualne położenie, np. <input type=”text” id=”lat” value=”" />

Aby przesłać do widoku kod js dla mapy wywołujemy

$info='<strong>Aktualna lokalizacja';
$this->template->gmaps_jscode=$gmaps->jsmap($lat, $lng, 14, 'ROADMAP',TRUE,TRUE,'Położenie',$info,TRUE);

Spowoduje to przesłanie kodu js z mapą o zadanych współrzędnych (będą w centrum mapy), przybliżeniu 14, typie mapy ROADMAP, z zaznaczonym markerem, którego można przesuwać, który posiada tytuł ‚Położenie’, z pogrubionym opisem ‚Aktualna lokalizacja’, a także zostaną zwrócone współrzędne markera (do inputów).

Kod zwrócony z funkcji jsmap() umieszczamy w nagłówku strony. Mapa zostanie załadowana do diva o id map-canvas, natomiast współrzędne zostaną wpisane do inputów o id=”lat” i id=”lng”.

<html>
  <head>
    <?php echo $gmaps_jscode?>
  </head>
  <body>
    <div id="map-canvas" style="width:700px;height:550px">
    <form action="/sample_controller/map_edit" method="post">
    <label for="lat">Lat: </label><input type="text" id="lat" name="lat"><br />
    <label for="lng">Lng: </label><input type="text" id="lng" name="lng"><br />
    <input type="submit" name="submit" value="Zapisz">
    </form>
  </body>
<html>

Wystarczy teraz wysłać formularz i zapisać do bazy współrzędne np. użytkownika, który wyszukał lub zaznaczył na mapie swoją lokalizację.

Przykładowy kod w kontrolerze do obsługi wyszukiwania, zaznaczania i zapisywania w bazie współrzędnych może przedstawiać się tak:

$gmaps=Gmaps::instance();
$this->template->error=NULL;

if(isset($_POST['search_submit'])){
    $search=$gmaps->geo_request($_POST['search']);

    if($search) {
      $lat=$search->Point->coordinates[1];
      $lng=$search->Point->coordinates[0];
    }else {
      $lat='0';
      $lng='0';
      $this->template->error='<span style="color:red">No place find</span>';}
}else{
    //From database
    $db=...;
    $lat=$db->lat ? $db->lat : '0';
    $lng=$db->lng ? $db->lng : '0';
}

$info='<strong>Info marker</strong><br />Some text, <br /><span style="color:green">Mark the place!</span>';
$this->template->gmaps_jscode=$gmaps->jsmap($lat, $lng, 14, 'ROADMAP',TRUE,TRUE,'Marker title',$info,TRUE);

if(isset($_POST['submit'])){
    //save in database
    $user=...;
    $user->lat=$_POST['lat'] !='' ? $_POST['lat'] : NULL;
    $user->lng=$_POST['lng'] !='' ? $_POST['lng'] : NULL;
    $user->save();
    unset ($_POST);
    $this->redirect = Request::initial()->controller().'/'.Request::initial()->action();
}

Natomiast kod widoku może prezentować się tak:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta http-equiv="Content-Language" content="pl"/>
        <?php echo $gmaps_jscode?>
    </head>
    <body>
        <div>
                <h2>Edit location:</h2>
                <?php echo  Form::open(Request::initial()->controller().'/'.Request::initial()->action()).
                Form::label('search', 'Place to find: ').
                Form::input('search',NULL,array('size'=>'50')).
                Form::submit('search_submit', 'Search').
                Form::close(); echo $error?>

                <div id="map-canvas" style="width:700px;height:550px"></div>

                <?php echo  Form::open(Request::initial()->controller().'/'.Request::initial()->action()).
                Form::label('lat', 'Lat: ').
                Form::input('lat',NULL,array('id'=>'lat')).
                Form::label('lat', ' Lng: ').
                Form::input('lng',NULL,array('id'=>'lng')).
                Form::submit('submit', 'Save').
                Form::close();?>
        </div>
    </body>
</html>

Dzięki moim zmianom w module gmaps możemy łatwo wyświetlić mapę i zaznaczyć na niej pewne punkty. Wystarczy przekazać do funkcji modułu pewne parametry i wyświetlić odpowiednio w widoku.
Google Maps ma dużo większe możliwości, jednakże te były mi potrzebne (chyba najczęściej pożądane) i dodałem je do modułu. W przyszłości można by dodać wyznaczanie trasy.

8 Odpowiedzi :“Moduł Gmaps – mapy Google”

  1. mrbongo napisał:

    w KO3.2 nie bedzie działać, trzeba zwrócić uwagę na ładowanie configu przez moduł.

    Gratuluję artykułu – bardzo ciekawy tekst:)

    Pozdrawiam.

  2. Mariusz napisał:

    No tak, w 3.2 była zmiana odwołania do configa:

    Kohana::$config->load('gmaps')

    ;)

  3. Kuba napisał:

    Próbuję odpalić ten moduł na K3.3

    $response->Status->code zwraca mi błąd 610 co po sprawdzeniu w statusach kodów oznacza G_GEO_BAD_KEY

    Jak to rozwiązać?

    • Mariusz napisał:

      Google zmieniło coś w api i funkcja geo_request nie zwraca pożądanych danych. Trzeba by to poprawić, jak znajdę czas to coś popatrzę, chyba, że ktoś mnie ubiegnie :) Poprawić odwołanie do konfigu co w 3.2 się zmieniło (komentarz wyżej). Dodatkowo w ko 3.3 trzeba zamienić nazwy klas na „z dużej litery”. Jeśli mamy współrzędne, to mapa statyczna i js powinny działać.

      • Kuba napisał:

        to wszystko już wcześniej poprawiłem tylko gmaps nie zwraca pożądanych danych

        • Mariusz napisał:

          Trzeba by poprawić metodę geo_request() klasy Gmaps, bo G coś zmieniło. Nie wiem czy też url do żądań się nie zmienił, trzeba by popatrzyć do api google maps.

  4. Kuba napisał:

    w sumie wychodzi na to, że jeśli nie chcemy sobie narobić na przyszłość dodatkowej pracy to lepiej nie używać tego typu rozszerzenia. Google coś znowu zmieni i klienci będą dzwonić z pretensjami:)

    • Mariusz napisał:

      Api często się nie zmienia (od kiedy pamiętam do teraz działało), ktoś jakby miał własną klasę do Google maps, to też przestałaby działać. Ale to tylko trzeba zerknąć jak ma być, bo może tylko url się zmienił i przez to metoda nie zwraca danych.

Dodaj komentarz

Dodając kod PHP używaj tagów: [php][/php]

*