Sujuvamman kartan prototyypit

Katsaus Google Mapsin toimintaan

Kun työskentelin Google Mapsilla UX-suunnittelijana, yksi niistä asioista, jotka todella halusin pystyväni tekemään, oli luoda prototyyppejä, jotka pystyvät synkronoimaan animaatiot zoomilla. JavaScript Maps -sovellusliittymällä on kuitenkin rajoitettu zoomauksen hallinta, joten suuremman hallinnan saamiseksi kokeilin HTML5-piirtoalustan avulla laattojen yhdistämistä täysin mukautetussa toteutuksessa.

Ymmärtääksesi, mikä tekee sujuvasta zoomista haastavan nykyaikaisille karttasovelluksille, se auttaa ensin ymmärtämään, kuinka kartta tehdään ja kuinka Google Maps (ja suurin osa muista) karttaasiakkaat toimivat - voit etsiä lihavoituja otsikoita siirtyäksesi sinne suoraan.

  1. Maan muuttaminen litteäksi - prosessi, jolla 3D-maapallo muuttuu 2D-karttoksi.
  2. Google Maps - kuinka Google muutti karttamaailmaa vuonna 2005 ja miten asiakas näyttää.
  3. Rasteroidun kartan animointi - mukautettu lähestymistapa, jonka avulla animaatiot sujuvat.

1. Maan muuttaminen litteäksi

Toivon, että siitä ei tule yllätys kenellekään, mutta maailma on pyöreä - vaikkakin kummallista kyllä, se ei oikeastaan ​​ole pallo, vaan melko hiukan ja keskeltä leveämpi.

Prosessi tämän enimmäkseen pallomaisen esineen ottamiseksi ja sen esittämiseksi 2D-muodossa on jotain, jonka kartografit ovat kamppailleet ja kiistelleet vuosituhansien ajan. Oikeastaan ​​ei ole "parasta" tapaa tehdä se, jokaisessa on kompromisseja.

Leveys-ja pituuspiiri

Jos kuvittelet maailmaa pallona, ​​joka pyörii akselinsa ympäri, pohjoisnapa on yläosassa, etelänapa on aivan alaosassa ja päiväntasaaja on kuvitteellinen viiva, joka kulkee keskellä.

asteikkolevyssä

Jos ajattelet päiväntasaajaa ympyränä, joka istuu vaakasuorassa (kuten hihnassa), voisit kuvitella ylimääräisiä vaakasuuntaisia ​​ympyröitä ylä- ja alapuolelta, jotka kaikki ovat yhdensuuntaiset päiväntasaajan kanssa. Seuraavan minkä tahansa oikealla olevan ympyrän jälkeen siirryt itään, seuraa minkä tahansa ympyrän vasemmalle suoraan länteen. Näitä kuvitteellisia viivoja kutsutaan leveyspiireiksi. Leveysasteilla on aina sama etäisyys toisistaan ​​riippumatta siitä, kuinka kaukana itään tai länteen matkustat.

Koska maa on kallistettu akselilleen, aurinko ei aina istu suoraan päiväntasaajan yläpuolella, vaan näyttää siltä vaeltavan hieman pohjoiseen ja etelään kiertoradan aikana. Syövän tropiikki on pohjoisin leveyspiiri, jolla aurinko voi ilmestyä suoraan yläpuolella (kesäpäivänseisauksella), ja Kauris tropiikki on vastaava eteläisellä pallonpuoliskolla (ja joulukuunpäivänseisaus). Se ei todellakaan ole tärkeää Google Mapsille, mutta se on hauskaa trivia.

Leveysaste osoittaa kuinka kaukana pohjoisessa tai etelässä olet (koska et ole kuinka kaukana itään tai länteen oletkin, et ole siirtynyt lainkaan pohjoiseen tai etelään).

Toiseen suuntaan, kohtisuoraan päiväntasaajaan nähden, ovat meridiaaneja tai pituuslinjoja - kukin yhdistää pohjoisnavan etelään suorassa linjassa. Minkä tahansa rivin jälkeen siirryt suoraan pohjoiseen, alaspäin etelään.

Pituusaste tarkoittaa, kuinka kaukana idässä tai lännessä olet (koska etpä kuinka kaukana pohjoiseen tai eteläänkin et mene, et ole koskaan siirtynyt itään tai länteen).

Kriittinen ero leveys- ja pituusasteiden välillä on, että vaikka leveysaste on aina yhtä etäisyyden päässä pallon päällä, pituusasteviivat ovat kauimpana toisistaan ​​keskellä (päiväntasaaja) ja lähentyvät toisiaan lähellä napoja (missä ne koskettavat).

Leveyden ja pituuden mittaaminen

Sekä leveys- että pituusaste mitataan asteina. Mittaamalla pallon keskipisteestä kullakin jokaisella ympyrällä (leveyspiirien yhdensuuntaiset ympyrät ja pituussuunnan kohtisuorat ympyrät).

Leveysaste on päiväntasaajasta muodostettu kulma, joten se on 0 ° päiväntasaajan kohdalla ja enintään 90 ° pohjoiseen tai etelään (napojen kohdalla). Puolivälissä kohti pohjoisnapaa olisi 45º N.

Pituusaste on kulma, joka mitataan päämeridiaanista (mielivaltainen viiva, joka kulkee Greenwichin, Englannin läpi). Se on 0º Greenwichissä ja jopa 180º itään tai länteen (maailman vastakkaiselle puolelle).

Globaali sijainti

Viimeinen trivia, jolla ei ole väliä Google Mapsille (mutta pidän siitä mielenkiintoista), on se, kuinka ihmiset sijoittautuivat ennen GPS: ää.

Leveysaste on suhteellisen yksinkertainen, sinun täytyy vain mitata horisontin ja tunnetun tähden (tai aurinkoomme) välinen kulma ja tehdä sitten pieni matematiikka. Ihmiset ovat navigoineet tähtiin perustuen tuhansien vuosien ajan, Polaris (pohjatähti) on erityisen suosittu - pohjoisnavalla Polaris on suoraan yläpuolella (90º horisontin kohdalla). Päiväntasaajan kohdalla Polaris näyttää istuvan horisontissa (0 °). Näiden kahden ääripään välillä kulma Polariksen kanssa on leveysastekulma pohjoiseen. Voit käyttää myös muita tähtiä, ne vain vaativat enemmän matematiikkaa.

Pituusaste on paljon, paljon, vaikeampaa - itse asiassa niin kovaa, että kukaan ei pystynyt siihen hyvin ennen 1700-luvun loppua (eikä helposti ennen paljon myöhemmin). Ratkaisu sisältää ajan - maa pyörii samalla nopeudella, 360 astetta 24 tunnin välein (tai 15 astetta tunnissa), joten jos tiedät aloitusajan ja ajan, missä olet, voit laskea etäisyyden eron perusteella. Helppo tehdä tänään, tarkat kellot, mutta erittäin vaikea tehdä aiemmin.

Alun perin he käyttivät taivaankappaleiden ennustettua sijaintia tiedossa olevilla aikoilla laskeakseen, mikä aika oli, ja sitten verrattiin sitä paikalliseen aikaan (käyttämällä aurinkoa keskipäivällä “paikallisen kellon” nollaamiseen). Laajimmin käytetty ennustejoukko oli Englannin Greenwichin kuninkaallisen observatorion julkaisema merialmanakki - mikäli oletko koskaan miettinyt, miksi sitä kutsuttiin GMT (Greenwichin keskimääräinen aika) tai miksi päämeridiaanit kulkevat Greenwichin läpi, se on koska pisimpään aikaa kaikki mittasivat suhteessa Greenwichin observatorioon.

Suurin läpimitta pituuden mittaamisessa oli tarkempia kelloja, jotta ne voisivat lopettaa tähtien katsomisen ja tarkistaa vain GMT - pituusaste oli tuntien lukumäärän kerrottuna 15º. Itse asiassa tämä on melko paljon siitä, kuinka kaikki laskivat pituutta, kunnes keksittiin GPS (Global Positioning System), joka on vain joukko avaruudessa istuvia erittäin tarkkoja atomikelloja (ja joitakin vaikuttavia matematiikoita).

Jos olet tästä puolet yhtä kiehtova kuin minä, suosittelen todella lukemaan tätä upeaa kirjaa siitä.

Projektion valitseminen

Menetelmää 3D-maapallon pisteiden kääntämiseksi 2D-tasoon kutsutaan karttaprojektioksi. On olemassa monia erilaisia ​​projektioita, joilla jokaisella on omat vahvuutensa ja rajoituksensa, ja yksikään niistä ei sisällä todellisen geometrian vääristymiä - tässä on vain muutama:

Ennusteet Wikipediassa

Projekti, jonka Google Maps valitsi, on muutettu versio Mercator-projektiosta, jonka otsikko on luovasti Web Mercator [tärkein ero on siinä, että maailma oletetaan pallo, sen sijaan, että se olisi tasainen ellipsoidi].

Mercatorin valintaan on muutamia syitä, mutta paras syy on se, että pohjoinen ja etelä ovat suoraan ylös ja alas ja itä ja länsi ovat suoraan vasemmalle ja oikealle - joissakin muissa projektioissa nämä linjat kaareutuvat tai poikkeavat, kun siirryt poikki. kartta. Tämä on hyvin samankaltainen kuin syy siihen, että Mercator otettiin käyttöön niin laajasti navigointiin - vakiovirtaradat (ts. Jos valitset kompassilaakerin ja pidät siitä) ovat täysin suorat. Sivuhyöty on se, että koska se on lieriömäinen projektio, voit kääriä vaakasuoraan ja laattaa kartan.

Jotkut muut Mercator-projektion erikoisominaisuudet ovat, että asteikko on sama joka suuntaan minkä tahansa paikallisen pisteen ympärillä (ts. Jos zoomaat kaupunkia, etäisyys pohjoisesta ja etelästä on sama kuin itään ja länteen) ja kaikki kulmat ovat kuvattu oikein (ts. itä on 90º pohjoisesta).

Suurin kritiikki Mercator-projektion suhteen on, että se vääristää merkittävästi niiden maiden mittasuhteita, joita kauempana pääset päiväntasaajasta (esim. Grönlanti näyttää yhtä suurelta kuin Afrikka, vaikka se on alle kymmenesosa koosta).

Ajattele mitä tapahtuu kun kuori appelsiini ja kuvittele sitten tekevän saman maan kanssa. Jos leikkaat pitkittäissuuntaista sarjaa, päädyt valikoimaksi kiilattuja viipaleita - maapallolla kukin pystysuora viiva näyttää suoralta, mutta kun käärität sen kahteen ulottuvuuteen, se muuttuu kaarevaksi (muista kuinka nuo pituusasteviivat) pääsivät lähempänä toisiaan?).

Maapallon purkaminen

Jotta Mercator-kartta liittyisi uudelleen, meidän on venytettävä näitä segmenttejä vaakasuoraan. Päiväntasaajan päällä he ovat jo koskettamassa, joten heidän ei tarvitse venyttää lainkaan, mutta napoissa on todella suuri aukko ja heidän täytyy venyttää paljon (teknisesti ääretön). Jotta etäisyydet ja kulmat pysyvät molemmissa suunnissa vaakatasossa, se venytetään saman verran pystysuunnassa. Mitä lähempänä se pääsee napoihin, sitä enemmän sen täytyy venyttää.

Tätä on hieman helpompi havaita, jos yrität piirtää samankokoisen ympyrän kartan eri pisteisiin. Mercator-projektiossa voit nähdä, että ympyrät näyttävät paljon suurempia napoja kohti (vaikka todellisuudessa ne ovat täsmälleen samankokoiset). Tämä johtuu siitä, että meidän piti venyttää karttaa enemmän napojen kohdalla, jotta se yhdistyisi.

Asteikon muodonmuutos

Tällä on merkitystä vain silloin, kun se on pienennetty hyvin, koska mittakaava on sama kaikilla paikallisilla alueilla, joten tietyssä kaupungissa tai jopa maassa kaikki pysyy verrannollisena. Ja se on todellakin vain pylväiden merkittävä ongelma, mutta koska pingviinit ja jääkarhut eivät käytä Google Mapsia, valituksia ei ole tehty paljon.

Jos ajatellaan takaisin palloon - missä leveysviivat olivat yhdensuuntaisia ​​ja aina saman etäisyyden päässä toisistaan, kun taas pituusviivat saivat lähemmäksi napoja - Mercatorin avulla leveysaste pysyy täysin yhdensuuntaisena ja pituusaste muuttuu täysin kohtisuoraksi. Kaikki on suoraa.

Tämä fantastinen Grafonautin video osoittaa koko muutoksen:

2. Google Maps

Vuonna 2005 Google Maps lanseerasi innovaatiolla, joka edelleen tukee kaikkia nykyisiä kartoituspalveluita - laatoitettua karttaa. Vuonna 2013 tehtiin suuri päivitys WebGL: n käyttämiseen ja asiakaspuolen renderoinnin lisäämiseen, mutta kaakeloitu lähestymistapa säilyy.

Minun on huomattava, että Google Maps ei keksinyt laatoitetun kartan konseptia, mutta se oli ehkä ensimmäinen yleinen sovellus, joka käytti sitä, ja sen yhdistäminen AJAX: n ja verkkoon varmasti auttoi popularisoimaan lähestymistapaa.

Laatoitetut kartat

Yhden kuvan esittämisen sijasta Google hajottaa kartan pienemmiksi ruuduiksi ja sijoittaa ne sitten vierekkäin muodostaen yhden suuremman kuvan - aivan kuten mosaiikki.

Laatoitettu kartta

Ensisijainen syy tähän on kuvan koko. Google Mapsin korkeimmalla zoomaustasolla kuva olisi yli 500 miljoonaa pikseliä neliö (kaksinkertainen HDPI-näyttöihin nähden), mikä on yli 25 000 teratavua (luulen?) Jopa erittäin optimistisella kuvanpakkauksella. Jos oletetaan, että selaimesi voi tuottaa kuvan, lataaminen Google Fiberillä vie yli 6 vuotta.

Toinen syy on palvelimen kuormitus. Laattojen käytön sijasta palvelin voi luoda jokaiselle käyttäjälle täydellisen kokoisen kartan tarkalla zoomaustasolla, leveys- ja pituusasteella ja oikealla kokoa ikkunan täyttämiseksi. Mutta se tarkoittaisi todennäköisesti, että jokainen käyttäjä tarvitsee täysin mukautetun kartan, ja yli miljardin kuukausittaisen käyttäjän kanssa se on paljon mukautettuja karttoja! Se tarkoittaisi myös, että jokaisella panoroimalla karttaa jopa muutama kuvapiste sinun on ladattava kokonaan uusi kartta.

Mukava asia laattojen suhteen on, että kaikki voivat jakaa ne, palvelin voi tallentaa ne välimuistiin (ja jopa luoda ne ennalta) ja asiakas voi helposti siirtää niitä. Jotkut käyttäjät voivat ladata muutama ylimääräinen laatta, jos ikkuna on suurempi, mutta ruudut on silti vain renderettävä.

Huomaa: Vuoden 2013 vektoripohjaiseen WebGL-toteutukseen palvelin lähettää kuvan laattojen lähettämisen sijasta vektoritiedot (jokainen polku ja monikulmio) ja asiakas toimittaa kuvat. Nämä vektoritiedot on kuitenkin edelleen ryhmitelty ”laattoihin” - samoista syistä (sallii palvelimen välimuistion ja tarjoaa asiakkaalle puhtaan tavan jakaa tietopyynnöt). Vaikka seuraavissa osissa käsitellään rasterin toteutusta (jota Maps Maps API edelleen käyttää), yleinen lähestymistapa pätee myös WebGL-versioon.

Zoom-tasot

Google Maps -palvelussa on vaihteleva määrä zoomaustasoja sijainnin perusteella - mutta se on yleensä noin 21. Pienennettynä (taso 0) koko karttaa edustaa yksi 256 x 256 pikselin neliöruutu. Jokaisella inkrementaalisella zoomaustasolla kartta kaksinkertaistuu kooltaan kumpaankin suuntaan - zoomauksen yhteydessä jokainen ruutu korvataan 4 yksityiskohtaisemmalla (2x2). Jokainen ruutu on edelleen vain 256 x 256 pikseliä, ja kun yhdistät ne yhteen, saat saman kartan (vain yksityiskohtaisempi).

Zoom-tasolla 0 maailmankartta on yksi laatta, zoomauksessa 1 kartta on 2 laattaa kumpaankin suuntaan, zoomilla 2 se on 4 laattaa leveä, zoomilla 3 se on 8 laattaa leveä ja niin edelleen (kaksinkertaistuu joka kerta) . Joten vaikka kokonaisleveys ja -korkeus kaksinkertaistuvat jokaisella tasolla, pinta-ala kasvaa nopeammin (1 laatta, 4 laattaa, 16 laattaa, 64 laattaa jne.). Siihen mennessä, kun se saavuttaa zoomtason 21, kartta on 2 miljoonan laatan leveä ja sisältää yhteensä yli 4 biljoonaa laattaa.

Karttalaatat kullakin zoomaustasolla

Jokainen zoomaustaso saa omat tyylisäännöt päättääkseen mitä tietoja pitäisi näyttää. Tietietojen lisäämiseen maailmankarttaan ei ole juurikaan lisättävää, eikä maarakentamiseen tarvittavaa tietoa rakenneta jne. On erittäin ahkera joukkue, joka tasapainottaa tarroja ja ominaisuuksia, jotka esitetään ja muotoillaan kullakin tasolla.

Yleinen nyrkkisääntö muutamat ensimmäiset tasot ovat melko vain maailmankarttaa. Zoom 5: llä mantereet ja maanmassat ovat ensisijaisia ​​piirteitä. Tason 10 mukaan kaupungin yksityiskohdat ilmestyvät. Tasolla 15 kadut ovat selvästi näkyvissä. Ja zoomilla 20 rakennukset kaikki renderoidaan.

Voimme helposti arvioida pikseliasteikon näille zoomauksille - voisimme tehdä sen tarkasti monimutkaisemmalla matematiikalla -, mutta päiväntasaajalla (missä Mercator-projektio ei venytä karttaa) se on yksinkertainen laskelma:

Zoomilla 1 jokainen pikseli edustaa 78 km (48 mailia), zoom 5 on 5 km (3 mailia), zoom 10 on 150 m (164 metriä), 15 on 5 m (5,5 metriä) ja zoomilla 20 joka pikseli vastaa 15 cm ( 6 tuumaa) - se on uskomattoman yksityiskohtainen!

paikannus

Google Maps tarjoaa leveyden ja pituuden lisäksi kolme koordinaattikäsitettä: maailman koordinaatit, pikselikoordinaatit ja laattakoordinaatit.

Maailman koordinaatit ovat riippumattomia zoomaustasosta, ja niitä käytetään kääntämään leveys- ja pituusasteiden ja nykyisen sijainnin välillä kartalla (tai päinvastoin). Ne lasketaan suhteessa yksittäiseen ruutuun zoomaustasolla 0. Leveys- ja pituusaste kartoitetaan kyseisen yksittäisen ruudun murto-osan x ja y pikseliin (luku välillä 0–256 - sen leveys ja korkeus).

Muuntaminen on erittäin helppoa, vaikka en voi väittää ymmärtävänsä matematiikkaa. Pituusasteiden kartoitus on helppo ymmärtää, koska se suoraan kääntää, mutta leveysaste on monimutkaisempi vinossa, kun se lähestyy napoja.

Pikselikoordinaatit viittaavat leveyden ja pituuden tarkkaan pikselin sijaintiin tietyllä zoomaustasolla. Ne voidaan laskea ottamalla maailman koordinaatit ja kertomalla zoomin tason kokonaismäärällä - mikä on helppo laskea, koska asteikko kaksinkertaistaa jokaisen zoomin.

Laattakoordinaatit ovat kuinka asiakas pyytää palvelimelta kuvia.

Laattojen koordinaatit

Ne on sijoitettu riveihin ja sarakkeisiin siten, että rivin 0 sarake 0 on vasemmassa yläkulmassa, rivit kasvavat oikealle ja sarakkeet, kun siirryt alas. Samoin kuin pikselikoordinaatit, ruudut ovat riippuvaisia ​​zoomaustasosta, itse asiassa se on yksinkertainen kartoitus pikselistä laattaan jakamalla pikselikoordinaatit ruudun koosta ja ottamalla integraaliluku.

Asiakas voi helposti selvittää tarvitsemansa ruudut laskemalla ruudun koordinaatit näytön jokaiseen nurkkaan. Yleensä se lisää hieman täyttöä esikuormituskeinona, vain siltä varalta, että käyttäjä panostaa karttaa muutamalla pikselillä.

Asiakkaat voivat helposti luoda ruudun URL-osoitteet näiden koordinaattien avulla - esimerkiksi zoomaustaso 1, rivi 0, sarake 0 on tämä laatta, joka sisältää Pohjois-Amerikan. Koodin rakentaminen on triviaalia, vaikka Maps-sovellusliittymä käsittelee sen sinulle (tyylin ja muiden etujen ohella).

panorointi

Karttojen kanssa tapahtuva vuorovaikutus on se, missä laatat todella todistavat arvonsa. Ennen Google Mapsia asiat toimivat hieman enemmän kuin atlas - jos päädyit kartan reunaan, tarvitsit kääntääksesi sivua nähdäksesi jotain enemmän. Mahtava asia laattojen suhteen on se, että se antoi käyttäjille mahdollisuuden tutkia vapaasti karttaa keskeytyksettä panoroidessaan ja lähentyessään.

Jokainen laatta on sijoitettu ehdottomasti säilytysastiaan, ja kun panoroit karttaa sen sijaan, että siirrät jokaista laattaa, vain säilön täytyy liikkua (ja ruudut muuttuvat sen mukana). Tämän avulla asiakas voi minimoida DOM-muutosten määrän.

Kontti liikkuu, ei laattoja

Kunkin ruudun sijainnin on helppo laskea kertomalla ruudun koordinaatti ruudun koosta.

Viimeinen paikantamis temppu on selainten tarjottavien laattojen kokonaismäärän minimointi.

Ylläpidä vakiokokoinen DOM

Kun käyttäjä panoi karttaa, asiakas tarkistaa, mitkä ruudut tulisi olla näkyvissä ja joko lataa uudet tai poistaa ne, joita ei enää näy.

Tämä tapahtuu niin nopeasti, että käyttäjä harvoin huomauttaa (ja sen sijaan, että se leikkuu näytön koviin rajoihin, se hakee usein muutama ylimääräinen laatta molemmilta puolilta puskurina). [Tämä lähestymistapa ei oikeastaan ​​eroa siitä, miten Google Photos toimii nyt]

zoomaus

Panorointi ympäri on saumatonta, mutta zoomaus on yksi haastealueista kaakeloidulla kartalla.

Tekniseltä kannalta haasteena on vähemmän laattojen sijoittaminen, vaan enemmän kuinka siirtyä tasojen välillä. Jokainen zoomaustaso on kaksinkertainen mittakaavassa, eikä laattojen välissä ole mitään apua.

Napsauttaminen tasojen välillä

Zoomaus oli alun perin hyvin yksinkertainen, se vain korvasi kartan seuraavalla laattasarjalla, mutta se oli hiukan häikäisevä, koska se yhtäkkiä “napsahtaa” tasojen välillä.

Yksi tapa, jolla tämä kompensoidaan, on sen sijaan, että lähentäisit kartan keskustaa, se pitää kohdistimen alla olevan paikan paikallaan (kiinnitetty kohdistimen alle). Tämän avulla käyttäjät voivat kirjaimellisesti "osoittaa" kiinnostavaan ominaisuuteen ja keskittyä niihin (he hallitsevat referenssipistettä).

Nopea animaatio (Maps JavaScript API)

Tuoreempi sopeutuminen sai sen tuntemaan olon reagoivammaksi. Kun zoomataan, se pitää väliaikaisesti molemmat zoom-tasot laattojen (vanhat ja uudet) arvoisina ja tekee erittäin nopean mitta-animaation niiden välillä - uudet laatat alkavat pienentää puoleen ja vanhat ruudut animoidaan kaksinkertaiseksi.

Se "napsahtaa" kerrosten välillä, kun animaatio päättyy, mutta kaikki tapahtuu niin nopeasti, että silmä kuvittelee välitilan.

Tätä skaalaus- ja napsautuslähestymistapaa käytetään edelleen Google Maps JavaScript -sovellusliittymässä, Bing Mapsissa, Here Mapsissa, Yahoo Mapsissa, MapQuestissa ja OpenStreetMapissa (LeafletJS).

Asteikon siirtyminen zoomin aikana

Mahdollisuus suurin rajoitus asteikolla ja napsautuksella on se, että käyttäjällä ei ole hallintaa animaatiosta, kun he laukaisevat zoomin, se suoritetaan loppuun saakka, kun ei ole kykyä hallita nopeutta tai keskeyttää välitilassa.

Vektorikartat

Vuonna 2013 Google Maps julkaisi merkittävän päivityksen osoitteeseen maps.google.com, joka lopetti PNG-laattojen käytön kuvissa ja aloitti vektorikuvien lataamisen. Näihin vektorilaatoihin viitataan edelleen niiden laattakoordinaateilla, ne käyttäytyvät edelleen hyvin samalla tavalla kuin rasteriruudut, mutta kuvan sijasta ne sisältävät kaikki tarrat, polut ja monikulmio - ja piirretään asiakkaalle.

Tämä on tärkeä syy monille syille - vektoritiedot pakkautuvat paremmin kuin kuvat (säästää siten kaistanleveyttä), mahdollistavat dynaamiset päivitykset ja muotoilun (esimerkiksi jos käyttäjä napsauttaa kuljetusreittiä) ja mahdollistaa huomattavasti parannetun zoomauksen .

Sujuva zoomaus

Rasteroitujen PNG-tunnisteiden avulla mittakaavassa kartta ei voi kertoa, mikä on tie (ja sen tulisi pysyä veistettynä saman leveydellä) tai mikä on puisto (ja sen tulisi olla suurempi), mikä tarkoittaa, että kaikki vain venytetään ja pikseloidaan. Vektoritietojen avulla asiakas voi pitää tarrat oikein sijoitettuna, ylläpitää tien leveyttä ja silti sovittaa kaikki polygonit - tulos on uskomattoman tasainen zoomauskokemus. Vielä parempi, se on täysin reagoiva, joten käyttäjä voi hallita nopeutta ja jopa pysähtyä murto-osaisilla zoomaustasoilla.

Jos kuitenkin katsot tarkkaan (tai mennä kokeilemaan itseäsi), kun laatat skaalautuvat erittäin sujuvasti, uutta tietoa ei ole, ennen kuin lopetat. Heti kun käyttäjä keskeyttää zoomauksen, kartta lataa nopeasti vektoriruudut uudelle zoomaustasolle ja vaihtaa ne pois. Se on todella sileä ja helppo.

MapBox on yksi muista asiakkaista, jotka käyttävät vektorigrafiikkaa verkossa, ja käyttävät myös tätä sileää ja napsauttavaa lähestymistapaa, vaikka ne lataavat aggressiivisemmin uudet ruudut zoomaussiirtymien aikana.

3. Rasteroidun kartan animointi

Kartan sujuvan animoinnin mahdollistamiseksi kriittisin elementti on kyky asettaa murto-osan zoomaustasot (esim. Kahden integroidun zoomaustason puolivälissä, jonka laatat tuottavat). Vektorilaatoilla tämä voidaan räätälöidä asiakkaalle, mutta rasterilaattojen kanssa meidän on oltava luovampia.

Tämän tueksi kirjoitin Maps JavaScript -sovellusliittymän täysin mukautetun version, joka käyttää Maps-palvelimen kuvakehyksiä uudelleen, mutta sijoittaa ne sitten ja käsittelee vuorovaikutuksen itse. Tämä mahdollisti kunkin ruudun skaalauksen ja sijainnin täydellisen hallinnan sekä zoomauksen ja animaation hallinnan. Kaikki kertoi, että se oli 4442 riviä kommentoitua koodia - on huomattavaa, kuinka vähän koodia asiakas tarvitsee, mutta jos ajattelee sitä, suurin osa todella kovasta työstä tehdään palvelimella (mikä tie, järvi, rakennus jne.) ovat näkyvissä jokaisessa ruudussa, päättämällä tyylit ja värit ja tekemällä sen sitten kuvina).

Tämä artikkelin loppuosa viittaa prototyyppikoodini, ei Google Mapsin normaaliin versioon.

Murtoluvun luominen

Samanlainen kuin Google Photos -tapa, jonka mukaan matalaresoluutioisten ja korkearesoluutioisten kuvien opasiteetti ristiin häivytetään yksityiskohtien sekoittamiseksi lataamisen aikana, teoriani oli, että voisimme sekoittaa ruudut eri zoomaustasoista luoda välitilan.

Voisimme ottaa alempia zoomaustasoja ja skaalata niitä suurempana kuin lähentäessään, tai tehdä päinvastoin ja pienentää korkeampia zoomaustasoja loitonnettaessa. Skaalaamalla ja päällekkäin ruudut useilta zoomaustasoilta voisimme siirtyä tasaisesti integroitujen zoomausten välillä ja tehdä sen matemaattisesti ennustettavalla tavalla (täydellinen animaatioiden synkronointiin).

Tämä on mahdollista, koska Google käyttää Mercator Projection - mittakaavaa on yhdenmukainen paikallisille alueille, joten laattojen lineaarinen skaalaaminen säilyttää muodot.

Peittokyvyn opasiteetin laskeminen on yksinkertaista ja lineaarista. Kun siirryt kahden zoomaustason välillä, seuraavan ruudun tulee olla täysin läpinäkyvä (opasiteetti 0) ensimmäisessä zoomausvaiheessa ja täysin läpinäkymätön (opasiteetti 1) seuraavassa. Joten opasiteetti on vain 1 miinus etäisyys, jolla laattojen zoomaus on kartan zoomauksesta (vaikka käytännössä se kiinnittyy arvoihin välillä 0 ja 1).

Myös mittakaava ei ole niin monimutkainen. Koska asteikko kaksinkertaistuu jokaisella zoomaustasolla, on mahdollista laskea mitattava määrä tason väliin käyttämällä 2: n voimia.

Jos mapZoom on täystasoa korkeampi kuin laatta (mapZoom - tileZoom = 1), matematiikka johtaisi 2¹ tai 2. Jos mapZoom on samalla tasolla kuin ruutu (mapZoom - tileZoom = 0), matematiikka olisi 2⁰ tai 1. Hienoa voimien laskemisessa on, että se toimii fraktioiden ja negatiivien kanssa. Jos mapZoom on täysin tasoa alempi kuin laatta (mapZoom - tileZoom = -1), saat 2⁻¹ tai 0.5. Puolivälissä zoomaustasojen välillä (mapZoom - tileZoom = 0,5) saat 2 ^ (0.5) tai 1.414, ja voit tehdä tämän skaalataksesi tasaisesti kunkin tilan välillä.

Seuraava kuva osoittaa, miten tämä pätee lähentäessäsi. Yksivärinen laatta on lähtö zoomaustaso ja värilliset ruudut ovat seuraava zoomaustaso (piirretty ruudukkolevyyn, jotta voit tarkkailla eroa). Voit nähdä, että mitä lähemmäksi päästämme seuraavaan zoomaustasoon, sitä enemmän värilliset laatat hallitsevat ja yksityiskohdat (esim. Tarrat) alkavat haalistua.

Lähennä

Tässä on vastakkainen suunta, loitonnut. Yksiväriset ovat uudelleen aloittavan zoomin tasoa ja värittivät edellistä zoomaustasoa - tässä tapauksessa menetämme yksityiskohdat loitottaessamme.

Loitonna12fps

Se toimii erittäin hyvin, tarjoamalla suhteellisen tasaisen zoomin (paljon parempi kuin skaalaus ja napsautus) ja vaikka se ei olekaan aivan yhtä tasainen kuin vektorin renderöinti (sileä ja napsahtava), se eliminoi napsautuskohdan kokonaan.

Olen jättänyt debug-peittokuvan päälle GIF-muodossa, jotta näet missä uudet ruudut latautuvat. Se on käytännössä sujuvampaa (60 kehystä sekunnissa), mutta rajoitin GIF: n 12 fps: iin. Tässä on video. Vaihtoehtoisesti tässä se on ilman virheenkorjauslinjoja.

Kummassakin ääripäässä kartta eroaa melkein käsittämättömästi integroidusta zoomista, vaikka sen keskellä se voi päästä hankalaan tilaan kilpailevien tarrojen kanssa. Tämä ei olisi loistava vaikutus, jos pysyt vain osittaisella zoomaustasolla, mutta se ei ole ongelma siirtymien aikana - ja osittaisen zoomauksen välttämiseksi asiakkaan on helppo “asettua” takaisin integroituun zoomaukseen, kun käyttäjä lopettaa zoomauksen, odottavat, kunnes ne päästään irti, joten he ovat tällä välin täysin hallinnassa.

Zoomaus tasojen 3 ja 4 välillä

Kutsummeko tätä efektivaakaa & sekoittumista? Se ei vain zoomaa sujuvasti, mutta myös reagoi käyttäjän syötteisiin jatkuvasti.

Animoi zoomaus nopeudella 24 kuvaa sekunnissa

HTML5-kangas

Parhaan suorituskyvyn saavuttamiseksi luopui normaalista verkkomenetelmästä käyttää tavallisia HTML-elementtejä. Kuten edellisessä osassa on kuvattu, Maps API käyttää DIV- ja IMG-elementtien yhdistelmää kartan tuottamiseen. Jokainen kuva sijoitetaan yläsäiliöön ja säilö siirretään karttanäkymänä. Normaaliverkkosovelluksissa, joissa selaimen annetaan hallita asioita, on paljon etuja, selain käsittelee kaikki päätökset, milloin ruudun piirretään uudelleen, miten elementit asetetaan ja sijoitetaan, sekä vuorovaikutuksen tehostamiseen (kuten vieritys ja napsautustapahtumat). Selaimen hyödyntäminen tätä varten on lähes aina paras tapa.

Joskus - etenkin hyvin mukautetun piirustuksen yhteydessä - on kuitenkin edullista tehdä tämä käsin. Tämän tueksi selaimet loivat kankaaselementin. Toisin kuin tavallinen HTML, jossa luot elementtejä ja lisäät niitä sivulle, kankaalla suoritat piirtokomennot sille. Voit piirtää viivoja, kaaria, ympyröitä, suorakulmioita ja jopa monimutkaisia ​​käyriä. Kangas ei tee sinulle mitään ylimääräistä, ja kohtelee tulosta aivan kuin kuva. Jos piirrät kuvan kankaalle, sinun on kerrottava tarkalleen missä ja minkä kokoinen on, ja jos päätät siirtää kuvaa muutamalla pikselillä, sinun on tyhjennettävä koko kangas ja maalattava kaikki se (myös muut rivit ja kuvia). Jos vierität normaalia verkkosivustoa, selain laskee sijainnit uudelleen ja piirtää uudelleen. Jos haluat antaa käyttäjien selata kangasta, sinun on laskettava jokainen sijainti manuaalisesti uudelleen ja piirrettävä sitten jokainen kappale itse.

Jos se kuulostaa paljon työtä, niin se todella on, ja se on yksi monista syistä, miksi kangasta ei käytetä useammin; mutta tietyissä tilanteissa kangas on paras tapa saavuttaa jotain, ja täysin mukautettu kartanmuodostaja on yksi niistä (koska jokaisen laatan skaalaaminen ja sijoittaminen oli joka tapauksessa mukautettu, kankaan käyttö lisäsi jonkin verran monimutkaisuutta, mutta vähensi yleiskustannuksia) .

Yksi tapa visualisoida ero sivun rakenteessa on tarkastelemalla tuloksena olevaa HTML-koodia. Normaali lähestymistapa luo kymmeniä elementtejä ja lisää ne sivulle, mutta kangaslähestymistavassa siellä on vain vähän, kaikki oli piirto-komento kankaassa.

Sivurakenteen ero elementtipohjaisen ja kangaslähestymistavan välillä

Varmuuslaatat

Yksi reunakotelo, jota käsitellään laattojen skaalaamisessa ja sekoittamisessa, tapahtuu, jos sekoitettavia laattoja ei ole. Jos alempaa zoomia ei ole vielä ladattu, on parempi aloittaa se täysin läpinäkymättömänä seuraavan tason animaation animoinnin sijasta - muuten kartassa on hajanaisia ​​aukkoja.

Asennuslevyjen peiton laskeminen on yksi alue, josta mukautettu kankaan koostumus todella loistaa - kukin piirtotoiminto voi asettaa mukautetun opasiteetin, ja koska kangas on todella tehokas pienille piirtotoiminnoille (esim. Kartan laattojen kokoinen), voimme määrittää tehokkaasti mukautetun opasiteetin tasot jokainen laatta. Jos luotamme selaimeen tehdä tämä mukautetuilla elementeillä, kaikki yksittäiset animaatiot voivat aiheuttaa hidastumisen.

Asiakas piirtää aina (alapuolella olevat) laatat täydellä opasiteetilla ja muuttaa vain niiden ensisijaisten (kohde zoom-taso) laattojen opasiteettiä, jotka se peittää päälle. Ennen maalausjaksoa se tarkistaa onko ensisijaisella laatalla täydellinen varapeitto - ts. Onko kaikki kyseisen laatan alla piirretty.

Esimerkiksi, jos zoomaamme tänne, zoomauksesta 0 - 1 - värillisillä laatoilla on täydellinen peitto ja niiden alla oleva yksi harmaa laatta on täysin päällekkäinen. Tämä tarkoittaa, että he voivat turvallisesti ansaita opasiteettinsä jättämättä aukkoja.

Päinvastainen ei kuitenkaan ole totta. Jos zoomaamme, nollasta 0: een (niin että värilliset laatat olisivat pohjakerros), emme voi animoida harmaan laatan opasiteettia, koska se jättäisi joitain aukkoja.

Yksi mahdollinen ratkaisu tähän olisi maalata peruslaatat ilman peittoa kerran täysin läpinäkymättömäksi pohjakerrokseksi, maalata sitten varalevyt ja muuttaa sitten turvallisesti ensisijaisten laattojen opasiteetti (pahimmassa tapauksessa se sekoittuu itseensä) - mutta se lisäisi veto-operaatioiden määrä vähän havaittavissa olevaa parannusta varten.

Toinen asia, jonka opasiteetin avulla voimme tehdä, on animoida nopeasti vasta ladattuihin laattoihin, joten paikoilleen napsautumisen sijaan tapahtuu nopea haalistuminen.

Zoomaussuunta ja -nopeus

Asiakas seuraa myös, mihin suuntaan käyttäjät zoomaavat (sisään tai ulos), sekä kuinka nopeasti he zoomaavat, ja käyttää tätä määrittämään, pitäisikö sen ladata uusia laattoja.

Esimerkiksi, jos zoomataan välillä 14-15, asiakas ei vaivaudu lataamaan lisää laattoja suurennusasteelta 14, vaan priorisoi sen sijaan tarvittavien uusien hakemisen 15: stä. Jos tapahtuu päinvastoin, zoomataan pois 15: stä. 14–14, asiakas yrittää ladata uudet laatat vain klo 14 alkaen.

Se käyttää zoomausnopeutta päättääkseen, onko mitään syytä ladata laattoja lainkaan vai onko todennäköistä, että kerros zoomataan ohi ennen kuin kuvia on mahdollisuus ladata. Esimerkiksi nopeasti zoomatessaan käyttäjä voi kilpailla zoomauksesta 4-15 15 sekunnissa - ja pisteitä ei ole ladattu vähän, 5, 6, 7, 8 ... koska se olisi vain laattojen tuhlausta. Onneksi lähentämistä varten voidaan skaalata vain muutama laatta (muista, että zoomilla 0 laatta edustaa koko maailmaa) pitämään värit / muodot epäselvästi edustavina.

Vältä pienentämistä

Koska kartta tarkentuu yhä yksityiskohtaisemmin suuremmilla zoomaustasoilla, oletin naiivasti, että olisi parempi käyttää korkeampia tasoja ja pienentää niitä pienennettäessä.

Liian monien laattojen pienentäminen

Käytännössä tämä ei kuitenkaan toiminut kovin hyvin - vaikka kaikkien monikulmioiden (esim. Vesi ja puistot) mittakaava säilyy hyvin, myös kaikki etiketit ja kuvakkeet skaalautuvat, mikä tekee kartasta, joka näyttää todella sotkevalta, etenkin keskeltä. Esitys otti myös valtavan osuman, koska muutaman kymmenen laatan piirtämisen sijasta yhtäkkiä satoja oli käytettävissä piirtämistä varten.

Tämän välttämiseksi estin laattojen pienentämisen yli yhdellä zoomauserolla. Eli zoomaamalla 14 sekunnin murto-osia (esim. 14.2), se voi käyttää laattoja zoomista 15, mutta ei koskaan, koskaan laattoja, jotka ovat vähintään 16.

animaatiot

Projektin alussa ilmoittani aikomukseni pystyä synkronoimaan animaatioita ohjelmoidusti zoomilla, vaikka sillä on myös hyöty siitä, että tunnen oloni paremmaksi - se on tasaisempi ja reagoivampi käyttäjän syötteisiin. Integroidulla zoomaustasolla se käyttäytyy samalla tavalla kuin normaali toteutus. Mielestäni se on kuitenkin varsin tehokas animointiin - voit arvioida itse.

Tässä on esimerkki mahdollisesta lentotiestä San Franciscosta Australiaan. [Vaihtoehtoisesti koko video tai video, jossa on vianetsintäpeittokuva]

Lentävät (ja animoivat sujuvasti) San Franciscosta Australiaan

Ei tietenkään ole mitään syytä, että sen on rajoituttava zoomausanimaatioihin. Yksi lisäetu maalaamalla kaikki kankaalle on se, että se antaa meidän tehdä joitain todella luovia asioita, jos haluamme.

kohde-out-maailmanlaajuinen komposiittioperaatio

Osoitettu on esimerkki, jossa kankaalla käytetään kohde-out-koostumustilaa muotojen “leikkaamiseksi” kartalta - tässä se peittää yksivärisen kartan värillisen päälle ja animoi sitten paljastuksen. [koko video]

Tuleva käyttö

Niin hauskaa kuin se oli kirjoittamista, ja yhtä hyödyllinen kuin tämä oli prototyyppilleni (se käytti kymmeniä prototyyppejä aikanaani joukkueessani) Googlella ja MapBoxilla on molemmilla vektorin renderointi, joka ylittää tämän mittakaavan ja sekoituksen lähestymistavan. Kannustan mielellään kaikkia muita, jotka eivät päivitä vektoritilauksiin, harkitsemaan jotain vastaavaa toteuttamista. Se on melko yksinkertainen tekniikka, joka ei lisää asiakkaalle paljon monimutkaisuutta (varmasti vähemmän työtä kuin vektorien renderointi), mutta mahdollistaa paljon sujuvamman ja reagoivamman kokemuksen.