"The explosive growth of the GeoWeb and geographic information has made GIS powerful media for the general public to communicate, but perhaps more importantly, GIS have also become media for constructive dialogs and interactions about social issues." - Sui & Goodchild
This is an old revision of the document!
Dans OpenLayers (acronyme OL3, http://openlayers.org), une carte est un ensemble de couches associée à des contrôles pour gérer l'interaction avec l'utilisateur. Une carte se construit avec trois ingrédients de base : du balisage HTML, des déclarations de style CSS, et du code JavaScript.
Pour la suite, le point d'entrée pour se documenter sur l'utilisation de cette API est ici (en version 3.9.0 pour ce tutoriel) : (docs/API, examples, code). Aussi, profitez de cette présentation OL3 partagée par les collègues du département Géomatique.
<html> <head> <title>ol3 - Ex1A - Create a first map with an OGC WMS layer</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map; $(document).ready(function () { map = new ol.Map({ target: 'map' }); var wmsLayer = new ol.layer.Image({ source: new ol.source.ImageWMS({ url: blWMS, params: { VERSION: "1.0.0", LAYERS: "ne_10m_admin_0_countries", FORMAT: "image/png" } }), }) map.addLayer(wmsLayer) // Set what we want to view var v0 = new ol.View({projection: "EPSG:4326"}); var bbox = v0.getProjection().getExtent(); v0.fit(bbox, map.getSize()); console.log("Map extent for entire view: " + v0.calculateExtent(map.getSize())); map.setView(v0); // -------------- showExtent(bbox); }); </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TODO ⇒ corrigé http://www.mediamaps.ch/oltuto/tutoEx1A.html
.ol-zoom:hover { background: lightskyblue; } .ol-zoom .ol-zoom-in, .ol-zoom .ol-zoom-out { background-color: tomato; border-radius: 50%; }
TODO ⇒ corrigé http://www.mediamaps.ch/oltuto/tutoEx1A.html
var v0 = new ol.View({projection: "EPSG:3857"}); console.log(v0.getProjection().getExtent());
Comparez avec précédemment.
var v0 = new ol.View({projection: "EPSG:4326"}); var bbox = [-18,38,38,55];
Jouez avec la taille de la fenêtre en rafraîchissant le navigateur à chaque fois.
// Change, live, the view projection $(document).keypress(function () { var v1 = new ol.View({projection: "EPSG:3857"}); var bbox = ol.proj.transformExtent([-18, 38, 38, 55], "EPSG:4326", "EPSG:3857"); v1.fit(bbox, map.getSize()); map.setView(v1); showExtent(bbox); });
var wmsLayer = new ol.layer.Tile({ source: new ol.source.TileWMS({ url: blWMS, params: { VERSION: "1.0.0", LAYERS: "ne_10m_admin_0_countries", FORMAT: "image/png" } }), })
Quelle différence en ajoutant une couche Tile plutôt que Image?
Avec une source ol.source.TileWMS c'est le client qui contrôle une grille de tuiles et il peut la garder en cache. Néanmoins, à chaque requête initiale de tuile, tout le processus de rendu cartographique se fait. Mais puisqu'une couche de tuiles fait des requêtes d'images selon une grille régulière, il est possible pour le serveur de préparer un cache de ces images.
Le service cartographique WMS permettant une grande flexibilité en terme de ce que le client peut demander. Côté serveur, cela rend difficile la mise en cache. A l'extrême opposé, un service peut aussi offrir des tuiles pour un ensemble prédéfini de niveaux de zoom et pour une grille régulière prédéfinie. On parle de couches de tuiles avec une source XYZ - avec X et Y indiquant la colonne et la rangée de la grille et Z le niveau de zoom. Il faut voir cela comme une pyramide de tuiles.
<html> <head> <title>ol3 - Ex2A - webmap with layer from tile server</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map; $(document).ready(function(){ map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ] }); var extent = map.getView().getProjection().getExtent() map.getView().fit(extent, map.getSize()); console.log("Map projection: " + map.getView().getProjection().getCode()); }); </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TODO ⇒ corrigé http://www.mediamaps.ch/oltuto/tutoEx2A.html
//map.getView().fit(extent, map.getSize()); map.getView().setCenter(ol.proj.transform([6.15,46.2],"EPSG:4326","EPSG:3857")) map.getView().setZoom(10);
console.log("LonLat Mercator: " + new ol.proj.transform([6.15,46.2],"EPSG:4326","EPSG:3857")); console.log("LonLat Google: " + new ol.proj.transform([6.15,46.2],"EPSG:4326","EPSG:900913"));
source: new ol.source.OSM({ url:"http://api.tiles.mapbox.com/v3/oertz.map-i2ak2ozc/{z}/{x}/{y}.png", attributions: [ new ol.Attribution({ html: "Based on <a href='www.openstreetmap.org'>OpenStreetMap</a> / MapBox restyled by oertz :: HEIG-VD" }) ] })
et ajouter l'instruction CSS suivante :
.ol-attribution { background-color: CornflowerBlue !important; right: 50px; left: initial; bottom: initial; top: 0px; }
source: new ol.source.XYZ({ url: "http://urbangene.heig-vd.ch/tilecache/{z}/{x}/{y}.png" })
defView = []; defView.push(new ol.View({projection: "EPSG:3857", center: new ol.proj.transform([6.865234, 45.832454], "EPSG:4326", "EPSG:3857"), zoom: 13})); defView.push(new ol.View({projection: "EPSG:3857", center: new ol.proj.transform([7.658360, 45.976536], "EPSG:4326", "EPSG:3857"), zoom: 14})); defView.push(new ol.View({projection: "EPSG:3857", center: new ol.proj.transform([86.9251707, 27.9878319], "EPSG:4326", "EPSG:3857"), zoom: 12})); idxViewAlea = Math.floor(Math.random() * 3); map.setView(defView[idxViewAlea]);
Rafraichissez le navigateur plusieurs fois. (a) Que se passe-t-il ? (b) Ajoutez votre(vos) vue(s) prédéfinie(s).
L'utilisation d'un cache serveur de tuiles a largement été popularisé par des services propriétaires comme Bing Maps. OpenLayers étant indépendant de toute source de données, l'API offre également un type de couche pour dialoguer avec de tels services.
TODO ⇒ corrigé http://www.mediamaps.ch/oltuto/tutoEx2B.html
map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.BingMaps({ key: 'Ak-dzM4wZjSqTlzveKz5u0d4IQ4bRzVI309GxmkgSVr1ewS6iPSrOvOKhA-CJlm3', imagerySet: 'AerialWithLabels' }) }) ] }); map.getView().setCenter(ol.proj.transform([6.15,46.2],"EPSG:4326","EPSG:3857")); map.getView().setZoom(10);
Swisstopo offre un service de tuiles basé sur le standard WMTS et que l'on peut exploiter comme suit. ⇒ http://ogo.heig-vd.ch/oltuto/tutoEx2C.html
<html> <head> <title>ol3 - Ex2C - webmap with Swisstopo WMTS</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map; $(document).ready(function () { var projection = new ol.proj.Projection({ code: 'EPSG:21781', units: 'm' }); ol.proj.addProjection(projection); var map = new ol.Map({ target: 'map', view: new ol.View({ projection: ol.proj.get("EPSG:21781"), center: [600000, 200000], zoom: 14, }) }); var tileGrid = new ol.tilegrid.WMTS({ origin: [420000, 350000], resolutions: [4000, 3750, 3500, 3250, 3000, 2750, 2500, 2250, 2000, 1750, 1500, 1250, 1000, 750, 650, 500, 250, 100, 50, 20, 10, 5, 2.5, 2, 1.5, 1, 0.5], matrixIds: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26] }); var layer = new ol.layer.Tile({ source: new ol.source.WMTS(({ url: "http://wmts.geo.admin.ch/1.0.0/{Layer}/default/20140520/21781/{TileMatrix}/{TileRow}/{TileCol}.jpeg", tileGrid: tileGrid, layer: "ch.swisstopo.pixelkarte-farbe", requestEncoding: 'REST' })) }); map.addLayer(layer); console.log(map.getView().getProjection().getCode()); }) </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
Pour le moment, c'est le serveur qui fait tourner son moteur cartographique pour créer une représentation image des données géographiques et ceci sur la base de styles prédéfinis. Voyons comment le client peut dire son mot et piloter le style “à distance”.
Le standard WMS offre beaucoup de libertés, parfois au détriment de la performance. Comme il permet de demander ce que l'on veut en termes d'enveloppe géographique (paramètre bbox) et de style parmis un ensemble de styles pré-configurer, il est aussi possible d'envoyer au serveur cartographique des instructions personnalisées de style.
<html> <head> <title>ol3 - Ex3A - use of a custom SLD style</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map; $(document).ready(function(){ map = new ol.Map({ view: new ol.View({ projection: "EPSG:4326" }), target: 'map' }); layer = new ol.layer.Image({ source: new ol.source.ImageWMS({ url: mcWMS, params:{ VERSION: "1.1.1", LAYERS: 'public.world_simple', FORMAT: 'image/png' } }), }); map.addLayer(layer); var extent = map.getView().getProjection().getExtent(); map.getView().fit(extent, map.getSize()); }); </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TODO
SLD: 'http://www.mediamaps.ch/oltuto/sld/pinkWorld.sld.xml'
<?xml version="1.0" encoding="UTF-8"?> <DescribeFeatureType version="1.1.0" service="WFS" xmlns="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"> <TypeName>public.world_simple</TypeName> </DescribeFeatureType>
puis lancer
<?xml version="1.0" encoding="UTF-8"?> <GetFeature version="1.1.0" service="WFS" xmlns="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"> <Query typeName="public.world_simple"> <PropertyName>REGION</PropertyName> </Query> </GetFeature>
... <Rule> <Filter xmlns="http://www.opengis.net/ogc"> <PropertyIsEqualTo> <PropertyName>region</PropertyName> <Literal>NorthAfrica</Literal> </PropertyIsEqualTo> </Filter> <PolygonSymbolizer> ...
... </Rule> <Rule> <ElseFilter/> <PolygonSymbolizer> <Fill> <CssParameter name="fill">#DDDDDD</CssParameter> <CssParameter name="fill-opacity">1.0</CssParameter> </Fill> <Stroke> <CssParameter name="stroke">#000000</CssParameter> <CssParameter name="stroke-width">1</CssParameter> </Stroke> </PolygonSymbolizer> </Rule> </FeatureTypeStyle> ...
<html> <head> <title>ol3 - Ex3B - webmap with your own MapBox basemap</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map; $(document).ready(function() { var token = "pk.eyJ1Ijoib2VydHoiLCJhIjoiT29aUVYyRSJ9.mz-_gaaigdhurQPHZf7fig"; var styleId = "oertz.d708b246"; map = new ol.Map({ layers: [ new ol.layer.Tile({ source: new ol.source.XYZ({ url: 'http://api.tiles.mapbox.com/v4/'+styleId+'/{z}/{x}/{y}.png?access_token=' + token }) }) ], target: 'map', view: new ol.View({ center: ol.proj.transform([6.7, 46.7], 'EPSG:4326', 'EPSG:3857'), zoom: 10 }) }); }) </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"> </div> </body> </html>
TODO
#building { polygon-fill: #c1b0ad; }
#landuse[class='parks'] { polygon-fill: #6db569; }
#poi_label[zoom>=19] { text-name: '[name]'; text-face-name: @sans_bold; text-size: 14; }
#road, #bridge, #tunnel { [class='motorway'],[class='motorway_link'] { line-color: #fc8; line-width: 3px; } }
En utilisant les couches liés aux “thèmes” mapbox.mapbox-terrain-v1 et mapbox.mapbox-streets-v5, on ajoute aux layers de l'exercice 1 les couches hillshade, (?) et contour. On représente les courbes de niveaux de cette dernière comme suit :
#contour[zoom>=14] { line-color: #b7b7b7; line-width: 1; text-name: '[ele]'; text-face-name: @sans; text-fill: #838383; text-size: 12; text-placement: line; [index=5],[index=10] { line-width: 3; } }
Le chargement de la source de géodonnées “dans MapBox” démarre une phase de découpage des données en tuiles vectoriels selon une pyramide de tuiles. Il ne reste donc plus qu'à habiller ces tuiles vectoriels avec un style pour produire les tuiles images qui sont demandées à la volée par les clients cartographiques.
Après initialisation d'un nouveau style par la composition des couches des thèmes mapbox.mapboxstreets-v5 + oertz.0cf75151, on peut construire le style “by night” suivant : style.mss
La composition peut se faire par un assemblage côté serveur. Ci-dessous un assemblage “à la demande”. Notez bien, plus il y a de couches disponibles sur le serveur cartographique, plus il y a de combinaisons.
<html> <head> <title>ol3 - Ex4A - one WMS request for two layers</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map; $(document).ready(function(){ map = new ol.Map({ target: 'map', layers: [ new ol.layer.Image({ source: new ol.source.ImageWMS({ url: mcWMS, params:{ VERSION: "1.1.1", LAYERS: 'public.world_simple,public.cities', FORMAT: 'image/png' } }), }) ] }); // default view is used here, that is with the Mercator EPSG:3857 projection map.getView().setCenter(ol.proj.transform([7, 47],"EPSG:4326","EPSG:3857")) map.getView().setZoom(5); }); </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TODO
Une application de cartographie en ligne se doit de permettre à l'utilisateur de personnaliser sa carte par ses choix pour la couche de référence (baselayer) et les couches à activer en superposition (overlays). Elle doit fournir la capacité de gérer la composition côté client.
<html> <head> <title>ol3 - Ex4B - two WMS overlayed layers</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map; $(document).ready(function () { map = new ol.Map({ target: 'map', layers: [ new ol.layer.Image({ title: 'World simple', source: new ol.source.ImageWMS({ url: mcWMS, params: { VERSION: "1.1.1", LAYERS: 'public.world_simple', FORMAT: 'image/png' } }) }), new ol.layer.Image({ title: 'Cities', source: new ol.source.ImageWMS({ url: mcWMS, params: { VERSION: "1.1.1", LAYERS: 'public.cities', FORMAT: 'image/png' } }) }) ] }); map.getView().setCenter(ol.proj.transform([7, 47], "EPSG:4326", "EPSG:3857")) map.getView().setZoom(5); }); </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TODO
new ol.layer.Image({ title: "Countries", source: new ol.source.ImageWMS({ url: blWMS, params: { VERSION: "1.0.0", LAYERS: "ne_10m_admin_0_countries", FORMAT: "image/png" } }), }), new ol.layer.Image({ title: "Lakes", source: new ol.source.ImageWMS({ url: blWMS, params: { VERSION: "1.0.0", LAYERS: "ne_10m_lakes", FORMAT: "image/png" } }), })
Visualiser le résultat. Qu'est-ce qui est “baselayer”, qu'est-ce qui est “overlays” ?
OL3 n'offre pour l'instant pas nativement de “UI manager” de composition cartographique. Néanmoins l'API offre ce qu'il faut pour concevoir son propre LayerSwitcher.
<html> <head> <title>ol3 - Ex4C - MyLayerSwitcher</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map, lyrs; $(document).ready(function () { map = new ol.Map({ target: 'map', layers: [ new ol.layer.Image({ source: new ol.source.ImageWMS({ url: blWMS, params: { VERSION: "1.0.0", LAYERS: "ne_10m_admin_0_countries", FORMAT: "image/png" } }), }), new ol.layer.Image({ source: new ol.source.ImageWMS({ url: mcWMS, params: { VERSION: "1.1.1", LAYERS: 'public.world_simple', FORMAT: 'image/png' } }) }), new ol.layer.Image({ source: new ol.source.ImageWMS({ url: blWMS, params: { VERSION: "1.0.0", LAYERS: "ne_10m_lakes", FORMAT: "image/png" } }), }), new ol.layer.Image({ source: new ol.source.ImageWMS({ url: mcWMS, params: { VERSION: "1.1.1", LAYERS: 'public.cities', FORMAT: 'image/png' } }) }) ] }); map.getView().setCenter(ol.proj.transform([7, 47], "EPSG:4326", "EPSG:3857")) map.getView().setZoom(5); initMyLayerSwitcher(); }); /*** * initMyLayerSwitcher: a first attempt to manage baselayers and overlayers. * * Remark: in the current state, the main drawback is that it is absolutly * not flexible and adaptative! * * @returns {undefined} */ function initMyLayerSwitcher(){ lyrs = map.getLayers().getArray(); // Set visibility of the baselayer lyrs[0].setVisible(true); lyrs[1].setVisible(false); // Set visibility of the overlays lyrs[2].setVisible(false); lyrs[3].setVisible(false); $('#overlay option').prop('selected', false); // Define the callback when the user does change the baselayer $("#base").change(function (e) { // Reset all baselayers lyrs[0].setVisible(false); lyrs[1].setVisible(false); // Activate the one that is selected (based on index) var idxVisible = $(this).find(":selected").index(); lyrs[idxVisible].setVisible(true); }); // Define the callback when the user does change the overlays $("#overlay").change(function (e) { $(this).find("option").each(function (i, e) { // i + 2 because the 1st and 2nd elements in the table of layers are the baselayers lyrs[i + 2].setVisible(e.selected); }); }); } </script> <style type="text/css"> #map { width: 80%; height: 100%; } #switcher { position: absolute; left: 82%; top: 2%; } </style> </head> <body> <div id="map"></div> <div id="switcher"> <p>Choose baselayer:</p> <select id="base"> <option value="base1">Countries</option> <option value="base2">World simple</option> </select> <p>Choose overlays:</p> <select id="overlay" size="2" multiple> <option value="overlay1">Lakes</option> <option value="overlay2">Cities</option> </select> </div> </body> </html>
TODO
new ol.layer.Tile({ source: new ol.source.OSM() })
opacity: 0.5,
Toutefois il existe des controls développés par la communauté de développeurs gravitant autour du core OL3, parmi lesquels un LayerSwitcher un peu plus malin.
<html> <head> <title>ol3 - Ex4D - A clever LayerSwitcher</title> <script type="text/javascript" src="js/config.js"></script> <link rel="stylesheet" href="lib/layerswitcher/ol3-layerswitcher.css" type="text/css"> <script src="lib/layerswitcher/ol3-layerswitcher.js" type="text/javascript"></script> <script type="text/javascript"> var map, lyrs; $(document).ready(function () { map = new ol.Map({ target: 'map', layers: [ new ol.layer.Image({ title: "Countries", type: "base", source: new ol.source.ImageWMS({ url: blWMS, params: { VERSION: "1.0.0", LAYERS: "ne_10m_admin_0_countries", FORMAT: "image/png" } }), }), new ol.layer.Image({ title: 'World simple', type: "base", source: new ol.source.ImageWMS({ url: mcWMS, params: { VERSION: "1.1.1", LAYERS: 'public.world_simple', FORMAT: 'image/png' } }) }), new ol.layer.Image({ title: "Lakes", source: new ol.source.ImageWMS({ url: blWMS, params: { VERSION: "1.0.0", LAYERS: "ne_10m_lakes", FORMAT: "image/png" } }), }), new ol.layer.Image({ title: 'Cities', source: new ol.source.ImageWMS({ url: mcWMS, params: { VERSION: "1.1.1", LAYERS: 'public.cities', FORMAT: 'image/png' } }) }) ] }); map.getView().setCenter(ol.proj.transform([7, 47], "EPSG:4326", "EPSG:3857")) map.getView().setZoom(5); var layerSwitcher = new ol.control.LayerSwitcher(); map.addControl(layerSwitcher); }); </script> <style type="text/css"> #map { width: 80%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TODO
Jusqu'à présent, les styles CartoCSS devaient être préparés et chargés avec le Studio vers un compte MapBox. Sur le même principe que WMS/SLD, la suite montre une approche plus souple permettant de définir “à la demande” le style à appliquer sur une couche de géodonnées chargées sur un compte CartoDB.
A partir de l'API CartoDB on peut construire une ol.layer.Tile ayant comme source la pyramide de tuiles construite par CartoDB sur la base des données de la couche my4capitals https://ogo.cartodb.com/tables/g4districts98/public.
<html> <head> <title>ol3 - Ex4E - On demand CartoCSS</title> <script type="text/javascript" src="js/config.js"></script> <script src="http://libs.cartocdn.com/cartodb.js/v3/3.11/cartodb.core.js"></script> <script type="text/javascript"> var map; $(document).ready(function () { map = new ol.Map({ view: new ol.View({ center: ol.proj.transform([6.8, 46.9], 'EPSG:4326', 'EPSG:3857'), zoom: 11 }), target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ] }); cartodb.Tiles.getTiles({ type: 'cartodb', user_name: 'ogo', sublayers: [{ sql: 'SELECT * FROM g4districts98', cartocss: "#g4districts98 { line-color: red; line-width: 2;}" }] }, function (tileTemplate) { // create layer with generated tiles URL tilesUrl = tileTemplate.tiles[0] .replace('{s}', 'a') .replace('{z}', '{z}') .replace('{x}', '{x}') .replace('{y}', '{y}'); admLyr = new ol.layer.Tile({ source: new ol.source.XYZ({ url: tilesUrl }) }) map.addLayer(admLyr); }); }); </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TODO
Dans les sections précédentes nous avons inséré des couches cartographiques sous la forme d'images construites par le serveur avec son moteur cartographique. Un serveur cartographique était donc nécessaire. A l'opposé, pour une couche ol.layer.Vector c'est le client qui joue le rôle de moteur cartographique pour créer la visualisation d'entités géographiques (Features en anglais).
Une couche ol.layer.Vector peut être alimentée par une source de données au format ol.source.GeoJSON (voir aussi http://geojson.org). Il existe de nombreux autres formats : ol.source.GPX, ol.source.TopoJSON, ol.source.KML, …)
<html> <head> <title>ol3 - Ex5A - GeoJSON vector overlay</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map; $(document).ready(function(){ map = new ol.Map({ view: new ol.View({ center:[738600, 5840171], zoom: 4 }), target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ] }); var vectorLayer = new ol.layer.Vector({ source: new ol.source.Vector({ url: "data/4capitals.json", format: new ol.format.GeoJSON() }) }); map.addLayer(vectorLayer) }); </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TODO
http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson
en dézoomant un peu le cas échéant.
url: 'http://www.visugpx.com/files/download.php?id=1416844831'
en recentrant la carte par ici :
view: new ol.View({ center:[766225, 5908730], zoom: 10 }),
Pourquoi cela ne fonctionne pas?
L'exemple ci-dessous décrit en détail ce qu'est une source de donnée ol.source.Vector pour une couche ol.layer.Vector en montrant comment la créer et l'alimenter à partir d'un format de source de géodonnées “fait maison”. En résumé, une source ol.source.Vector est composée d'entités géographiques (ol.Feature) chacune composée d'une géométrie (ol.geom) et d'une liste d'attributs.
La source de données est un fichier texte formaté comme suit:
2.3332999999999999 48.866700000000002 Paris,7.4333 46.950000000000003 Bern,12.5 41.883299999999998 Rome,-3.71 40.409999999999997 Madrid
La structure de formatage est simple : c'est une suite de triplets “Longitude Latitude Nom” dont le séparateur interne est l'espace. Le séparateur entre triplets est la virgule. Chaque triplet correspond à une entité géographique. Le code ci-dessous déchiffre cette structure et transforme les triplets en ol.Feature.
<html> <head> <title>ol3 - Ex5B - custom format for vector overlay</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map; $(document).ready(function () { map = new ol.Map({ view: new ol.View({ center: ol.proj.transform([2, 48], 'EPSG:4326', 'EPSG:3857'), zoom: 5 }), target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }), ] }); $.get("data/4capitals.txt", createCustomOverlay); }); function createCustomOverlay(response) { // Create/add a new empty vector layer vectors = new ol.layer.Vector({ source: new ol.source.Vector() }); map.addLayer(vectors); // Declare an empty array ready to receive some features features = new Array(); // Lets's decode the "home made" format tabCapitals = response.split(","); for (i = 0; i < tabCapitals.length; i++) { tabCapital = tabCapitals[i].split(" "); // Create a feature built of a geometry (a Point in our case) and a property (name) var feature = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.transform([parseFloat(tabCapital[0]), parseFloat(tabCapital[1])], 'EPSG:4326', 'EPSG:3857')), name: tabCapital[2] }); // Add the feature created to the array of features features.push(feature); } // Add the set of features to the ol.source.Vector which is in relation to the ol.layer.Vector vectors.getSource().addFeatures(features); } </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TODO
2.3332999999999999 48.866700000000002 Paris France,7.4333 46.950000000000003 Bern Suisse,12.5 41.883299999999998 Rome Italy,-3.71 40.409999999999997 Madrid Spain
OpenLayers met à disposition un ensemble de classes ol.style permettant d'appliquer des styles aux features (entités géographiques) d'une couche ol.vector.
Openlayers applique un style par défaut aux features, mais il est possible de redéfinir ce style (forme, couleur, etc.).
<html> <head> <title>ol3 - Ex6A - One feature, one style</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map; $(document).ready(function () { map = new ol.Map({ view: new ol.View({ center: ol.proj.transform([2, 48], 'EPSG:4326', 'EPSG:3857'), zoom: 5 }), target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ] }); vectLayer = new ol.layer.Vector({ source: new ol.source.Vector() }); map.addLayer(vectLayer); // Prepare a stroke style var redStroke = new ol.style.Stroke({ color: '#ff0000', width: 3 }); // Create a styling symbolizer var style = new ol.style.Style({ image: new ol.style.RegularShape({ points: 4, stroke: redStroke, radius: 10, radius1: 0, radius2: 0 }) }); // Create and style a feature var feature = new ol.Feature({ geometry: new ol.geom.Point([738600, 5840171]) }); feature.setStyle(style); // Add it to the vector layer vectLayer.getSource().addFeature(feature); }); </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TODO
var style = new ol.style.Style({ image: new ol.style.Icon({ src:"http://www.cretasolaris.gr/gfx/marker.png", size:[36,33], opacity:1 }) })
geometry: new ol.geom.LineString([[738600, 5840171],[1938600, 6840171]])
et adapter un style adéquat utilisant l'option lineDash de ol.style.Stroke.
L'approche la plus répandue consiste à associer un style à une couche.
<html> <head> <title>ol3 - Ex6B - One layer, one style</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map; $(document).ready(function () { var fill = new ol.style.Fill({ color: '#acc000' }); var stroke = new ol.style.Stroke({ color: '#ff0000', width: 3 }); var style = new ol.style.Style({ image: new ol.style.Icon({ src: "http://www.cretasolaris.gr/gfx/marker.png", size: [36, 33], opacity: 1 }) }) map = new ol.Map({ view: new ol.View({ center: ol.proj.transform([2, 48], 'EPSG:4326', 'EPSG:3857'), zoom: 5 }), target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ] }) vecLayer = new ol.layer.Vector({ source: new ol.source.Vector({}), style: style }) var feature1 = new ol.Feature({ geometry: new ol.geom.Point([738600, 5840171]), name: "The precious is here!", author: "Gollum" }); map.addLayer(vecLayer); vecLayer.getSource().addFeature(feature1); }); </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TODO
var feature2 = new ol.Feature({ geometry: new ol.geom.Point([1938600, 6840171]), name: "The hobbits are far away...", author: "Gandalf" }); vecLayer.getSource().addFeature(feature2)
var feature1 = new ol.Feature({ geometry: new ol.geom.LineString([[738600, 6840171],[1938600, 6840171]]) }); var feature2 = new ol.Feature({ geometry: new ol.geom.LineString([[738600, 5840171],[1938600, 7840171]]) });
Adapter la représentation des lignes avec un style highway comme illustré ci-après :
Plutôt que d'appliquer un style identique à toutes les entités d'une couche, il est possible d'appliquer un style différents basé sur les propriétés de chacune des entités. Pour cela, Openlayers propose de remplacer l'objet ol.style.Style par une fonction ol.style.StyleFunction(). Dans l'exemple ci-dessous on affiche une étiquette différente en fonction de la propriété “name” de chaque entité.
<html> <head> <title>ol3 - Ex6C - Styling function</title> <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript"> var map; $(document).ready(function () { var icon = new ol.style.Icon({ src: "http://www.cretasolaris.gr/gfx/marker.png", size: [36, 33], opacity: 1 }); function createLordStyle(feature, resolution) { var style = new ol.style.Style({ image: icon, text: new ol.style.Text({ text: feature.get('name'), offsetY: 25, font: '15px Calibri,sans-serif', fill: new ol.style.Fill({ color: "#000" }) }) }) return [style]; }; map = new ol.Map({ view: new ol.View({ center: ol.proj.transform([2, 48], 'EPSG:4326', 'EPSG:3857'), zoom: 5 }), target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ] }); vecLayer = new ol.layer.Vector({ source: new ol.source.Vector(), style: createLordStyle }); var feature = new ol.Feature({ geometry: new ol.geom.Point([738600, 5840171]), name: "The precious is here!", author: "Gollum" }); map.addLayer(vecLayer); var feature2 = new ol.Feature({ geometry: new ol.geom.Point([1938600, 6840171]), name: "The hobbits are far away...", author: "Gandalf" }); vecLayer.getSource().addFeatures([feature, feature2]); }); </script> <style type="text/css"> #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TODO