Funksjonelle geografiske kart ved hjelp av SVG og jQuery. Ya.Maps og SVG

Interaktive kart er en flott måte å gi geografisk informasjon til brukerne på nettstedet ditt. Et av de populære alternativene for å implementere dette er tjenester som f.eks Google Maps og Open Street Maps, som utmerker seg ved å visualisere data ned til gatenivå. Men for småskala kart mest passende alternativ er kart i SVG-format. De er lette, fullt tilpassbare og uhindret av lisensieringsbegrensninger.

Du kan finne en rekke SVG-kart utgitt under tillatte lisenser på Wikipedia. Dessverre er det kanskje ikke nok for deg det du ender opp med å finne. Kartet du trenger finnes kanskje ikke, kan være utdatert (for eksempel på grunn av grenseendringer), eller kanskje ikke formatert godt nok for bruk på nettstedet ditt. Denne artikkelen forklarer hvordan du lager dine egne SVG-kart ved hjelp av Natural Earth-data og åpen kildekode-verktøy. Deretter vil du kunne lage SVG-kart for alle regioner i verden, ved å bruke hvilken som helst projeksjon og hvilken som helst oppløsning. Som et eksempel vil vi lage et SVG verdenskart.

Vi må gjøre følgende:

  • last ned geografiske data fra Natural Earth-data;
  • vise og redigere data ved hjelp av QGIS;
  • Konverter geografiske data til SVG ved å bruke Kartograph.py.
Henter geografiske data

For det første trenger vi geografiske data om grensene til land. Disse dataene er tilgjengelige på Natural Earth. Natural Earth er skapt av frivillige med støtte fra North American Mapping Survey. informasjonssamfunnet(NACIS, nordamerikansk kartografisk informasjonssamfunn). Denne tjenesten spesialiserer seg på småskala kart som er godt egnet for nett. Dette betyr at kartene vil se flotte ut på land- og provinsnivå, men ikke nok høy oppløsning for å vise omgivelsene i byen. Natural Earth gir ut kartene sine til det offentlige domene.

For å se alle kart som er tilgjengelige for nedlasting, besøk Natural Earth-nedlastingssiden.

Mange grenser rundt om i verden er heftig omstridt. Natural Earths politikk er å trekke grenser basert på hvem som kontrollerer situasjonen på bakken. Vi skal primært jobbe med småskala politisk kart, som inneholder alle 247 land i verden, og hvorfra grensene som går gjennom innsjøene er fjernet. Du kan laste den ned i et zip-arkiv (186 Kb).

Dataene du lastet ned lagres i et shapefile (.shp)-format. Shapefile er et åpent standard vektorformat for geospatiale data laget av Esri. Formfilen er ledsaget av tilleggsfiler med utvidelser .dbf , .prj og .shx . Sammen inneholder disse filene vektorgeometri, attributter (navn, id, etc.) og geospatiale data for hvert land. For enkelhets skyld, når folk refererer til en shapefil, mener de faktisk denne gruppen av filer.

Se geografiske data

For å se dataene vi nettopp lastet ned, må vi bruke programvare GIS ( geografiske informasjonssystemer). QGIS er åpen kildekode GIS-programvare som kjører på Linux, Mac OS X og Windows. Last ned programvare fra QGIS. Denne opplæringen vil bruke QGIS 2.8.2 Wien.

Når du har installert QGIS, åpner du QGIS Desktop-applikasjonen. QGIS er kraftig program, som kan fungere med et stort antall typer geografiske data. Av denne grunn kan hun se ganske skummel ut. Vi vil bare bruke en liten brøkdel av funksjonaliteten og kan ignorere mye av det QGIS vil tilby. For eksempel siden vi ikke jobber med rasterbilder(f.eks. satellittbilder), kan vi ignorere verktøy relatert til rasterbilder.

Først legger vi formfilen vår til prosjektet vårt som et vektorlag:

  • velg lag → Legg til lag → Legg til vektorlag;
  • velg og åpne filen ne_110m_admin_0_countries_lakes.shp ;
  • kartet skal vises i vinduet (fargen kan avvike fra din).
Verdenskart vektorlag

Vær oppmerksom på at ne_110m_admin_0_countries_lakes.shp er lagt til i dialogboksen Lag.

Nytt lag

Lag i QGIS ligner på lag du kan finne i slike grafiske redaktører som Photoshop eller GIMP. Du må velge et lag før du kan jobbe med det. Hvis gjennomgående denne håndboken vil du oppdage at programmet ikke fungerer som det skal, du har sannsynligvis glemt å velge gjeldende lag.

Det er også mulig å skjule lag ved å fjerne merket i boksen. Dette lar deg legge til flere shapefiler til prosjektet ditt og vise dem individuelt.

Etter å ha lagt til vektorlaget, vil det være en god idé å lagre arbeidet ditt: Prosjekt → Lagre.

Hvert land inneholder en liste over attributter. Du kan se disse attributtene i tabellen: Lag → Åpne attributttabell.


Landattributttabell.

Natural Earth-data inneholder enormt beløp informasjon om hvert land. For å identifisere land unikt, vil vi bruke ISO-koder på to bokstaver, som er lagret i variabelen iso_a2. Vi vil også bruke landets navn (navn) for å merke landene i vår SVG-fil e. Utforsk gjerne tabellen for å forstå dataene. Lukk bordet når du er ferdig.

Redigering av geografiske data

(du kan hoppe over denne delen hvis du er fornøyd med standarddataene levert av Natural Earth)

Ved å bruke QGIS kan du redigere individuelle geografiske figurer. Du trenger kanskje ikke å tegne grensene på nytt, men du kan dele landet inn i deler.

Hver form i shapefilen vår tilsvarer et objekt i QGIS. For å velge en funksjon, velg Vis → Velg → Velg funksjon(er) og klikk deretter på målet ditt. Hele objektet skal bli gult. For eksempel, dette er hvordan Frankrike vil se ut når du klikker på det:


Frankrike er fremhevet og fremhevet.

Merk at Frankrike også inkluderer Fransk Guyana i Sør-Amerika. Dette er fordi Fransk Guyana er en oversjøisk avdeling og region i Frankrike (Fransk Guyana på Wikipedia). Fransk Guyana har imidlertid sin egen unike ISO-kode, og for mange applikasjoner betyr dette at den må vises som en egen enhet i seg selv.

Å dele Frankrike i to separate enheter er en enkel prosess som krever noen få trinn:


Opprette SVG-filer med Kartograph.py Endre kartprojeksjonen

Det kan du legge merke til dette kartet ser litt annerledes ut enn kartet i QGIS. Spise en hel serie på ulike måter projisere vår tredimensjonale jord på todimensjonalt rom. Som standard bruker Kartograph Robinson-projeksjonen, en pen projeksjon som vanligvis brukes til verdenskart. Det kan imidlertid hende du foretrekker å jobbe med Mercator-projeksjonen (brukt i Google Maps), som projiserer bredde- og lengdegrad som rette linjer. For å gjøre dette, legg til et proj-objekt etter lagobjektet i config.json-filen:

"proj": ( "id":"mercator")

Redusere filstørrelse

Ofte kan den genererte SVG-filen være for stor for praktisk bruk i en nettapplikasjon. Kartograf inkluderer Visvalingam-Wyatt-forenklingsalgoritmen, som kan redusere filstørrelsen dramatisk når du gjør mindre visuelle endringer i landegrenser. Filen vår er allerede ganske liten (231 KB), så vi kan forenkle den ytterligere ved å legge til simplify-egenskapen på slutten av landobjektet:

"forenkle": 1

Jo høyere forenklingsverdien er, desto flere landegrenser vil bli forenklet, og jo mindre blir utdatafilen.

Filtrering av objekter

Som standard vil kartet inkludere alle funksjonene som er representert i shapefilen. Men du kan ekskludere visse objekter fra SVG-filen. Det kan for eksempel hende vi ønsker å fjerne Antarktis fordi det ikke er relevant for vårt problem. Kartograph inkluderer et filtreringsverktøy som lar deg filtrere funksjoner basert på deres attributter. Vi kan ekskludere Antarktis ved å bruke ISO-koden. For å gjøre dette, legg til en filteregenskap til landslaget:

"filter": ["iso_a2", "ikke i", ["AQ"]],

Lagre data i en SVG-fil

Til slutt ønsker vi at SVG-kartet vårt skal inkludere dataattributter med ISO-koden og navnet til hvert land. Dette gjør at SVG-elementer kan identifiseres i nettleseren. For å gjøre dette, legg til en attributt-egenskap i landslaget:

"attributes": ("id": "iso_a2", "navn": "navn"),

Å sette det hele sammen

Etter å ha gjort alle endringene, vil config.json se slik ut:

( "lag": ( "land": ( "src": "ne_110m_admin_0_countries_lakes.shp", "filter": ["iso_a2", "ikke i", ["AQ"]], "attributter": ( "id" : "iso_a2", "name": "navn" ), "simplify": "1") ), "proj": ( "id": "mercator") )

Kjør den samme Kartograph-kommandoen som før (med et nytt SVG-filnavn):

Kartograf config.json -o world.svg

Kartograf vil lage nytt kart world.svg, som er mindre og ser litt annerledes ut:

Hvis du åpner denne filen i tekstredigerer, vil du se at hver nå inneholder identifiserende informasjon i følgende skjema:

Data-id="US" data-name="USA" id="US"

Legger til et SVG-kart på nettstedet

Nå som du har laget et SVG-kart, vil du sannsynligvis tilpasse det og legge det til på nettstedet ditt. Moderne nettlesere støtter naturlig SVG, slik at du kan legge til SVG-bilde til nettsiden din på samme måte som du legger til andre bilder:

Å bygge inn et kart på denne måten gjør det imidlertid vanskelig å endre utseende kart og gjør det interaktivt. En enkel måte å aktivere bruke CSS og JavaScript for kartet - bygg inn SVG-filen i HTML-koden. Bare åpne world.svg i et tekstredigeringsprogram, kopier hele elementet og lim det direkte inn i sidekoden.

Elementet inneholder en egen for hvert land. For å endre stilen på kartet, bruk ganske enkelt CSS på alle elementene. Bruk fyll- og strekegenskapene for å endre henholdsvis hvert lands farge og kant. For eksempel kan vi gjøre alle land lysegrå og legge til en sveveeffekt:

Sti (fyll: lysegrå; strek: hvit;) sti:sveve (fyll: grå;)

På samme måte kan vi bruke JavaScript til å definere hendelsesbehandlere. Følgende kode vil sendes ut modalt vindu med navnet på landet når du klikker på det:

//

  • Opplæring

La oss skape interaktivt kart. Noe. Hva betyr interaktiv? Vel, den må samhandle med brukeren og dataene på nettsiden den er på. Jeg tror dette er nok til å betrakte det som interaktivt.

Vel, la oss ta SVG. Hvorfor? Ja, fordi det er enkelt å jobbe med for en person som er kjent med HTML. SVG er vektorformat, basert på XML. Det vil si at et SVG-bilde har sin egen DOM, så ulike elementer du kan bruke CSS-regler og kontrollere gammelt JavaScript.

Så skal vi begynne?

De mest utålmodige kan umiddelbart se demoen, men jeg foreslår at du leser om alt i rekkefølge.

Forberede kartet Først trenger vi essensen. Det vil si selve kortet. Hvis Google ikke hjelper, kan du tegne det selv, selv om det ikke er vanskelig å gjøre det i Inkscape.

For eksempel tar jeg et kart over ett rundt land (kilde på Wikimedia Commons)

Siden, i henhold til planen min, områdene på kartet ikke skal ha forskjellige farger, så klipper jeg først ut fyll- og strekstilene fra taggene som interesserer meg, men til gjengjeld gir jeg disse elementene klassen og id-en jeg trenger. For eksempel class="area" for regioner og class="city" for byer.

Deretter plasserer vi det smertelig kjente i bildedelen:
.area (strek: svart; strekbredde: 2px; fyll: #E9FFE9; ) .city (strek: svart; strekbredde: 2px; fyll: rød; )
Her er CSS-en jeg lovet i aksjon. I prinsippet er dette allerede nok. Forskj.

Resultat:

Sette inn SVG i HTML Denne prosessen ble dekket i tilstrekkelig detalj i habratopic om spørsmålet om bruk av SVG på tvers av nettlesere.

Vi vil bruke HTML5 og bruke den enkleste, mest humane og standard måten:

Alle nettlesere som støtter SVG vil "spise" den riktig og vise den. Og de vil til og med la oss jobbe med ham. Under én betingelse: hvis webserveren serverer den med MIME-typen image/svg+xml. En annen MIME-type kan forvirre Google Chrome kraftig (men ikke Opera, som godt vet fra taggen at den går etter SVG og ikke gir etter for provokasjoner).

Sekund riktig metode- Sett inn SVG-kode direkte i HTML. Flott fra et skriptsynspunkt, men nettleserstøtten er fortsatt dårligere. Merk forresten at SVG satt inn i "liberal" HTML fortsatt forblir "hard" XML, så sitater og avsluttende tagger er påkrevd.

Undervannsrive Men ikke alt er så enkelt. Du kan umiddelbart legge merke til at nettlesere hardnakket ikke vil skalere kartet vårt, og hvis det ikke passer, viser de rullefelt som dette:

For å få nettlesere til å fungere med SVG slik vi forventer, bør vi fjerne bredde- og høydeattributtene fra taggen i SVG-filen (eller sette dem til 100%), og sette inn et viewBox-attributt spesialdesignet for nettlesere med verdier for koordinatene til øvre venstre og nedre høyre bildevinkel:
viewBox="0 0 493 416" Forskj.

Etter dette forbedres situasjonen betraktelig, men Google Chrome gir oss en annen rake: den streber konstant etter å skalere bildet i høyden til høyden på elementet, og ikke øke høyden i henhold til bredden på taggen og proporsjonene til bildet , som andre nettlesere oppfører seg.


Det er synd. Du må bruke JavaScript og justere elementets høyde manuelt.
var viewBox = svgdom.rootElement.getAttribute("viewBox").split(" "); var aspectRatio = viewBox / viewBox; svgobject.height = parseInt(svgobject.offsetWidth / aspectRatio);

Resultat:

Forskj.

Interaksjon med SVG Vi trenger ikke noe for å samhandle med SVG skrevet direkte inn i HTML - det er allerede en del av DOM-en til nettsiden.
Det er litt vanskeligere å få tilgang til SVG-er satt inn via: jQuery(window).load(function () ( // Vi må vente til all grafikken (og kartet vårt også) er lastet inn, så vi bruker window.onload, var svgobject = document.getElementById("svgmap"); / / Finn taggen if ("contentDocument" i svgobject) ( // Har vi virkelig noe der? var svgdom = jQuery(svgobject.contentDocument); // Access objektmodell
Ja, jQuery fungerer med SVG, men bare delvis. For eksempel la jeg merke til at addClass- og removeClass-funksjonene, samt klassesøk (jQuery(".class"), ikke fungerer. Vi må pervertere.

Merk at jeg bruker window.onload-hendelsen siden vi må vente full last sider, sammen med alle relaterte elementer (inkludert kartet vårt). Men også her har Google Chrome det travelt med å skru på oss: hvis skriptet med window.onload er i html-koden før taggen, så kjøres koden i behandleren FØR kartet faktisk lastes. Derfor må lappen plasseres etter kartet vårt. Trist men sant.

Interaktivitet en: marker områder på kartet ved å klikke på avmerkingsboksen på siden. For denne interaksjonen vil vi trenge avmerkingsbokser i hver rad i tabellen med områder, samt matchende eller lignende IDer for tabellradene og områdene på kartet.

Her, når du klikker på en avkrysningsboks, vil vi sette eller fjerne den valgte klassen fra det tilsvarende området på kartet, og fra selve linjen. Det er enkelt:
$("#areas input").change(function() ( var rad = $(this).parent().parent(); var id = row.attr("id"); if (this.checked) ( row.addClass("selected"); $("#"+id, svgdom).myAddClass("selected"); $("#"+id, svgdom). myRemoveClass ("valgt");
Følgelig må du legge til stildefinisjoner for denne klassen. Jeg overlater til deg å gjøre dette selv, i henhold til din smak og preferanser. Forskj.

Den andre interaktiviteten: vi åpner/viser navnene på kartet ved å klikke på avkrysningsboksen på siden. Denne interaksjonen er gjort enda enklere. Vi setter inn litt JavaScript på siden, som legger til/fjerner klassen skjult (synlighet: skjult;) til alle elementer knyttet til navn på kartet:
$("#titleswitch").change(function () ( var elements = $(svgdom.getElementsByClassName("areatitle")) .add($(svgdom.getElementsByClassName("bytittel"))) .add($(svgdom. getElementsByClassName("tittelboks"))) .add($(svgdom.getElementsByClassName("tittellinje"))); if (this.checked) (elements.myAddClass("hidden"); ) else (elements.myRemoveClass("hidden" ); ) ));
Som dette.

Interaktivitet tre: fremhev områder på kartet når du holder musepekeren over en tabellrad (og omvendt) For å gjøre dette, må du henge på hendelsesbehandlere som på et bord:
// Marker regionen på kartet når du holder musen over den tilsvarende. tabellrad. $("#areas tr").hover(function () ( var id = $(this).attr("id"); $("#"+id, svgdom).myAddClass("highlight"); ), function () ( var id = $(this).attr("id"); $("#"+id, svgdom).myRemoveClass("highlight"); ));
...og til områder på kartet:
// Marker en rad i tabellen når du holder musen over den tilsvarende. region på kartet $(svgdom.getElementsByClassName("area")).hover(function () ( var id = $(this).attr("id"); $("#areas #"+id).addClass( " highlight"); ), function () ( var id = $(this).attr("id"); $("#areas #"+id).removeClass("highlight"); ));
For at vi skal se dette, vil vi legge til de tilsvarende CSS-reglene på siden:
tr.highlight, tr:hover, tr:nth-child(even):hover ( bakgrunn: lysgul; ) ...og til SVG-kartet: .highlight, .area:hover ( fyll: lysgul; strek: svart; )
Når du holder musepekeren over en rad i tabellen (eller over et område på kartet), legges klassen som kreves for utheving til det tilsvarende området på kartet (på raden i tabellen). For at koden ovenfor skal fungere, må områdene på kartet og radene i tabellen ha samme (eller lignende) id. Forskj.

Interaktivitet fire: Vise data fra en side på et kart Vel, den banale tildelingen av klasser er sannsynligvis allerede kjedelig. La kartet vise oss noen data.

Første ting først: data. La oss legge til et par kolonner i tabellen vår, for eksempel "Mennesker" og "Penger". Oppmerksomhet: Dataene er hentet fra en idiot og har ingenting med den ekte Amestris å gjøre. Og også radioknapper som vi vil bruke for å bytte hvilke data som skal vises.

For det andre trenger vi et sted på kartet hvor dataene skal vises. La oss legge til fem blokker til kartet (en for hver region, som korrelerer ID-ene deres med regionene) og de tilsvarende stilene i:

Vel, JavaScript-koden som tar data fra tabellceller og plasserer dem i tekstblokker:
$("input").change(function () ( var descnum = $(this).parent().prevAll().length+1; $("#areas tbody tr").each(function() ( var id = $(this).attr("id").substring(4); var verdi = $(this).children(":nth-child("+descnum+")".text(); +id, svgdom).text(verdi ));
Og ved å bytte på radioknappene vil kortet vise de nødvendige tallene. Voila!

Interaktivitet femte: verktøytips Dette kan bli for mye, men la det være. For godt mål.

For denne interaksjonen, la oss ta jQuery.tooltip-pluginen og binde den til områder på kartet. Vi tar selvfølgelig teksten for hintene fra tabellen:
$(svgdom.getElementsByClassName("area")).tooltip(( bodyHandler: function() ( var id = $(this).attr("id"); var area = $("#areas #"+id+" td :nth-child(2)").text(); var resultat = $("

").append($("").text(area)); $("#areas #"+id+" td:nth-child(2)").nextAll().each(function())( var pos = $(this).prevAll().length+1; var title = $("#areas thead th:nth-child("+pos+")").text(); tekst (); result.append($(");

").text(tittel + ": " + verdi)); )); returner resultat; ) ));


Forskj.

Og så videre... Mulighetene for å samhandle med SVG er selvsagt ikke begrenset til dette. Du kan gjøre hva som helst. Bland DOM, endre siden og SVG ved å bruke AJAX-forespørsler og mye, mye mer. Gå for det Resultat
Gjenværende fallgruver Fra kjente problemer Foreløpig kan det bemerkes at Google Chrome ikke skriver ut SVG-bilder. Dette er enten dens feil eller en feil av WebKit generelt Bakoverkompatibilitet Nesten alt moderne nettlesere støtte SVG: IE 9+, Opera 8+, Firefox 3+ (Firefox 1.5+ har delvis støtte), Chrome alle versjoner, Safari 3.2+ (mer fullstendig liste)

Men dessverre, den lyse fremtiden kommer fortsatt ikke i det hele tatt, og vi må fortsatt tenke på å støtte gamle nettlesere.

Den standard og enkleste måten hvis SVG bare er et bilde: sett inn erstatningsinnholdet (gjengitt i PNG-bilde og et avsnitt med tekst) inne i taggen.

Beklager, du bruker utdatert versjon nettleser som ikke støtter det interaktive kartet.


Hvis nettleseren ikke støtter SVG, vil et PNG-bilde og en tekst vises som varsler brukerne om at nettleseren deres er utdatert. Ingen interaktivitet. Imidlertid er det kanskje ikke virkelig nødvendig. Riktignok er det en ulempe - som jeg la merke til, laster moderne nettlesere hardna ned et erstatnings-png-bilde, til tross for at de fortsatt ikke vil vise det.

De som er interesserte kan dra nytte av SVG-støttedeteksjon ved hjelp av Modernizr og lage noe mer komplekst i JavaScript.

I mer vanskelige saker Tallrike Flash-, VML- eller Canvas-løsninger (eller alle) kan hjelpe deg. Listen finner du her: HTML5 Crossbrowser Polyfills, men løsningene jeg prøvde hjalp meg dessverre ikke. Kanskje fordi SVG med CSS som jeg skisserte på kneet mitt viste seg å være for tøft for dem.

Konvertere SVG til PNG Det er mange steder på nettet hvor du kan konvertere et SVG-bilde til noe annet. Jeg vil foreslå å bruke kommandoen rsvg-convert fra librsvg2-bin-pakken. Noe sånt som dette:
cat map.svg | rsvg-konverter > map.png
Den kan imidlertid konvertere til andre formater, samt forstørre/redusere bildet, se --help.
For massekonverteringer kan du skrive en mer kompleks kommando eller se eksempler i Legg til tagger


Jeg ønsker å kunne tegne på kartet selv ved hjelp av SVG.

Ideen er denne: Jeg lager et lag på størrelse med HELE kartet av gjeldende skala og tegner så på dette laget og konverterer geopunkter til piksler.

Hvordan gjøre det mest på en enkel måte? Gjennom IOverlay eller ILayer, eller kanskje det er noe annet mer praktisk?

","contentType":"text/html"),"proposedBody":("kilde":"

Jeg ønsker å kunne tegne på kartet selv ved hjelp av SVG.

Ideen er denne: Jeg lager et lag på størrelse med HELE kartet av gjeldende skala og tegner så på dette laget og konverterer geopunkter til piksler.

Hvordan gjøre dette på enklest måte? Gjennom IOverlay eller ILayer, eller kanskje det er noe annet mer praktisk?

Jeg ønsker å kunne tegne på kartet selv ved hjelp av SVG.

Ideen er denne: Jeg lager et lag på størrelse med HELE kartet av gjeldende skala og tegner så på dette laget og konverterer geopunkter til piksler.

Hvordan gjøre dette på enklest måte? Gjennom IOverlay eller ILayer, eller kanskje det er noe annet mer praktisk?

","contentType":"text/html"),"authorId":"20653410","slug":"6812","canEdit":false,"canComment":false,"isBanned":false,"canPublish" :false,"viewType":"old","isDraft":false,"isOnModeration":false,"isSubscriber":false,"commentsCount":9,"modificationDate":"Tor 01 Jan 1970 03:00:00 GMT +0000 (UTC)","showPreview":true,"approvedPreview":("kilde":"

Jeg ønsker å kunne tegne på kartet selv ved hjelp av SVG.

Ideen er denne: Jeg lager et lag på størrelse med HELE kartet av gjeldende skala og tegner så på dette laget og konverterer geopunkter til piksler.

Hvordan gjøre dette på enklest måte? Gjennom IOverlay eller ILayer, eller kanskje det er noe annet mer praktisk?

","html":"Jeg ønsker å kunne tegne på kartet selv via SVG. ","contentType":"tekst/html"),"proposedPreview":("kilde":"

Jeg ønsker å kunne tegne på kartet selv ved hjelp av SVG.

Ideen er denne: Jeg lager et lag på størrelse med HELE kartet av gjeldende skala og tegner så på dette laget og konverterer geopunkter til piksler.

Hvordan gjøre dette på enklest måte? Gjennom IOverlay eller ILayer, eller kanskje det er noe annet mer praktisk?

","html":"Jeg ønsker å kunne tegne på kartet selv ved hjelp av SVG. ","contentType":"text/html"),"titleImage":null,"tags":[("displayName":"API 1.x","slug":"api-1-x","categoryId" ":"150000131","url":"/blog/mapsapi??tag=api-1-x")],"isModerator":false,"commentsEnabled":true,"url":"/blog/mapsapi/ 6812","urlTemplate":"/blog/mapsapi/%slug%","fullBlogUrl":"https://yandex.ru/blog/mapsapi","addCommentUrl":"/blog/createComment/mapsapi/6812" "updateCommentUrl":"/blog/updateComment/mapsapi/6812","addCommentWithCaptcha":"/blog/createWithCaptcha/mapsapi/6812","changeCaptchaUrl":"/blog/api/captcha/new","put":Url "/blog/image/put","urlBlog":"/blog/mapsapi","urlEditPost":"/blog/56a9a2b3b15b79e31e0d72f2/edit","urlSlug":"/blog/post/generateSlug","urlPublishPost": "/blog/56a9a2b3b15b79e31e0d72f2/publish","urlUnpublishPost":"/blog/56a9a2b3b15b79e31e0d72f2/unpublish","urlRemovePost":"/blog/537emovemoved ","urlDraft":"/blog/mapsapi/6812/draft", "urlDraftTemplate":"/blog/mapsapi/%slug%/draft","urlRemoveDraft":"/blog/56a9a2b3b15b79e31e0d72f2/removeDraft","urlTagSuggest":"/blog/api/suggestur"", /blog/mapsapi","isAuthor":false,"subscribeUrl":"/blog/api/subscribe/56a9a2b3b15b79e31e0d72f2","unsubscribeUrl":"/blog/api/unsubscribe/56a9a2b3b15e2b3b15b79e31e0d72f2" mapsapi/56a9a2b3b15b79e31e0d72f2/edit","urlForTranslate":"/blog/post/translate","urlRelateIssue":"/blog/post/updateIssue","urlUpdateTranslate":"/blog/post/updateTranslate","urlRelateIssue" "/blog/post/loadTranslate","urlTranslationStatus":"/blog/mapsapi/6812/translationInfo","urlRelatedArticles":"/blog/api/relatedArticles/mapsapi/6812","author":("id": "20653410","uid":("value":"20653410","lite":false,"hosted":false),,"aliaser":(),"login":"shasoft","display_name": ("navn":"shasoft","avatar":("default":"21493/20653410-939638","tom":false)),,"adresse":" [e-postbeskyttet]","defaultAvatar":"21493/20653410-939638","imageSrc":"https://avatars.mds.yandex.net/get-yapic/21493/20653410-939638/islands-middle","is":YandexStaff false),"originalModificationDate":"1970-01-01T00:00:00.000Z","socialImage":("orig":("fullPath":"https://avatars.mds.yandex.net/get-yablogs /47421/file_1456488726678/orig")))))">

Når jeg trenger å lage kart, er det første jeg gjør Google Charts eller et annet spesialbibliotek. Men noen ganger kan jeg trenge spesifikke funksjoner som jeg ikke finner der. Det er her SVG-bilder viser seg å være svært verdifulle (nyttige).

Nylig trengte jeg å designe en rapportside som kunne vise et kart over Italia der hver region ville ha en annen farge basert på noen eksempelverdier fra databasen. Takket være SVG har denne oppgaven blitt veldig enkel.

Lag et SVG-kart i Illustrator

Først av alt tegnet jeg et kart over Italia i Adobe Illustrator:

Hver region ble tegnet som et eget objekt, som ble plassert for seg selv separat lag, med navnet som samsvarer med koden som brukes i databasen for å identifisere de relaterte dataene (for eksempel "tos" for Toscana).

Til slutt skal kartet lagres i SVG-format. Du bør være oppmerksom på å angi "CSS-egenskap"-alternativet i "Stylelementer"-kolonnen i Illustrator som vist nedenfor:

Når du åpner filen du nettopp opprettet, vil du se at den inneholder et sett med g-tagger hvis ID-er samsvarer med navnene på nivåene i Illustrator.

Bygger vår HTML-fil EN

Hvert element i g-taggene har en klasse st0, slik at CSS-strek- og fyllegenskapene er strek og fyll:

Hvis du prøver å endre disse verdiene, endres kartet også:

Nå kan vi bruke denne koden til å lage HTML-filen vår med innebygd SVG, som vist nedenfor (koden er forkortet for enkelhets skyld):

Karteksempel .map svg ( høyde: auto; width: 350px; ) .map g ( fyll: #ccc; stroke: #333; stroke-width: 1; )

Du vil legge merke til at stilattributtet fra svg-taggen har blitt flyttet til head-delen, og alle g-elementene er i utgangspunktet fylt med en lys grå farge.

St0-klassen brukes ikke lenger (den kan fjernes fra koden din) og er erstattet av .map g-velgeren. Uansett, dette var ikke en nødvendig handling - du kan bruke hvilken som helst CSS-velgere- etter eget skjønn.

Det andre trinnet er å koble kartet vårt til dataene hentet fra ekstern kilde. I i dette eksemplet vi vil male regioner i farger avhengig av befolkningen i disse regionene.

Legger til JSON-data og JavaScript

Vi mottar data inn JSON-format, og sett dem inn i HTML-filen direkte (i virkelige forhold vil vi selvfølgelig motta data via Ajax, eller en lignende metode).

Siden vår vil nå inneholde JSON inne i JavaScript-filen vår, som vil se omtrent slik ut:

Var regions=[ ( "region_name": "Lombardia", "region_code": "lom", "population": 9794525 ), ( "region_name": "Campania", "region_code": "cam", "population": 5769750 ), // etc ... ];

Etter det velger vi fargen (i i dette tilfellet- #0b68aa), og ta det som fargen på regionen med størst befolkning. De resterende områdene vil bli farget i toner av hovedfargen i forhold til prosentandelen av befolkningen (i forhold til maksimal befolkning).

Det første trinnet er å bestemme regionen med størst befolkning. Dette kan gjøres med noen få linjer med kode.

Når vi har kompilert en matrise med populasjonsstørrelsesverdier, kan vi få fra den maksimal verdi ved å bruke Math.max-metoden:

Var temp_array= regions.map(function(item) (retur item.population;)); var høyeste_verdi = Math.max.apply(Math, temp_array);

$(funksjon() ( for(i=0; i< regions.length; i++) { $("#"+ regions[i].region_code).css({"fill": "rgba(11, 104, 170," + regions[i].population/highest_value + ")"}); } });

Og her er resultatet:

Legg til interaktivitet med bruker CSS og jQuery

Kartet kan forbedres ved å legge til litt interaktivitet. Vi ønsker å vise populasjonsstørrelsen når vi svever over en region.

La oss først legge til CSS-regler for g:hover-velgeren og info_panel-klassen for å style info-popup-blokken:

Kart g:hover (fyll: #fc0 !important; cursor: help; ) .info_panel (bakgrunnsfarge: rgba(255,255,255, .7); utfylling: .3em; font-size: .8em; font-family: Helvetica, Arial, sans-serif posisjon: absolutt; .info_panel::first-line (font-weight: bold;

Den!viktige modifikatoren i g:hover .map-velgeren er nødvendig for å overstyre fill-egenskapen, ellers vil elementets innebygde CSS-regel bli brukt.

Vi må også modifisere for løkke, definert tidligere for å legge til et dataattributt som vil lagre verdien som vises ved pekeren:

For (i = 0; i< regions.length; i++) { $("#"+ regions[i].region_code) .css({"fill": "rgba(11, 104, 170," + regions[i].population/highest_value +")"}).data("region", regions[i]); }

Og til slutt, la oss diversifisere skriptet vårt ved å legge til noen sveveeffekter:

$(".map g").mouseover(function (e) ( var region_data=$(this).data("region"); $("" + region_data.region_name + "
" + "Befolkning: " + region_data.population.toLocaleString("en-UK") + "").appendTo("body"); )).mouseleave(function () ( $(".info_panel").remove( ); )).mousemove(function(e) ( var mouseX = e.pageX, // X-koordinater for mus musY = e.pageY; // Y-koordinater for mus $(".info_panel").css(( øverst: mouseY-50, venstre: mouseX - ($(".info_panel").width() / 2) ));

Hvordan fungerer dette:

  • ved å bruke mouseover la vi til div element, som inneholder informasjonen som skal vises (regionsnavn og befolkning). En div opprettes hver gang g-elementet holdes, og legges til body-elementet i dokumentet;
  • mouseeleave fjerner denne div når markøren forlater området;
  • Den siste metoden, mousemove, henter musekoordinatene og bruker dem på de genererte divene.