diff --git a/src/ol/render/canvas/LineStringBuilder.js b/src/ol/render/canvas/LineStringBuilder.js index b64021e722..d8f3a1424c 100644 --- a/src/ol/render/canvas/LineStringBuilder.js +++ b/src/ol/render/canvas/LineStringBuilder.js @@ -6,6 +6,7 @@ import CanvasInstruction, { beginPathInstruction, strokeInstruction, } from './Instruction.js'; +import {defaultLineDash, defaultLineDashOffset} from '../canvas.js'; class CanvasLineStringBuilder extends CanvasBuilder { /** @@ -67,8 +68,8 @@ class CanvasLineStringBuilder extends CanvasBuilder { state.lineCap, state.lineJoin, state.miterLimit, - state.lineDash, - state.lineDashOffset, + defaultLineDash, + defaultLineDashOffset, ], beginPathInstruction ); diff --git a/src/ol/render/canvas/hitdetect.js b/src/ol/render/canvas/hitdetect.js index 85d471240c..69014b87b9 100644 --- a/src/ol/render/canvas/hitdetect.js +++ b/src/ol/render/canvas/hitdetect.js @@ -74,6 +74,7 @@ export function createHitDetectionImageData( const stroke = style.getStroke(); if (stroke) { stroke.setColor(color); + stroke.setLineDash(null); } style.setText(undefined); const image = originalStyle.getImage(); diff --git a/test/spec/ol/layer/vector.test.js b/test/spec/ol/layer/vector.test.js index 9794123ad6..4bb498caa5 100644 --- a/test/spec/ol/layer/vector.test.js +++ b/test/spec/ol/layer/vector.test.js @@ -1,8 +1,10 @@ import Feature from '../../../../src/ol/Feature.js'; import ImageStyle from '../../../../src/ol/style/Image.js'; import Layer from '../../../../src/ol/layer/Layer.js'; +import LineString from '../../../../src/ol/geom/LineString.js'; import Map from '../../../../src/ol/Map.js'; import Point from '../../../../src/ol/geom/Point.js'; +import Stroke from '../../../../src/ol/style/Stroke.js'; import Style, {createDefaultStyle} from '../../../../src/ol/style/Style.js'; import VectorLayer from '../../../../src/ol/layer/Vector.js'; import VectorSource from '../../../../src/ol/source/Vector.js'; @@ -120,9 +122,27 @@ describe('ol.layer.Vector', function () { }); describe('#getFeatures()', function () { - let map, layer; - + let map; beforeEach(function () { + const container = document.createElement('div'); + container.style.width = '256px'; + container.style.height = '256px'; + document.body.appendChild(container); + map = new Map({ + target: container, + view: new View({ + zoom: 2, + center: [0, 0], + }), + }); + }); + + afterEach(function () { + document.body.removeChild(map.getTargetElement()); + map.setTarget(null); + }); + + it('detects features properly', function (done) { const source = new VectorSource({ features: [ new Feature({ @@ -158,36 +178,52 @@ describe('ol.layer.Vector', function () { source.addFeature(feature); - layer = new VectorLayer({ + const layer = new VectorLayer({ source, }); - const container = document.createElement('div'); - container.style.width = '256px'; - container.style.height = '256px'; - document.body.appendChild(container); - map = new Map({ - target: container, - layers: [layer], - view: new View({ - zoom: 2, - center: [0, 0], - }), - }); - }); - - afterEach(function () { - document.body.removeChild(map.getTargetElement()); - map.setTarget(null); - }); - - it('detects features properly', function (done) { + map.addLayer(layer); map.renderSync(); + const pixel = map.getPixelFromCoordinate([-1000000, 0]); + layer.getFeatures(pixel).then(function (features) { expect(features.length).to.equal(1); expect(features[0].get('name')).to.be('feature1'); done(); }); }); + + it('hits lines even if they are dashed', function (done) { + const geometry = new LineString([ + [-1e6, 0], + [1e6, 0], + ]); + const feature = new Feature(geometry); + const layer = new VectorLayer({ + source: new VectorSource({ + features: [feature], + }), + style: new Style({ + stroke: new Stroke({ + color: 'black', + width: 8, + lineDash: [10, 20], + }), + }), + }); + map.addLayer(layer); + map.renderSync(); + + const pixel = map.getPixelFromCoordinate([0, 0]); + + layer + .getFeatures(pixel) + .then(function (features) { + expect(features.length).to.equal(1); + expect(features[0]).to.be(feature); + done(); + }, done) + .catch(done); + }); }); }); diff --git a/test/spec/ol/renderer/map.test.js b/test/spec/ol/renderer/map.test.js index 52cfcbb697..9c57b3feee 100644 --- a/test/spec/ol/renderer/map.test.js +++ b/test/spec/ol/renderer/map.test.js @@ -5,9 +5,10 @@ import MapRenderer from '../../../../src/ol/renderer/Map.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 {Circle, Fill, Style} from '../../../../src/ol/style.js'; +import {Circle, Fill, Stroke, Style} from '../../../../src/ol/style.js'; import { GeometryCollection, + LineString, MultiPoint, Point, } from '../../../../src/ol/geom.js'; @@ -41,10 +42,12 @@ describe('ol.renderer.Map', function () { }), }); }); + afterEach(function () { document.body.removeChild(map.getTargetElement()); map.setTarget(null); }); + it('calls callback with feature, layer and geometry', function () { let hit; const point = new Point([0, 0]); @@ -87,6 +90,41 @@ describe('ol.renderer.Map', function () { expect(hit.feature).to.be(multiGeometry); expect(hit.geometry).to.be(multiPoint); }); + + it('hits lines even if they are dashed', function () { + const geometry = new LineString([ + [-1e6, 0], + [1e6, 0], + ]); + const feature = new Feature(geometry); + const layer = new VectorLayer({ + source: new VectorSource({ + features: [feature], + }), + style: new Style({ + stroke: new Stroke({ + color: 'black', + width: 8, + lineDash: [10, 20], + }), + }), + }); + map.addLayer(layer); + map.renderSync(); + const hit = map.forEachFeatureAtPixel( + [50, 50], + (feature, layer, geometry) => ({ + feature, + layer, + geometry, + }) + ); + + expect(hit).to.be.ok(); + expect(hit.feature).to.be(feature); + expect(hit.layer).to.be(layer); + expect(hit.geometry).to.be(geometry); + }); }); describe('#forEachFeatureAtCoordinate', function () {