In deze zelfstudie laat ik zien hoe OpenLayers te gebruiken, een eenvoudig te gebruiken open source JavaScript-bibliotheek om kaarten te laden, weer te geven en weer te geven, met GeoNames.org WFS om markeringen op je kaart weer te geven, net zoals je ziet op Google Maps. Het enige dat nodig is, is wat HTML, CSS en JavaScript - dat is alles!
Voordat we iets doen, moeten we eerst ons GeoNames.org-account instellen. GeoNames Met WebServices kunt u aanvragen doen van 30000 studiepunten per dag, een uurlimiet van 2000 credits. Verschillende vragen vereisen verschillende punten, zonder dat de kosten meer dan 4 kosten. Voor veel kleine sites en eenvoudige ontwikkelingsonderzoeken zou dit meer dan genoeg moeten zijn. Ze bieden Premium-diensten voor een prijs, maar vandaag gaan we de gratis dingen doen. Gratis is altijd leuk, is het niet?
Om uw account aan te maken, gaat u naar de aanmeldingspagina van GeoNames.org en stelt u uw gratis account in. U moet het account in uw e-mail bevestigen, maar dit zou vrij snel moeten gaan. Zodra je bent bevestigd, ben je klaar om te gaan.
"Er zijn meer dan 30 verschillende soorten vragen die u kunt stellen met GeoNames WebServices. Een lijst hiervan is hier te vinden."
Vervolgens moeten we de OpenLayers-broncode en afbeeldingen pakken. Die zijn te vinden op de startpagina van OpenLayers. Je kunt de .zip of .tar.gz downloaden. Voor deze zelfstudie hebben we alleen het bestand OpenLayers.js en de img-map nodig. Voor extra smaak en bruikbaarheid zullen we de JScrollPane van Kelvin Luck en de jQuery-muiswielplug-ins van Brandon Aaron gebruiken om onze resultaten te verbeteren en te verfraaien. Pak de js en css van JScrollPane. Ik heb een paar kleine wijzigingen aangebracht in de CSS, alleen om in de stijl te passen die ik voor deze tutorial wilde, maar style het zoals je zou willen. Grijp de muiswielplugin van GitHub. Last, but not least, pak de nieuwste versie van jQuery.
"Natuurlijk zijn alle benodigde bestanden voor deze tutorial te vinden in de downloadlink Bronbestanden bovenaan."
De tutorial van vandaag zal aan bod komen findNearbyPostalCodes. Laten we nu wat code gaan schrijven!
Ga je gang en maak een directorystructuur voor je applicatie. Ik heb de mijne genoemd GeoNames
. Binnen geonames, voeg drie extra mappen toe: img, js
en css
. De afbeeldingen van OpenLayers gaan in de map img, de JavaScript-bestanden van OpenLayers, JScrollPane en jQuery mousewheel en jQuery wordt in de map js geplaatst en de stylesheet van JScrollPane wordt in de map css geplaatst. Ook een paar afbeeldingen die ik heb gemaakt en een paar dat ik van iconfinder heb gepakt, zijn te vinden in de bronbestanden. Leg ze in de img
map ook.
Hier hebben we een eenvoudige pagina met enkele HTML-elementen. Het meeste van ons vlees zit in onze JavaScript, dus dit deel is vrij kort. Sla dit bestand op als index.html
.
Openlayers / Geonames Tutorial Zoeken
resultaten
Dit is de CSS die we hebben gemaakt voor gebruik in deze zelfstudie. Niks vreselijk baanbrekend, alleen wat styling. Sla dit bestand op als style.css
in de css
map die u hebt gemaakt.
* font-family: Helvetica; de kleur zwart; html height: 100%; marge: 0; overflow-y: scroll; body achtergrondkleur: wit; lettertype: normaal 13px arial, schreefloos; hoogte: 100%; marge: 0; #map background: #ccc; hoogte: 100%; positie: absoluut; breedte: 100%; z-index: 1; #searchContainer border-radius: 2px; -moz-border-radius: 2px; -o-border-radius: 2px; -webkit-border-radius: 2px; achtergrondkleur: rgba (247.247.247,0.5); border: 1px solid #ffffff; vakschaduw: 0 0 3px # C5C5C5; -moz-box-shadow: 0 0 3px # C5C5C5; -webkit-box-shadow: 0 0 3px # C5C5C5; Hoogte: 158px; Breedte: 250 pixels; positie: absoluut; z-index: 2; top: 20px; rechts: 20px; opvulling: 4px 4px 4px 4px; #searchBox background-color: rgba (247.247.247,0.7); border-bottom-left-radius: 2px; border-bottom-right-radius: 2px; border: 1px solid #ffffff; Hoogte: 136px; Breedte: 250 pixels; text-align: center; regelhoogte: 44px; #resultContainer border-radius: 2px; -moz-border-radius: 2px; -o-border-radius: 2px; -webkit-border-radius: 2px; achtergrondkleur: rgba (247.247.247,0.5); border: 1px solid #ffffff; -moz-box-shadow: 0 0 3px # C5C5C5; -webkit-box-shadow: 0 0 3px # C5C5C5; vakschaduw: 0 0 3px # C5C5C5; width: 252px; positie: absoluut; z-index: 2; top: 208 px; rechts: 20px; opvulling: 4px 4px 4px 4px; Geen weergeven; #resultHeader, #searchHeader width: 250px; hoogte: 20px; border-top-left-radius: 2px; border-top-right-radius: 2px; border-left: 1px solid #ffffff; border-top: 1px solid #ffffff; border-right: 1px solid #ffffff; positie: relatief; achtergrondherhaling: repeat-x; achtergrond: -webkit-gradiënt (lineair, 0% 0%, 0% 100%, van (# C2DCFD), tot (#DDECFD)); achtergrond: -webkit-lineaire gradiënt (bovenaan, #DDECFD, # C2DCFD); achtergrond: -moz-linear-gradient (bovenaan, #DDECFD, # C2DCFD); achtergrond: -ms-linear-gradient (bovenaan, #DDECFD, # C2DCFD); achtergrond: -o-lineaire gradiënt (bovenkant, #DDECFD, # C2DCFD); text-align: center; font-size: 16px; tekst-schaduw: 0px 0px 1px # 96B0BB; #resultBox background-color: rgba (247.247.247,0.7); border-bottom-left-radius: 2px; border-bottom-right-radius: 2px; border: 1px solid #ffffff; max-height: 418px; min-height: 250 pixels; Breedte: 250 pixels; overloop: automatisch; .item0, .item1 float: left; opvulling: 5px 4px 5px 4px; width: 242px; border-top: 1px solid #dcdcdc; .item1 achtergrondkleur: #FFFFFF; .helder duidelijk: beide; .olPopupCloseBox background: url ("... /img/close.gif") geen herhaling; cursor: pointer; .olFramedCloudPopupContent opvulling: 5px; overloop: automatisch;
Op dit punt zou uw pagina er ongeveer zo uit moeten zien:
Het is niet zo heel veel om naar te kijken, dus laten we in de goede dingen stappen.
var $ r = $ ('# resultaten'), $ rContainer = $ ('# resultContainer'), $ rBox = $ ('# resultBox');
U wilt uw jQuery-objecten altijd instellen op variabelen. Altijd de beste werkwijzen!
var Observation = function (target) _target = target; _arrObservers = []; var binder = function (observer) _arrObservers.push (waarnemer); ; var inform = function () for (var x = 0; x<_arrObservers.length; x++) _arrObservers[x](_target); ; return binder: binder, inform: inform ;
Dit is slechts een eenvoudige luisterfunctie die we hebben gemaakt. Wanneer we de gebeurtenis creëren waarnaar we willen luisteren, geven we deze het object door waarnaar we willen luisteren; Ik heb dit argument genoemd: doelwit
. Het bevat twee variabelen: _doelwit
- een variabele die we gelijk stellen aan ons argument en _arrObservers
- een lege array die we zullen gebruiken om te vullen met luisteraars. Observatie bevat ook twee functies: binder
en informeren
.
var binder = function (observer) _arrObservers.push (waarnemer); ;
Functie binder
voegt elke luisteraar toe, of waarnemer
voor een reeks luisteraars. In deze zelfstudie maken we slechts één aangepaste gebeurtenis, maar door elke luisteraar aan een array toe te voegen, kunt u meerdere luisteraars toewijzen met één functie.
var inform = function () for (var x = 0; x<_arrObservers.length; x++) _arrObservers[x](_target); ;
Functie informeren
vuurt een bericht naar de luisteraar om het te laten weten dat de gebeurtenis plaatsvindt. Ten slotte, zoals u hierboven ziet, geven we beide functies terug, zodat ze beschikbaar zijn voor gebruik.
var makeGeoNamesModel = function () var _results = , country = 'US', radius = 30, gebruikersnaam = 'openlayers_tutorial', maxRows = 20; var notifySearchComplete = new Observation (this); var search = function (val) $ .ajax (url: 'http://api.geonames.org/findNearbyPostalCodesJSON', data: postcode: val, land: land, straal: radius, gebruikersnaam: gebruikersnaam, maxRows: maxRows, dataType: 'jsonp', jsonpCallback: 'geoNamesResponse'); ; geoNamesResponse = function (geoData) _resultaten = geoData; notifySearchComplete.inform (); ; var getResults = function () return _resultaten; ; var clear = function () _results = ; ; return notifySearchComplete: notifySearchComplete, search: search, geoNamesResponse: geoNamesResponse, getResults: getResults, clear: clear; ;
Hier hebben we ons GeoNames-model. Dit model behandelt het creëren, opslaan en retourneren van de waarde van ons GeoNames WebServices-verzoek.
var _results = , country = 'US', radius = 30, gebruikersnaam = 'openlayers_tutorial', maxRows = 20;
Dit zijn slechts enkele variabelen die we zullen gebruiken, meestal in ons ajax-verzoek. Voor het gebruik van onze tutorial gaan we alleen naar de Verenigde Staten (sorry, ik ben bevooroordeeld), maar je kunt je applicatie wijzigen om de invoer van de landcode te accepteren als je dat wilt. De maximale straal die we hebben met onze gratis account is 30 kilometer. Ik heb ook het maximale aantal geretourneerde locaties ingesteld op 20, maar je kunt die waarde naar boven halen als je dat wilt. Draad openlayers_tutorial
is de naam van het account dat ik heb ingesteld voor deze zelfstudie, dus verander deze reeks naar de gebruikersnaam die je hebt gemaakt toen je het bovenstaande account instelde. Ten slotte bereiden we ons model voor met een leeg voorwerp genaamd _results
om op een later tijdstip te worden gevuld.
var notifySearchComplete = new Observation (this); var search = function (val) $ .ajax (url: 'http://api.geonames.org/findNearbyPostalCodesJSON', data: postcode: val, land: land, straal: radius, gebruikersnaam: gebruikersnaam, maxRows: maxRows, dataType: 'jsonp', jsonpCallback: 'geoNamesResponse'); ; geoNamesResponse = function (geoData) _resultaten = geoData; notifySearchComplete.inform (); ;
Hier hebben we de allerbelangrijkste webservice-aanvraag: zoeken
en onze melding van een evenement. Omdat dit een verzoek van een derde partij is, stellen we het gegevenstype in op 'jsonp' en geven we de aanvraag door aan onze variabelen die we eerder hebben gedefinieerd. Argument val
zal later worden gedefinieerd in onze visie. We gaan ook expliciet de naam van de callback-functie instellen - geoNamesResponse
- en behandel het succesvolle verzoek. Ik had code kunnen toevoegen om onjuiste invoer te verwerken, maar voor deze tutorial gaan we ervan uit dat je een correcte 5-cijferige postcode invoert. We geven GeoNames de postcode door die de gebruiker heeft ingevoerd, maar voor deze specifieke zoekopdracht kunt u breedtegraad en lengtegraad opgeven als LAT
en lng
als je wilt. Op dit punt zullen we onze luisteraar ook laten weten dat deze zoekopdracht is voltooid.
var getResults = function () return _resultaten; ; var clear = function () _results = ; ;
Het laatste deel van ons model verwerkt het retourneren van onze resultaten wanneer ernaar wordt gevraagd, en ook het legen van ons resultaatobject wanneer de gebruiker op de knop "Markeringen wissen" klikt.
var makeGeoNamesFormController = function () return handleSearch: function (txtVal, geoNamesModel) geoNamesModel.search (txtVal); , handleClear: function (geoNamesModel) geoNamesModel.clear (); , handleResult: function (geoNamesModel) testResults = geoNamesModel.getResults (); return testResultaten; ; ;
Onze controller doet echt niets anders dan toegang krijgen tot functies en retourneert variabelen van ons GeoNames-model op basis van invoer vanuit de gebruikersinterface. We retourneren drie functies:
handleSearch
- dit neemt de waarde van de invoer van de gebruiker en het geoNamesModel als argumenten, en roept de geoNamesModel's aan zoeken
functie, doorgeven van de waarde die we willen verzenden naar de GeoNames WebServices.
handleClear
- dit roept de geoNamesModel's aan duidelijk
functie zodat we ons resultaatobject kunnen wissen.
handleResult
- dit roept de geoNamesModel's aan getResults
functie zodat we toegang hebben tot de resultaten van ons WFS-verzoek.
var makeGeoNamesFormView = function (initGeoNamesModel, initOpenLayersMapModel, initGeoNamesFormController, initOpenLayersMapController) var _geoNamesModel = initGeoNamesModel, _openLayersMapModel = initOpenLayersMapModel, _geoNamesFormController = initGeoNamesFormController, _openLayersMapController = initOpenLayersMapController, $ txtSearch = $ ( '# txtSearch'), $ btnSearch = $ ( '# btnSearch '), $ btnClear = $ (' # btnClear '); $ btnSearch.on ("click", function () _geoNamesFormController.handleClear (_geoNamesModel); _openLayersMapController.handleClear (_openLayersMapModel); $ r.html (""); _geoNamesFormController.handleSearch ($ txtSearch.val (), _ geoNamesModel); ); $ btnClear.on ("click", function () _geoNamesFormController.handleClear (_geoNamesModel); _openLayersMapController.handleClear (_openLayersMapModel); $ r.html (""); $ txtSearch.val (""); $ rContainer.slideUp ( 500);); $ (window) .on ("load", function () _openLayersMapController.render (_openLayersMapModel);); var showPoints = function () var olPoints = _geoNamesFormController.handleResult (_geoNamesModel); var olResults = _openLayersMapController.handleMarkers (_openLayersMapModel, olPoints); $ ( '# ResultContainer') slideDown (500).; $ r.append (olResults.join (")); $ rBox.jScrollPane (showArrows: true, autoReinitialise: true);; _geoNamesModel.notifySearchComplete.binder (function () showPoints (););;
De GeoNames View definieert onze klikgebeurtenissen en behandelt het oproepen van de controllerfuncties om onze weergave te manipuleren. Het werkt nauw samen met de controller, maar laat het model toegang tot en manipulatie tot aan de controller.
var _geoNamesModel = initGeoNamesModel, _openLayersMapModel = initOpenLayersMapModel, _geoNamesFormController = initGeoNamesFormController, _openLayersMapController = initOpenLayersMapController, $ txtSearch = $ ('# txtSearch'), $ btnSearch = $ ('# btnSearch'), $ btnClear = $ ('# btnClear');
Het enige wat we hier doen, zijn ingestelde variabelen gelijk aan de respectieve functieargumenten, en zoals altijd, stel je jQuery-objecten in op variabelen.
$ btnSearch.on ("click", function () _geoNamesFormController.handleClear (_geoNamesModel); _openLayersMapController.handleClear (_openLayersMapModel); $ r.html (""); _geoNamesFormController.handleSearch ($ txtSearch.val (), _ geoNamesModel); ); $ btnClear.on ("click", function () _geoNamesFormController.handleClear (_geoNamesModel); _openLayersMapController.handleClear (_openLayersMapModel); $ r.html (""); $ txtSearch.val (""); $ rContainer.slideUp ( 500);); $ (window) .on ("load", function () _openLayersMapController.render (_openLayersMapModel););
Dit zijn onze enige gebeurtenissen met twee klikken, plus een gebeurtenis voor het laden van vensters. De eerste bindt aan onze "Search GeoNames.org" -knop en verzendt de waarde van het tekstvak en het model waarmee we willen omgaan met onze controller om het werk aan te kunnen. De tweede bindt aan onze knop "Markeringen wissen" die we hebben genoemd in het gedeelte GeoNames Model. Deze gebeurtenis roept het wissen van het resultaatobject in het GeoNames-model op en ook de markeringen in de weergave, die we hieronder zullen behandelen. Ten slotte worden ook ons formulier en de resultatensectie in onze weergave bijgewerkt en worden de resultaten verborgen omdat dat gebied nu leeg is. De gebeurtenis window laden belast de rendering van de kaart wanneer het venster volledig is geladen.
var showPoints = function () var olPoints = _geoNamesFormController.handleResult (_geoNamesModel); var olResults = _openLayersMapController.handleMarkers (_openLayersMapModel, olPoints); $ ( '# ResultContainer') slideDown (500).; $ r.append (olResults.join (")); $ rBox.jScrollPane (showArrows: true, autoReinitialise: true);; _geoNamesModel.notifySearchComplete.binder (function () showPoints (););
Het laatste deel van onze GeoNames View gaat over het nemen van onze resultaten en het manipuleren van zowel onze resultatenweergave als de kaart. Het beeld weet dat het de kaart en de resultatenweergave moet bijwerken omdat het zich heeft geabonneerd op het model van het GeoNames-model notifySearchComplete
evenement zoals we hierboven kunnen zien. Nadat het evenement is voltooid, roept het beeld het showPoints
functie, en het behandelt het bijwerken van de resultaten-indeling en het weergeven van de markeringen op de kaart.
var makeOpenLayersMapModel = function () var map, center = nieuwe OpenLayers.LonLat (-90.3658472,38.742575), // Gecentreerd op Lambert St Louis International omdat ik een voorkeur heb voor zoomLevel = 6, numZoomLevels = 15, iconSize = 32, autoSizeFramedCloud = OpenLayers .Class (OpenLayers.Popup.FramedCloud, 'autoSize': true), size = new OpenLayers.Size (iconSize, iconSize), calculateOffset = function (size) plaats nieuwe OpenLayers.Pixel (-size.w / 2, -size.h / 2); , icon = nieuwe OpenLayers.Icon ('img / redpin.png', size, null, calculationOffset); var renderMap = function () var options = controls: [nieuwe OpenLayers.Control.Navigation (), nieuwe OpenLayers.Control.PanZoomBar (), nieuwe OpenLayers.Control.KeyboardDefaults ()], eenheden: "km", numZoomLevels: numZoomLevels, maxExtent: nieuwe OpenLayers.Bounds (-170.0, 10, -60, 80), center: center; map = nieuwe OpenLayers.Map ('kaart', opties); wmslayer = nieuwe OpenLayers.Layer.WMS ("OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", layers: 'basic'); markers = nieuwe OpenLayers.Layer.Markers ("Postcode markeringen"); map.addLayers ([wmslayer, markers]); map.zoomTo (zoomLevel); ; var addMarker = function (ll, icon, popupClass, popupContentHTML) var marker = new OpenLayers.Marker (ll, icon); markers.addMarker (marker); marker.events.register ('mousedown', marker, function (evt) for (var i = map.popups.length-1; i> = 0; i -) map.removePopup (map.popups [i] );; var popup = new OpenLayers.Popup.FramedCloud (null, marker.lonlat, null, popupContentHTML, null, true, null); popup.closeOnMove = true; map.addPopup (popup); OpenLayers.Event.stop ( evt);); ; var buildMarkers = function (pts) var rHTML = [], y = 0; $ .each (pts.postalCodes, functie (i, v) if (i === 0) newCenterLL = nieuwe OpenLayers.LonLat (v.lng, v.lat); latit = v.lat; longit = v .lng; markerIcon = icon.clone (); lonLatMarker = nieuwe OpenLayers.LonLat (longit, latit); popupClass = autoSizeFramedCloud; popupContentHTML = ''+ v.placeName +', '+ v.adminCode1 + "+ v.postalCode +'
'; rHTML [y ++] = ''; rHTML [y ++] = (i + 1) + ')' + v.placeName + ',' + v.adminCode1 + "+ v.postalCode + ''; addMarker (lonLatMarker, markerIcon, popupClass, popupContentHTML); ); map.setCenter (newCenterLL, 12); retourneer rHTML; ; var clear = function () for (var x = markers.markers.length-1; x> = 0; x--) markers.markers [x] .destroy (); markers.removeMarker (markers.markers [x]); map.setCenter (center, zoomLevel); ; return renderMap: renderMap, addMarker: addMarker, buildMarkers: buildMarkers, clear: clear;
'; rHTML [y ++] = v.lat.toFixed (5) + ',' + v.lng.toFixed (5); rHTML [y ++] = '
Hier hebben we ons OpenLayers-model. Dit model behandelt het maken van de OpenLayers-kaart, onze kaartmarkeringen om de GeoNames WebServices-resultaatset weer te geven, evenals het opruimen van die markeringen van onze kaart.
var map, center = nieuwe OpenLayers.LonLat (-90.3658472,38.742575), // Gecentreerd op Lambert St Louis International omdat ik vooringenomen zoomLevel = 6, numZoomLevels = 15, iconSize = 32, autoSizeFramedCloud = OpenLayers.Class (OpenLayers.Popup. FramedCloud, 'autoSize': true), size = new OpenLayers.Size (iconSize, iconSize), calculateOffset = function (size) retourneer nieuwe OpenLayers.Pixel (-size.w / 2, -size.h / 2) ; , icon = nieuwe OpenLayers.Icon ('img / redpin.png', size, null, calculationOffset);
We hebben een aantal waarden vooraf gedefinieerd voor onze kaart - zoomniveau
is de variabele waarop we onze initiële zoomfactor instellen. Het zoomniveausgetal neemt toe naarmate u dichter bij de aarde komt. Zoals je waarschijnlijk wel kunt raden, numZoomLevels
is het aantal zoomniveaus dat deze kaart toestaat. Voor onze punaise markers moeten we de maat van de marker aangeven, dus iconSize
, hoewel niet expliciet te zeggen, is ingesteld op 32 en OpenLayers begrijpt deze waarde in pixels. De andere items die u hier ziet, zijn specifiek voor OpenLayers. De calculateOffset
vertel het pictogram eenvoudigweg om het pictogrambeeld te verschuiven zodat het beeld gecentreerd is op de breedtegraad en lengtegraad van het punt, niet op de linkerbovenhoek of rechtsboven. De OpenLayers.Size
constructor maakt een grootte op basis van de iconSize die we willen. Ten slotte, de OpenLayers.Icon
constructor definieert het pictogram dat we als onze markeringen op de kaart gebruiken.
var renderMap = function () var options = controls: [nieuwe OpenLayers.Control.Navigation (), nieuwe OpenLayers.Control.PanZoomBar (), nieuwe OpenLayers.Control.KeyboardDefaults ()], eenheden: "km", numZoomLevels: numZoomLevels, maxExtent: nieuwe OpenLayers.Bounds (-170.0, 10, -60, 80), center: center; map = nieuwe OpenLayers.Map ('kaart', opties); wmslayer = nieuwe OpenLayers.Layer.WMS ("OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", layers: 'basic'); markers = nieuwe OpenLayers.Layer.Markers ("Postcode markeringen"); map.addLayers ([wmslayer, markers]); map.zoomTo (zoomLevel); ;
Hier is de belangrijkste code om onze kaart te maken. De OpenLayers.Map
constructor neemt twee parameters, het DOM-object dat de kaart bevat, en de opties, wat een optioneel object is met eigenschappen die de kaart zal hebben. Laten we de opties bekijken die ik heb toegevoegd.
OpenLayers biedt u de flexibiliteit om verschillende bronnen voor uw kaarttegels te gebruiken.
De controls
voeg simpelweg basisinteractie van muis en toetsenbord toe met de kaart. Deze voegen ook de zoombalk en de richtingknoppen boven de kaart toe. De units
zijn in kilometers, hoewel deze optie voor deze tutorial niet echt nodig is, omdat we geen berekeningen uitvoeren met OpenLayers, alleen GeoNames. De numZoomLevels
bepaalt het aantal zoomniveaus dat deze kaart zal hebben. De centrum
vertelt de kaart waar hij zichzelf moet centreren bij het renderen. De maxExtent
optie is ingesteld op een OpenLayers-element met de naam Bounds. U geeft eenvoudigweg een nieuwe OpenLayers.Bounds aan en we geven die 4 parameters - Zuidwestelijke lengtegraad, Zuidwestelijke breedtegraad, Noordoost-lengtegraad en Noordoost-breedtegraad. Dit geeft ons, wat we in de GIS-wereld noemen, een begrenzingsvak. Omdat we in deze zelfstudie alleen met de Verenigde Staten te maken hebben, heb ik de grenzen gesteld om Noord-Amerika alleen te vermelden bij het weergeven van de kaart. Als u de hele wereld wilt laten zien, laat u deze optie gewoon staan. Op dit moment hebben we onze kaart klaarliggen. Nu kunnen we beginnen met het toevoegen van lagen aan de kaart.
OpenLayers biedt u de flexibiliteit om verschillende bronnen voor uw kaarttegels te gebruiken. Sommige daarvan omvatten Bing Maps, Google Maps en OpenStreetMap. Je kunt ook je eigen kaarttegels gebruiken als je dat soort instellingen hebt. Voor deze tutorial gebruiken we de generieke OSGeo-kaarttegels die OpenLayers gebruikt in hun eigen voorbeelden. We doen dit door een nieuw te maken OpenLayers.Layer.WMS
constructeur. WMS staat voor Web Mapping Services. We geven het een titel, een URL om naar de tegels te wijzen en de parameters die specifiek zijn voor de tegelhost. Vervolgens maken we een markeerlaag met behulp van de OpenLayers.Layer.Markers
constructeur. Het enige wat we op dit punt moeten doen, is het een naam geven. Ten slotte voegen we deze twee lagen die we hebben gemaakt toe aan onze kaart met de addLayers
functie, en we zoomen op het juiste zoomniveau dat we hebben gedefinieerd.
var addMarker = function (ll, icon, popupClass, popupContentHTML) var marker = new OpenLayers.Marker (ll, icon); markers.addMarker (marker); marker.events.register ('mousedown', marker, function (evt) for (var i = map.popups.length-1; i> = 0; i -) map.removePopup (map.popups [i] );; var popup = new OpenLayers.Popup.FramedCloud (null, marker.lonlat, null, popupContentHTML, null, true, null); popup.closeOnMove = true; map.addPopup (popup); OpenLayers.Event.stop ( evt);); ;
De addMarker
functie neemt de markeerinformatie die we in de volgende sectie zullen verschaffen en maakt markeringen en pop-upwolken die moeten worden toegevoegd aan onze kaart. We maken eerst onze marker met de OpenLayers.Marker
constructeur. Het enige dat we moeten doen is het doorgeven van onze LonLat-variabele en het pictogram dat we willen gebruiken. Dan gebruiken we gewoon de addMarker
functioneer met de markervariabele als zijn argument en de markering wordt toegevoegd aan de kaart. Om een pop-upvenster te laten werken als we op de markering klikken, registreren we gewoon een evenement voor deze markering. We doen dit door het events
eigendom van deze marker en gebruik de registreren
functie om de gebeurtenis te binden zoals in jQuery. De pop-up wordt gemaakt met behulp van de OpenLayers.Popup.FramedCloud
constructor, die zeven parameters vereist: id, lonlat, contentSize, contentHTML, anchor, closeBox, closeBoxCallback. Het enige dat we echt nodig hebben, zijn de lonlat, contentHTML en de mogelijkheid om de pop-up te sluiten, dus al het andere kan nul zijn. Om de popup toe te voegen, gebruiken we gewoon de functie addPopup
het doorgeven van de popup-variabele. Zo simpel is het.
var buildMarkers = function (pts) var rHTML = [], y = 0; $ .each (pts.postalCodes, functie (i, v) if (i === 0) newCenterLL = nieuwe OpenLayers.LonLat (v.lng, v.lat); latit = v.lat; longit = v .lng; markerIcon = icon.clone (); lonLatMarker = nieuwe OpenLayers.LonLat (longit, latit); popupClass = autoSizeFramedCloud; popupContentHTML = ''+ v.placeName +', '+ v.adminCode1 + "+ v.postalCode +'
'; rHTML [y ++] = ''; rHTML [y ++] = (i + 1) + ')' + v.placeName + ',' + v.adminCode1 + "+ v.postalCode + ''; addMarker (lonLatMarker, markerIcon, popupClass, popupContentHTML); ); map.setCenter (newCenterLL, 12); retourneer rHTML; ;
'; rHTML [y ++] = v.lat.toFixed (5) + ',' + v.lng.toFixed (5); rHTML [y ++] = '
De buildMarkers
functie neemt de JSON en loopt door de resultatenset. Voor de eenvoud gaan we ervan uit dat het eerste punt dat door de GeoNames WebServices-aanvraag wordt geretourneerd hoogstwaarschijnlijk het punt is dat je hebt gezocht, dus we maken dat tot ons nieuwe middelpunt en stellen dat in op een OpenLayers.LonLat
voorwerp. We hebben ons OpenLayers-pictogram al gemaakt, dus om het steeds opnieuw te gebruiken, bellen we het kloon
methode, die eenvoudigweg een kopie van dat pictogram maakt. De rest van de lus schrijft eenvoudigweg wat HTML naar een array, die we in de formulierweergave van GeoNames hebben gezien en die wordt gebruikt om de resultaten-div te maken. Het schrijven van meerdere HTML-regels en deze in een array duwen, is een snelle manier om HTML dynamisch te maken zonder steeds opnieuw toegang te hebben tot de DOM. Aan het einde van deze lus roepen we de addMarker
functie die we hierboven hebben gecreëerd. Zodra we onze markeringen hebben gemaakt en de lus is voltooid, zullen we ons concentreren op en inzoomen op onze resultaten met de setCenter
functie.
var clear = function () for (var x = markers.markers.length-1; x> = 0; x--) markers.markers [x] .destroy (); markers.removeMarker (markers.markers [x]); map.setCenter (center, zoomLevel); ;
Deze functie zorgt ervoor dat de punaises van de kaart worden verwijderd en verwijdert ze uit de laag markers. De vernietigen
functie verwijdert de markering van de kaart. De removeMarker
functie verwijdert de markering uit de markeringslaag. Merk op dat we in onze for-lus decrementeren in plaats van verhogen zoals we normaal zouden doen. We doen dit omdat we OpenLayer's gebruiken vernietigen
en removeMarker
functies wordt het markeringsobject bijgewerkt. Als we bijvoorbeeld 5 markeringen hadden die we wilden verwijderen en we onze lus verhoogden, zouden we na de eerste vernietiging 4 markeringen over hebben. Na de 2e vernietiging zouden we nog 3 markeringen over hebben. Nadat de 3e vernietiging heeft plaatsgevonden, hebben we nog 2 markeringen over. Op dat moment echter bevinden onze resterende markeringen zich op positie 1 en 2, dus het verwijderen van de 4e marker zou geen effect hebben omdat die positie niet bestaat, daarom verwijderen we ze vanaf het einde en werken we onze weg vooruit.
var makeOpenLayersMapController = function () return render: function (openLayersMapModel) openLayersMapModel.renderMap (); , handleMarkers: function (openLayersMapModel, mrkr) openLayersMapModel.buildMarkers (mrkr); , handleClear: function (openLayersMapModel) openLayersMapModel.clear (); ; ;
Deze controller, zoals hierboven beschreven, doet niets anders dan toegang krijgen tot functies en retourneert variabelen van het model op basis van invoer vanuit de gebruikersinterface, alleen deze keer vanuit ons OpenLayers-model. We retourneren drie functies:
geven
- hiermee wordt de OpenLayers-kaart feitelijk naar het scherm weergegeven. handleMarkers
- dit roept de buildMarkers-functie van het openLayersMapModel aan, zodat we ons GeoNames WFS-resultaat kunnen nemen en onze pushpins op de kaart kunnen maken. handleClear
- dit roept de heldere functie van het openLayersMapModel op, zodat we de kaart van onze markeringen kunnen wissen. Wanneer deze kaartcode wordt weergegeven, ziet uw pagina er ongeveer zo uit:
Ten slotte is alles wat we moeten doen onze modellen, weergaven en contollers instantiëren.
(Functie () var geoNamesModel = makeGeoNamesModel (); var openLayersMapModel = makeOpenLay