Changes for the CircleStyle inconsistency seen in #9395

Change hit detection test to reflect fix for #9395 CircleStyle inconsistency

Update ol/style/Circle and ol/style/RegularShapen tests
Revise test for no fill
Add test for transparent fill

Update Upgrade notes
Changes to hit detection with unfilled styles
This commit is contained in:
mike-000
2019-09-25 21:17:58 +01:00
parent e1d9f8dd59
commit e28fa56edd
5 changed files with 73 additions and 20 deletions

View File

@@ -279,6 +279,10 @@ The `getGetFeatureInfoUrl` of `ol/source/ImageWMS` and `ol/source/TileWMS` is no
`getFeaturesAtPixel` now returns an empty array instead of null if no features were found.
##### Hit detection with unfilled styles
Hit detection over styled Circle geometry and Circle and RegularShape styles is now consistent with that for styled Polygon geometry. There is no hit detection over the interior of unfilled shapes. To get the previous behavior, specify a Fill style with transparent color.
#### Other changes
##### Allow declutter in image render mode

View File

@@ -2,6 +2,7 @@
* @module ol/style/RegularShape
*/
import {asArray} from '../color.js';
import {asColorLike} from '../colorlike.js';
import {createCanvasContext2D} from '../dom.js';
import ImageState from '../ImageState.js';
@@ -429,17 +430,31 @@ class RegularShape extends ImageStyle {
*/
createHitDetectionCanvas_(renderOptions) {
this.hitDetectionImageSize_ = [renderOptions.size, renderOptions.size];
this.hitDetectionCanvas_ = this.canvas_;
if (this.fill_) {
this.hitDetectionCanvas_ = this.canvas_;
return;
let color = this.fill_.getColor();
// determine if fill is transparent (or pattern or gradient)
let opacity = 0;
if (typeof color === 'string') {
color = asArray(color);
}
if (color === null) {
opacity = 1;
} else if (Array.isArray(color)) {
opacity = color.length === 4 ? color[3] : 1;
}
if (opacity === 0) {
// if a transparent fill style is set, create an extra hit-detection image
// with a default fill style
const context = createCanvasContext2D(renderOptions.size, renderOptions.size);
this.hitDetectionCanvas_ = context.canvas;
this.drawHitDetectionCanvas_(renderOptions, context, 0, 0);
}
}
// if no fill style is set, create an extra hit-detection image with a
// default fill style
const context = createCanvasContext2D(renderOptions.size, renderOptions.size);
this.hitDetectionCanvas_ = context.canvas;
this.drawHitDetectionCanvas_(renderOptions, context, 0, 0);
}
/**

View File

@@ -393,23 +393,21 @@ describe('ol.renderer.canvas.VectorLayer', function() {
geometry: new Circle([7.5, 7.5], 1.5),
fillType: 'transparent'
}),
// CircleStyle transparent and no fill hit detection
// is currently the opposite of ol/Style
new Feature({
geometry: new Point([1.5, 1.5]),
fillType: 'transparent'
fillType: 'none'
}),
new Feature({
geometry: new Point([2.5, 2.5]),
fillType: 'transparent'
fillType: 'none'
}),
new Feature({
geometry: new Point([6.5, 1.5]),
fillType: 'none'
fillType: 'transparent'
}),
new Feature({
geometry: new Point([7.5, 2.5]),
fillType: 'none'
fillType: 'transparent'
})
]
});

View File

@@ -14,13 +14,31 @@ describe('ol.style.Circle', function() {
expect(style.getImageSize()).to.eql([21, 21]);
expect(style.getOrigin()).to.eql([0, 0]);
expect(style.getAnchor()).to.eql([10.5, 10.5]);
// hit-detection image is created, because no fill style is set
// no hit-detection image is created, because no fill style is set
expect(style.getImage()).to.be(style.getHitDetectionImage());
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
expect(style.getHitDetectionImageSize()).to.eql([21, 21]);
});
it('creates a canvas (transparent fill-style)', function() {
const style = new CircleStyle({
radius: 10,
fill: new Fill({
color: 'transparent'
})
});
expect(style.getImage()).to.be.an(HTMLCanvasElement);
expect(style.getSize()).to.eql([21, 21]);
expect(style.getImageSize()).to.eql([21, 21]);
expect(style.getOrigin()).to.eql([0, 0]);
expect(style.getAnchor()).to.eql([10.5, 10.5]);
// hit-detection image is created, because transparent fill style is set
expect(style.getImage()).to.not.be(style.getHitDetectionImage());
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
expect(style.getHitDetectionImageSize()).to.eql([21, 21]);
});
it('creates a canvas (fill-style)', function() {
it('creates a canvas (non-transparent fill-style)', function() {
const style = new CircleStyle({
radius: 10,
fill: new Fill({
@@ -32,7 +50,7 @@ describe('ol.style.Circle', function() {
expect(style.getImageSize()).to.eql([21, 21]);
expect(style.getOrigin()).to.eql([0, 0]);
expect(style.getAnchor()).to.eql([10.5, 10.5]);
// no hit-detection image is created, because fill style is set
// no hit-detection image is created, because non-transparent fill style is set
expect(style.getImage()).to.be(style.getHitDetectionImage());
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
expect(style.getHitDetectionImageSize()).to.eql([21, 21]);

View File

@@ -40,13 +40,31 @@ describe('ol.style.RegularShape', function() {
expect(style.getImageSize()).to.eql([21, 21]);
expect(style.getOrigin()).to.eql([0, 0]);
expect(style.getAnchor()).to.eql([10.5, 10.5]);
// hit-detection image is created, because no fill style is set
// no hit-detection image is created, because no fill style is set
expect(style.getImage()).to.be(style.getHitDetectionImage());
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
expect(style.getHitDetectionImageSize()).to.eql([21, 21]);
});
it('creates a canvas (transparent fill-style)', function() {
const style = new RegularShape({
radius: 10,
fill: new Fill({
color: 'transparent'
})
});
expect(style.getImage()).to.be.an(HTMLCanvasElement);
expect(style.getSize()).to.eql([21, 21]);
expect(style.getImageSize()).to.eql([21, 21]);
expect(style.getOrigin()).to.eql([0, 0]);
expect(style.getAnchor()).to.eql([10.5, 10.5]);
// hit-detection image is created, because transparent fill style is set
expect(style.getImage()).to.not.be(style.getHitDetectionImage());
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
expect(style.getHitDetectionImageSize()).to.eql([21, 21]);
});
it('creates a canvas (fill-style)', function() {
it('creates a canvas (non-transparent fill-style)', function() {
const style = new RegularShape({
radius: 10,
fill: new Fill({
@@ -58,7 +76,7 @@ describe('ol.style.RegularShape', function() {
expect(style.getImageSize()).to.eql([21, 21]);
expect(style.getOrigin()).to.eql([0, 0]);
expect(style.getAnchor()).to.eql([10.5, 10.5]);
// no hit-detection image is created, because fill style is set
// no hit-detection image is created, because non-transparent fill style is set
expect(style.getImage()).to.be(style.getHitDetectionImage());
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
expect(style.getHitDetectionImageSize()).to.eql([21, 21]);