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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
| import Map from 'ol/Map.js'; import OSMXML from 'ol/format/OSMXML.js'; import VectorSource from 'ol/source/Vector.js'; import View from 'ol/View.js'; import XYZ from 'ol/source/XYZ.js'; import {Circle as CircleStyle, Fill, Stroke, Style} from 'ol/style.js'; import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer.js'; import {bbox as bboxStrategy} from 'ol/loadingstrategy.js'; import {transformExtent} from 'ol/proj.js';
let map = null;
const styles = { 'amenity': { 'parking': new Style({ stroke: new Stroke({ color: 'rgba(170, 170, 170, 1.0)', width: 1, }), fill: new Fill({ color: 'rgba(170, 170, 170, 0.3)', }), }), }, 'building': { '.*': new Style({ zIndex: 100, stroke: new Stroke({ color: 'rgba(246, 99, 79, 1.0)', width: 1, }), fill: new Fill({ color: 'rgba(246, 99, 79, 0.3)', }), }), }, 'highway': { 'service': new Style({ stroke: new Stroke({ color: 'rgba(255, 255, 255, 1.0)', width: 2, }), }), '.*': new Style({ stroke: new Stroke({ color: 'rgba(255, 255, 255, 1.0)', width: 3, }), }), }, 'landuse': { 'forest|grass|allotments': new Style({ stroke: new Stroke({ color: 'rgba(140, 208, 95, 1.0)', width: 1, }), fill: new Fill({ color: 'rgba(140, 208, 95, 0.3)', }), }), }, 'natural': { 'tree': new Style({ image: new CircleStyle({ radius: 2, fill: new Fill({ color: 'rgba(140, 208, 95, 1.0)', }), stroke: null, }), }), }, };
const vectorSource = new VectorSource({ format: new OSMXML(), loader: function (extent, resolution, projection, success, failure) { const epsg4326Extent = transformExtent(extent, projection, 'EPSG:4326'); const client = new XMLHttpRequest(); client.open('POST', 'https://overpass-api.de/api/interpreter'); client.addEventListener('load', function () { const features = new OSMXML().readFeatures(client.responseText, { featureProjection: map.getView().getProjection(), }); vectorSource.addFeatures(features); success(features); }); client.addEventListener('error', failure); const query = '(node(' + epsg4326Extent[1] + ',' + Math.max(epsg4326Extent[0], -180) + ',' + epsg4326Extent[3] + ',' + Math.min(epsg4326Extent[2], 180) + ');rel(bn)->.foo;way(bn);node(w)->.foo;rel(bw););out meta;'; client.send(query); }, strategy: bboxStrategy, });
const vector = new VectorLayer({ source: vectorSource, style: function (feature) { for (const key in styles) { const value = feature.get(key); if (value !== undefined) { for (const regexp in styles[key]) { if (new RegExp(regexp).test(value)) { return styles[key][regexp]; } } } } return null; }, });
const key = 'Get your own API key at https://www.maptiler.com/cloud/'; const attributions = '<a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> ' + '<a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>';
const raster = new TileLayer({ source: new XYZ({ attributions: attributions, url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key, maxZoom: 20, }), });
map = new Map({ layers: [raster, vector], target: document.getElementById('map'), view: new View({ center: [739218, 5906096], maxZoom: 19, zoom: 17, }), });
|