From f47fa8b40709939bfad0a5ee1d4fd182cf9392c3 Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Sat, 12 Oct 2019 16:08:57 +0100 Subject: [PATCH 1/3] Add crossOrigin option for icons Make the crossOrigin setting for icons configurable to avoid errors when KML files reference images when are not CORS enabled Pass scope in readPlacemark_ and to handle IconStyle in a placemark style map Test crossOrigin option for icons Add tests for IconStyle in style maps and shared styles --- src/ol/format/KML.js | 25 +- test/spec/ol/format/kml.test.js | 410 +++++++++++++++++++++++++++++++- 2 files changed, 423 insertions(+), 12 deletions(-) diff --git a/src/ol/format/KML.js b/src/ol/format/KML.js index b6965bcab7..86d00d2fab 100644 --- a/src/ol/format/KML.js +++ b/src/ol/format/KML.js @@ -386,6 +386,8 @@ function createStyleDefaults() { * @property {Array' + + ' ' + + ''; + const fs = format.readFeatures(text); + expect(fs).to.have.length(1); + const f = fs[0]; + expect(f).to.be.an(Feature); + const styleFunction = f.getStyleFunction(); + expect(styleFunction).not.to.be(undefined); + const styleArray = styleFunction(f, 0); + expect(styleArray).to.be.an(Array); + expect(styleArray).to.have.length(1); + const style = styleArray[0]; + expect(style).to.be.an(Style); + expect(style.getFill()).to.be(getDefaultFillStyle()); + expect(style.getStroke()).to.be(getDefaultStrokeStyle()); + const imageStyle = style.getImage(); + expect(imageStyle).to.be.an(Icon); + expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://foo.png').href); + expect(imageStyle.getAnchor()).to.be(null); + expect(imageStyle.getOrigin()).to.be(null); + expect(imageStyle.getRotation()).to.eql(0); + expect(imageStyle.getSize()).to.be(null); + expect(imageStyle.getScale()).to.be(1); + expect(imageStyle.getImage().crossOrigin).to.be(null); expect(style.getText()).to.be(getDefaultTextStyle()); expect(style.getZIndex()).to.be(undefined); }); @@ -2066,8 +2107,6 @@ describe('ol.format.KML', function() { ' ' + ''; const fs = format.readFeatures(text); - - expect(fs).to.have.length(1); const f = fs[0]; expect(f).to.be.an(Feature); @@ -2552,6 +2591,99 @@ describe('ol.format.KML', function() { expect(s.getFill().getColor()).to.eql([0, 0, 0, 0]); }); + it('can read a normal IconStyle', function() { + const text = + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' normal' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''; + const fs = format.readFeatures(text); + expect(fs).to.have.length(1); + const f = fs[0]; + expect(f).to.be.an(Feature); + const styleFunction = f.getStyleFunction(); + expect(styleFunction).not.to.be(undefined); + const styleArray = styleFunction(f, 0); + expect(styleArray).to.be.an(Array); + expect(styleArray).to.have.length(1); + const style = styleArray[0]; + expect(style).to.be.an(Style); + expect(style.getFill()).to.be(getDefaultFillStyle()); + expect(style.getStroke()).to.be(getDefaultStrokeStyle()); + const imageStyle = style.getImage(); + expect(imageStyle).to.be.an(Icon); + expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://bar.png').href); + expect(imageStyle.getAnchor()).to.be(null); + expect(imageStyle.getOrigin()).to.be(null); + expect(imageStyle.getRotation()).to.eql(0); + expect(imageStyle.getSize()).to.be(null); + expect(imageStyle.getScale()).to.be(1); + expect(imageStyle.getImage().crossOrigin).to.eql('anonymous'); + expect(style.getText()).to.be(getDefaultTextStyle()); + expect(style.getZIndex()).to.be(undefined); + }); + + it('can read a normal IconStyle with crossOrigin option', function() { + format = new KML({crossOrigin: null}); + const text = + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' normal' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''; + const fs = format.readFeatures(text); + expect(fs).to.have.length(1); + const f = fs[0]; + expect(f).to.be.an(Feature); + const styleFunction = f.getStyleFunction(); + expect(styleFunction).not.to.be(undefined); + const styleArray = styleFunction(f, 0); + expect(styleArray).to.be.an(Array); + expect(styleArray).to.have.length(1); + const style = styleArray[0]; + expect(style).to.be.an(Style); + expect(style.getFill()).to.be(getDefaultFillStyle()); + expect(style.getStroke()).to.be(getDefaultStrokeStyle()); + const imageStyle = style.getImage(); + expect(imageStyle).to.be.an(Icon); + expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://bar.png').href); + expect(imageStyle.getAnchor()).to.be(null); + expect(imageStyle.getOrigin()).to.be(null); + expect(imageStyle.getRotation()).to.eql(0); + expect(imageStyle.getSize()).to.be(null); + expect(imageStyle.getScale()).to.be(1); + expect(imageStyle.getImage().crossOrigin).to.be(null); + expect(style.getText()).to.be(getDefaultTextStyle()); + expect(style.getZIndex()).to.be(undefined); + }); + it('ignores highlight styles', function() { const text = '' + @@ -2582,7 +2714,6 @@ describe('ol.format.KML', function() { const s = styleArray[0]; expect(s).to.be.an(Style); expect(s).to.be(getDefaultStyle()); - }); it('uses normal styles instead of highlight styles', function() { @@ -2701,7 +2832,7 @@ describe('ol.format.KML', function() { ' ' + ' normal' + ' #foo' + - ' ' + + ' ' + ' ' + ' ' + + ' ' + + ' #fooMap' + + ' ' + + ' ' + + ''; + const fs = format.readFeatures(text); + expect(fs).to.have.length(1); + const f = fs[0]; + expect(f).to.be.an(Feature); + const styleFunction = f.getStyleFunction(); + expect(styleFunction).not.to.be(undefined); + const styleArray = styleFunction(f, 0); + expect(styleArray).to.be.an(Array); + expect(styleArray).to.have.length(1); + const style = styleArray[0]; + expect(style).to.be.an(Style); + expect(style.getFill()).to.be(getDefaultFillStyle()); + expect(style.getStroke()).to.be(getDefaultStrokeStyle()); + const imageStyle = style.getImage(); + expect(imageStyle).to.be.an(Icon); + expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://bar.png').href); + expect(imageStyle.getAnchor()).to.be(null); + expect(imageStyle.getOrigin()).to.be(null); + expect(imageStyle.getRotation()).to.eql(0); + expect(imageStyle.getSize()).to.be(null); + expect(imageStyle.getScale()).to.be(1); + expect(imageStyle.getImage().crossOrigin).to.eql('anonymous'); + expect(style.getText()).to.be(getDefaultTextStyle()); + expect(style.getZIndex()).to.be(undefined); + }); + + it('can use IconStyles with crossOrigin option in StyleMaps before they are defined', function() { + format = new KML({crossOrigin: null}); + const text = + '' + + ' ' + + ' ' + + ' ' + + ' normal' + + ' #foo' + + ' ' + + ' ' + + ' ' + + ' ' + + ' #fooMap' + + ' ' + + ' ' + + ''; + const fs = format.readFeatures(text); + expect(fs).to.have.length(1); + const f = fs[0]; + expect(f).to.be.an(Feature); + const styleFunction = f.getStyleFunction(); + expect(styleFunction).not.to.be(undefined); + const styleArray = styleFunction(f, 0); + expect(styleArray).to.be.an(Array); + expect(styleArray).to.have.length(1); + const style = styleArray[0]; + expect(style).to.be.an(Style); + expect(style.getFill()).to.be(getDefaultFillStyle()); + expect(style.getStroke()).to.be(getDefaultStrokeStyle()); + const imageStyle = style.getImage(); + expect(imageStyle).to.be.an(Icon); + expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://bar.png').href); + expect(imageStyle.getAnchor()).to.be(null); + expect(imageStyle.getOrigin()).to.be(null); + expect(imageStyle.getRotation()).to.eql(0); + expect(imageStyle.getSize()).to.be(null); + expect(imageStyle.getScale()).to.be(1); + expect(imageStyle.getImage().crossOrigin).to.be(null); + expect(style.getText()).to.be(getDefaultTextStyle()); + expect(style.getZIndex()).to.be(undefined); + }); + }); describe('shared styles', function() { @@ -2762,6 +2990,91 @@ describe('ol.format.KML', function() { expect(fillStyle.getColor()).to.eql([0x78, 0x56, 0x34, 0x12 / 255]); }); + it('can apply a shared IconStyle to a feature', function() { + const text = + '' + + ' ' + + ' ' + + ' ' + + ' #foo' + + ' ' + + ' ' + + ''; + const fs = format.readFeatures(text); + expect(fs).to.have.length(1); + const f = fs[0]; + expect(f).to.be.an(Feature); + const styleFunction = f.getStyleFunction(); + expect(styleFunction).not.to.be(undefined); + const styleArray = styleFunction(f, 0); + expect(styleArray).to.be.an(Array); + expect(styleArray).to.have.length(1); + const style = styleArray[0]; + expect(style).to.be.an(Style); + expect(style.getFill()).to.be(getDefaultFillStyle()); + expect(style.getStroke()).to.be(getDefaultStrokeStyle()); + const imageStyle = style.getImage(); + expect(imageStyle).to.be.an(Icon); + expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://bar.png').href); + expect(imageStyle.getAnchor()).to.be(null); + expect(imageStyle.getOrigin()).to.be(null); + expect(imageStyle.getRotation()).to.eql(0); + expect(imageStyle.getSize()).to.be(null); + expect(imageStyle.getScale()).to.be(1); + expect(imageStyle.getImage().crossOrigin).to.eql('anonymous'); + expect(style.getText()).to.be(getDefaultTextStyle()); + expect(style.getZIndex()).to.be(undefined); + }); + + it('can apply a shared IconStyle with crossOrigin option to a feature', function() { + format = new KML({crossOrigin: null}); + const text = + '' + + ' ' + + ' ' + + ' ' + + ' #foo' + + ' ' + + ' ' + + ''; + const fs = format.readFeatures(text); + expect(fs).to.have.length(1); + const f = fs[0]; + expect(f).to.be.an(Feature); + const styleFunction = f.getStyleFunction(); + expect(styleFunction).not.to.be(undefined); + const styleArray = styleFunction(f, 0); + expect(styleArray).to.be.an(Array); + expect(styleArray).to.have.length(1); + const style = styleArray[0]; + expect(style).to.be.an(Style); + expect(style.getFill()).to.be(getDefaultFillStyle()); + expect(style.getStroke()).to.be(getDefaultStrokeStyle()); + const imageStyle = style.getImage(); + expect(imageStyle).to.be.an(Icon); + expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://bar.png').href); + expect(imageStyle.getAnchor()).to.be(null); + expect(imageStyle.getOrigin()).to.be(null); + expect(imageStyle.getRotation()).to.eql(0); + expect(imageStyle.getSize()).to.be(null); + expect(imageStyle.getScale()).to.be(1); + expect(imageStyle.getImage().crossOrigin).to.be(null); + expect(style.getText()).to.be(getDefaultTextStyle()); + expect(style.getZIndex()).to.be(undefined); + }); + it('can read a shared style from a Folder', function() { const text = '' + @@ -2794,6 +3107,95 @@ describe('ol.format.KML', function() { expect(fillStyle.getColor()).to.eql([0x78, 0x56, 0x34, 0x12 / 255]); }); + it('can read a shared IconStyle from a Folder', function() { + const text = + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' #foo' + + ' ' + + ' ' + + ''; + const fs = format.readFeatures(text); + expect(fs).to.have.length(1); + const f = fs[0]; + expect(f).to.be.an(Feature); + const styleFunction = f.getStyleFunction(); + expect(styleFunction).not.to.be(undefined); + const styleArray = styleFunction(f, 0); + expect(styleArray).to.be.an(Array); + expect(styleArray).to.have.length(1); + const style = styleArray[0]; + expect(style).to.be.an(Style); + expect(style.getFill()).to.be(getDefaultFillStyle()); + expect(style.getStroke()).to.be(getDefaultStrokeStyle()); + const imageStyle = style.getImage(); + expect(imageStyle).to.be.an(Icon); + expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://bar.png').href); + expect(imageStyle.getAnchor()).to.be(null); + expect(imageStyle.getOrigin()).to.be(null); + expect(imageStyle.getRotation()).to.eql(0); + expect(imageStyle.getSize()).to.be(null); + expect(imageStyle.getScale()).to.be(1); + expect(imageStyle.getImage().crossOrigin).to.eql('anonymous'); + expect(style.getText()).to.be(getDefaultTextStyle()); + expect(style.getZIndex()).to.be(undefined); + }); + + it('can read a shared IconStyle with crossOrigin option from a Folder', function() { + format = new KML({crossOrigin: null}); + const text = + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' #foo' + + ' ' + + ' ' + + ''; + const fs = format.readFeatures(text); + expect(fs).to.have.length(1); + const f = fs[0]; + expect(f).to.be.an(Feature); + const styleFunction = f.getStyleFunction(); + expect(styleFunction).not.to.be(undefined); + const styleArray = styleFunction(f, 0); + expect(styleArray).to.be.an(Array); + expect(styleArray).to.have.length(1); + const style = styleArray[0]; + expect(style).to.be.an(Style); + expect(style.getFill()).to.be(getDefaultFillStyle()); + expect(style.getStroke()).to.be(getDefaultStrokeStyle()); + const imageStyle = style.getImage(); + expect(imageStyle).to.be.an(Icon); + expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://bar.png').href); + expect(imageStyle.getAnchor()).to.be(null); + expect(imageStyle.getOrigin()).to.be(null); + expect(imageStyle.getRotation()).to.eql(0); + expect(imageStyle.getSize()).to.be(null); + expect(imageStyle.getScale()).to.be(1); + expect(imageStyle.getImage().crossOrigin).to.be(null); + expect(style.getText()).to.be(getDefaultTextStyle()); + expect(style.getZIndex()).to.be(undefined); + }); + it('can apply a shared style to multiple features', function() { const text = '' + From f13ebbee3f272a5a44eba7ebcddaee28efca5d8c Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Thu, 12 Dec 2019 17:21:14 +0000 Subject: [PATCH 2/3] Add crossOrigin option for icons Add * @this {KML} to functions invoked using .call --- src/ol/format/KML.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ol/format/KML.js b/src/ol/format/KML.js index 86d00d2fab..cc29b0cb16 100644 --- a/src/ol/format/KML.js +++ b/src/ol/format/KML.js @@ -1121,6 +1121,7 @@ const STYLE_MAP_PARSERS = makeStructureNS( /** + * @this {KML} * @param {Element} node Node. * @param {Array<*>} objectStack Object stack. * @return {Array' + - ' ' + - ' ' + - ' ' + - ' ' + - ''; - const fs = format.readFeatures(text); - expect(fs).to.have.length(1); - const f = fs[0]; - expect(f).to.be.an(Feature); - const styleFunction = f.getStyleFunction(); - expect(styleFunction).not.to.be(undefined); - const styleArray = styleFunction(f, 0); - expect(styleArray).to.be.an(Array); - expect(styleArray).to.have.length(1); - const style = styleArray[0]; - expect(style).to.be.an(Style); - expect(style.getFill()).to.be(getDefaultFillStyle()); - expect(style.getStroke()).to.be(getDefaultStrokeStyle()); - const imageStyle = style.getImage(); - expect(imageStyle).to.be.an(Icon); - expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://bar.png').href); - expect(imageStyle.getAnchor()).to.be(null); - expect(imageStyle.getOrigin()).to.be(null); - expect(imageStyle.getRotation()).to.eql(0); - expect(imageStyle.getSize()).to.be(null); - expect(imageStyle.getScale()).to.be(1); - expect(imageStyle.getImage().crossOrigin).to.eql('anonymous'); - expect(style.getText()).to.be(getDefaultTextStyle()); - expect(style.getZIndex()).to.be(undefined); - }); - - it('can read a normal IconStyle with crossOrigin option', function() { + it('can read a normal IconStyle (and set the crossOrigin option)', function() { format = new KML({crossOrigin: null}); const text = '' + @@ -2859,55 +2813,7 @@ describe('ol.format.KML', function() { expect(s.getFill().getColor()).to.eql([120, 86, 52, 18 / 255]); }); - it('can use IconStyles in StyleMaps before they are defined', function() { - const text = - '' + - ' ' + - ' ' + - ' ' + - ' normal' + - ' #foo' + - ' ' + - ' ' + - ' ' + - ' ' + - ' #fooMap' + - ' ' + - ' ' + - ''; - const fs = format.readFeatures(text); - expect(fs).to.have.length(1); - const f = fs[0]; - expect(f).to.be.an(Feature); - const styleFunction = f.getStyleFunction(); - expect(styleFunction).not.to.be(undefined); - const styleArray = styleFunction(f, 0); - expect(styleArray).to.be.an(Array); - expect(styleArray).to.have.length(1); - const style = styleArray[0]; - expect(style).to.be.an(Style); - expect(style.getFill()).to.be(getDefaultFillStyle()); - expect(style.getStroke()).to.be(getDefaultStrokeStyle()); - const imageStyle = style.getImage(); - expect(imageStyle).to.be.an(Icon); - expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://bar.png').href); - expect(imageStyle.getAnchor()).to.be(null); - expect(imageStyle.getOrigin()).to.be(null); - expect(imageStyle.getRotation()).to.eql(0); - expect(imageStyle.getSize()).to.be(null); - expect(imageStyle.getScale()).to.be(1); - expect(imageStyle.getImage().crossOrigin).to.eql('anonymous'); - expect(style.getText()).to.be(getDefaultTextStyle()); - expect(style.getZIndex()).to.be(undefined); - }); - - it('can use IconStyles with crossOrigin option in StyleMaps before they are defined', function() { + it('can use IconStyles in StyleMaps before they are defined (and set the crossOrigin option)', function() { format = new KML({crossOrigin: null}); const text = '' + @@ -2990,49 +2896,7 @@ describe('ol.format.KML', function() { expect(fillStyle.getColor()).to.eql([0x78, 0x56, 0x34, 0x12 / 255]); }); - it('can apply a shared IconStyle to a feature', function() { - const text = - '' + - ' ' + - ' ' + - ' ' + - ' #foo' + - ' ' + - ' ' + - ''; - const fs = format.readFeatures(text); - expect(fs).to.have.length(1); - const f = fs[0]; - expect(f).to.be.an(Feature); - const styleFunction = f.getStyleFunction(); - expect(styleFunction).not.to.be(undefined); - const styleArray = styleFunction(f, 0); - expect(styleArray).to.be.an(Array); - expect(styleArray).to.have.length(1); - const style = styleArray[0]; - expect(style).to.be.an(Style); - expect(style.getFill()).to.be(getDefaultFillStyle()); - expect(style.getStroke()).to.be(getDefaultStrokeStyle()); - const imageStyle = style.getImage(); - expect(imageStyle).to.be.an(Icon); - expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://bar.png').href); - expect(imageStyle.getAnchor()).to.be(null); - expect(imageStyle.getOrigin()).to.be(null); - expect(imageStyle.getRotation()).to.eql(0); - expect(imageStyle.getSize()).to.be(null); - expect(imageStyle.getScale()).to.be(1); - expect(imageStyle.getImage().crossOrigin).to.eql('anonymous'); - expect(style.getText()).to.be(getDefaultTextStyle()); - expect(style.getZIndex()).to.be(undefined); - }); - - it('can apply a shared IconStyle with crossOrigin option to a feature', function() { + it('can apply a shared IconStyle to a feature (and set the crossOrigin option)', function() { format = new KML({crossOrigin: null}); const text = '' + @@ -3107,51 +2971,7 @@ describe('ol.format.KML', function() { expect(fillStyle.getColor()).to.eql([0x78, 0x56, 0x34, 0x12 / 255]); }); - it('can read a shared IconStyle from a Folder', function() { - const text = - '' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' #foo' + - ' ' + - ' ' + - ''; - const fs = format.readFeatures(text); - expect(fs).to.have.length(1); - const f = fs[0]; - expect(f).to.be.an(Feature); - const styleFunction = f.getStyleFunction(); - expect(styleFunction).not.to.be(undefined); - const styleArray = styleFunction(f, 0); - expect(styleArray).to.be.an(Array); - expect(styleArray).to.have.length(1); - const style = styleArray[0]; - expect(style).to.be.an(Style); - expect(style.getFill()).to.be(getDefaultFillStyle()); - expect(style.getStroke()).to.be(getDefaultStrokeStyle()); - const imageStyle = style.getImage(); - expect(imageStyle).to.be.an(Icon); - expect(new URL(imageStyle.getSrc()).href).to.eql(new URL('http://bar.png').href); - expect(imageStyle.getAnchor()).to.be(null); - expect(imageStyle.getOrigin()).to.be(null); - expect(imageStyle.getRotation()).to.eql(0); - expect(imageStyle.getSize()).to.be(null); - expect(imageStyle.getScale()).to.be(1); - expect(imageStyle.getImage().crossOrigin).to.eql('anonymous'); - expect(style.getText()).to.be(getDefaultTextStyle()); - expect(style.getZIndex()).to.be(undefined); - }); - - it('can read a shared IconStyle with crossOrigin option from a Folder', function() { + it('can read a shared IconStyle from a Folder (and set the crossOrigin option)', function() { format = new KML({crossOrigin: null}); const text = '' +