niedziela, 16 marca 2014

Potyczka z klawiaturą mechaniczną KBC Poker II - recenzja

Podłoże historyczne:
Od dłuższego czasu chciałem kupić sobie porządną klawiaturę. Okazuje się, że jako pracujący student, całkiem sporo czasu spędzam pisząc (jakieś prace dyplomowe, różne głupie referaty, czy po prostu jakiś kod). O klawiaturach mechanicznych wiedziałem od jakiegoś czasu i do zakupu własnej przymierzałem się chyba od października 2013. W końcu sprawiłem sobie własne maleństwo, które chcę zrecenzować.

Sprzęt:
KBC/Vortex Poker II biała z przełącznikami Chery MX Blue. Podłączona do mojego laptopa (Lenovo y570).

Potyczka!
O co chodzi z klawiaturami mechanicznymi nie będę tłumaczył. Polecam tego subreddita jeżeli ktoś chce zaczerpnąć wiedzy na ten temat.

Teraz do samej klawiatury. Na początku myślałem nad WASD v2. Bardzo podoba mi się ta klawiatura i to że można w dużym stopniu ją spersonalizować jeszcze przed zamówieniem. Ale jakoś się rozmyśliłem.
Wszyscy zachwycają się Das Keyboard ale mi się ona jakoś nie podoba. Wydaje mi się, że to przez połyskującą obudowę.
Jest mnóstwo innych świetnych klawiatur, czemu więc Poker II? Kwestia gusty, po prostu bardzo mi się podobała. Jest to też niezwykle solidny kawał sprzętu, świetnie wykonany, niemal niezniszczalny.

Klawiatura 60%
No właśnie, rozmiar. Poker II nie ma części numerycznej, nie ma części funkcyjnej, nie ma klawiszy FX. Jest skompresowany do klawiatury alfanumerycznej, 61 klawiszy w układzie ANSI. I szczerze mówiąc widzę w tym tylko plusy.
Wszystkie klawisze funkcyjne są dostępne przez kombinację z fn. Dodatkowo są nadrukowane na frontach klawiszy, więc nie musiałem się niczego uczyć na pamięć. Strzałki są wygodnie pod WSAD-em, capslock można zamienić na fn (co zresztą zrobiłem) i wtedy dostęp do strzałek i innych kombinacji jest bardzo prosty. I wielkim plusem tego wszystkiego jest to, że jak położę ręce na klawiaturze to już nie muszę ich stamtąd ruszać. To jest niezwykle wygodne. Nie trzeba sięgać za delete'm, ani za strzałkami, nie ma 3 kilometrów przez numpad do myszki, nie trzeba podnosić nadgarstków żeby sięgnąć do F7. Dla mnie osobiście to jest cudo.

Mechaniczne przełączniki, czyli jak się na tym pisze?
Niebieskie przełączniki są znane ze swojego klikającego dźwięku. Dodatkowo walenie w klawisze w klawiaturze mechanicznej jest dość głośne samo w sobie. Więc tak, ta klawiatura jest całkiem głośna. Ale znowu, dla mnie to jest właśnie to. Lubię fizyczny i dźwiękowy sygnał, że klawisz został kliknięty. To jest też całkiem inne uczucie niż pisanie na klawiaturze laptopa, albo na zwykłym gumiaku.
Dodatkowo ja wcześniej używałem dosyć płaskich klawiatur. Ta w moim lenovo jest bardzo dobra jeżeli chodzi o laptopy, ale od ponad pół roku używałem na co dzień logitecha za 20 złotych.
No więc dochodzimy do momentu w którym trzeba odpowiedzieć na pytanie, jak się na tym pisze?
Doskonale! Niesamowicie przyjemnie, sprawnie, efektywnie. Dużą przyjemność sprawia klikanie w te klikające klawisze (tak wiem, powtarzam się). Czy piszę jakoś specjalnie szybciej? Chyba nie, szczerze mówiąc dalej się do niej przyzwyczajam, więc to może jeszcze ulec zmianie.
Ogólnie pisanie na klawiaturze mechanicznej to czysta przyjemność. Niesie wartość dodaną z procesu jakim jest pisanie i sprawia, że czerpie się przyjemność z tak przezroczystej czynności jaką jest klepanie w klawisze.

Poker II, uwagi dotyczące budowy, dodatkowe funkcje
Jak już powiedziałem, ta klawiatura jest chyba niezniszczalna. Wykonana z tak grubego plastiku obudowa i metalowa płyta podstawowa sprawiają, że to maleństwo nie gnie się nawet pod dużymi siłami. Klawisze z PBT są również bardzo grube i miłe w dotyku. Dodatkowo w zestawie przyszło klika kolorowych klawiszy, wykonanych równie dobrze.
Ciekawą funkcją Pokera jest możliwość programowania klawiszy. Pod dowolny klawisz można przypisać kombinację lub sekwencję innych. Na razie specjalnie tego nie wykorzystywałem, ale to się na pewno zmieni.
Wspomniałem również o możliwości zamiany capsloca na fn. Klawiatura ma 4 głębokie przełączniki odpowiedzialne za sprzętową zamianę klawiszy miejscami. Super przydatne! Ja u siebie zamieniłem capslock na fn, super na capslock a pod tak ustawiony nowy capslock zaprogramowałem super (dostępny przez kombinację pn+super). Zrobiłem tak, bo jednak w linuxie nie korzysta się tak często z klawisza windows, a fn jak najbardziej się przydaje.
Klawiatura fabrycznie nie jest podświetlana, ale(!) jej płyta jest w pełni gotowa żeby takie podświetlenie zamontować. To prawdopodobnie będzie mój projekt wakacyjny.

Podsumowanie
Poker II to niesamowicie kompaktowa klawiatura. Dzięki swojemu rozmiarowi jest nie tylko niesamowicie mobilna, ale też strasznie ergonomiczna. Dla osób tak leniwych, że nie chce im się ruszyć ręką do strzałek albo klawiszy funkcyjnych (tak, mówię tu między innymi o sobie) jest to strzał w dziesiątkę. Ponadto piszę się na niej całkowicie bajecznie. Niesamowicie solidna konstrukcja sprawia wrażenie jakby miała przetrwać wybuch nuklearny, a dźwięk stukających klawiszy brzmi jak karabin maszynowy. Polecam szczerze i z całego serca!

Link do albumu na imgurze, link do wątku na /r/MechanicallKeyboards

sobota, 15 marca 2014

Potyczka z Linuxem, przemyślenia po ponad roku używania

Podłoże historyczne:

Ponad rok temu zdecydowałem się na porzucenie Windowsa na rzecz Linuxa. Od tego czasu spróbowałem kilku dystrybucji, dużo się nauczyłem, bardzo dużo się irytowałem, ale wytrwałem i jestem z tego bardzo zadowolony

Co opiszę:

Chcę się podzielić swoimi przemyśleniami, doświadczeniami i odczuciami z używania Linuxa jako podstawowego systemu operacyjnego.

Potyczka!

Na co dzień używam laptopa lenovo y570, ważną rzeczą w nim jest to, że posiada dwie karty graficzne: zintegrowanego intela i dedykowanego geforca. To wszystko pod Windowsem obsługuje Nvidia Optimus, sprawnie przełączając karty w razie potrzeby (chociaż czasem też się pierdzieli). To takie tło, będzie miało znaczenie później.

No więc zdecydowałem się na instalację linuxa. Ale jakiego? Pierwszą kwestią jest dobór dystrybucji. Ja specjalnie nie szalałem, nie czułem się na tyle zaawansowany żeby bawić się z ręczną konfiguracją miliarda rzeczy i zdecydowałem się na Ubuntu. Wtedy dostępna była chyba wersja 12.04 (albo 12.10, nie jestem pewien).
Ubuntu jest niesamowicie przyjazny dla użytkownika, dodatkowo moim zdaniem jest również bardzo ładny. Kolejną zaletą jest ogromna ilość tutoriali, poradników i innych tego typu rzeczy w internecie. Każdy problem jaki możesz mieć ze swoim Ubuntu ktoś już miał, rozwiązał i opisał w sieci. Każdy! A to jest na prawdę przydatne.
No więc wybrałem Ubuntu, ale że trochę się bałem zrobiłem więc dual boota (Ubuntu obok Windowsa). Na swojego nowego linuxa przeznaczyłem jakieś 150 giga. I tutaj protip: zróbcie osobną partycję na home. Zawsze bezwzględnie to jest podstawa życia i w ogóle! Nic tak nie ułatwia życia, zwłaszcza jak dopiero zaczynacie z linuxami i będziecie je często zmieniać (a będziecie, trzeba się wyszaleć). Co to daje? W katalogach użytkownika przechowywanych na partycji home są wszystkie wasze pliki i niemal wszystkie pliki konfiguracyjne przypisane do waszego profilu. Jeżeli katalog home jest na osobnej partycji to zostaje nietknięty w trakcie instalacji i macie całą waszą konfigurację tak jak ją zostawiliście.

Problemy pierwszego tygodnia.
Okazuje się, że mój konkretny model laptopa, przez jakiś błąd biosu czy coś takiego, przy ówczesnej wersji jądra linuxa za chiny nie chciał współpracować z programem do zarządzania dwoma kartami graficznymi. I dobry boże, ile ja miałem z tym problemów. Znaczy nic nie stało na przeszkodzie zostawić to tak jak jest, tyle że absolutnie nie uśmiechało mi się przez cały czas słuchać wycia 2. karty graficznej. No i laptop się nagrzewał... i bateria szybciej schodziła.
Ale jak wspominałem, problem był już opisany, był też rozwiązany. I (prawie) bez problemu udało mi się to obejść. Na dzień dzisiejszy wszystko działa już bez problemu, nowa wersja jądra linuxa radzi sobie z moimi nieszczęsnymi kartami.

Zamienniki Windowsowych programów:
Jakoś z tym nie miałem problemów. Nie używam office'a, kilka razy jak był potrzebny to używałem libreoffice. Ogólnie dla linuxa istnieje cała masa niesamowicie fajnych narzędzi. Szczególnie polecam zapoznać się z Vim-em. Są wersje niezbędnych do życia programów. Jest firefox, jest chromium (linuxowa wersja chrome), jest dropbox. Czego chcieć więcej.
Jest nawet linuxowa wersja napiprojekt - qnapi. Z tego odkrycia byłem bardzo zadowolony bo był to program za którym bardzo tęskniłem na początku.

Różne dystrybucje ten sam system:
Nie wiem jak dokładnie opisać czym są dystrybucje. Ciężko to wytłumaczyć bez wchodzenia w instalatory pakietów, repozytoria i środowiska graficzne. Grunt, że są różne, jest mnóstwo artykułów o tym która dystrybucja jest dla ciebie. Jeśli nie wiesz co to w ogóle jest polecam Ubuntu, dla trochę pewniejszych użytkowników pewnie Mint'a. Ale to wszystko kwestia gustu.
Ja osobiście próbowałem chyba 5 różnych dystrybucji i najbardziej byłem zadowolony z Debiana i Ubuntu.
Debian to król stabilności, ten system się nie zawiesza. Nigdy! Serio, ani razu przez jakieś 4 miesiące używania.
Ale jest w nim dużo grzebania. Babrałem się z nim długo i stwierdziłem, że jednak to nie jest dla mnie. Mojego Debiana pokonały 2 monitory. Nie mogłem jakoś zmusić go do automatycznej konfiguracji po przyłączeniu/odłączeniu tak jakbym chciał.
Dlatego obecnie używam Ubuntu. Ten system doskonale radzi sobie ze sprzętem. To głównie zasługa Steama. Są eleganckie sterowniki do kart graficznych. Są gry. Jest fajnie.

Gry:
Krótko i na temat: nie gram na linuxie. Jak chcę pograć przełączam się na Windowsa. Jeszcze nie jest to na tyle dobrze poukładane żeby wszystko odbywało się bezstresowo. Steam działa, mogę odpalić gry z moją mocniejszą kartą. Ale jest z tym za dużo zabawy. Gram żeby się odstresować, nie potrzebuje grzebać w jakiejś konfiguracji, to mam na co dzień.

Praca:
Jakiekolwiek aktywności informatyczno-programistyczne pod linuxem to czysty fun. Wszystko jest przyjemne. Instalacja bibliotek, debugowanie, kompilacja, instalacja serwerów. Wszystko jest proste i przede wszystkim, wszystko działa. Żeby zainstalować SDL (biblioteka C++ do gier) musiałem się męczyć przez 2-3 godziny, kopiować pliki z jednego katalogu do drugiego, kopać szturchać. Linux? 2 minuty. Szybko i sprawnie.


Podsumowanie:
Obecnie używam Windowsa tylko i wyłącznie do gier. Codzienna aktywność komputerowa, jak i prace programistyczne, wszystko wykonuje pod linuxem. I jestem z niego niesamowicie zadowolony! Polecam każdemu, kto chce spróbować czegoś innego, albo szuka środowiska do pracy.

poniedziałek, 23 września 2013

Potyczka z generatorem cząsteczek

Opis problemu:

Stworzyć prosty generator cząsteczek. Ma to być okno w którym po kliknięciu myszką we wszystkie kierunki lecą kolorowe kuleczki.

Zastosowane technologie:

Python, Pygame - biblioteka oparta na SDL, z którym miałem do czynienia przy okazji jednego projektu z C++.

Potyczka!

Od pewnego czasu przymierzam się do nauczenia się Python'a. W tym tygodniu z racji braku konkretnych zajęć i poważniejszych obowiązków stwierdziłem, że będzie świetna okazja żeby się w końcu do tego zabrać. Ale jak to bywa z nauką nowego języka, samą teorią nic się nie zdziała, trzeba coś w tym napisać. Padło na prosty generator cząsteczek.
Co do wyboru pygame jako biblioteki to nie bardzo miałem ochotę na robienie jakiegoś projektu backendowego, za to do robienia około-growych rzeczy zawsze znajduje w sobie zacięcie. No i jak już wspominałem miałem bazę, bo kiedyś zrobiłem sidesroller'a w C++ z wykorzystaniem SDL.
Świetne materiały do nauki tej biblioteki można znaleźć TUTAJ. Gorąco polecam, darmową książkę Albert'a Sweigart'a, miło się czyta i wszystko jest prosto wytłumaczone.
Teraz już do samego projektu.
Dla przejrzystości kod podzieliłem na dwa moduły:

  • particles.py - zawiera klasę Particle
  • particlesMaker.py - zawiera main'a, trochę stałych i funkcji
  • Klasa Particle
    class Particle():
      """simple particle class"""
      def __init__(self,x,y,xVel,yVel,color,screenWidth,screenHeight):
        self.x          = x
        self.y          = y
        self.startX     = x
        self.startY     = y
        self.xVel       = xVel
        self.yVel       = yVel
        self.scrWidth   = screenWidth
        self.scrHeight  = screenHeight
        self.color      = color
    
      def update(self):
        self.x += self.xVel
        self.y += self.yVel
        if self.x > self.scrWidth 
    or self.y > self.scrHeight 
    or self.x < 0 or self.y < 0:
          self.x = self.startX
          self.y = self.startY
    
    Jak widać nie jest to jakoś specjalnie rozbudowane. W konstruktorze inicjujemy podstawowe wartości - 'x' i 'y' to nasze współrzędne początkowe, 'xVel' i 'yVel' to wektory przesunięcia reszty już nie będę tłumaczył. Powiem tylko, że 'self.x' i 'self.y' to aktualne położenie cząsteczki, natomiast 'self.startX' i 'self.startY' to jej punkt startowy. Będzie do niego wracać po wypadnięciu z ekranu.
    Co się dzieje w metodzie update? Aktualizujemy pozycję cząsteczki i, jeżeli jest poza ekranem, sprowadzamy ją z powrotem do punktu startowego.
    Jak widać sama cząsteczka nie jest specjalnie skomplikowana - nie używa też żadnych metod z pygame.

    Moduł particlesMaker
    Zaczynamy kilkoma importami i deklaracją potrzebnych zmiennych:
    import pygame,sys,particles,random
    from pygame.locals import *
    from collections import deque
    
    #definitions of global constans
    SCRWIDTH  = 800
    SCRHEIGHT = 600
    MAXPARTICLES = 800
    FPS = 40
    NEWPARTICLES = 2
    MAXXVEL = 4
    MAXYVEL = 4
    
    #colors
    #name        R    G    B
    GRAY     = (100, 100, 100)
    NAVYBLUE = ( 60,  60, 100)
    WHITE    = (255, 255, 255)
    RED      = (255,   0,   0)
    GREEN    = (  0, 255,   0)
    BLUE     = (  0,   0, 255)
    YELLOW   = (255, 255,   0)
    ORANGE   = (255, 128,   0)
    PURPLE   = (255,   0, 255)
    CYAN     = (  0, 255, 255)
    
    ALLCOLORS = [RED, GREEN, GRAY, BLUE, YELLOW, ORANGE, PURPLE, CYAN, NAVYBLUE]
    
    No dobra, w pierwszej linijce importujemy potrzebne nam moduły, w tym nasz moduł particles. W drugiej linijce mamy import wszystkiego z pygame.locals - są tam deklaracje stałych takich jak typy eventów i dzięki temu importowi możemy się do nich odwoływać bezpośrednio, a nie przez pygame.locals.NAZWA_STALEJ.
    W trzeciej linii importuje klasę deque, będącą zgrabną implementacją kolejki (my wykorzystamy ją konkretnie jako FIFO). Będziemy w niej przechowywać nasze cząsteczki.
    Ze stałych wyjaśnię tylko 'MAXPARTICLES' - będzie to liczba cząsteczek do wygenerowania w każdej klatce.
    Dalej mamy definicję kolorów i wrzucenie ich do jednej listy. Kolory w pygame są reprezentowane przez trójkę wartości z zakresu 0-255, odpowiadającą wartością RGB.
    Lecimy dalej.
    def main():
      pygame.init()
      SCREEN = pygame.display.set_mode((SCRWIDTH,SCRHEIGHT))
      pygame.display.set_caption("Particles generator")
      CLOCK = pygame.time.Clock()
      particles = deque([],MAXPARTICLES)
      mouseDown = False
      mousePos = (None,None)
    
      running = True
      while running:
        SCREEN.fill(WHITE)
        #events handling
        for event in pygame.event.get():
          if event.type == QUIT:
            running = False
          elif event.type == KEYDOWN:
            if event.key == K_ESCAPE:
              pause()
          elif event.type == MOUSEBUTTONDOWN:
            mouseDown = True
            mousePos = event.pos
          elif event.type == MOUSEBUTTONUP:
            mouseDown = False
          elif event.type == MOUSEMOTION:
            mousePos = event.pos
    
        #add new particles if mouse button is hold
        if mouseDown:
          generateParticles(particles,mousePos)
        #draw particles
        for part in particles:
          part.update()
          pygame.draw.circle(SCREEN,part.color,(part.x,part.y),2)
    
        pygame.display.flip()
        CLOCK.tick(FPS)
      pygame.quit()
      sys.exit()
    
    main()
    Zaczynamy od odpalenia pygame przez funkcję 'init()'. Bez tego nic nie ruszy.
    Dalej inicjujemy "powierzchnię" do której będziemy rysować. Ogólnie wygląda to tak, że na monitor rzucamy przygotowany wcześniej pojedynczy obraz. Dla przykładu gdy mamy 3 drzewa, gracza i pieska to nie wyświetlamy najpierw tła, potem drzew, potem... Wrzucamy to wszystko na jeden "obrazek" i dopiero ten "obrazek" wyświetlamy na monitorze.
    4 linijka to ustawienie tytułu okna, 5 to inicjacja zegara (wyjaśnię po co za chwilę). Dalej mamy konstrukcję naszej kolejki, pierwszy argument to dane jakie zostaną dodane, chcemy pustą kolejkę więc jest tam pusta lista. Drugi argument to maksymalny rozmiar kolejki, bardzo fajna sprawa, bo myślałem, że będę musiał sprawdzać ręcznie czy się nie przepełniła. A tak gdy przekroczymy dozwoloną ilość cząsteczek to kolejka pozbędzie się kilku "najstarszych" elementów.
    Dalej mamy zmienne sterujące.

    Gra będzie działała w pętli while, z każdym przebiegiem wykonując 3 główne typy zadań:

  • Sprawdzenie i obsługa oczekujących eventów - zdarzeń takich jak naciśnięcie klawisza czy przesunięcie myszki
  • Aktualizacja stanu - logika gry, rzeczy takie jak poruszanie obiektów, wykrywanie kolizji itp.
  • Wyświetlanie aktualnego stanu

  • Zaczynamy od wypełnienia całego naszego ekrany białym tłem - kasujemy w ten sposób to co działo się w poprzedniej klatce. W pętli for obsługujemy zdarzenia. Ich listę zwraca nam pygame.event.get(). Dalej sprawdzamy jaki event nastąpił i przeprowadzamy odpowiednią akcję. Nazwy eventów raczej mówią same za siebie: QUIT - dla przykładu to kliknięcie "krzyżyka" zamykającego okno. Na kliknięcie escape wywołuję pauzę, ale jeszcze nie chciało mi się jej implementować, więc to nic nie robi. Kliknięcie przycisku myszy przełącza flagę mouseDown na true i pobiera pozycję kursora na ekranie. Przy zwolnieniu przycisku myszki przestawiam flagę na false, a przy ruchu aktualizuję pozycję kursora. Nic trudnego.
    Jeżeli przycisk myszki jest wciśnięty wywołuje generator cząsteczek. Opisze jego działanie za chwilę. Na koniec wywołuję metodę update() dla każdej cząsteczki w naszej kolejce. W linii 34 rysuję okrąg odpowiedniego koloru we współrzędnych x i y naszego obiektu. Tak robię dla wszystkich naszych cząsteczek.
    pygame.display.filp() jest funkcją wrzucającą nasz SCREEN na monitor (wcześniej rysowaliśmy do SCREEN).
    No i jest nasz zegar - jego zadaniem jest tutaj zapewnienie, żeby pętla nie wykonała się więcej razy niż 'FPS' w ciągu sekundy. Gdyby tego tu nie było pętla leciałaby tak szybko jak mogła - w przypadku tego programu pewnie i z 200 razy na sekundę - zżerając niepotrzebnie zasoby.
    Po wyjściu z pętli while wywołujemy pygame.quit() aby zamknąć wszystkie moduły i sys.exit(), które kończy działanie aplikacji.

    generateParticles
    Zostało tylko wyjaśnić jedną funkcję pomocniczą.
    def generateParticles(list,pos):
      """generates new particles and maintaining there is not to much of then"""
      for i in range(NEWPARTICLES):
        list.append(particles.Particle(pos[0],pos[1],random.randint(-MAXXVEL,MAXXVEL)
    ,random.randint(-MAXYVEL,MAXYVEL)
    ,ALLCOLORS[random.randint(0,len(ALLCOLORS)-1)],SCRWIDTH,SCRHEIGHT))
    
    Dużo znowu się tutaj nie dzieje. Jako że nasza kolejka sama dba o zachowanie odpowiedniej wielkości, wystarczy że dodamy do niej określoną liczbę cząsteczek. To się dzieje w pętli for i jest w niej wywoływany konstruktor Particle z aktualną pozycją myszki, randomowymi wektorami przesunięć, losowym kolorem i naszymi rozmiarami ekranu. Tyle.

    Małe podsumowanie

    --Przemyślenia - można pominąć--
    Nie jest to specjalnie zaawansowany projekt, w sam raz dla kogoś kto startuje z pythonem i pygame. Ja sam mam zamiar rozwinąć go o kilka dodatkowych typów cząsteczek i jakiś interfejs, w którym użytkownik będzie mógł trochę namieszać ze zmiennymi - szybkością, ilością, typem itd.

    Kod źródłowy jest dostępny w moim repozytorium na gitHub.
    Serdecznie zachęcam do zabawy z kodem!

    sobota, 21 września 2013

    Potyczka z Google Maps 1/2

    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/000
    Kilka 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)2
    d<r2
    Gdzie środek okręgu jest w punkcie (x,y) a punkt mamy w punkcie (a,b).
    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!