Skip to content

Commit

Permalink
Merge pull request #1236 from OpenGeoscience/uncross-polygon-annotations
Browse files Browse the repository at this point in the history
perf: Uncross polygon annotations.
  • Loading branch information
manthey authored Jun 30, 2022
2 parents e8aceeb + 3aeb434 commit 6d3d1ea
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# GeoJS Change Log

## Version 1.10.6

### Improvements

- Uncross polygon annotations ([#1236](../../pull/1236))

## Version 1.10.5

### Improvements
Expand Down
43 changes: 42 additions & 1 deletion src/annotation/polygonAnnotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ var polygonAnnotation = function (args) {
annotation.call(this, 'polygon', args);

var m_this = this,
s_actions = this.actions;
s_actions = this.actions,
s_state = this.state;

/**
* Get a list of renderable features for this annotation. When the polygon
Expand Down Expand Up @@ -245,6 +246,46 @@ var polygonAnnotation = function (args) {
return continuousVerticesActions(m_this, s_actions, state, 'polygon', arguments);
};

/**
* Get or set the state of this annotation.
*
* @param {string|undefined} [arg] If `undefined`, return the state,
* otherwise change it. This should be one of the
* {@link geo.annotation.state} values.
* @returns {this|string} The current state or this annotation.
* @fires geo.event.annotation.state
*/
this.state = function (arg) {
const oldState = s_state();
if (arg && arg !== oldState && ((oldState === annotationState.create || oldState === annotationState.edit) && arg === annotationState.done)) {
/* Uncross polygons when they are complete. */
const opts = {style: 'object-listlist-outer-list'};
const polys = util.polyops.union(m_this.options('vertices'), [], opts);
let merged = true;
while (polys.length > 1 && merged) {
merged = false;
for (let i = 0; !merged && i < polys[0].outer.length; i += 1) {
const pt1 = polys[0].outer[i];
for (let p = 1; !merged && p < polys.length; p += 1) {
for (let j = 0; !merged && j < polys[p].outer.length; j += 1) {
const pt2 = polys[p].outer[j];
if (pt1.x === pt2.x && pt1.y === pt2.y) {
polys[0].inner = polys[0].inner.concat(polys[p].inner);
polys[0].outer = polys[0].outer.slice(0, i).concat(polys[p].outer.slice(j)).concat(polys[p].outer.slice(0, j)).concat(polys[0].outer.slice(i));
polys.splice(p, 1);
merged = true;
}
}
}
}
}
if (polys.length === 1) {
m_this.options('vertices', polys[0].inner.length ? polys[0] : polys[0].outer);
}
}
return s_state(arg);
};

/**
* Process any actions for this annotation.
*
Expand Down
52 changes: 52 additions & 0 deletions tests/cases/annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,58 @@ describe('geo.annotation', function () {
expect(ann.options('vertices').length).toBe(3);
expect(ann.state()).toBe(geo.annotation.state.done);
});
it('crossed polygon', function () {
var map = createMap();
var layer = map.createLayer('annotation', {
annotations: ['polygon']
});
var ann = geo.annotation.polygonAnnotation({layer: layer});
var time = Date.now();
ann.state(geo.annotation.state.create);
ann.mouseClick({
buttonsDown: {left: true},
time: time,
map: {x: 10, y: 20},
mapgcs: map.displayToGcs({x: 10, y: 20}, null)
});
expect(ann.options('vertices').length).toBe(2);
ann.mouseClick({
buttonsDown: {left: true},
time: time,
map: {x: 50, y: 20},
mapgcs: map.displayToGcs({x: 50, y: 20}, null)
});
expect(ann.options('vertices').length).toBe(3);
ann.mouseClick({
buttonsDown: {left: true},
time: time,
map: {x: 40, y: 30},
mapgcs: map.displayToGcs({x: 40, y: 30}, null)
});
expect(ann.options('vertices').length).toBe(4);
ann.mouseClick({
buttonsDown: {left: true},
time: time,
map: {x: 30, y: 10},
mapgcs: map.displayToGcs({x: 30, y: 10}, null)
});
expect(ann.options('vertices').length).toBe(5);
ann.mouseClick({
buttonsDown: {left: true},
time: time,
map: {x: 20, y: 30},
mapgcs: map.displayToGcs({x: 20, y: 30}, null)
});
expect(ann.options('vertices').length).toBe(6);
ann.mouseClick({
buttonsDown: {left: true},
time: time,
map: {x: 10, y: 20},
mapgcs: map.displayToGcs({x: 10, y: 20}, null)
});
expect(ann.options('vertices').length).toBe(9);
expect(ann.state()).toBe(geo.annotation.state.done);
});
});

describe('geo.annotation.polygonAnnotation with holes', function () {
Expand Down

0 comments on commit 6d3d1ea

Please sign in to comment.