From 1249ecee45f0deeba205662cf0263f2325abb6a6 Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Mon, 25 Oct 2021 10:18:18 +0100 Subject: [PATCH 1/7] add setDisplacement method --- src/ol/style/Image.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ol/style/Image.js b/src/ol/style/Image.js index 8914886975..73a948341d 100644 --- a/src/ol/style/Image.js +++ b/src/ol/style/Image.js @@ -203,6 +203,16 @@ class ImageStyle { return abstract(); } + /** + * Set the displacement. + * + * @param {Array} displacement Displacement. + * @api + */ + setDisplacement(displacement) { + this.displacement_ = displacement; + } + /** * Set the opacity. * From 9267d2994d7e40443500d9671d7b3d95a462304a Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Mon, 25 Oct 2021 10:20:36 +0100 Subject: [PATCH 2/7] handle updateable displacement --- src/ol/style/RegularShape.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/ol/style/RegularShape.js b/src/ol/style/RegularShape.js index fbac91dc62..920e40565e 100644 --- a/src/ol/style/RegularShape.js +++ b/src/ol/style/RegularShape.js @@ -126,12 +126,6 @@ class RegularShape extends ImageStyle { */ this.stroke_ = options.stroke !== undefined ? options.stroke : null; - /** - * @private - * @type {Array} - */ - this.anchor_ = null; - /** * @private * @type {import("../size.js").Size} @@ -177,7 +171,12 @@ class RegularShape extends ImageStyle { * @api */ getAnchor() { - return this.anchor_; + const size = this.size_; + if (!size) { + return null; + } + const displacement = this.getDisplacement(); + return [size[0] / 2 - displacement[0], size[1] / 2 + displacement[1]]; } /** @@ -467,9 +466,7 @@ class RegularShape extends ImageStyle { render() { this.renderOptions_ = this.createRenderOptions(); const size = this.renderOptions_.size; - const displacement = this.getDisplacement(); this.canvas_ = {}; - this.anchor_ = [size / 2 - displacement[0], size / 2 + displacement[1]]; this.size_ = [size, size]; } From a0da16e4e901e9de1b2c52caadac8118c7f5068c Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Mon, 25 Oct 2021 10:22:40 +0100 Subject: [PATCH 3/7] handle updateable displacement --- src/ol/style/Icon.js | 83 +++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/src/ol/style/Icon.js b/src/ol/style/Icon.js index 244bbf2525..1a40e35711 100644 --- a/src/ol/style/Icon.js +++ b/src/ol/style/Icon.js @@ -32,7 +32,7 @@ import {getUid} from '../util.js'; * to provide the size of the image, with the `imgSize` option. * @property {Array} [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 {Array} [displacement=[0,0]] Displacement the icon + * @property {Array} [displacement=[0,0]] Displacement of the icon. * @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. @@ -244,53 +244,50 @@ class Icon extends ImageStyle { * @api */ getAnchor() { - if (this.normalizedAnchor_) { - return this.normalizedAnchor_; - } - let anchor = this.anchor_; - const size = this.getSize(); - if ( - this.anchorXUnits_ == IconAnchorUnits.FRACTION || - this.anchorYUnits_ == IconAnchorUnits.FRACTION - ) { - if (!size) { - return null; - } - anchor = this.anchor_.slice(); - if (this.anchorXUnits_ == IconAnchorUnits.FRACTION) { - anchor[0] *= size[0]; - } - if (this.anchorYUnits_ == IconAnchorUnits.FRACTION) { - anchor[1] *= size[1]; - } - } - - if (this.anchorOrigin_ != IconOrigin.TOP_LEFT) { - if (!size) { - return null; - } - if (anchor === this.anchor_) { + let anchor = this.normalizedAnchor_; + if (!anchor) { + anchor = this.anchor_; + const size = this.getSize(); + if ( + this.anchorXUnits_ == IconAnchorUnits.FRACTION || + this.anchorYUnits_ == IconAnchorUnits.FRACTION + ) { + if (!size) { + return null; + } anchor = this.anchor_.slice(); + if (this.anchorXUnits_ == IconAnchorUnits.FRACTION) { + anchor[0] *= size[0]; + } + if (this.anchorYUnits_ == IconAnchorUnits.FRACTION) { + anchor[1] *= size[1]; + } } - if ( - this.anchorOrigin_ == IconOrigin.TOP_RIGHT || - this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT - ) { - anchor[0] = -anchor[0] + size[0]; - } - if ( - this.anchorOrigin_ == IconOrigin.BOTTOM_LEFT || - this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT - ) { - anchor[1] = -anchor[1] + size[1]; + + if (this.anchorOrigin_ != IconOrigin.TOP_LEFT) { + if (!size) { + return null; + } + if (anchor === this.anchor_) { + anchor = this.anchor_.slice(); + } + if ( + this.anchorOrigin_ == IconOrigin.TOP_RIGHT || + this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT + ) { + anchor[0] = -anchor[0] + size[0]; + } + if ( + this.anchorOrigin_ == IconOrigin.BOTTOM_LEFT || + this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT + ) { + anchor[1] = -anchor[1] + size[1]; + } } + this.normalizedAnchor_ = anchor; } const displacement = this.getDisplacement(); - anchor[0] -= displacement[0]; - anchor[1] += displacement[1]; - - this.normalizedAnchor_ = anchor; - return this.normalizedAnchor_; + return [anchor[0] - displacement[0], anchor[1] + displacement[1]]; } /** From eb0bfc970e40650ffaa0e38f79e88214e5d6a453 Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Mon, 25 Oct 2021 10:27:18 +0100 Subject: [PATCH 4/7] Test setDisplacement Test getAnchor with displacement --- test/browser/spec/ol/style/regularshape.test.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/browser/spec/ol/style/regularshape.test.js b/test/browser/spec/ol/style/regularshape.test.js index af92e7c5b4..dc9f4e05ba 100644 --- a/test/browser/spec/ol/style/regularshape.test.js +++ b/test/browser/spec/ol/style/regularshape.test.js @@ -87,6 +87,7 @@ describe('ol.style.RegularShape', function () { expect(style.getDisplacement()).to.an('array'); expect(style.getDisplacement()[0]).to.eql(0); expect(style.getDisplacement()[1]).to.eql(0); + expect(style.getAnchor()).to.eql([5, 5]); }); it('will use the larger radius to calculate the size', function () { let style = new RegularShape({ @@ -109,6 +110,12 @@ describe('ol.style.RegularShape', function () { expect(style.getDisplacement()).to.an('array'); expect(style.getDisplacement()[0]).to.eql(10); expect(style.getDisplacement()[1]).to.eql(20); + expect(style.getAnchor()).to.eql([-5, 25]); + style.setDisplacement([20, 10]); + expect(style.getDisplacement()).to.an('array'); + expect(style.getDisplacement()[0]).to.eql(20); + expect(style.getDisplacement()[1]).to.eql(10); + expect(style.getAnchor()).to.eql([-15, 15]); }); }); From f16482b420534ffc49b772c1aefa1b1f8f03f73f Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Mon, 25 Oct 2021 10:28:54 +0100 Subject: [PATCH 5/7] Test setDisplacement --- test/browser/spec/ol/style/icon.test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/browser/spec/ol/style/icon.test.js b/test/browser/spec/ol/style/icon.test.js index 0cb4fc8fce..5606b214a9 100644 --- a/test/browser/spec/ol/style/icon.test.js +++ b/test/browser/spec/ol/style/icon.test.js @@ -198,6 +198,11 @@ describe('ol.style.Icon', function () { size[0] / 2 - 20, size[1] / 2 + 10, ]); + iconStyle.setDisplacement([10, 20]); + expect(iconStyle.getAnchor()).to.eql([ + size[0] / 2 - 10, + size[1] / 2 + 20, + ]); }); }); From 6640d2d069fcf47ced4d18555931a3cd5b87e3f6 Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Mon, 25 Oct 2021 10:33:31 +0100 Subject: [PATCH 6/7] new example --- examples/data/openweather/weather.json | 1 + examples/wind-arrows.html | 13 +++++ examples/wind-arrows.js | 80 ++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 examples/data/openweather/weather.json create mode 100644 examples/wind-arrows.html create mode 100644 examples/wind-arrows.js diff --git a/examples/data/openweather/weather.json b/examples/data/openweather/weather.json new file mode 100644 index 0000000000..18676eb39e --- /dev/null +++ b/examples/data/openweather/weather.json @@ -0,0 +1 @@ +{"message":"accurate","cod":"200","count":50,"list":[{"id":4337845,"name":"Port Fourchon","coord":{"lat":29.1058,"lon":-90.1945},"main":{"temp":299.63,"feels_like":299.63,"temp_min":299.63,"temp_max":299.63,"pressure":993,"humidity":92,"sea_level":993,"grnd_level":993},"dt":1630275030,"wind":{"speed":29.47,"deg":214},"sys":{"country":"US"},"rain":{"1h":5.62},"snow":null,"clouds":{"all":95},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4330751,"name":"Leeville","coord":{"lat":29.248,"lon":-90.2076},"main":{"temp":297.6,"feels_like":298.5,"temp_min":297.6,"temp_max":298.16,"pressure":988,"humidity":92,"sea_level":988,"grnd_level":988},"dt":1630275028,"wind":{"speed":31.43,"deg":213},"sys":{"country":"US"},"rain":{"1h":6.48},"snow":null,"clouds":{"all":88},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4323131,"name":"Dulac","coord":{"lat":29.3888,"lon":-90.714},"main":{"temp":297.59,"feels_like":298.47,"temp_min":297.59,"temp_max":297.59,"pressure":983,"humidity":91,"sea_level":983,"grnd_level":983},"dt":1630275025,"wind":{"speed":21.65,"deg":268},"sys":{"country":"US"},"rain":{"1h":8.65},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4325859,"name":"Golden Meadow","coord":{"lat":29.3791,"lon":-90.2601},"main":{"temp":297.66,"feels_like":298.57,"temp_min":297.04,"temp_max":298.15,"pressure":982,"humidity":92,"sea_level":982,"grnd_level":982},"dt":1630275026,"wind":{"speed":27.31,"deg":210},"sys":{"country":"US"},"rain":{"1h":27.34},"snow":null,"clouds":{"all":93},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4319668,"name":"Chauvin","coord":{"lat":29.4386,"lon":-90.5954},"main":{"temp":297.59,"feels_like":298.52,"temp_min":297.59,"temp_max":297.6,"pressure":979,"humidity":93,"sea_level":979,"grnd_level":979},"dt":1630275025,"wind":{"speed":19.89,"deg":256},"sys":{"country":"US"},"rain":{"1h":11.53},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4325424,"name":"Galliano","coord":{"lat":29.4422,"lon":-90.2992},"main":{"temp":297.63,"feels_like":298.56,"temp_min":297.04,"temp_max":298.15,"pressure":979,"humidity":93,"sea_level":979,"grnd_level":979},"dt":1630275026,"wind":{"speed":23.92,"deg":211},"sys":{"country":"US"},"rain":{"1h":31.58},"snow":null,"clouds":{"all":97},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4333695,"name":"Montegut","coord":{"lat":29.4744,"lon":-90.557},"main":{"temp":297.59,"feels_like":298.52,"temp_min":297.15,"temp_max":297.6,"pressure":977,"humidity":93,"sea_level":977,"grnd_level":977},"dt":1630275170,"wind":{"speed":18.27,"deg":252},"sys":{"country":"US"},"rain":{"1h":2.65},"snow":null,"clouds":{"all":100},"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}]},{"id":4343313,"name":"Terrebonne Parish","coord":{"lat":29.3766,"lon":-90.8501},"main":{"temp":297.59,"feels_like":298.47,"temp_min":297.59,"temp_max":297.59,"pressure":987,"humidity":91,"sea_level":987,"grnd_level":987},"dt":1630275031,"wind":{"speed":21.22,"deg":278},"sys":{"country":"US"},"rain":{"1h":9.99},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4326198,"name":"Grand Isle","coord":{"lat":29.2366,"lon":-89.9873},"main":{"temp":298.16,"feels_like":299.14,"temp_min":298.16,"temp_max":298.16,"pressure":993,"humidity":93,"sea_level":993,"grnd_level":993},"dt":1630275026,"wind":{"speed":30.22,"deg":192},"sys":{"country":"US"},"rain":{"1h":6.48},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4317709,"name":"Bourg","coord":{"lat":29.5536,"lon":-90.6023},"main":{"temp":297.57,"feels_like":298.57,"temp_min":297.04,"temp_max":298.15,"pressure":976,"humidity":96,"sea_level":976,"grnd_level":976},"dt":1630274970,"wind":{"speed":12.98,"deg":268},"sys":{"country":"US"},"rain":{"1h":0.15},"snow":null,"clouds":{"all":100},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}]},{"id":4321399,"name":"Cut Off","coord":{"lat":29.5427,"lon":-90.3381},"main":{"temp":297.6,"feels_like":298.56,"temp_min":297.04,"temp_max":298.15,"pressure":976,"humidity":94,"sea_level":976,"grnd_level":976},"dt":1630274970,"wind":{"speed":17.22,"deg":205},"sys":{"country":"US"},"rain":{"1h":17.76},"snow":null,"clouds":{"all":100},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4330185,"name":"Lafourche Parish","coord":{"lat":29.5669,"lon":-90.3834},"main":{"temp":297.59,"feels_like":298.6,"temp_min":297.04,"temp_max":298.15,"pressure":975,"humidity":96,"sea_level":975,"grnd_level":975},"dt":1630275170,"wind":{"speed":13.65,"deg":210},"sys":{"country":"US"},"rain":{"1h":2.69},"snow":null,"clouds":{"all":100},"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}]},{"id":4338040,"name":"Presquille","coord":{"lat":29.5638,"lon":-90.6462},"main":{"temp":297.58,"feels_like":298.59,"temp_min":297.15,"temp_max":297.6,"pressure":977,"humidity":96,"sea_level":977,"grnd_level":977},"dt":1630275170,"wind":{"speed":13.19,"deg":280},"sys":{"country":"US"},"rain":{"1h":2.99},"snow":null,"clouds":{"all":100},"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}]},{"id":4330541,"name":"Larose","coord":{"lat":29.5724,"lon":-90.3818},"main":{"temp":297.6,"feels_like":298.61,"temp_min":297.05,"temp_max":298.16,"pressure":975,"humidity":96,"sea_level":975,"grnd_level":975},"dt":1630275170,"wind":{"speed":13.29,"deg":208},"sys":{"country":"US"},"rain":{"1h":2.69},"snow":null,"clouds":{"all":100},"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}]},{"id":4328010,"name":"Houma","coord":{"lat":29.5958,"lon":-90.7195},"main":{"temp":297.58,"feels_like":298.59,"temp_min":297.15,"temp_max":297.6,"pressure":978,"humidity":96,"sea_level":978,"grnd_level":978},"dt":1630274960,"wind":{"speed":14.3,"deg":301},"sys":{"country":"US"},"rain":{"1h":7.99},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4331530,"name":"Lockport","coord":{"lat":29.646,"lon":-90.5393},"main":{"temp":297.56,"feels_like":298.56,"temp_min":297.04,"temp_max":298.15,"pressure":941,"humidity":96},"dt":1630275170,"wind":{"speed":15.2,"deg":80},"sys":{"country":"US"},"rain":{"1h":1.81},"snow":null,"clouds":{"all":100},"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}]},{"id":4331531,"name":"Lockport Heights","coord":{"lat":29.6505,"lon":-90.5465},"main":{"temp":297.56,"feels_like":298.56,"temp_min":297.04,"temp_max":298.15,"pressure":941,"humidity":96},"dt":1630275170,"wind":{"speed":15.2,"deg":80},"sys":{"country":"US"},"rain":{"1h":1.81},"snow":null,"clouds":{"all":100},"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}]},{"id":4315768,"name":"Bayou Cane","coord":{"lat":29.6241,"lon":-90.7512},"main":{"temp":297.57,"feels_like":298.6,"temp_min":297.15,"temp_max":297.6,"pressure":978,"humidity":97,"sea_level":978,"grnd_level":978},"dt":1630274960,"wind":{"speed":15.11,"deg":312},"sys":{"country":"US"},"rain":{"1h":8.91},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4332788,"name":"Mathews","coord":{"lat":29.6863,"lon":-90.5468},"main":{"temp":297.55,"feels_like":298.55,"temp_min":297.04,"temp_max":298.15,"pressure":941,"humidity":96},"dt":1630275170,"wind":{"speed":15.2,"deg":80},"sys":{"country":"US"},"rain":{"1h":13.46},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4338298,"name":"Raceland","coord":{"lat":29.7274,"lon":-90.599},"main":{"temp":297.53,"feels_like":298.53,"temp_min":297.03,"temp_max":298.14,"pressure":941,"humidity":96},"dt":1630275030,"wind":{"speed":15.2,"deg":80},"sys":{"country":"US"},"rain":{"1h":27.34},"snow":null,"clouds":{"all":100},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4326320,"name":"Gray","coord":{"lat":29.6977,"lon":-90.7865},"main":{"temp":297.57,"feels_like":298.6,"temp_min":297.06,"temp_max":298.14,"pressure":976,"humidity":97},"dt":1630275170,"wind":{"speed":21.9,"deg":355},"sys":{"country":"US"},"rain":{"1h":16.33},"snow":null,"clouds":{"all":100},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4330172,"name":"Lafitte","coord":{"lat":29.6669,"lon":-90.1084},"main":{"temp":297.61,"feels_like":298.57,"temp_min":297.04,"temp_max":298.15,"pressure":981,"humidity":94,"sea_level":981,"grnd_level":981},"dt":1630275170,"wind":{"speed":22.87,"deg":155},"sys":{"country":"US"},"rain":{"1h":48.63},"snow":null,"clouds":{"all":100},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":7708264,"name":"Donna Lynns Mobile Home Park","coord":{"lat":29.6393,"lon":-90.9604},"main":{"temp":297.59,"feels_like":298.49,"temp_min":297.15,"temp_max":298.15,"pressure":986,"humidity":92,"sea_level":986,"grnd_level":986},"dt":1630275025,"wind":{"speed":17.32,"deg":318},"sys":{"country":"US"},"rain":{"1h":13.32},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4341007,"name":"Schriever","coord":{"lat":29.7421,"lon":-90.8104},"main":{"temp":297.57,"feels_like":298.6,"temp_min":297.06,"temp_max":298.14,"pressure":976,"humidity":97},"dt":1630275170,"wind":{"speed":21.9,"deg":355},"sys":{"country":"US"},"rain":{"1h":17.76},"snow":null,"clouds":{"all":100},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4315845,"name":"Bayou Gauche","coord":{"lat":29.7874,"lon":-90.4131},"main":{"temp":297.54,"feels_like":298.54,"temp_min":297.05,"temp_max":298.16,"pressure":974,"humidity":96,"sea_level":974,"grnd_level":974},"dt":1630275168,"wind":{"speed":9.1,"deg":97},"sys":{"country":"US"},"rain":{"1h":26.84},"snow":null,"clouds":{"all":100},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4315422,"name":"Barataria","coord":{"lat":29.7233,"lon":-90.1237},"main":{"temp":297.61,"feels_like":298.7,"temp_min":297.05,"temp_max":298.16,"pressure":980,"humidity":99,"sea_level":980,"grnd_level":980},"dt":1630275168,"wind":{"speed":22.12,"deg":144},"sys":{"country":"US"},"rain":{"1h":23.68},"snow":null,"clouds":{"all":100},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4328931,"name":"Jean Lafitte","coord":{"lat":29.736,"lon":-90.1267},"main":{"temp":297.6,"feels_like":298.69,"temp_min":297.04,"temp_max":298.15,"pressure":980,"humidity":99,"sea_level":980,"grnd_level":980},"dt":1630275170,"wind":{"speed":22.1,"deg":141},"sys":{"country":"US"},"rain":{"1h":23.68},"snow":null,"clouds":{"all":100},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4328978,"name":"Jefferson","coord":{"lat":29.7335,"lon":-90.1001},"main":{"temp":297.6,"feels_like":298.69,"temp_min":297.04,"temp_max":298.15,"pressure":981,"humidity":99,"sea_level":981,"grnd_level":981},"dt":1630275028,"wind":{"speed":23.28,"deg":142},"sys":{"country":"US"},"rain":{"1h":20.51},"snow":null,"clouds":{"all":100},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4322016,"name":"Des Allemands","coord":{"lat":29.8238,"lon":-90.4751},"main":{"temp":297.53,"feels_like":298.53,"temp_min":297.04,"temp_max":298.15,"pressure":974,"humidity":96,"sea_level":974,"grnd_level":974},"dt":1630274970,"wind":{"speed":10.14,"deg":70},"sys":{"country":"US"},"rain":{"1h":36.46},"snow":null,"clouds":{"all":100},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4337452,"name":"Plaquemines","coord":{"lat":29.4502,"lon":-89.7001},"main":{"temp":297.87,"feels_like":298.83,"temp_min":297.05,"temp_max":298.16,"pressure":995,"humidity":93,"sea_level":995,"grnd_level":995},"dt":1630275030,"wind":{"speed":24.84,"deg":161},"sys":{"country":"US"},"rain":{"1h":8.21},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4343429,"name":"Thibodaux","coord":{"lat":29.7958,"lon":-90.8229},"main":{"temp":297.52,"feels_like":298.55,"temp_min":297.05,"temp_max":297.6,"pressure":976,"humidity":97},"dt":1630274970,"wind":{"speed":21.9,"deg":355},"sys":{"country":"US"},"rain":{"1h":15.38},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4314724,"name":"Amelia","coord":{"lat":29.6663,"lon":-91.102},"main":{"temp":297.64,"feels_like":298.49,"temp_min":297.16,"temp_max":298.16,"pressure":991,"humidity":90,"sea_level":991,"grnd_level":991},"dt":1630275024,"wind":{"speed":17.56,"deg":322},"sys":{"country":"US"},"rain":{"1h":3.16},"snow":null,"clouds":{"all":100},"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}]},{"id":4337859,"name":"Port Sulphur","coord":{"lat":29.4805,"lon":-89.6939},"main":{"temp":297.82,"feels_like":298.8,"temp_min":297.04,"temp_max":298.15,"pressure":995,"humidity":94,"sea_level":995,"grnd_level":995},"dt":1630275030,"wind":{"speed":24.76,"deg":158},"sys":{"country":"US"},"rain":{"1h":8.21},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4336492,"name":"Paradis","coord":{"lat":29.8797,"lon":-90.434},"main":{"temp":297.52,"feels_like":298.49,"temp_min":296.51,"temp_max":298.21,"pressure":976,"humidity":95,"sea_level":976,"grnd_level":976},"dt":1630275170,"wind":{"speed":14.94,"deg":80},"sys":{"country":"US"},"rain":{"1h":18.45},"snow":null,"clouds":{"all":100},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4317718,"name":"Boutte","coord":{"lat":29.9024,"lon":-90.3881},"main":{"temp":297.52,"feels_like":298.52,"temp_min":297.04,"temp_max":298.21,"pressure":987,"humidity":96},"dt":1630274970,"wind":{"speed":21.61,"deg":80},"sys":{"country":"US"},"rain":{"1h":15.38},"snow":null,"clouds":{"all":90},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"},{"id":741,"main":"Fog","description":"fog","icon":"50d"}]},{"id":4323873,"name":"Estelle","coord":{"lat":29.8458,"lon":-90.1067},"main":{"temp":297.59,"feels_like":298.28,"temp_min":297.04,"temp_max":298.18,"pressure":989,"humidity":84},"dt":1630274960,"wind":{"speed":10.73,"deg":71},"sys":{"country":"US"},"rain":{"1h":30.73},"snow":null,"clouds":{"all":90},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"},{"id":701,"main":"Mist","description":"mist","icon":"50d"}]},{"id":4319507,"name":"Chackbay","coord":{"lat":29.8835,"lon":-90.7973},"main":{"temp":297.54,"feels_like":298.57,"temp_min":297.07,"temp_max":298.19,"pressure":982,"humidity":97,"sea_level":982,"grnd_level":982},"dt":1630275025,"wind":{"speed":17.7,"deg":8},"sys":{"country":"US"},"rain":{"1h":5.62},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4330088,"name":"Labadieville","coord":{"lat":29.8374,"lon":-90.9562},"main":{"temp":297.57,"feels_like":298.6,"temp_min":297.05,"temp_max":298.18,"pressure":986,"humidity":97,"sea_level":986,"grnd_level":986},"dt":1630275028,"wind":{"speed":18.8,"deg":349},"sys":{"country":"US"},"rain":{"1h":6.48},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4333811,"name":"Morgan City","coord":{"lat":29.6994,"lon":-91.2068},"main":{"temp":297.65,"feels_like":298.48,"temp_min":297.59,"temp_max":298.15,"pressure":994,"humidity":89,"sea_level":994,"grnd_level":994},"dt":1630275170,"wind":{"speed":16.89,"deg":324},"sys":{"country":"US"},"rain":{"1h":0.6},"snow":null,"clouds":{"all":100},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}]},{"id":4346615,"name":"Woodmere","coord":{"lat":29.858,"lon":-90.0804},"main":{"temp":297.59,"feels_like":298.28,"temp_min":297.04,"temp_max":298.18,"pressure":990,"humidity":84},"dt":1630275170,"wind":{"speed":10.73,"deg":71},"sys":{"country":"US"},"rain":{"1h":31.58},"snow":null,"clouds":{"all":90},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"},{"id":701,"main":"Mist","description":"mist","icon":"50d"}]},{"id":7707966,"name":"Hassel's Trailer Park","coord":{"lat":29.8528,"lon":-90.0603},"main":{"temp":297.6,"feels_like":298.29,"temp_min":297.04,"temp_max":298.18,"pressure":990,"humidity":84},"dt":1630275256,"wind":{"speed":10.73,"deg":71},"sys":{"country":"US"},"rain":{"1h":31.58},"snow":null,"clouds":{"all":90},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"},{"id":701,"main":"Mist","description":"mist","icon":"50d"}]},{"id":4316523,"name":"Berwick","coord":{"lat":29.6947,"lon":-91.219},"main":{"temp":297.65,"feels_like":298.48,"temp_min":297.59,"temp_max":298.15,"pressure":994,"humidity":89,"sea_level":994,"grnd_level":994},"dt":1630274970,"wind":{"speed":16.83,"deg":323},"sys":{"country":"US"},"rain":{"1h":0.65},"snow":null,"clouds":{"all":100},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}]},{"id":4332109,"name":"Luling","coord":{"lat":29.9322,"lon":-90.3665},"main":{"temp":297.51,"feels_like":298.51,"temp_min":297.03,"temp_max":298.2,"pressure":987,"humidity":96},"dt":1630274970,"wind":{"speed":21.61,"deg":80},"sys":{"country":"US"},"rain":{"1h":15.38},"snow":null,"clouds":{"all":90},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"},{"id":741,"main":"Fog","description":"fog","icon":"50d"}]},{"id":4342089,"name":"South Vacherie","coord":{"lat":29.9274,"lon":-90.6998},"main":{"temp":297.51,"feels_like":298.51,"temp_min":297.04,"temp_max":298.21,"pressure":980,"humidity":96,"sea_level":980,"grnd_level":980},"dt":1630275030,"wind":{"speed":17.5,"deg":28},"sys":{"country":"US"},"rain":{"1h":11.53},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4315225,"name":"Avondale","coord":{"lat":29.913,"lon":-90.2037},"main":{"temp":297.55,"feels_like":298.24,"temp_min":297.04,"temp_max":298.21,"pressure":987,"humidity":84},"dt":1630274970,"wind":{"speed":13.86,"deg":83},"sys":{"country":"US"},"rain":{"1h":31.58},"snow":null,"clouds":{"all":90},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"},{"id":741,"main":"Fog","description":"fog","icon":"50d"}]},{"id":4322034,"name":"Destrehan","coord":{"lat":29.943,"lon":-90.3518},"main":{"temp":297.51,"feels_like":298.51,"temp_min":297.03,"temp_max":298.2,"pressure":987,"humidity":96},"dt":1630275170,"wind":{"speed":21.61,"deg":80},"sys":{"country":"US"},"rain":{"1h":13.32},"snow":null,"clouds":{"all":90},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"},{"id":741,"main":"Fog","description":"fog","icon":"50d"}]},{"id":4344819,"name":"Waggaman","coord":{"lat":29.9185,"lon":-90.2109},"main":{"temp":297.55,"feels_like":298.24,"temp_min":297.04,"temp_max":298.21,"pressure":987,"humidity":84},"dt":1630275170,"wind":{"speed":13.86,"deg":83},"sys":{"country":"US"},"rain":{"1h":27.34},"snow":null,"clouds":{"all":90},"weather":[{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"},{"id":741,"main":"Fog","description":"fog","icon":"50d"}]},{"id":4342949,"name":"Supreme","coord":{"lat":29.8594,"lon":-90.9812},"main":{"temp":297.55,"feels_like":298.45,"temp_min":296.5,"temp_max":298.18,"pressure":988,"humidity":92,"sea_level":988,"grnd_level":987},"dt":1630275170,"wind":{"speed":19.24,"deg":351},"sys":{"country":"US"},"rain":{"1h":7.49},"snow":null,"clouds":{"all":100},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}]},{"id":4345968,"name":"Westwego","coord":{"lat":29.906,"lon":-90.1423},"main":{"temp":297.57,"feels_like":298.34,"temp_min":297.04,"temp_max":298.18,"pressure":990,"humidity":87},"dt":1630275170,"wind":{"speed":13.86,"deg":83},"sys":{"country":"US"},"rain":{"1h":27.34},"snow":null,"clouds":{"all":90},"weather":[{"id":701,"main":"Mist","description":"mist","icon":"50d"},{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]},{"id":4340551,"name":"Saint Rose","coord":{"lat":29.9469,"lon":-90.3231},"main":{"temp":297.51,"feels_like":298.51,"temp_min":297.03,"temp_max":298.2,"pressure":987,"humidity":96},"dt":1630274970,"wind":{"speed":21.61,"deg":80},"sys":{"country":"US"},"rain":{"1h":17.76},"snow":null,"clouds":{"all":90},"weather":[{"id":741,"main":"Fog","description":"fog","icon":"50d"},{"id":503,"main":"Rain","description":"very heavy rain","icon":"10d"}]}]} diff --git a/examples/wind-arrows.html b/examples/wind-arrows.html new file mode 100644 index 0000000000..b70441b342 --- /dev/null +++ b/examples/wind-arrows.html @@ -0,0 +1,13 @@ +--- +layout: example.html +title: Wind Arrows +shortdesc: Example of Wind Arrows styled using Regular Shapes. +docs: > + This example shows wind arrows styled using regular shapes for the + arrow shaft and head. The shaft is scaled based on the wind speed + and a corresponding displacement is used to position the unscaled + arrow head at the end of the scaled shaft. + The weather data is provided by OpenWeather. +tags: "vector, symbol, regularshape, style, arrow" +--- +
diff --git a/examples/wind-arrows.js b/examples/wind-arrows.js new file mode 100644 index 0000000000..30f24e4896 --- /dev/null +++ b/examples/wind-arrows.js @@ -0,0 +1,80 @@ +import Feature from '../src/ol/Feature.js'; +import Map from '../src/ol/Map.js'; +import OSM from '../src/ol/source/OSM.js'; +import Point from '../src/ol/geom/Point.js'; +import TileLayer from '../src/ol/layer/Tile.js'; +import VectorLayer from '../src/ol/layer/Vector.js'; +import VectorSource from '../src/ol/source/Vector.js'; +import View from '../src/ol/View.js'; +import {Fill, RegularShape, Stroke, Style} from '../src/ol/style.js'; +import {fromLonLat} from '../src/ol/proj.js'; + +const shaft = new RegularShape({ + points: 2, + radius: 20, + stroke: new Stroke({ + width: 2, + color: 'rgba(0,0,0,0.5)', + }), + rotateWithView: true, +}); + +const head = new RegularShape({ + points: 3, + radius: 10, + fill: new Fill({ + color: 'rgba(0,0,0,0.5)', + }), + rotateWithView: true, +}); + +const styles = [new Style({image: shaft}), new Style({image: head})]; + +const source = new VectorSource(); + +const map = new Map({ + layers: [ + new TileLayer({ + source: new OSM(), + }), + new VectorLayer({ + source: source, + style: function (feature) { + const wind = feature.get('wind'); + // rotate arrow away from wind origin + const angle = ((wind.deg - 180) * Math.PI) / 180; + const scale = wind.speed / 10; + shaft.setScale([1, scale]); + shaft.setRotation(angle); + head.setDisplacement([ + 0, + head.getRadius() / 2 + shaft.getRadius() * scale, + ]); + head.setRotation(angle); + return styles; + }, + }), + ], + target: 'map', + view: new View({ + center: [0, 0], + zoom: 2, + }), +}); + +fetch('data/openweather/weather.json') + .then(function (response) { + return response.json(); + }) + .then(function (data) { + const features = []; + data.list.forEach(function (report) { + const feature = new Feature( + new Point(fromLonLat([report.coord.lon, report.coord.lat])) + ); + feature.setProperties(report); + features.push(feature); + }); + source.addFeatures(features); + map.getView().fit(source.getExtent()); + }); From f1c0781eb22c8ede3999ebba99948b49c8bd8d7d Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Tue, 26 Oct 2021 16:55:56 -0600 Subject: [PATCH 7/7] Example style update --- examples/wind-arrows.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/wind-arrows.js b/examples/wind-arrows.js index 30f24e4896..c3fb5834fe 100644 --- a/examples/wind-arrows.js +++ b/examples/wind-arrows.js @@ -11,26 +11,29 @@ import {fromLonLat} from '../src/ol/proj.js'; const shaft = new RegularShape({ points: 2, - radius: 20, + radius: 5, stroke: new Stroke({ width: 2, - color: 'rgba(0,0,0,0.5)', + color: 'black', }), rotateWithView: true, }); const head = new RegularShape({ points: 3, - radius: 10, + radius: 5, fill: new Fill({ - color: 'rgba(0,0,0,0.5)', + color: 'black', }), rotateWithView: true, }); const styles = [new Style({image: shaft}), new Style({image: head})]; -const source = new VectorSource(); +const source = new VectorSource({ + attributions: + 'Weather data by OpenWeather', +}); const map = new Map({ layers: [