Rendering raster tiles with WebGL
This commit is contained in:
committed by
Andreas Hocevar
parent
2dd212cdac
commit
af80477c1d
11
examples/cog-math.html
Normal file
11
examples/cog-math.html
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: NDVI from a Sentinel 2 COG
|
||||
shortdesc: Calculating NDVI and applying a custom color map.
|
||||
docs: >
|
||||
The GeoTIFF layer in this example draws from two Sentinel 2 sources: a red band and a near infrared band.
|
||||
The layer style includes a `color` expression that calculates the Normalized Difference Vegetation Index (NDVI)
|
||||
from values in the two bands. The `interpolate` expression is used to map NDVI values to colors.
|
||||
tags: "cog, ndvi"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
105
examples/cog-math.js
Normal file
105
examples/cog-math.js
Normal file
@@ -0,0 +1,105 @@
|
||||
import GeoTIFF from '../src/ol/source/GeoTIFF.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import Projection from '../src/ol/proj/Projection.js';
|
||||
import TileLayer from '../src/ol/layer/WebGLTile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import proj4 from 'proj4';
|
||||
import {getCenter} from '../src/ol/extent.js';
|
||||
import {register} from '../src/ol/proj/proj4.js';
|
||||
|
||||
proj4.defs('EPSG:32636', '+proj=utm +zone=36 +datum=WGS84 +units=m +no_defs');
|
||||
register(proj4);
|
||||
|
||||
const projection = new Projection({
|
||||
code: 'EPSG:32636',
|
||||
extent: [166021.44, 0.0, 534994.66, 9329005.18],
|
||||
});
|
||||
|
||||
// metadata from https://s3.us-west-2.amazonaws.com/sentinel-cogs/sentinel-s2-l2a-cogs/2020/S2A_36QWD_20200701_0_L2A/S2A_36QWD_20200701_0_L2A.json
|
||||
const sourceExtent = [499980, 1790220, 609780, 1900020];
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
style: {
|
||||
color: [
|
||||
'interpolate',
|
||||
['linear'],
|
||||
// calculate NDVI, bands come from the sources below
|
||||
[
|
||||
'/',
|
||||
['-', ['band', 2], ['band', 1]],
|
||||
['+', ['band', 2], ['band', 1]],
|
||||
],
|
||||
// color ramp for NDVI values, ranging from -1 to 1
|
||||
-0.2,
|
||||
[191, 191, 191],
|
||||
-0.1,
|
||||
[219, 219, 219],
|
||||
0,
|
||||
[255, 255, 224],
|
||||
0.025,
|
||||
[255, 250, 204],
|
||||
0.05,
|
||||
[237, 232, 181],
|
||||
0.075,
|
||||
[222, 217, 156],
|
||||
0.1,
|
||||
[204, 199, 130],
|
||||
0.125,
|
||||
[189, 184, 107],
|
||||
0.15,
|
||||
[176, 194, 97],
|
||||
0.175,
|
||||
[163, 204, 89],
|
||||
0.2,
|
||||
[145, 191, 82],
|
||||
0.25,
|
||||
[128, 179, 71],
|
||||
0.3,
|
||||
[112, 163, 64],
|
||||
0.35,
|
||||
[97, 150, 54],
|
||||
0.4,
|
||||
[79, 138, 46],
|
||||
0.45,
|
||||
[64, 125, 36],
|
||||
0.5,
|
||||
[48, 110, 28],
|
||||
0.55,
|
||||
[33, 97, 18],
|
||||
0.6,
|
||||
[15, 84, 10],
|
||||
0.65,
|
||||
[0, 69, 0],
|
||||
],
|
||||
},
|
||||
source: new GeoTIFF({
|
||||
sources: [
|
||||
{
|
||||
// visible red, band 1 in the style expression above
|
||||
url:
|
||||
'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/2020/S2A_36QWD_20200701_0_L2A/B04.tif',
|
||||
nodata: 0,
|
||||
max: 10000,
|
||||
},
|
||||
{
|
||||
// near infrared, band 2 in the style expression above
|
||||
url:
|
||||
'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/2020/S2A_36QWD_20200701_0_L2A/B08.tif',
|
||||
nodata: 0,
|
||||
max: 10000,
|
||||
},
|
||||
],
|
||||
}),
|
||||
extent: sourceExtent,
|
||||
}),
|
||||
],
|
||||
view: new View({
|
||||
center: getCenter(sourceExtent),
|
||||
extent: sourceExtent,
|
||||
zoom: 9,
|
||||
projection: projection,
|
||||
}),
|
||||
});
|
||||
12
examples/cog-overviews.html
Normal file
12
examples/cog-overviews.html
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: GeoTIFF with Overviews
|
||||
shortdesc: Rendering a GeoTIFF with external overviews as a layer.
|
||||
docs: >
|
||||
In some cases, a GeoTIFF may have external overviews. This example uses the
|
||||
`overviews` property to provide URLs for the external overviews. The example
|
||||
composes a false color composite using shortwave infrared (B6), near infrared (B5),
|
||||
and visible green (B3) bands from a Landsat 8 image.
|
||||
tags: "cog"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
68
examples/cog-overviews.js
Normal file
68
examples/cog-overviews.js
Normal file
@@ -0,0 +1,68 @@
|
||||
import GeoTIFF from '../src/ol/source/GeoTIFF.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import Projection from '../src/ol/proj/Projection.js';
|
||||
import TileLayer from '../src/ol/layer/WebGLTile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import proj4 from 'proj4';
|
||||
import {getCenter} from '../src/ol/extent.js';
|
||||
import {register} from '../src/ol/proj/proj4.js';
|
||||
|
||||
proj4.defs('EPSG:32645', '+proj=utm +zone=45 +datum=WGS84 +units=m +no_defs');
|
||||
register(proj4);
|
||||
|
||||
const projection = new Projection({
|
||||
code: 'EPSG:32645',
|
||||
extent: [166021.44, 0.0, 534994.66, 9329005.18],
|
||||
});
|
||||
|
||||
const sourceExtent = [382200, 2279370, 610530, 2512500];
|
||||
|
||||
const base =
|
||||
'https://landsat-pds.s3.amazonaws.com/c1/L8/139/045/LC08_L1TP_139045_20170304_20170316_01_T1/LC08_L1TP_139045_20170304_20170316_01_T1';
|
||||
|
||||
// scale values in this range to 0 - 1
|
||||
const min = 10000;
|
||||
const max = 15000;
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
extent: sourceExtent,
|
||||
style: {
|
||||
saturation: -0.3,
|
||||
},
|
||||
source: new GeoTIFF({
|
||||
sources: [
|
||||
{
|
||||
url: `${base}_B6.TIF`,
|
||||
overviews: [`${base}_B6.TIF.ovr`],
|
||||
min: min,
|
||||
max: max,
|
||||
nodata: 0,
|
||||
},
|
||||
{
|
||||
url: `${base}_B5.TIF`,
|
||||
overviews: [`${base}_B5.TIF.ovr`],
|
||||
min: min,
|
||||
max: max,
|
||||
nodata: 0,
|
||||
},
|
||||
{
|
||||
url: `${base}_B3.TIF`,
|
||||
overviews: [`${base}_B3.TIF.ovr`],
|
||||
min: min,
|
||||
max: max,
|
||||
nodata: 0,
|
||||
},
|
||||
],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
view: new View({
|
||||
center: getCenter(sourceExtent),
|
||||
extent: sourceExtent,
|
||||
zoom: 8,
|
||||
projection: projection,
|
||||
}),
|
||||
});
|
||||
11
examples/cog.html
Normal file
11
examples/cog.html
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Cloud Optimized GeoTIFF (COG)
|
||||
shortdesc: Rendering a COG as a tiled layer.
|
||||
docs: >
|
||||
Tiled data from a Cloud Optimized GeoTIFF (COG) can be rendered as a layer. In this
|
||||
example, a single 3-band GeoTIFF is used to render RGB data. The `nodata` property is
|
||||
used to avoid rendering pixels where all three bands are 0.
|
||||
tags: "cog"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
43
examples/cog.js
Normal file
43
examples/cog.js
Normal file
@@ -0,0 +1,43 @@
|
||||
import GeoTIFF from '../src/ol/source/GeoTIFF.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import Projection from '../src/ol/proj/Projection.js';
|
||||
import TileLayer from '../src/ol/layer/WebGLTile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import proj4 from 'proj4';
|
||||
import {getCenter} from '../src/ol/extent.js';
|
||||
import {register} from '../src/ol/proj/proj4.js';
|
||||
|
||||
proj4.defs('EPSG:32636', '+proj=utm +zone=36 +datum=WGS84 +units=m +no_defs');
|
||||
register(proj4);
|
||||
|
||||
const projection = new Projection({
|
||||
code: 'EPSG:32636',
|
||||
extent: [166021.44, 0.0, 534994.66, 9329005.18],
|
||||
});
|
||||
|
||||
// metadata from https://s3.us-west-2.amazonaws.com/sentinel-cogs/sentinel-s2-l2a-cogs/2020/S2A_36QWD_20200701_0_L2A/S2A_36QWD_20200701_0_L2A.json
|
||||
const sourceExtent = [499980, 1790220, 609780, 1900020];
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new GeoTIFF({
|
||||
sources: [
|
||||
{
|
||||
url:
|
||||
'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/2020/S2A_36QWD_20200701_0_L2A/TCI.tif',
|
||||
nodata: 0,
|
||||
},
|
||||
],
|
||||
}),
|
||||
extent: sourceExtent,
|
||||
}),
|
||||
],
|
||||
view: new View({
|
||||
center: getCenter(sourceExtent),
|
||||
extent: sourceExtent,
|
||||
zoom: 9,
|
||||
projection: projection,
|
||||
}),
|
||||
});
|
||||
9
examples/data-tiles.html
Normal file
9
examples/data-tiles.html
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Data Tiles
|
||||
shortdesc: Generating tile data from scratch.
|
||||
docs: >
|
||||
This example generates RGBA tile data from scratch.
|
||||
tags: "data tiles"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
43
examples/data-tiles.js
Normal file
43
examples/data-tiles.js
Normal file
@@ -0,0 +1,43 @@
|
||||
import DataTile from '../src/ol/source/DataTile.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import TileLayer from '../src/ol/layer/WebGLTile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
|
||||
const size = 256;
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = size;
|
||||
canvas.height = size;
|
||||
|
||||
const context = canvas.getContext('2d');
|
||||
context.strokeStyle = 'white';
|
||||
context.textAlign = 'center';
|
||||
context.font = '24px sans-serif';
|
||||
const lineHeight = 30;
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new DataTile({
|
||||
loader: function (z, x, y) {
|
||||
const half = size / 2;
|
||||
context.clearRect(0, 0, size, size);
|
||||
context.fillStyle = 'rgba(100, 100, 100, 0.5)';
|
||||
context.fillRect(0, 0, size, size);
|
||||
context.fillStyle = 'black';
|
||||
context.fillText(`z: ${z}`, half, half - lineHeight);
|
||||
context.fillText(`x: ${x}`, half, half);
|
||||
context.fillText(`y: ${y}`, half, half + lineHeight);
|
||||
context.strokeRect(0, 0, size, size);
|
||||
const data = context.getImageData(0, 0, size, size).data;
|
||||
return Promise.resolve(data);
|
||||
},
|
||||
}),
|
||||
}),
|
||||
],
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 0,
|
||||
}),
|
||||
});
|
||||
13
examples/webgl-sea-level.css
Normal file
13
examples/webgl-sea-level.css
Normal file
@@ -0,0 +1,13 @@
|
||||
#level {
|
||||
display: inline-block;
|
||||
width: 150px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
a.location {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#map {
|
||||
background: #8bd4ff;
|
||||
}
|
||||
37
examples/webgl-sea-level.html
Normal file
37
examples/webgl-sea-level.html
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Sea Level (with WebGL)
|
||||
shortdesc: Render sea level at different elevations
|
||||
docs: >
|
||||
<p>
|
||||
The <code>style</code> property of a WebGL tile layer accepts a <code>color</code> expression that
|
||||
can be used to modify pixel values before rendering. Here, RGB tiles representing elevation
|
||||
data are loaded and rendered so that values at or below sea level are blue, and values
|
||||
above sea level are transparent. The <code>color</code> expression operates on normalized pixel
|
||||
values ranging from 0 to 1. The <code>band</code> operator is used to select normalized values
|
||||
from a single band.
|
||||
</p><p>
|
||||
After converting the normalized RGB values to elevation, the <code>interpolate</code> expression
|
||||
is used to pick colors to apply at a given elevation. Instead of using constant
|
||||
numeric values as the stops in the colors array, the <code>var</code> operator allows you to
|
||||
use a value that can be modified by your application. When the user drags the
|
||||
sea level slider, the <code>layer.updateStyleVariables()</code> function is called to update
|
||||
the <code>level</code> style variable with the value from the slider.
|
||||
</p>
|
||||
tags: "webgl, math, flood"
|
||||
cloak:
|
||||
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
|
||||
value: Get your own API key at https://www.maptiler.com/cloud/
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<label>
|
||||
Sea level
|
||||
<input id="level" type="range" min="0" max="100" value="1"/>
|
||||
+<span id="output"></span> m
|
||||
</label>
|
||||
<br>
|
||||
Go to
|
||||
<a class="location" data-center="-122.3267,37.8377" data-zoom="11">San Francisco</a>,
|
||||
<a class="location" data-center="-73.9338,40.6861" data-zoom="11">New York</a>,
|
||||
<a class="location" data-center="72.9481,18.9929" data-zoom="11">Mumbai</a>, or
|
||||
<a class="location" data-center="120.831,31.160" data-zoom="9">Shanghai</a>
|
||||
90
examples/webgl-sea-level.js
Normal file
90
examples/webgl-sea-level.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import TileLayer from '../src/ol/layer/WebGLTile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import XYZ from '../src/ol/source/XYZ.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
|
||||
const key = 'get_your_own_D6rA4zTHduk6KOKTXzGB';
|
||||
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 elevation = new TileLayer({
|
||||
opacity: 0.6,
|
||||
source: new XYZ({
|
||||
url:
|
||||
'https://api.maptiler.com/tiles/terrain-rgb/{z}/{x}/{y}.png?key=' + key,
|
||||
maxZoom: 10,
|
||||
tileSize: 512,
|
||||
crossOrigin: 'anonymous',
|
||||
}),
|
||||
style: {
|
||||
variables: {
|
||||
level: 0,
|
||||
},
|
||||
color: [
|
||||
'interpolate',
|
||||
['linear'],
|
||||
// band math operates on normalized values from 0-1
|
||||
// so we scale by 255 to align with the elevation formula
|
||||
// from https://cloud.maptiler.com/tiles/terrain-rgb/
|
||||
[
|
||||
'+',
|
||||
-10000,
|
||||
[
|
||||
'*',
|
||||
0.1 * 255,
|
||||
[
|
||||
'+',
|
||||
['*', 256 * 256, ['band', 1]],
|
||||
['+', ['*', 256, ['band', 2]], ['band', 3]],
|
||||
],
|
||||
],
|
||||
],
|
||||
// use the `level` style variable as a stop in the color ramp
|
||||
['var', 'level'],
|
||||
[139, 212, 255, 1],
|
||||
['+', 0.01, ['var', 'level']],
|
||||
[139, 212, 255, 0],
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new XYZ({
|
||||
url: 'https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=' + key,
|
||||
attributions: attributions,
|
||||
crossOrigin: 'anonymous',
|
||||
tileSize: 512,
|
||||
}),
|
||||
}),
|
||||
elevation,
|
||||
],
|
||||
view: new View({
|
||||
center: fromLonLat([-122.3267, 37.8377]),
|
||||
zoom: 11,
|
||||
}),
|
||||
});
|
||||
|
||||
const control = document.getElementById('level');
|
||||
const output = document.getElementById('output');
|
||||
control.addEventListener('input', function () {
|
||||
output.innerText = control.value;
|
||||
elevation.updateStyleVariables({level: parseFloat(control.value)});
|
||||
});
|
||||
output.innerText = control.value;
|
||||
|
||||
const locations = document.getElementsByClassName('location');
|
||||
for (let i = 0, ii = locations.length; i < ii; ++i) {
|
||||
locations[i].addEventListener('click', relocate);
|
||||
}
|
||||
|
||||
function relocate(event) {
|
||||
const data = event.target.dataset;
|
||||
const view = map.getView();
|
||||
view.setCenter(fromLonLat(data.center.split(',').map(Number)));
|
||||
view.setZoom(Number(data.zoom));
|
||||
}
|
||||
4
examples/webgl-tile-style.css
Normal file
4
examples/webgl-tile-style.css
Normal file
@@ -0,0 +1,4 @@
|
||||
#controls {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
31
examples/webgl-tile-style.html
Normal file
31
examples/webgl-tile-style.html
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: WebGL Tile Layer Styles
|
||||
shortdesc: Styling raster tiles with WebGL.
|
||||
docs: >
|
||||
The `style` property of a WebGL tile layer can be used to adjust properties like
|
||||
`exposure`, `contrast`, and `saturation`. Typically those values would be set to
|
||||
numeric constants to apply a filter to imagery. In this example, the style properties
|
||||
are set to variables that can be updated based on application state. Adjusting the
|
||||
sliders results in a call to `layer.updateStyleVariables()` to use new values for the
|
||||
associated style properties.
|
||||
tags: "webgl, style"
|
||||
cloak:
|
||||
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
|
||||
value: Get your own API key at https://www.maptiler.com/cloud/
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<div id="controls">
|
||||
<label>
|
||||
<input id="exposure" type="range" min="-0.5" max="0.5" step="0.01">
|
||||
<br>exposure <span id="exposure-value"></span>
|
||||
</label>
|
||||
<label>
|
||||
<input id="contrast" type="range" min="-0.5" max="0.5" step="0.01">
|
||||
<br>contrast <span id="contrast-value"></span>
|
||||
</label>
|
||||
<label>
|
||||
<input id="saturation" type="range" min="-0.5" max="0.5" step="0.01">
|
||||
<br>saturation <span id="saturation-value"></span>
|
||||
</label>
|
||||
</div>
|
||||
55
examples/webgl-tile-style.js
Normal file
55
examples/webgl-tile-style.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import TileLayer from '../src/ol/layer/WebGLTile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import XYZ from '../src/ol/source/XYZ.js';
|
||||
|
||||
const key = 'get_your_own_D6rA4zTHduk6KOKTXzGB';
|
||||
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 variables = {
|
||||
exposure: 0,
|
||||
contrast: 0,
|
||||
saturation: 0,
|
||||
};
|
||||
|
||||
const layer = new TileLayer({
|
||||
style: {
|
||||
exposure: ['var', 'exposure'],
|
||||
contrast: ['var', 'contrast'],
|
||||
saturation: ['var', 'saturation'],
|
||||
variables: variables,
|
||||
},
|
||||
source: new XYZ({
|
||||
crossOrigin: 'anonymous', // TODO: determine if we can avoid this
|
||||
attributions: attributions,
|
||||
url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key,
|
||||
maxZoom: 20,
|
||||
}),
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
layers: [layer],
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 0,
|
||||
}),
|
||||
});
|
||||
|
||||
for (const name in variables) {
|
||||
const element = document.getElementById(name);
|
||||
const value = variables[name];
|
||||
element.value = value.toString();
|
||||
document.getElementById(`${name}-value`).innerText = `(${value})`;
|
||||
|
||||
element.addEventListener('input', function (event) {
|
||||
const value = parseFloat(event.target.value);
|
||||
document.getElementById(`${name}-value`).innerText = `(${value})`;
|
||||
|
||||
const updates = {};
|
||||
updates[name] = value;
|
||||
layer.updateStyleVariables(updates);
|
||||
});
|
||||
}
|
||||
9
examples/webgl-tiles.html
Normal file
9
examples/webgl-tiles.html
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: WebGL Tiles
|
||||
shortdesc: Rendering raster data with WebGL.
|
||||
docs: >
|
||||
This example uses WebGL to raster tiles on a map.
|
||||
tags: "webgl, osm"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
17
examples/webgl-tiles.js
Normal file
17
examples/webgl-tiles.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import TileLayer from '../src/ol/layer/WebGLTile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM(),
|
||||
}),
|
||||
],
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 0,
|
||||
}),
|
||||
});
|
||||
@@ -101,6 +101,8 @@ export default {
|
||||
resolve: {
|
||||
fallback: {
|
||||
fs: false,
|
||||
http: false,
|
||||
https: false,
|
||||
},
|
||||
alias: {
|
||||
// allow imports from 'ol/module' instead of specifiying the source path
|
||||
|
||||
Reference in New Issue
Block a user