Compare commits

...

62 Commits

Author SHA1 Message Date
ahocevar
5891aaadf9 Update package version to 6.0.0-beta.6 2019-04-17 18:24:29 -07:00
Andreas Hocevar
3ba7ecc602 Merge pull request #9442 from ahocevar/raster-no-transition
Disable opacity transition for raster source sources
2019-04-17 18:21:38 -07:00
ahocevar
887d8e8a90 Disable opacity transition for raster source sources 2019-04-17 17:38:50 -07:00
Andreas Hocevar
251fc79484 Merge pull request #9441 from ahocevar/view-center-no-round
Do not round view center to pixels
2019-04-17 16:30:00 -07:00
ahocevar
752b69680e Do not round view center to pixels 2019-04-17 15:52:58 -07:00
Frédéric Junod
84a82ea5b2 Merge pull request #9435 from fredj/api_default
Set the default values after the property name
2019-04-17 08:29:28 +02:00
Frederic Junod
08dd5f58a2 Set the default values after the property name 2019-04-15 16:44:06 +02:00
Frédéric Junod
04963c83d6 Merge pull request #9433 from fredj/cleanup
Remove unused private variables, remove trailing whitespace
2019-04-15 13:36:54 +02:00
Frederic Junod
711dacf4b7 Remove unused private variables, remove trailing whitespaces 2019-04-15 11:31:18 +02:00
Frédéric Junod
6fbd196132 Merge pull request #9416 from fredj/circle_rotate
Implement rotate and translate functions for circle geometry
2019-04-15 08:22:29 +02:00
Andreas Hocevar
5969ac31ea Merge pull request #9432 from openlayers/greenkeeper/handlebars-4.1.2
Update handlebars to the latest version 🚀
2019-04-13 22:23:22 +02:00
greenkeeper[bot]
21c51ff784 chore(package): update handlebars to version 4.1.2 2019-04-13 14:21:50 +00:00
Tim Schaub
3d10e92218 Merge pull request #9431 from openlayers/greenkeeper/webpack-4.30.0
Update webpack to the latest version 🚀
2019-04-13 06:32:19 -06:00
greenkeeper[bot]
84371fe4be chore(package): update webpack to version 4.30.0 2019-04-12 20:36:52 +00:00
Frédéric Junod
1995164219 Merge pull request #9429 from fredj/update_dev_deps
Update all devDependencies
2019-04-12 12:42:10 +02:00
greenkeeper[bot]
4f128a1ec0 chore(package): update ol-mapbox-style to version 4.3.1 2019-04-12 10:59:30 +02:00
greenkeeper[bot]
f11744da56 chore(package): update webpack-dev-server to version 3.3.1 2019-04-12 10:25:32 +02:00
greenkeeper[bot]
08434ed3d5 chore(package): update webpack-dev-middleware to version 3.6.2 2019-04-12 10:24:32 +02:00
greenkeeper[bot]
2c76d7531b chore(package): update globby to version 9.2.0 2019-04-12 10:24:17 +02:00
greenkeeper[bot]
bbec7d76d4 chore(package): update eslint to version 5.16.0 2019-04-12 10:24:03 +02:00
greenkeeper[bot]
255c4b34ba chore(package): update sinon to version 7.3.1 2019-04-12 10:23:46 +02:00
greenkeeper[bot]
fd220f9cce chore(package): update copy-webpack-plugin to version 5.0.2 2019-04-12 10:23:19 +02:00
greenkeeper[bot]
34d68aadbd chore(package): update @types/geojson to version 7946.0.7 2019-04-12 10:22:37 +02:00
greenkeeper[bot]
3bc822e8ef chore(package): update @openlayers/eslint-plugin to version 4.0.0-beta.2 2019-04-12 10:22:11 +02:00
Frédéric Junod
7340e865a3 Merge pull request #9427 from openlayers/greenkeeper/mocha-6.1.3
Update mocha to the latest version 🚀
2019-04-12 08:41:43 +02:00
Frédéric Junod
5b231fe990 Merge pull request #9425 from fredj/rm_unused_webgl
Remove unused ol/render/webgl module
2019-04-12 08:41:24 +02:00
greenkeeper[bot]
9c55256de2 chore(package): update mocha to version 6.1.3 2019-04-12 00:32:49 +00:00
Frederic Junod
491020f027 Remove unused ol/render/webgl module 2019-04-11 16:37:50 +02:00
Frederic Junod
2989c84248 Implement translate function for circle geometry 2019-04-11 16:12:41 +02:00
Andreas Hocevar
db1515a9f3 Merge pull request #9420 from openlayers/greenkeeper/jquery-3.4.0
Update jquery to the latest version 🚀
2019-04-11 09:06:34 +02:00
greenkeeper[bot]
a774b1a278 chore(package): update jquery to version 3.4.0 2019-04-10 19:55:54 +00:00
Andreas Hocevar
81865f70e4 Merge pull request #9418 from ahocevar/reexport-geometrycollection
Re-export GeometryCollection in ol/geom
2019-04-10 10:30:33 +02:00
Frédéric Junod
c6db2d07bb Use .js extension for import
Co-Authored-By: ahocevar <andreas.hocevar@gmail.com>
2019-04-10 09:09:50 +02:00
ahocevar
91215b303e Re-export GeometryCollection in ol/geom 2019-04-09 20:08:11 +02:00
Frederic Junod
319a905ec0 Implement rotate function for circle geometry 2019-04-09 16:58:44 +02:00
Frédéric Junod
9883b7d3d9 Merge pull request #9411 from fredj/raster_state_test
Fix tile state condition in raster layer test
2019-04-09 08:27:43 +02:00
Frédéric Junod
07e31840eb Merge pull request #9410 from fredj/MouseWheelZoom_max_zoom
Add new maxDelta property to MouseWheelZoom constructor
2019-04-09 08:27:27 +02:00
Andreas Hocevar
03483b5439 Merge pull request #9412 from openlayers/greenkeeper/mocha-6.1.2
Update mocha to the latest version 🚀
2019-04-08 21:36:22 +02:00
greenkeeper[bot]
9a42ab73d8 chore(package): update mocha to version 6.1.2 2019-04-08 19:02:57 +00:00
Frederic Junod
746f92d597 Fix tile state condition in raster layer test
The state was duplicated from the beginning, see 3ddb8712a3
2019-04-08 17:04:37 +02:00
Frederic Junod
238fbca650 Add new maxDelta property to MouseWheelZoom constructor 2019-04-08 15:02:21 +02:00
Frédéric Junod
3875147812 Merge pull request #9409 from fredj/rm_opt_this
Remove more opt_this parameters
2019-04-08 14:37:59 +02:00
Frederic Junod
be065cdacc Update upgrade-notes 2019-04-08 13:46:54 +02:00
Frederic Junod
187f58c1c3 Remove opt_this param in ol/extent 2019-04-08 13:46:54 +02:00
Frederic Junod
c20bdedcac Remove opt_this param in ol/structs/LRUCache 2019-04-08 13:46:54 +02:00
Frederic Junod
617dd9f031 Remove opt_this param in ol/structs/RBush 2019-04-08 13:46:54 +02:00
Frédéric Junod
077afac90a Merge pull request #9408 from openlayers/greenkeeper/mocha-6.1.1
chore(package): update mocha to version 6.1.1
2019-04-08 10:26:54 +02:00
Frédéric Junod
f091d96b6c Merge pull request #9406 from openlayers/greenkeeper/clean-css-cli-4.3.0
Update clean-css-cli to the latest version 🚀
2019-04-08 08:48:03 +02:00
greenkeeper[bot]
a30aa78726 chore(package): update mocha to version 6.1.1
Closes #9407
2019-04-07 23:07:05 +00:00
greenkeeper[bot]
66f49559ee chore(package): update clean-css-cli to version 4.3.0 2019-04-06 09:49:54 +00:00
Andreas Hocevar
8899c3e3c5 Merge pull request #9405 from openlayers/greenkeeper/marked-0.6.2
Update marked to the latest version 🚀
2019-04-05 17:39:42 +02:00
Andreas Hocevar
10a2b718f5 Merge pull request #9286 from ahocevar/interim-transition
Disable transition when an interim tile is available
2019-04-05 17:33:58 +02:00
Andreas Hocevar
c72f699c90 Merge pull request #9404 from jahow/fix-view-jump-glitch
View / apply constraints when an interaction starts
2019-04-05 17:30:33 +02:00
ahocevar
16e132caea Mark new animate_ method private 2019-04-05 17:21:23 +02:00
ahocevar
070c1ec029 Resolve constraints for View#animate() API calls 2019-04-05 17:13:55 +02:00
greenkeeper[bot]
21c26cabed chore(package): update marked to version 0.6.2 2019-04-05 14:34:13 +00:00
Olivier Guyot
0f73f16cfa View / apply constraints when an interaction starts
Previously, an interaction could begin while target values
(center/resolution) were out of the allowed range, causing a
glitch where the view zoom/position would jump suddenly.
2019-04-05 11:55:35 +02:00
Andreas Hocevar
dfa8506549 Merge pull request #9390 from jahow/add-webgl-filtering
Add a new WebGL example for filtering features
2019-04-04 12:34:20 +02:00
Olivier Guyot
8fb6ed5c6f Add a new webgl example with real time feature filtering 2019-04-02 23:46:13 +02:00
Olivier Guyot
c6a859d1ed Webgl / clarify premultiplied alpha handling
By default, alpha premultiplying should be done by the initial rendering
(eg quads) and not the final post processing pass.

The default post processing pass expects premultiplied color values and
will not do this operation itself.
2019-04-02 22:12:47 +02:00
Olivier Guyot
b955579a9c Webgl / clarified the buffer binding/flushing logic
The Webgl points layer renderer has also been optimized accordingly,
giving out much better performance.
2019-04-02 21:05:31 +02:00
ahocevar
56f37ab347 Disable transition when an interim tile is available 2019-03-03 23:07:46 +01:00
73 changed files with 46162 additions and 257 deletions

View File

@@ -4,6 +4,16 @@
#### Backwards incompatible changes
#### Removal of optional this arguments
The optional this (i.e. opt_this) arguments were removed from the following methods.
Please use closures, the es6 arrow function or the bind method to achieve this effect (Bind is explained here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).
* `forEachCorner` in `ol/extent`
* `LRUCache#forEach`
* `RBush#forEach` and `RBush#forEachInExtent`
##### The `setCenter`, `setZoom`, `setResolution` and `setRotation` methods on `ol/View` do not bypass constraints anymore
Previously, these methods allowed setting values that were inconsistent with the given view constraints.

View File

@@ -100,8 +100,7 @@ function xyz2rgb(x) {
const raster = new RasterSource({
sources: [new Stamen({
layer: 'watercolor',
transition: 0
layer: 'watercolor'
})],
operation: function(pixels, data) {
const hcl = rgb2hcl(pixels[0]);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
---
layout: example.html
title: Filtering features with WebGL
shortdesc: Using WebGL to filter large quantities of features
docs: >
This example shows how to use `ol/renderer/webgl/PointsLayer` to dynamically filter a large amount
of point geometries. The above map is based on a dataset from the NASA containing 45k recorded meteorite
landing sites. Each meteorite is marked by a circle on the map (the bigger the circle, the heavier
the object). A pulse effect has been added, which is slightly offset by the year of the impact.
Adjusting the sliders causes the objects outside of the date range to be filtered out of the map. This is done using
a custom fragment shader on the layer renderer, and by using the `v_opacity` attribute of the rendered objects
to store the year of impact.
tags: "webgl, icon, sprite, filter, feature"
---
<div id="map" class="map"></div>
<form>
<div id="status">Show impacts between <span class="min-year"></span> and <span class="max-year"></span></div>
<label>Minimum year:</label>
<input id="min-year" type="range" min="1850" max="2015" step="1" value="1850"/>
<label>Maximum year:</label>
<input id="max-year" type="range" min="1850" max="2015" step="1" value="2015"/>
</form>

View File

@@ -0,0 +1,162 @@
import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import TileLayer from '../src/ol/layer/Tile.js';
import Feature from '../src/ol/Feature';
import Point from '../src/ol/geom/Point';
import VectorLayer from '../src/ol/layer/Vector';
import {Vector} from '../src/ol/source';
import {fromLonLat} from '../src/ol/proj';
import WebGLPointsLayerRenderer from '../src/ol/renderer/webgl/PointsLayer';
import {clamp, lerp} from '../src/ol/math';
import Stamen from '../src/ol/source/Stamen';
const features = [];
const vectorSource = new Vector({
features: [],
attributions: 'NASA'
});
const oldColor = [180, 140, 140];
const newColor = [255, 80, 80];
const startTime = Date.now() * 0.001;
// hanle input values & events
const minYearInput = document.getElementById('min-year');
const maxYearInput = document.getElementById('max-year');
function updateStatusText() {
const div = document.getElementById('status');
div.querySelector('span.min-year').textContent = minYearInput.value;
div.querySelector('span.max-year').textContent = maxYearInput.value;
}
minYearInput.addEventListener('input', updateStatusText);
minYearInput.addEventListener('change', updateStatusText);
maxYearInput.addEventListener('input', updateStatusText);
maxYearInput.addEventListener('change', updateStatusText);
updateStatusText();
class WebglPointsLayer extends VectorLayer {
createRenderer() {
return new WebGLPointsLayerRenderer(this, {
colorCallback: function(feature, vertex, component) {
// component at index 3 is alpha
if (component === 3) {
return 1;
}
// color is interpolated based on year
const ratio = clamp((feature.get('year') - 1800) / (2013 - 1800), 0, 1);
return lerp(oldColor[component], newColor[component], ratio) / 255;
},
sizeCallback: function(feature) {
return 18 * clamp(feature.get('mass') / 200000, 0, 1) + 8;
},
fragmentShader: [
'precision mediump float;',
'uniform float u_time;',
'uniform float u_minYear;',
'uniform float u_maxYear;',
'varying vec2 v_texCoord;',
'varying float v_opacity;',
'varying vec4 v_color;',
'void main(void) {',
' float impactYear = v_opacity;',
// filter out pixels if the year is outside of the given range
' if (impactYear < u_minYear || v_opacity > u_maxYear) {',
' discard;',
' }',
' vec2 texCoord = v_texCoord * 2.0 - vec2(1.0, 1.0);',
' float sqRadius = texCoord.x * texCoord.x + texCoord.y * texCoord.y;',
' float value = 2.0 * (1.0 - sqRadius);',
' float alpha = smoothstep(0.0, 1.0, value);',
' vec3 color = v_color.rgb;',
' float period = 8.0;',
' color.g *= 2.0 * (1.0 - sqrt(mod(u_time + impactYear * 0.025, period) / period));',
' gl_FragColor = vec4(color, v_color.a);',
' gl_FragColor.a *= alpha;',
' gl_FragColor.rgb *= gl_FragColor.a;',
'}'
].join(' '),
opacityCallback: function(feature) {
// here the opacity channel of the vertices is used to store the year of impact
return feature.get('year');
},
uniforms: {
u_time: function() {
return Date.now() * 0.001 - startTime;
},
u_minYear: function() {
return parseInt(minYearInput.value);
},
u_maxYear: function() {
return parseInt(maxYearInput.value);
}
}
});
}
}
function loadData() {
const client = new XMLHttpRequest();
client.open('GET', 'data/csv/meteorite_landings.csv');
client.onload = function() {
const csv = client.responseText;
let curIndex;
let prevIndex = 0;
let line;
while ((curIndex = csv.indexOf('\n', prevIndex)) > 0) {
line = csv.substr(prevIndex, curIndex - prevIndex).split(',');
prevIndex = curIndex + 1;
// skip header
if (prevIndex === 0) {
continue;
}
const coords = fromLonLat([parseFloat(line[4]), parseFloat(line[3])]);
features.push(new Feature({
mass: parseFloat(line[1]) || 0,
year: parseInt(line[2]) || 0,
geometry: new Point(coords)
}));
}
vectorSource.addFeatures(features);
};
client.send();
}
loadData();
const map = new Map({
layers: [
new TileLayer({
source: new Stamen({
layer: 'toner'
})
}),
new WebglPointsLayer({
source: vectorSource
})
],
target: document.getElementById('map'),
view: new View({
center: [0, 0],
zoom: 2
})
});
// animate the map
function animate() {
map.render();
window.requestAnimationFrame(animate);
}
animate();

View File

@@ -24,8 +24,7 @@ function flood(pixels, data) {
const key = 'pk.eyJ1IjoidHNjaGF1YiIsImEiOiJjaW5zYW5lNHkxMTNmdWttM3JyOHZtMmNtIn0.CDIBD8H-G2Gf-cPkIuWtRg';
const elevation = new XYZ({
url: 'https://api.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}.pngraw?access_token=' + key,
crossOrigin: 'anonymous',
transition: 0
crossOrigin: 'anonymous'
});
const raster = new RasterSource({

View File

@@ -100,8 +100,7 @@ function shade(inputs, data) {
const elevation = new XYZ({
url: 'https://{a-d}.tiles.mapbox.com/v3/aj.sf-dem/{z}/{x}/{y}.png',
crossOrigin: 'anonymous',
transition: 0
crossOrigin: 'anonymous'
});
const raster = new Raster({

View File

@@ -1,6 +1,6 @@
{
"name": "ol",
"version": "5.3.0",
"version": "6.0.0-beta.6",
"description": "OpenLayers mapping library",
"keywords": [
"map",
@@ -41,28 +41,28 @@
"rbush": "2.0.2"
},
"devDependencies": {
"@openlayers/eslint-plugin": "^4.0.0-beta.1",
"@openlayers/eslint-plugin": "^4.0.0-beta.2",
"@types/arcgis-rest-api": "^10.4.4",
"@types/geojson": "^7946.0.6",
"@types/geojson": "^7946.0.7",
"@types/pbf": "^3.0.1",
"@types/rbush": "^2.0.2",
"@types/topojson-specification": "^1.0.1",
"buble": "^0.19.7",
"buble-loader": "^0.5.1",
"chaikin-smooth": "^1.0.4",
"clean-css-cli": "4.2.1",
"copy-webpack-plugin": "^5.0.1",
"clean-css-cli": "4.3.0",
"copy-webpack-plugin": "^5.0.2",
"coveralls": "3.0.3",
"eslint": "^5.15.2",
"eslint": "^5.16.0",
"eslint-config-openlayers": "^11.0.0",
"expect.js": "0.3.1",
"front-matter": "^3.0.1",
"fs-extra": "^7.0.1",
"glob": "^7.1.2",
"globby": "^9.1.0",
"handlebars": "4.1.1",
"globby": "^9.2.0",
"handlebars": "4.1.2",
"istanbul": "0.4.5",
"jquery": "3.3.1",
"jquery": "3.4.0",
"jsdoc": "3.5.5",
"jsdoc-plugin-typescript": "^1.0.7",
"karma": "^4.0.1",
@@ -73,24 +73,24 @@
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^4.0.0-rc.2",
"loglevelnext": "^3.0.0",
"marked": "0.6.1",
"mocha": "6.0.2",
"ol-mapbox-style": "^4.2.1",
"marked": "0.6.2",
"mocha": "6.1.3",
"ol-mapbox-style": "^4.3.1",
"pixelmatch": "^4.0.2",
"pngjs": "^3.4.0",
"proj4": "2.5.0",
"puppeteer": "~1.14.0",
"serve-static": "^1.13.2",
"shx": "^0.3.2",
"sinon": "^7.2.7",
"sinon": "^7.3.1",
"terser-webpack-plugin": "^1.2.3",
"typescript": "^3.2.2",
"url-polyfill": "^1.1.5",
"walk": "^2.3.9",
"webpack": "4.29.6",
"webpack": "4.30.0",
"webpack-cli": "^3.3.0",
"webpack-dev-middleware": "^3.6.1",
"webpack-dev-server": "^3.2.1",
"webpack-dev-middleware": "^3.6.2",
"webpack-dev-server": "^3.3.1",
"yargs": "^13.2.2"
},
"eslintConfig": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 935 B

After

Width:  |  Height:  |  Size: 1016 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 891 B

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -131,4 +131,4 @@ const map = new Map({
});
map.getView().fit(vectorSource.getExtent());
render({tolerance: 0.02});
render({tolerance: 0.021});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@@ -103,4 +103,4 @@ const map = new Map({
});
map.getView().fit(vectorSource.getExtent());
render({tolerance: 0.02});
render({tolerance: 0.024});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 778 B

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 801 B

After

Width:  |  Height:  |  Size: 910 B

View File

@@ -170,6 +170,9 @@ class Tile extends EventTarget {
// cleaned up by refreshInterimChain)
do {
if (tile.getState() == TileState.LOADED) {
// Show tile immediately instead of fading it in after loading, because
// the interim tile is in place already
this.transition_ = 0;
return tile;
}
tile = tile.interimTile;

View File

@@ -44,7 +44,7 @@ class TileCache extends LRUCache {
this.remove(getKey(tile.tileCoord));
tile.dispose();
}
}, this);
}.bind(this));
}
}

View File

@@ -284,8 +284,6 @@ class View extends BaseObject {
*/
this.updateAnimationKey_;
this.updateAnimations_ = this.updateAnimations_.bind(this);
/**
* @private
* @const
@@ -452,6 +450,17 @@ class View extends BaseObject {
* @api
*/
animate(var_args) {
if (this.isDef() && !this.getAnimating()) {
this.resolveConstraints(0);
}
this.animate_.apply(this, arguments);
}
/**
* @private
* @param {...(AnimationOptions|function(boolean): void)} var_args Animation options.
*/
animate_(var_args) {
let animationCount = arguments.length;
let callback;
if (animationCount > 1 && typeof arguments[animationCount - 1] === 'function') {
@@ -641,11 +650,7 @@ class View extends BaseObject {
// prune completed series
this.animations_ = this.animations_.filter(Boolean);
if (more && this.updateAnimationKey_ === undefined) {
this.updateAnimationKey_ = requestAnimationFrame(this.updateAnimations_);
}
if (!this.getAnimating()) {
setTimeout(this.resolveConstraints.bind(this), 0);
this.updateAnimationKey_ = requestAnimationFrame(this.updateAnimations_.bind(this));
}
}
@@ -929,13 +934,9 @@ class View extends BaseObject {
const center = /** @type {import("./coordinate.js").Coordinate} */ (this.getCenter());
const projection = this.getProjection();
const resolution = /** @type {number} */ (this.getResolution());
const pixelResolution = resolution / pixelRatio;
const rotation = this.getRotation();
return {
center: [
Math.round(center[0] / pixelResolution) * pixelResolution,
Math.round(center[1] / pixelResolution) * pixelResolution
],
center: center.slice(0),
projection: projection !== undefined ? projection : null,
resolution: resolution,
rotation: rotation,
@@ -1085,7 +1086,7 @@ class View extends BaseObject {
const callback = options.callback ? options.callback : VOID;
if (options.duration !== undefined) {
this.animate({
this.animate_({
resolution: resolution,
center: this.getConstrainedCenter(center, resolution),
duration: options.duration,
@@ -1312,7 +1313,7 @@ class View extends BaseObject {
this.cancelAnimations();
}
this.animate({
this.animate_({
rotation: newRotation,
center: newCenter,
resolution: newResolution,
@@ -1325,9 +1326,13 @@ class View extends BaseObject {
/**
* Notify the View that an interaction has started.
* The view state will be resolved to a stable one if needed
* (depending on its constraints).
* @api
*/
beginInteraction() {
this.resolveConstraints(0);
this.setHint(ViewHint.INTERACTING, 1);
}

View File

@@ -400,26 +400,25 @@ export function extendXY(extent, x, y) {
* callback returns a truthy value the function returns that value
* immediately. Otherwise the function returns `false`.
* @param {Extent} extent Extent.
* @param {function(this:T, import("./coordinate.js").Coordinate): S} callback Callback.
* @param {T=} opt_this Value to use as `this` when executing `callback`.
* @param {function(import("./coordinate.js").Coordinate): S} callback Callback.
* @return {S|boolean} Value.
* @template S, T
* @template S
*/
export function forEachCorner(extent, callback, opt_this) {
export function forEachCorner(extent, callback) {
let val;
val = callback.call(opt_this, getBottomLeft(extent));
val = callback(getBottomLeft(extent));
if (val) {
return val;
}
val = callback.call(opt_this, getBottomRight(extent));
val = callback(getBottomRight(extent));
if (val) {
return val;
}
val = callback.call(opt_this, getTopRight(extent));
val = callback(getTopRight(extent));
if (val) {
return val;
}
val = callback.call(opt_this, getTopLeft(extent));
val = callback(getTopLeft(extent));
if (val) {
return val;
}

View File

@@ -4,6 +4,7 @@
export {default as Circle} from './geom/Circle.js';
export {default as Geometry} from './geom/Geometry.js';
export {default as GeometryCollection} from './geom/GeometryCollection.js';
export {default as LineString} from './geom/LineString.js';
export {default as MultiLineString} from './geom/MultiLineString.js';
export {default as MultiPoint} from './geom/MultiPoint.js';

View File

@@ -5,6 +5,8 @@ import {createOrUpdate, forEachCorner, intersects} from '../extent.js';
import GeometryType from './GeometryType.js';
import SimpleGeometry from './SimpleGeometry.js';
import {deflateCoordinate} from './flat/deflate.js';
import {rotate, translate} from './flat/transform.js';
/**
* @classdesc
@@ -143,7 +145,7 @@ class Circle extends SimpleGeometry {
return true;
}
return forEachCorner(extent, this.intersectsCoordinate, this);
return forEachCorner(extent, this.intersectsCoordinate.bind(this));
}
return false;
@@ -212,6 +214,29 @@ class Circle extends SimpleGeometry {
this.flatCoordinates[this.stride] = this.flatCoordinates[0] + radius;
this.changed();
}
/**
* @inheritDoc
* @api
*/
rotate(angle, anchor) {
const center = this.getCenter();
const stride = this.getStride();
this.setCenter(rotate(center, 0, center.length, stride, angle, anchor, center));
this.changed();
}
/**
* @inheritDoc
* @api
*/
translate(deltaX, deltaY) {
const center = this.getCenter();
const stride = this.getStride();
this.setCenter(translate(center, 0, center.length, stride, deltaX, deltaY, center));
this.changed();
}
}

View File

@@ -111,7 +111,7 @@ export function pan(view, delta, opt_duration) {
const currentCenter = view.getCenter();
if (currentCenter) {
const center = [currentCenter[0] + delta[0], currentCenter[1] + delta[1]];
view.animate({
view.animate_({
duration: opt_duration !== undefined ? opt_duration : 250,
easing: linear,
center: view.getConstrainedCenter(center)

View File

@@ -8,13 +8,6 @@ import Interaction, {zoomByDelta} from './Interaction.js';
import {clamp} from '../math.js';
/**
* Maximum mouse wheel delta.
* @type {number}
*/
const MAX_DELTA = 1;
/**
* @enum {string}
*/
@@ -30,6 +23,7 @@ export const Mode = {
* takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a
* boolean to indicate whether that event should be handled. Default is
* {@link module:ol/events/condition~always}.
* @property {number} [maxDelta=1] Maximum mouse wheel delta.
* @property {number} [duration=250] Animation duration in milliseconds.
* @property {number} [timeout=80] Mouse wheel timeout duration in milliseconds.
* @property {boolean} [useAnchor=true] Enable zooming using the mouse's
@@ -65,6 +59,12 @@ class MouseWheelZoom extends Interaction {
*/
this.lastDelta_ = 0;
/**
* @private
* @type {number}
*/
this.maxDelta_ = options.maxDelta !== undefined ? options.maxDelta : 1;
/**
* @private
* @type {number}
@@ -235,8 +235,7 @@ class MouseWheelZoom extends Interaction {
if (view.getAnimating()) {
view.cancelAnimations();
}
const maxDelta = MAX_DELTA;
const delta = clamp(this.totalDelta_, -maxDelta, maxDelta);
const delta = clamp(this.totalDelta_, -this.maxDelta_, this.maxDelta_);
zoomByDelta(view, -delta, this.lastAnchor_, this.duration_);
this.mode_ = undefined;
this.totalDelta_ = 0;

View File

@@ -27,7 +27,6 @@ import WebGLPointsLayerRenderer from '../renderer/webgl/PointsLayer';
* of the heatmap, specified as an array of CSS color strings.
* @property {number} [radius=8] Radius size in pixels.
* @property {number} [blur=15] Blur size in pixels.
* @property {number} [shadow=250] Shadow size in pixels.
* @property {string|function(import("../Feature.js").default):number} [weight='weight'] The feature
* attribute to use for the weight or a function that returns a weight from a feature. Weight values
* should range from 0 to 1 (and values outside will be clamped to that range).
@@ -75,7 +74,6 @@ class Heatmap extends VectorLayer {
delete baseOptions.gradient;
delete baseOptions.radius;
delete baseOptions.blur;
delete baseOptions.shadow;
delete baseOptions.weight;
super(baseOptions);
@@ -85,24 +83,6 @@ class Heatmap extends VectorLayer {
*/
this.gradient_ = null;
/**
* @private
* @type {number}
*/
this.shadow_ = options.shadow !== undefined ? options.shadow : 250;
/**
* @private
* @type {string|undefined}
*/
this.circleImage_ = undefined;
/**
* @private
* @type {Array<Array<import("../style/Style.js").default>>}
*/
this.styleCache_ = null;
listen(this,
getChangeEventType(Property.GRADIENT),
this.handleGradientChanged_, this);
@@ -206,15 +186,15 @@ class Heatmap extends VectorLayer {
attribute float a_rotateWithView;
attribute vec2 a_offsets;
attribute float a_opacity;
uniform mat4 u_projectionMatrix;
uniform mat4 u_offsetScaleMatrix;
uniform mat4 u_offsetRotateMatrix;
uniform float u_size;
varying vec2 v_texCoord;
varying float v_opacity;
void main(void) {
mat4 offsetMatrix = u_offsetScaleMatrix;
if (a_rotateWithView == 1.0) {
@@ -229,16 +209,16 @@ class Heatmap extends VectorLayer {
precision mediump float;
uniform float u_resolution;
uniform float u_blurSlope;
varying vec2 v_texCoord;
varying float v_opacity;
void main(void) {
vec2 texCoord = v_texCoord * 2.0 - vec2(1.0, 1.0);
float sqRadius = texCoord.x * texCoord.x + texCoord.y * texCoord.y;
float value = (1.0 - sqrt(sqRadius)) * u_blurSlope;
float alpha = smoothstep(0.0, 1.0, value) * v_opacity;
gl_FragColor = vec4(1.0, 1.0, 1.0, alpha);
gl_FragColor = vec4(alpha, alpha, alpha, alpha);
}`,
uniforms: {
u_size: function() {
@@ -273,9 +253,7 @@ class Heatmap extends VectorLayer {
}
}
],
opacityCallback: function(feature) {
return this.weightFunction_(feature);
}.bind(this)
opacityCallback: this.weightFunction_
});
}
}

View File

@@ -1,102 +0,0 @@
/**
* @module ol/render/webgl
*/
/**
* @const
* @type {string}
*/
export const DEFAULT_FONT = '10px sans-serif';
/**
* @const
* @type {import("../color.js").Color}
*/
export const DEFAULT_FILLSTYLE = [0.0, 0.0, 0.0, 1.0];
/**
* @const
* @type {string}
*/
export const DEFAULT_LINECAP = 'round';
/**
* @const
* @type {Array<number>}
*/
export const DEFAULT_LINEDASH = [];
/**
* @const
* @type {number}
*/
export const DEFAULT_LINEDASHOFFSET = 0;
/**
* @const
* @type {string}
*/
export const DEFAULT_LINEJOIN = 'round';
/**
* @const
* @type {number}
*/
export const DEFAULT_MITERLIMIT = 10;
/**
* @const
* @type {import("../color.js").Color}
*/
export const DEFAULT_STROKESTYLE = [0.0, 0.0, 0.0, 1.0];
/**
* @const
* @type {number}
*/
export const DEFAULT_TEXTALIGN = 0.5;
/**
* @const
* @type {number}
*/
export const DEFAULT_TEXTBASELINE = 0.5;
/**
* @const
* @type {number}
*/
export const DEFAULT_LINEWIDTH = 1;
/**
* @const
* @type {number}
*/
export const EPSILON = Number.EPSILON || 2.220446049250313e-16;
/**
* Calculates the orientation of a triangle based on the determinant method.
* @param {number} x1 First X coordinate.
* @param {number} y1 First Y coordinate.
* @param {number} x2 Second X coordinate.
* @param {number} y2 Second Y coordinate.
* @param {number} x3 Third X coordinate.
* @param {number} y3 Third Y coordinate.
* @return {boolean|undefined} Triangle is clockwise.
*/
export const triangleIsCounterClockwise = function(x1, y1, x2, y2, x3, y3) {
const area = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
return (area <= EPSILON && area >= -EPSILON) ?
undefined : area > 0;
};

View File

@@ -110,8 +110,7 @@ const FRAGMENT_SHADER = `
*
* The following uniform is used for the main texture: `u_texture`.
*
* Please note that the main shader output should have premultiplied alpha, otherwise the colors will be blended
* additively.
* Please note that the main shader output should have premultiplied alpha, otherwise visual anomalies may occur.
*
* Points are rendered as quads with the following structure:
*
@@ -323,6 +322,9 @@ class WebGLPointsLayerRenderer extends LayerRenderer {
baseIndex + 1, baseIndex + 2, baseIndex + 3
);
});
this.helper_.flushBufferData(ARRAY_BUFFER, this.verticesBuffer_);
this.helper_.flushBufferData(ELEMENT_ARRAY_BUFFER, this.indicesBuffer_);
}
// write new data

View File

@@ -288,8 +288,7 @@ class RasterSource extends ImageSource {
frameState.focus = center;
frameState.size[0] = Math.round(getWidth(extent) / resolution);
frameState.size[1] = Math.round(getHeight(extent) / resolution);
frameState.time = Date.now();
frameState.animate = false;
frameState.time = Infinity;
const viewState = frameState.viewState;
viewState.center = center;

View File

@@ -485,7 +485,7 @@ class VectorSource extends Source {
}
} else {
if (this.featuresRtree_) {
this.featuresRtree_.forEach(this.removeFeatureInternal, this);
this.featuresRtree_.forEach(this.removeFeatureInternal.bind(this));
for (const id in this.nullGeometryFeatures_) {
this.removeFeatureInternal(this.nullGeometryFeatures_[id]);
}

View File

@@ -96,17 +96,15 @@ class LRUCache extends EventTarget {
/**
* @param {function(this: S, T, string, LRUCache): ?} f The function
* @param {function(T, string, LRUCache): ?} f The function
* to call for every entry from the oldest to the newer. This function takes
* 3 arguments (the entry value, the entry key and the LRUCache object).
* The return value is ignored.
* @param {S=} opt_this The object to use as `this` in `f`.
* @template S
*/
forEach(f, opt_this) {
forEach(f) {
let entry = this.oldest_;
while (entry) {
f.call(opt_this, entry.value_, entry.key_, this);
f(entry.value_, entry.key_, this);
entry = entry.newer;
}
}

View File

@@ -156,41 +156,35 @@ class RBush {
* Calls a callback function with each value in the tree.
* If the callback returns a truthy value, this value is returned without
* checking the rest of the tree.
* @param {function(this: S, T): *} callback Callback.
* @param {S=} opt_this The object to use as `this` in `callback`.
* @param {function(T): *} callback Callback.
* @return {*} Callback return value.
* @template S
*/
forEach(callback, opt_this) {
return this.forEach_(this.getAll(), callback, opt_this);
forEach(callback) {
return this.forEach_(this.getAll(), callback);
}
/**
* Calls a callback function with each value in the provided extent.
* @param {import("../extent.js").Extent} extent Extent.
* @param {function(this: S, T): *} callback Callback.
* @param {S=} opt_this The object to use as `this` in `callback`.
* @param {function(T): *} callback Callback.
* @return {*} Callback return value.
* @template S
*/
forEachInExtent(extent, callback, opt_this) {
return this.forEach_(this.getInExtent(extent), callback, opt_this);
forEachInExtent(extent, callback) {
return this.forEach_(this.getInExtent(extent), callback);
}
/**
* @param {Array<T>} values Values.
* @param {function(this: S, T): *} callback Callback.
* @param {S=} opt_this The object to use as `this` in `callback`.
* @param {function(T): *} callback Callback.
* @private
* @return {*} Callback return value.
* @template S
*/
forEach_(values, callback, opt_this) {
forEach_(values, callback) {
let result;
for (let i = 0, l = values.length; i < l; i++) {
result = callback.call(opt_this, values[i]);
result = callback(values[i]);
if (result) {
return result;
}

View File

@@ -5,7 +5,7 @@
/**
* @typedef {Object} Options
* @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [color] A color, gradient or pattern.
* @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [color=null] A color, gradient or pattern.
* See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.
* Default null; if null, the Canvas/renderer default black will be used.
*/

View File

@@ -16,14 +16,14 @@ import ImageStyle from './Image.js';
/**
* @typedef {Object} Options
* @property {Array<number>} [anchor=[0.5, 0.5]] Anchor. Default value is the icon center.
* @property {import("./IconOrigin.js").default} [anchorOrigin] Origin of the anchor: `bottom-left`, `bottom-right`,
* `top-left` or `top-right`. Default is `top-left`.
* @property {import("./IconAnchorUnits.js").default} [anchorXUnits] Units in which the anchor x value is
* @property {import("./IconOrigin.js").default} [anchorOrigin='top-left'] Origin of the anchor: `bottom-left`, `bottom-right`,
* `top-left` or `top-right`.
* @property {import("./IconAnchorUnits.js").default} [anchorXUnits='fraction'] Units in which the anchor x value is
* specified. A value of `'fraction'` indicates the x value is a fraction of the icon. A value of `'pixels'` indicates
* the x value in pixels. Default is `'fraction'`.
* @property {import("./IconAnchorUnits.js").default} [anchorYUnits] Units in which the anchor y value is
* the x value in pixels.
* @property {import("./IconAnchorUnits.js").default} [anchorYUnits='fraction'] Units in which the anchor y value is
* specified. A value of `'fraction'` indicates the y value is a fraction of the icon. A value of `'pixels'` indicates
* the y value in pixels. Default is `'fraction'`.
* the y value in pixels.
* @property {import("../color.js").Color|string} [color] Color to tint the icon. If not specified,
* the icon will be left as is.
* @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that you must provide a
@@ -34,8 +34,8 @@ import ImageStyle from './Image.js';
* to provide the size of the image, with the `imgSize` option.
* @property {Array<number>} [offset=[0, 0]] Offset, which, together with the size and the offset origin, define the
* sub-rectangle to use from the original icon image.
* @property {import("./IconOrigin.js").default} [offsetOrigin] Origin of the offset: `bottom-left`, `bottom-right`,
* `top-left` or `top-right`. Default is `top-left`.
* @property {import("./IconOrigin.js").default} [offsetOrigin='top-left'] Origin of the offset: `bottom-left`, `bottom-right`,
* `top-left` or `top-right`.
* @property {number} [opacity=1] Opacity of the icon.
* @property {number} [scale=1] Scale.
* @property {boolean} [rotateWithView=false] Whether to rotate the icon with the view.

View File

@@ -18,13 +18,13 @@ const DEFAULT_FILL_COLOR = '#333';
* @typedef {Object} Options
* @property {string} [font] Font style as CSS 'font' value, see:
* https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font. Default is '10px sans-serif'
* @property {number} [maxAngle] When `placement` is set to `'line'`, allow a maximum angle between adjacent characters.
* @property {number} [maxAngle=Math.PI/4] When `placement` is set to `'line'`, allow a maximum angle between adjacent characters.
* The expected value is in radians, and the default is 45° (`Math.PI / 4`).
* @property {number} [offsetX=0] Horizontal text offset in pixels. A positive will shift the text right.
* @property {number} [offsetY=0] Vertical text offset in pixels. A positive will shift the text down.
* @property {boolean} [overflow=false] For polygon labels or when `placement` is set to `'line'`, allow text to exceed
* the width of the polygon at the label position or the length of the path that it follows.
* @property {import("./TextPlacement.js").default|string} [placement] Text placement.
* @property {import("./TextPlacement.js").default|string} [placement='point'] Text placement.
* @property {number} [scale] Scale.
* @property {boolean} [rotateWithView=false] Whether to rotate the text with the view.
* @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).

View File

@@ -23,8 +23,8 @@ import {getContext} from '../webgl';
/**
* @typedef {Object} BufferCacheEntry
* @property {import("./Buffer.js").default} buf
* @property {WebGLBuffer} buffer
* @property {import("./Buffer.js").default} buffer
* @property {WebGLBuffer} webGlBuffer
*/
/**
@@ -153,15 +153,24 @@ export const DefaultAttrib = {
* ### Binding WebGL buffers and flushing data into them:
*
* Data that must be passed to the GPU has to be transferred using `WebGLArrayBuffer` objects.
* A buffer has to be created only once, but must be bound everytime the data it holds is changed. Using `WebGLHelper.bindBuffer`
* will bind the buffer and flush the new data to the GPU.
* A buffer has to be created only once, but must be bound everytime the buffer content should be used for rendering.
* This is done using `WebGLHelper.bindBuffer`.
* When the buffer's array content has changed, the new data has to be flushed to the GPU memory; this is done using
* `WebGLHelper.flushBufferData`. Note: this operation is expensive and should be done as infrequently as possible.
*
* For now, the `WebGLHelper` class expects {@link module:ol/webgl/Buffer~WebGLArrayBuffer} objects.
* When binding a `WebGLArrayBuffer`, a `target` parameter must be given: it should be either {@link module:ol/webgl~ARRAY_BUFFER}
* (if the buffer contains vertices data) or {@link module:ol/webgl~ELEMENT_ARRAY_BUFFER} (if the buffer contains indices data).
*
* Examples below:
* ```js
* // at initialization phase
* this.verticesBuffer = new WebGLArrayBuffer([], DYNAMIC_DRAW);
* this.indicesBuffer = new WebGLArrayBuffer([], DYNAMIC_DRAW);
*
* // when array values have changed
* this.context.flushBufferData(ARRAY_BUFFER, this.verticesBuffer);
* this.context.flushBufferData(ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
*
* // at rendering phase
* this.context.bindBuffer(ARRAY_BUFFER, this.verticesBuffer);
* this.context.bindBuffer(ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
@@ -342,24 +351,35 @@ class WebGLHelper extends Disposable {
* Just bind the buffer if it's in the cache. Otherwise create
* the WebGL buffer, bind it, populate it, and add an entry to
* the cache.
* TODO: improve this, the logic is unclear: we want A/ to bind a buffer and B/ to flush data in it
* @param {number} target Target.
* @param {import("./Buffer").default} buf Buffer.
* @param {number} target Target, either ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER.
* @param {import("./Buffer").default} buffer Buffer.
* @api
*/
bindBuffer(target, buf) {
bindBuffer(target, buffer) {
const gl = this.getGL();
const arr = buf.getArray();
const bufferKey = getUid(buf);
const bufferKey = getUid(buffer);
let bufferCache = this.bufferCache_[bufferKey];
if (!bufferCache) {
const buffer = gl.createBuffer();
const webGlBuffer = gl.createBuffer();
bufferCache = this.bufferCache_[bufferKey] = {
buf: buf,
buffer: buffer
buffer: buffer,
webGlBuffer: webGlBuffer
};
}
gl.bindBuffer(target, bufferCache.buffer);
gl.bindBuffer(target, bufferCache.webGlBuffer);
}
/**
* Update the data contained in the buffer array; this is required for the
* new data to be rendered
* @param {number} target Target, either ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER.
* @param {import("./Buffer").default} buffer Buffer.
* @api
*/
flushBufferData(target, buffer) {
const gl = this.getGL();
const arr = buffer.getArray();
this.bindBuffer(target, buffer);
let /** @type {ArrayBufferView} */ arrayBuffer;
if (target == ARRAY_BUFFER) {
arrayBuffer = new Float32Array(arr);
@@ -367,7 +387,7 @@ class WebGLHelper extends Disposable {
arrayBuffer = this.hasOESElementIndexUint ?
new Uint32Array(arr) : new Uint16Array(arr);
}
gl.bufferData(target, arrayBuffer, buf.getUsage());
gl.bufferData(target, arrayBuffer, buffer.getUsage());
}
/**

View File

@@ -28,7 +28,6 @@ const DEFAULT_FRAGMENT_SHADER = `
void main() {
gl_FragColor = texture2D(u_image, v_texCoord);
gl_FragColor.rgb *= gl_FragColor.a;
}
`;
@@ -59,6 +58,9 @@ const DEFAULT_FRAGMENT_SHADER = `
* a pixel which is 100% red with an opacity of 50% must have a color of (r=0.5, g=0, b=0, a=0.5).
* Failing to provide pixel colors with premultiplied alpha will result in render anomalies.
*
* The default post-processing pass does *not* multiply color values with alpha value, it expects color values to be
* premultiplied.
*
* Default shaders are shown hereafter:
*
* * Vertex shader:
@@ -91,7 +93,6 @@ const DEFAULT_FRAGMENT_SHADER = `
*
* void main() {
* gl_FragColor = texture2D(u_image, v_texCoord);
* gl_FragColor.rgb *= gl_FragColor.a;
* }
* ```
*

View File

@@ -76,7 +76,7 @@ main() {
npm install
npm run build-package
cd ${BUILT_PACKAGE}
npm publish
npm publish --tag beta
}
if test ${#} -ne 1; then

View File

@@ -239,13 +239,6 @@ describe('ol.extent', function() {
}
);
it('calls the callback with given scope', function() {
const extent = [1, 2, 3, 4];
const scope = {humpty: 'dumpty'};
_ol_extent_.forEachCorner(extent, callbackTrue, scope);
expect(callbackTrue.calledOn(scope)).to.be(true);
});
});
describe('getArea', function() {

View File

@@ -263,6 +263,34 @@ describe('ol.geom.Circle', function() {
});
describe('#rotate', function() {
it('rotates the center around the anchor', function() {
circle.setCenter([1, 0]);
circle.rotate(Math.PI / 2, [2, 0]);
expect(circle.getCenter()).to.eql([2, -1]);
expect(circle.getExtent()).to.eql([1, -2, 3, 0]);
});
it('does not change if the anchor equals the center', function() {
const center = [1, 0];
circle.setCenter(center);
const extent = circle.getExtent();
circle.rotate(Math.PI / 2, center);
expect(circle.getCenter()).to.eql(center);
expect(circle.getExtent()).to.eql(extent);
});
});
describe('#translate', function() {
it('translates the circle', function() {
circle.setCenter([1, 1]);
circle.translate(5, 10);
expect(circle.getCenter()).to.eql([6, 11]);
expect(circle.getExtent()).to.eql([5, 10, 7, 12]);
});
});
});
});

View File

@@ -24,7 +24,7 @@ describe('ol.interaction.KeyboardPan', function() {
describe('handleEvent()', function() {
it('pans on arrow keys', function() {
const view = map.getView();
const spy = sinon.spy(view, 'animate');
const spy = sinon.spy(view, 'animate_');
const event = new MapBrowserEvent('keydown', map, {
type: 'keydown',
target: map.getTargetElement(),
@@ -51,7 +51,7 @@ describe('ol.interaction.KeyboardPan', function() {
expect(spy.getCall(3).args[0].center).to.eql([128, 0]);
view.setCenter([0, 0]);
view.animate.restore();
view.animate_.restore();
});
});

View File

@@ -41,13 +41,18 @@ describe('ol.renderer.canvas.TileLayer', function() {
document.body.removeChild(target);
});
it('properly handles interim tiles', function() {
it('properly handles interim tiles', function(done) {
const layer = map.getLayers().item(0);
source.once('tileloadend', function(e) {
expect(e.tile.inTransition()).to.be(false);
done();
});
source.updateParams({TIME: '1'});
map.renderSync();
const tiles = map.getRenderer().getLayerRenderer(layer).renderedTiles;
expect(tiles.length).to.be(1);
expect(tiles[0]).to.equal(tile);
expect(tile.inTransition()).to.be(true);
});
});

View File

@@ -402,7 +402,7 @@ where('Uint8ClampedArray').describe('ol.source.Raster', function() {
map2.once('moveend', function() {
expect(tileCache.getCount()).to.equal(1);
const state = tileCache.peekLast().getState();
expect(state === TileState.LOADED || state === TileState.LOADED).to.be(true);
expect(state === TileState.LOADING || state === TileState.LOADED).to.be(true);
done();
});

View File

@@ -531,8 +531,8 @@ describe('ol.source.Vector', function() {
loader: function(extent) {
setTimeout(function() {
const lonLatExtent = transformExtent(extent, 'EPSG:3857', 'EPSG:4326');
expect(lonLatExtent[0]).to.roughlyEqual(-99.261474609, 1e-9);
expect(lonLatExtent[2]).to.roughlyEqual(-95.965576171, 1e-9);
expect(lonLatExtent[0]).to.roughlyEqual(-99.259349218, 1e-9);
expect(lonLatExtent[2]).to.roughlyEqual(-95.963450781, 1e-9);
done();
}, 0);
}

View File

@@ -1801,6 +1801,52 @@ describe('ol.View', function() {
});
});
describe('does not start unexpected animations during interaction', function() {
let map;
beforeEach(function() {
map = new Map({
target: createMapDiv(512, 256)
});
});
afterEach(function() {
disposeMap(map);
});
it('works when initialized with #setCenter() and #setZoom()', function(done) {
const view = map.getView();
let callCount = 0;
view.on('change:resolution', function() {
++callCount;
});
view.setCenter([0, 0]);
view.setZoom(0);
view.beginInteraction();
view.endInteraction();
setTimeout(function() {
expect(callCount).to.be(1);
done();
}, 500);
});
it('works when initialized with #animate()', function(done) {
const view = map.getView();
let callCount = 0;
view.on('change:resolution', function() {
++callCount;
});
view.animate({
center: [0, 0],
zoom: 0
});
view.beginInteraction();
view.endInteraction();
setTimeout(function() {
expect(callCount).to.be(1);
done();
}, 500);
});
});
describe('ol.View.isNoopAnimation()', function() {
const cases = [{