In questo tutorial, ti mostrerò come usare OpenLayers, una libreria JavaScript open source semplice da usare per caricare, visualizzare e renderizzare le mappe, con il WFS GeoNames.org per visualizzare gli indicatori sulla tua mappa, proprio come vedi su Google Mappe. Tutto quello che serve è un po 'di HTML, CSS e JavaScript - il gioco è fatto!
Prima di fare qualsiasi cosa, dobbiamo prima configurare il nostro account GeoNames.org. GeoNames WebServices consente di effettuare richieste per un valore di 30000 punti di credito al giorno, un limite orario di 2000 crediti. Domande diverse richiedono diversi punti di credito, senza che la query 'costi' più di 4. Per molti piccoli siti e semplici test di sviluppo, questo dovrebbe essere più che sufficiente. Offrono servizi Premium a un prezzo, ma oggi ci occuperemo delle cose gratis. Il servizio è sempre bello, no??
Per creare il tuo account, accedi al login GeoNames.org e imposta il tuo account gratuito. Dovrai confermare l'account nella tua email, ma questo dovrebbe andare abbastanza velocemente. Una volta che sei confermato, sei pronto per andare.
"Ci sono oltre 30 diversi tipi di query che puoi fare con i servizi Web di GeoNames. Un elenco di questi può essere trovato qui."
Successivamente avremo bisogno di afferrare il codice sorgente e le immagini di OpenLayers. Questi possono essere trovati sulla home page di OpenLayers. Puoi scaricare il file .zip o .tar.gz. Per questo tutorial, tutto ciò di cui abbiamo bisogno sono il file OpenLayers.js e la cartella img. Per aggiungere sapore e usabilità, includeremo i plug-in JQuery JScrollPane di Kelvin Luck e quelli jQuery di Brandon Aaron, solo per migliorare e abbellire i nostri risultati div. Prendi js e css da JScrollPane. Ho apportato alcune lievi modifiche al css, giusto per adattarlo allo stile che volevo per questo tutorial, ma lo stile come vorresti. Prendi il plugin della rotellina del mouse da GitHub. Ultimo, ma non meno importante, prendi l'ultima versione di jQuery.
"Ovviamente, tutti i file necessari per questo tutorial sono disponibili nel link di download dei file sorgente in alto."
Il tutorial di oggi sarà affrontato findNearbyPostalCodes. Ora iniziamo a scrivere del codice!
Vai avanti e crea una struttura di directory per la tua applicazione. Ho chiamato il mio geonames
. All'interno dei geonames, includi tre cartelle aggiuntive: img, js
e css
. Le immagini da OpenLayers andranno nella cartella img, i file JavaScript da OpenLayers, JScrollPane e jQuery mousewheel, e jQuery andrà nella cartella js, e il foglio di stile da JScrollPane andrà nella cartella css. Inoltre, alcune immagini che ho creato e una coppia afferrata da iconfinder possono essere trovate nei file sorgente. Mettili nel img
cartella pure.
Qui abbiamo una pagina semplice con alcuni elementi HTML. La maggior parte della nostra carne sarà nel nostro JavaScript, quindi questa parte è piuttosto breve. Salva questo file come index.html
.
Openlayers / Geonames Tutorial Ricerca
risultati
Ecco il CSS che abbiamo creato per l'uso in questo tutorial. Niente di terribilmente innovativo qui, solo un po 'di stile. Salva questo file come style.css
nel css
cartella che hai creato.
* font-family: Helvetica; colore nero; html height: 100%; margine: 0; overflow-y: scroll; body background-color: white; font: normale 13px arial, sans-serif; altezza: 100%; margine: 0; #map background: #ccc; altezza: 100%; posizione: assoluta; larghezza: 100%; z-index: 1; #searchContainer border-radius: 2px; -moz-border-radius: 2px; -o-border-radius: 2px; -webkit-border-radius: 2px; colore di sfondo: rgba (247,247,247,0,5); border: 1px solid #ffffff; box-shadow: 0 0 3px # C5C5C5; -moz-box-shadow: 0 0 3px # C5C5C5; -webkit-box-shadow: 0 0 3px # C5C5C5; altezza: 158px; larghezza: 250px; position: absolute; z-index: 2; sopra: 20px; a destra: 20px; imbottitura: 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; altezza: 136px; larghezza: 250px; allineamento del testo: centro; altezza della linea: 44px; #resultContainer border-radius: 2px; -moz-border-radius: 2px; -o-border-radius: 2px; -webkit-border-radius: 2px; colore di sfondo: rgba (247,247,247,0,5); border: 1px solid #ffffff; -moz-box-shadow: 0 0 3px # C5C5C5; -webkit-box-shadow: 0 0 3px # C5C5C5; box-shadow: 0 0 3px # C5C5C5; larghezza: 252px; position: absolute; z-index: 2; superiore: 208 px; a destra: 20px; imbottitura: 4px 4px 4px 4px; display: nessuno; #resultHeader, #searchHeader width: 250px; altezza: 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; posizione: relativa; background-repeat: repeat-x; background: -webkit-gradient (lineare, 0% 0%, 0% 100%, da (# C2DCFD), a (#DDECFD)); background: -webkit-linear-gradient (in alto, #DDECFD, # C2DCFD); background: -moz-linear-gradient (in alto, #DDECFD, # C2DCFD); background: -ms-linear-gradient (in alto, #DDECFD, # C2DCFD); background: -o-linear-gradient (in alto, #DDECFD, # C2DCFD); allineamento del testo: centro; font-size: 16px; text-shadow: 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: 250px; larghezza: 250px; overflow: auto; .item0, .item1 float: left; imbottitura: 5px 4px 5px 4px; larghezza: 242px; border-top: 1px solid #dcdcdc; .item1 background-color: #FFFFFF; . chiaro chiaro: entrambi; .olPopupCloseBox background: url ("... /img/close.gif") no-repeat; cursore: puntatore; .olFramedCloudPopupContent padding: 5px; overflow: auto;
A questo punto, la tua pagina dovrebbe apparire in questo modo:
Non è molto da guardare, quindi entriamo nella roba buona.
var $ r = $ ('# risultati'), $ rContainer = $ ('# resultContainer'), $ rBox = $ ('# resultBox');
Vuoi sempre impostare i tuoi oggetti jQuery su variabili. Sempre migliori pratiche!
var Observation = function (target) _target = target; _arrObservers = []; var binder = function (observer) _arrObservers.push (observer); ; var informa = function () for (var x = 0; x<_arrObservers.length; x++) _arrObservers[x](_target); ; return binder: binder, inform: inform ;
Questa è solo una semplice funzione listener che abbiamo creato. Quando creiamo l'evento che vogliamo ascoltare, passiamo l'oggetto a cui vogliamo ascoltare; Ho chiamato questo argomento: bersaglio
. Contiene due variabili: _bersaglio
- una variabile che impostiamo uguale al nostro argomento e _arrObservers
- una matrice vuota che useremo per popolare con gli ascoltatori. L'osservazione contiene anche due funzioni: legante
e far sapere
.
var binder = function (observer) _arrObservers.push (observer); ;
Funzione legante
aggiunge ogni ascoltatore, o osservatore
a una schiera di ascoltatori. In questo tutorial creeremo solo un evento personalizzato, ma l'aggiunta di ogni listener a un array consente di assegnare più listener con una funzione.
var informa = function () for (var x = 0; x<_arrObservers.length; x++) _arrObservers[x](_target); ;
Funzione far sapere
lancia un messaggio all'ascoltatore facendogli sapere che l'evento si sta verificando. Infine, come vedrai sopra, restituiremo entrambe queste funzioni in modo che siano disponibili per l'uso.
var makeGeoNamesModel = function () var _results = , country = 'US', raggio = 30, username = 'openlayers_tutorial', maxRows = 20; var notifySearchComplete = new Observation (this); var search = function (val) $ .ajax (url: 'http://api.geonames.org/findNearbyPostalCodesJSON', dati: codice postale: val, paese: paese, raggio: raggio, nome utente: username, maxRows: maxRows, dataType: 'jsonp', jsonpCallback: 'geoNamesResponse'); ; geoNamesResponse = function (geoData) _results = geoData; notifySearchComplete.inform (); ; var getResults = function () return _results; ; var clear = function () _results = ; ; return notifySearchComplete: notifySearchComplete, search: search, geoNamesResponse: geoNamesResponse, getResults: getResults, clear: clear; ;
Qui abbiamo il nostro modello GeoNames. Questo modello gestirà la creazione, l'archiviazione e la restituzione del valore della nostra richiesta WebServices di GeoNames.
var _results = , country = 'US', raggio = 30, username = 'openlayers_tutorial', maxRows = 20;
Queste sono solo alcune variabili che useremo, principalmente nella nostra richiesta Ajax. Per l'uso del nostro tutorial, stiamo solo andando a cercare negli Stati Uniti (mi dispiace, sono di parte), ma puoi modificare la tua applicazione per accettare l'input del codice paese, se lo desideri. Il raggio massimo consentito con il nostro account gratuito è di 30 chilometri. Ho anche impostato il numero massimo di posizioni restituite a 20, anche se è possibile aumentare tale valore se lo si desidera. Stringa openlayers_tutorial
è il nome dell'account che ho impostato per questo tutorial, quindi cambia questa stringa con il nome utente che hai creato quando hai configurato l'account sopra. Infine, prepariamo il nostro modello con un oggetto vuoto chiamato _results
essere riempito in un secondo momento.
var notifySearchComplete = new Observation (this); var search = function (val) $ .ajax (url: 'http://api.geonames.org/findNearbyPostalCodesJSON', dati: codice postale: val, paese: paese, raggio: raggio, nome utente: username, maxRows: maxRows, dataType: 'jsonp', jsonpCallback: 'geoNamesResponse'); ; geoNamesResponse = function (geoData) _results = geoData; notifySearchComplete.inform (); ;
Qui abbiamo la richiesta di tutti i servizi web più importanti: ricerca
e la nostra notifica dell'evento. Poiché si tratta di una richiesta di terze parti, impostiamo dataType su "jsonp" e inoltriamo la richiesta alle nostre variabili definite in precedenza. Discussione val
sarà definito più tardi nella nostra visione. Stiamo anche impostando esplicitamente il nome della funzione di callback - geoNamesResponse
- e gestire la richiesta di successo. Potrei aver aggiunto del codice per gestire l'input errato, ma per questo tutorial, assumeremo che inserirai un codice postale corretto di 5 cifre. Stiamo passando a GeoNames il codice postale che l'utente ha inserito, ma per questa particolare query è possibile passare latitudine e longitudine come lat
e lng
se tu volessi. A questo punto, notificheremo anche al nostro ascoltatore che questa ricerca è stata completata.
var getResults = function () return _results; ; var clear = function () _results = ; ;
L'ultima parte del nostro modello si occupa di restituire i nostri risultati quando vengono richiesti e di svuotare il nostro oggetto risultato quando l'utente fa clic sul pulsante "Cancella marcatori".
var makeGeoNamesFormController = function () return handleSearch: function (txtVal, geoNamesModel) geoNamesModel.search (txtVal); , handleClear: function (geoNamesModel) geoNamesModel.clear (); , handleResult: function (geoNamesModel) testResults = geoNamesModel.getResults (); return testResults; ; ;
Il nostro controller non fa altro che accedere alle funzioni e restituire variabili dal nostro modello GeoNames in base all'input dell'interfaccia utente. Restituiamo tre funzioni:
handleSearch
- questo prende il valore dell'input dell'utente e il geoNamesModel come argomenti, e invoca il geoNamesModel's ricerca
funzione, passandogli il valore che vogliamo inviare ai servizi Web GeoNames.
handleClear
- questo invoca il geoNamesModel chiaro
funzione in modo da poter cancellare il nostro oggetto risultato.
handleResult
- questo invoca il geoNamesModel getResults
funzione in modo che possiamo accedere ai risultati della nostra richiesta WFS.
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 (););;
La vista GeoNames definisce i nostri eventi di clic e gestisce la chiamata alle funzioni del controller per manipolare la nostra vista. Funziona a stretto contatto con il controller, ma lascia il modello che accede e manipola fino al controller.
var _geoNamesModel = initGeoNamesModel, _openLayersMapModel = initOpenLayersMapModel, _geoNamesFormController = initGeoNamesFormController, _openLayersMapController = initOpenLayersMapController, $ txtSearch = $ ('# txtSearch'), $ btnSearch = $ ('# btnSearch'), $ btnClear = $ ('# btnClear');
Tutto ciò che facciamo qui è impostare le variabili uguali ai rispettivi argomenti della funzione e, come sempre, impostare gli oggetti jQuery sulle variabili.
$ 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););
Questi sono i nostri unici due eventi di clic, oltre a un evento di caricamento della finestra. Il primo si lega al nostro pulsante "Cerca GeoNames.org" e invia il valore della casella di testo e il modello che vogliamo trattare con il nostro controller per gestire il lavoro. Il secondo si lega al pulsante "Clear Markers" che abbiamo menzionato nella sezione del modello GeoNames. Questo evento chiama la cancellazione dell'oggetto risultati nel modello GeoNames e anche i marcatori nella vista, che verranno trattati di seguito. Infine aggiorna anche il nostro modulo e la sezione dei risultati nella nostra vista, e nasconde i risultati poiché quell'area è ora vuota. L'evento di caricamento della finestra gestisce il rendering della mappa quando la finestra è completamente caricata.
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 (););
La parte finale della nostra vista GeoNames si occupa di prendere i nostri risultati e manipolare sia la nostra visualizzazione dei risultati che la mappa. La vista sa che deve aggiornare la mappa e la visualizzazione dei risultati perché è stata sottoscritta ai modelli di GeoNames notifySearchComplete
evento come possiamo vedere sopra. Al termine dell'evento, la vista chiama il showPoints
funzione, e gestisce l'aggiornamento del div dei risultati e la visualizzazione dei marcatori sulla mappa.
var makeOpenLayersMapModel = function () var map, center = new OpenLayers.LonLat (-90.3658472,38.742575), // Centrato su Lambert St Louis International perché sono polarizzato zoomLevel = 6, numZoomLevels = 15, iconSize = 32, autoSizeFramedCloud = OpenLayers .Class (OpenLayers.Popup.FramedCloud, 'autoSize': true), size = new OpenLayers.Size (iconSize, iconSize), calculateOffset = function (size) return new OpenLayers.Pixel (-size.w / 2, -size.h / 2); , icon = new OpenLayers.Icon ('img / redpin.png', dimensione, null, calculateOffset); var renderMap = function () var options = controls: [new OpenLayers.Control.Navigation (), new OpenLayers.Control.PanZoomBar (), new OpenLayers.Control.KeyboardDefaults ()], units: "km", numZoomLevels: numZoomLevels, maxExtent: new OpenLayers.Bounds (-170.0, 10, -60, 80), center: center; map = new OpenLayers.Map ('mappa', opzioni); wmslayer = new OpenLayers.Layer.WMS ("OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", layers: 'basic'); markers = new OpenLayers.Layer.Markers ("Indicatori di codice postale"); map.addLayers ([wmslayer, marker]); map.zoomTo (zoomLevel); ; var addMarker = function (ll, icon, popupClass, popupContentHTML) var marker = new OpenLayers.Marker (ll, icona); markers.addMarker (marker); marker.events.register ('mousedown', marker, function (evt) per (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, function (i, v) if (i === 0) newCenterLL = new OpenLayers.LonLat (v.lng, v.lat); latit = v.lat; longit = v .lng; markerIcon = icon.clone (); lonLatMarker = new 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); return 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 ++] = '
Qui abbiamo il nostro modello OpenLayers. Questo modello gestirà la creazione della mappa OpenLayers, i nostri indicatori di mappa per rappresentare il set di risultati WebServices di GeoNames, oltre a cancellare quei marker dalla nostra mappa.
var map, center = new OpenLayers.LonLat (-90.3658472,38.742575), // Centrato su Lambert St Louis International perché sono polarizzato zoomLevel = 6, numZoomLevels = 15, iconSize = 32, autoSizeFramedCloud = OpenLayers.Class (OpenLayers.Popup. FramedCloud, 'autoSize': true), size = new OpenLayers.Size (iconSize, iconSize), calculateOffset = function (size) return new OpenLayers.Pixel (-size.w / 2, -size.h / 2) ; , icon = new OpenLayers.Icon ('img / redpin.png', dimensione, null, calculateOffset);
Abbiamo predefinito alcuni valori per la nostra mappa - zoomLevel
è la variabile a cui imposteremo il nostro zoom iniziale. Il numero di livelli di zoom aumenta man mano che ti avvicini sempre di più alla Terra. Come puoi probabilmente indovinare, numZoomLevels
è il numero di livelli di zoom consentiti da questa mappa. Per i nostri marcatori a puntina, dobbiamo dichiarare la dimensione del marcatore, quindi iconSize
, mentre non lo dice esplicitamente, è impostato su 32, e OpenLayers capisce che questo valore è espresso in pixel. Gli altri articoli che vedi qui sono specifici di OpenLayers. Il calculateOffset
indica semplicemente all'icona di spostare l'immagine dell'icona in modo che l'immagine sia centrata sulla latitudine e longitudine del punto, non in alto a sinistra o in alto a destra. Il OpenLayers.Size
costruttore crea una dimensione in base all'icona che vogliamo. Infine, il OpenLayers.Icon
costruttore definisce l'icona che useremo come nostri marcatori sulla mappa.
var renderMap = function () var options = controls: [new OpenLayers.Control.Navigation (), new OpenLayers.Control.PanZoomBar (), new OpenLayers.Control.KeyboardDefaults ()], units: "km", numZoomLevels: numZoomLevels, maxExtent: new OpenLayers.Bounds (-170.0, 10, -60, 80), center: center; map = new OpenLayers.Map ('mappa', opzioni); wmslayer = new OpenLayers.Layer.WMS ("OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", layers: 'basic'); markers = new OpenLayers.Layer.Markers ("Indicatori di codice postale"); map.addLayers ([wmslayer, marker]); map.zoomTo (zoomLevel); ;
Ecco il codice più importante per creare la nostra mappa. Il OpenLayers.Map
il costruttore prende due parametri, l'oggetto DOM che ospiterà la mappa e le opzioni, che è un oggetto facoltativo con proprietà che avrà la mappa. Diamo un'occhiata alle opzioni che ho incluso.
OpenLayers ti offre la flessibilità di utilizzare diverse fonti per le tue mappe.
Il controlli
aggiungi semplicemente l'interazione di base del mouse e della tastiera con la mappa. Questi aggiungono anche la barra dello zoom e i pulsanti direzionali sopra la mappa. Il unità
sono in chilometri, anche se ai fini di questo tutorial, questa opzione non è realmente necessaria, dato che non stiamo facendo calcoli con OpenLayers, solo GeoNames. Il numZoomLevels
imposta il numero di livelli di zoom che questa mappa avrà. Il centro
dice alla mappa dove concentrarsi sul rendering. Il maxExtent
l'opzione è impostata su un elemento OpenLayers chiamato Bounds. Dichiarate semplicemente un nuovo OpenLayers.Bounds e diamo i 4 parametri: SouthWest Longitude, SouthWest Latitude, NorthEast Longitude e NorthEast Latitude. Questo ci dà, ciò che chiamiamo nel mondo GIS, un riquadro di delimitazione. Dato che ci occupiamo solo degli Stati Uniti in questo tutorial, ho fissato i limiti per includere solo il Nord America nella visualizzazione della mappa. Se vuoi mostrare il mondo intero, lascia semplicemente questa opzione. A questo punto abbiamo la nostra mappa pronta. Ora possiamo iniziare ad aggiungere layer alla mappa.
OpenLayers ti offre la flessibilità di utilizzare diverse fonti per le tue mappe. Alcuni di questi includono Bing Maps, Google Maps e OpenStreetMap. Puoi anche usare le tue tessere mappa se hai quel tipo di configurazione. Ai fini di questo tutorial, utilizzeremo le mappe generiche della mappa OSGeo che OpenLayers utilizza nei propri esempi. Lo facciamo creando un nuovo OpenLayers.Layer.WMS
costruttore. WMS sta per Web Mapping Services. Gli diamo un titolo, un URL per indicare le tessere e i parametri specifici per l'host del riquadro. Quindi creeremo un livello marcatore usando il OpenLayers.Layer.Markers
costruttore. Tutto quello che dobbiamo fare a questo punto è dargli un nome. Infine, aggiungeremo questi due livelli che abbiamo creato alla nostra mappa con il addLayers
funzione, e andremo a zoomare al livello di zoom appropriato che abbiamo definito.
var addMarker = function (ll, icon, popupClass, popupContentHTML) var marker = new OpenLayers.Marker (ll, icona); markers.addMarker (marker); marker.events.register ('mousedown', marker, function (evt) per (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);); ;
Il addMarker
la funzione prende le informazioni sul marker che forniremo nella prossima sezione e crea marcatori e nuvole popup da aggiungere alla nostra mappa. Per prima cosa facciamo il nostro marcatore con il OpenLayers.Marker
costruttore. Tutto ciò che dobbiamo fare è passare la nostra variabile LonLat e l'icona che vogliamo utilizzare. Quindi usiamo semplicemente il addMarker
funziona con la variabile marker come argomento e il marker verrà aggiunto alla mappa. Per fare in modo che una finestra popup funzioni, se clicchiamo sul marker, registriamo semplicemente un evento per questo marcatore. Lo facciamo chiamando il eventi
proprietà di questo marcatore e usa il Registrare
funzione per legare l'evento come faremmo in jQuery. Il popup è creato usando il OpenLayers.Popup.FramedCloud
costruttore, che accetta sette parametri: id, lonlat, contentSize, contentHTML, anchor, closeBox, closeBoxCallback. Tutto ciò di cui abbiamo veramente bisogno sono il lonlat, contentHTML e la possibilità di chiudere il popup, quindi tutto il resto può essere nullo. Per aggiungere il popup usiamo semplicemente la funzione addPopup
passando la variabile popup. E 'così semplice.
var buildMarkers = function (pts) var rHTML = [], y = 0; $ .each (pts.postalCodes, function (i, v) if (i === 0) newCenterLL = new OpenLayers.LonLat (v.lng, v.lat); latit = v.lat; longit = v .lng; markerIcon = icon.clone (); lonLatMarker = new 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); return rHTML; ;
'; rHTML [y ++] = v.lat.toFixed (5) + ',' + v.lng.toFixed (5); rHTML [y ++] = '
Il buildMarkers
funzione prende il JSON e loop attraverso il set di risultati. Per semplicità, assumiamo che il primo punto restituito dalla richiesta GeoNames WebServices sia molto probabilmente il punto cercato, quindi lo rendiamo il nostro nuovo centro e lo impostiamo su OpenLayers.LonLat
oggetto. Abbiamo già creato la nostra icona OpenLayers, quindi per utilizzarla più e più volte, chiameremo il clone
metodo, che fa semplicemente una copia di quell'icona. Il resto del ciclo scrive semplicemente un codice HTML in un array, che abbiamo visto nella vista modulo GeoNames per essere utilizzato per creare il div dei risultati. Scrivere più righe di HTML e inserirle in un array è un modo rapido per creare dinamicamente HTML senza dover accedere al DOM più e più volte. Alla fine di questo ciclo, invocheremo il addMarker
funzione che abbiamo creato sopra. Una volta che abbiamo creato i nostri marcatori e il ciclo è stato completato, ci concentreremo e ingrandiremo i risultati con setCenter
funzione.
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); ;
Questa funzione si occupa di cancellare i simboli dalla mappa e di rimuoverli dal livello dei marker. Il distruggere
la funzione rimuove il marker dalla mappa. Il removeMarker
la funzione rimuove l'indicatore dal livello dei marcatori. Si noti che stiamo decrementando nel nostro ciclo for anziché incrementare come faremmo normalmente. Lo facciamo perché utilizziamo OpenLayer's distruggere
e removeMarker
funzioni, l'oggetto marcatore viene aggiornato. Ad esempio, se avessimo 5 marcatori che volevamo eliminare, e abbiamo incrementato il nostro ciclo, dopo il 1 ° distruggi, avremmo lasciato 4 marcatori. Dopo la 2a distruzione, avremmo lasciato 3 segnalini. Dopo la 3a distruzione, avremmo lasciato 2 segnalini. A quel punto, però, i nostri marcatori rimanenti sono nelle posizioni 1 e 2, quindi eliminare il 4 ° marcatore non avrebbe alcun effetto perché quella posizione non esiste, quindi li rimuoviamo iniziando alla fine e procediamo in avanti.
var makeOpenLayersMapController = function () return render: function (openLayersMapModel) openLayersMapModel.renderMap (); , handleMarkers: function (openLayersMapModel, mrkr) openLayersMapModel.buildMarkers (mrkr); , handleClear: function (openLayersMapModel) openLayersMapModel.clear (); ; ;
Questo controller, come quello sopra, non fa altro che accedere alle funzioni e restituire variabili dal modello in base all'input dall'interfaccia utente, solo questa volta dal nostro modello OpenLayers. Restituiamo tre funzioni:
rendere
- questo rende effettivamente la mappa OpenLayers sullo schermo. handleMarkers
- questo invoca la funzione buildMarkers di openLayersMapModel in modo che possiamo prendere il risultato WFS di GeoNames e creare i nostri simboli sulla mappa. handleClear
- questo richiama la chiara funzione di openLayersMapModel in modo che possiamo cancellare la mappa dei nostri marcatori. Quando viene eseguito questo codice, la tua pagina dovrebbe apparire in questo modo:
Infine, tutto ciò che dobbiamo fare è creare un'istanza dei nostri modelli, viste e contollers.
(Function () var geoNamesModel = makeGeoNamesModel (); var openLayersMapModel = makeOpenLayersMapModel (); var geoNamesFormController = makeGeoNamesFormController (); var openLayersMapController = makeOpenLayersMapController (); var geoNamesFormView = makeGeoNamesFormView (geoNamesModel, openLayersMapModel, geoNamesFormController, openLayersMapController);) ( );
Per pr