From 918a34a9cbb88b227e888813d7ec791f6ae33b94 Mon Sep 17 00:00:00 2001 From: David Manthey Date: Mon, 9 May 2022 15:15:49 -0400 Subject: [PATCH] Accept polygons with holes for annotations via geojson. --- CHANGELOG.md | 12 +++++++++++ src/annotationLayer.js | 38 ++++++++++++++++++++++++---------- tests/cases/annotationLayer.js | 12 +++++++++++ 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 768b6afacb..ee740fad03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # GeoJS Change Log +## Version 1.8.4 + +### Improvements + +- Support polygon annotations with holes through geojson ([#1201](../../pull/1201)) + +## Version 1.8.3 + +### Improvements + +- Support polygon annotations with holes ([#1200](../../pull/1200)) + ## Version 1.8.2 ### Improvements diff --git a/src/annotationLayer.js b/src/annotationLayer.js index 93ee0a40d8..253d03fc78 100644 --- a/src/annotationLayer.js +++ b/src/annotationLayer.js @@ -706,14 +706,25 @@ var annotationLayer = function (arg) { return; } // make a copy of the position array to avoid mutating the original. - position = position.outer.slice(); - if (position[position.length - 1][0] === position[0][0] && - position[position.length - 1][1] === position[0][1]) { - position.splice(position.length - 1, 1); - if (position.length < 3) { + position = { + outer: position.outer.slice(), + inner: (position.inner || []).map((h) => h.slice()) + }; + if (position.outer[position.outer.length - 1][0] === position.outer[0][0] && + position.outer[position.outer.length - 1][1] === position.outer[0][1]) { + position.outer.splice(position.outer.length - 1, 1); + if (position.outer.length < 3) { return; } } + position.inner.forEach((h) => { + if (h.length > 3 && h[h.length - 1][0] === h[0][0] && h[h.length - 1][1] === h[0][1]) { + h.splice(h.length - 1, 1); + } + }); + if (!position.inner || !position.inner.length) { + position = position.outer; + } break; case 'marker': position = data.geometry.coordinates[0].slice(0, 4); @@ -722,15 +733,20 @@ var annotationLayer = function (arg) { position = [feature.position()(data, data_idx)]; break; } - for (i = 0; i < position.length; i += 1) { - position[i] = util.normalizeCoordinates(position[i]); - } datagcs = ((data.crs && data.crs.type === 'name' && data.crs.properties && data.crs.properties.type === 'proj4' && data.crs.properties.name) ? data.crs.properties.name : gcs); - if (datagcs !== map.gcs()) { - position = transform.transformCoordinates(datagcs, map.gcs(), position); - } + [position.outer || position].concat(position.inner || []).forEach((poslist) => { + for (i = 0; i < poslist.length; i += 1) { + poslist[i] = util.normalizeCoordinates(poslist[i]); + } + if (datagcs !== map.gcs()) { + const transposlist = transform.transformCoordinates(datagcs, map.gcs(), poslist); + for (i = 0; i < poslist.length; i += 1) { + poslist[i] = transposlist[i]; + } + } + }); options.coordinates = position; /* For each style listed in the geojsonStyleProperties object, check if * is given under any of the variety of keys as a valid instance of the diff --git a/tests/cases/annotationLayer.js b/tests/cases/annotationLayer.js index 2ebcea52ad..d868ab901f 100644 --- a/tests/cases/annotationLayer.js +++ b/tests/cases/annotationLayer.js @@ -841,6 +841,18 @@ describe('geo.annotationLayer', function () { attr = layer.geojson().features[0].properties; expect(attr.strokeOffset).toBe(0.5); expect(attr.lineCap).toBe('round'); + + var holepoly = { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [[-1.2, 50.75], [-1.4, 50.75], [-1.4, 50.85], [-1.2, 50.85], [-1.2, 50.75]], + [[-1.25, 50.78], [-1.35, 50.78], [-1.35, 50.82], [-1.25, 50.82], [-1.25, 50.78]] + ] + } + }; + expect(layer.geojson(holepoly, true)).toBe(1); }); }); it('Test destroy layer.', function () {