Correctly triangulate bad polygons.
This commit is contained in:
@@ -1701,11 +1701,6 @@ ol.render.webgl.PolygonReplay = function(tolerance, maxExtent) {
|
|||||||
changed: false
|
changed: false
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.rtree_ = new ol.structs.RBush();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
ol.inherits(ol.render.webgl.PolygonReplay, ol.render.webgl.Replay);
|
ol.inherits(ol.render.webgl.PolygonReplay, ol.render.webgl.Replay);
|
||||||
|
|
||||||
@@ -1721,8 +1716,9 @@ ol.render.webgl.PolygonReplay.prototype.drawCoordinates_ = function(
|
|||||||
flatCoordinates, holeFlatCoordinates, stride) {
|
flatCoordinates, holeFlatCoordinates, stride) {
|
||||||
// Triangulate the polygon
|
// Triangulate the polygon
|
||||||
var outerRing = new ol.structs.LinkedList();
|
var outerRing = new ol.structs.LinkedList();
|
||||||
|
var rtree = new ol.structs.RBush();
|
||||||
// Initialize the outer ring
|
// Initialize the outer ring
|
||||||
var maxX = this.processFlatCoordinates_(flatCoordinates, stride, outerRing, true);
|
var maxX = this.processFlatCoordinates_(flatCoordinates, stride, outerRing, rtree, true);
|
||||||
|
|
||||||
// Eliminate holes, if there are any
|
// Eliminate holes, if there are any
|
||||||
if (holeFlatCoordinates.length) {
|
if (holeFlatCoordinates.length) {
|
||||||
@@ -1735,20 +1731,17 @@ ol.render.webgl.PolygonReplay.prototype.drawCoordinates_ = function(
|
|||||||
};
|
};
|
||||||
holeLists.push(holeList);
|
holeLists.push(holeList);
|
||||||
holeList.maxX = this.processFlatCoordinates_(holeFlatCoordinates[i],
|
holeList.maxX = this.processFlatCoordinates_(holeFlatCoordinates[i],
|
||||||
stride, holeList.list, false);
|
stride, holeList.list, rtree, false);
|
||||||
}
|
}
|
||||||
holeLists.sort(function(a, b) {
|
holeLists.sort(function(a, b) {
|
||||||
return b.maxX - a.maxX;
|
return b.maxX - a.maxX;
|
||||||
});
|
});
|
||||||
for (i = 0; i < holeLists.length; ++i) {
|
for (i = 0; i < holeLists.length; ++i) {
|
||||||
this.bridgeHole_(holeLists[i].list, holeLists[i].maxX, outerRing, maxX);
|
this.bridgeHole_(holeLists[i].list, holeLists[i].maxX, outerRing, maxX, rtree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.classifyPoints_(outerRing, false);
|
this.classifyPoints_(outerRing, rtree, false);
|
||||||
this.triangulate_(outerRing);
|
this.triangulate_(outerRing, rtree);
|
||||||
|
|
||||||
// We clear the R-Tree here, because hit detection does not call finish()
|
|
||||||
this.rtree_.clear();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1758,11 +1751,12 @@ ol.render.webgl.PolygonReplay.prototype.drawCoordinates_ = function(
|
|||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
* @param {number} stride Stride.
|
* @param {number} stride Stride.
|
||||||
* @param {ol.structs.LinkedList} list Linked list.
|
* @param {ol.structs.LinkedList} list Linked list.
|
||||||
|
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||||
* @param {boolean} clockwise Coordinate order should be clockwise.
|
* @param {boolean} clockwise Coordinate order should be clockwise.
|
||||||
* @return {number} Maximum X value.
|
* @return {number} Maximum X value.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.PolygonReplay.prototype.processFlatCoordinates_ = function(
|
ol.render.webgl.PolygonReplay.prototype.processFlatCoordinates_ = function(
|
||||||
flatCoordinates, stride, list, clockwise) {
|
flatCoordinates, stride, list, rtree, clockwise) {
|
||||||
var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(flatCoordinates,
|
var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(flatCoordinates,
|
||||||
0, flatCoordinates.length, stride);
|
0, flatCoordinates.length, stride);
|
||||||
var i, ii, maxX;
|
var i, ii, maxX;
|
||||||
@@ -1807,7 +1801,7 @@ ol.render.webgl.PolygonReplay.prototype.processFlatCoordinates_ = function(
|
|||||||
extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),
|
extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),
|
||||||
Math.max(p0.y, p1.y)]);
|
Math.max(p0.y, p1.y)]);
|
||||||
}
|
}
|
||||||
this.rtree_.load(extents, segments);
|
rtree.load(extents, segments);
|
||||||
|
|
||||||
return maxX;
|
return maxX;
|
||||||
};
|
};
|
||||||
@@ -1817,10 +1811,11 @@ ol.render.webgl.PolygonReplay.prototype.processFlatCoordinates_ = function(
|
|||||||
* Classifies the points of a polygon list as convex, reflex. Removes collinear vertices.
|
* Classifies the points of a polygon list as convex, reflex. Removes collinear vertices.
|
||||||
* @private
|
* @private
|
||||||
* @param {ol.structs.LinkedList} list Polygon ring.
|
* @param {ol.structs.LinkedList} list Polygon ring.
|
||||||
|
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||||
* @param {boolean} ccw The orientation of the polygon is counter-clockwise.
|
* @param {boolean} ccw The orientation of the polygon is counter-clockwise.
|
||||||
* @return {boolean} There were reclassified points.
|
* @return {boolean} There were reclassified points.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.PolygonReplay.prototype.classifyPoints_ = function(list, ccw) {
|
ol.render.webgl.PolygonReplay.prototype.classifyPoints_ = function(list, rtree, ccw) {
|
||||||
var start = list.firstItem();
|
var start = list.firstItem();
|
||||||
var s0 = start;
|
var s0 = start;
|
||||||
var s1 = list.nextItem();
|
var s1 = list.nextItem();
|
||||||
@@ -1831,7 +1826,7 @@ ol.render.webgl.PolygonReplay.prototype.classifyPoints_ = function(list, ccw) {
|
|||||||
ol.render.webgl.triangleIsCounterClockwise(s0.p0.x, s0.p0.y, s0.p1.x,
|
ol.render.webgl.triangleIsCounterClockwise(s0.p0.x, s0.p0.y, s0.p1.x,
|
||||||
s0.p1.y, s1.p1.x, s1.p1.y);
|
s0.p1.y, s1.p1.x, s1.p1.y);
|
||||||
if (reflex === undefined) {
|
if (reflex === undefined) {
|
||||||
this.removeItem_(s0, s1, list);
|
this.removeItem_(s0, s1, list, rtree);
|
||||||
pointsReclassified = true;
|
pointsReclassified = true;
|
||||||
if (s1 === start) {
|
if (s1 === start) {
|
||||||
start = list.getNextItem();
|
start = list.getNextItem();
|
||||||
@@ -1855,9 +1850,10 @@ ol.render.webgl.PolygonReplay.prototype.classifyPoints_ = function(list, ccw) {
|
|||||||
* @param {number} holeMaxX Maximum X value of the hole.
|
* @param {number} holeMaxX Maximum X value of the hole.
|
||||||
* @param {ol.structs.LinkedList} list Linked list of the polygon.
|
* @param {ol.structs.LinkedList} list Linked list of the polygon.
|
||||||
* @param {number} listMaxX Maximum X value of the polygon.
|
* @param {number} listMaxX Maximum X value of the polygon.
|
||||||
|
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.PolygonReplay.prototype.bridgeHole_ = function(hole, holeMaxX,
|
ol.render.webgl.PolygonReplay.prototype.bridgeHole_ = function(hole, holeMaxX,
|
||||||
list, listMaxX) {
|
list, listMaxX, rtree) {
|
||||||
var seg = hole.firstItem();
|
var seg = hole.firstItem();
|
||||||
while (seg.p1.x !== holeMaxX) {
|
while (seg.p1.x !== holeMaxX) {
|
||||||
seg = hole.nextItem();
|
seg = hole.nextItem();
|
||||||
@@ -1871,7 +1867,7 @@ ol.render.webgl.PolygonReplay.prototype.bridgeHole_ = function(hole, holeMaxX,
|
|||||||
/** @type {ol.WebglPolygonVertex} */
|
/** @type {ol.WebglPolygonVertex} */
|
||||||
var p5;
|
var p5;
|
||||||
|
|
||||||
var intersectingSegments = this.getIntersections_({p0: p1, p1: p2}, true);
|
var intersectingSegments = this.getIntersections_({p0: p1, p1: p2}, rtree, true);
|
||||||
for (i = 0, ii = intersectingSegments.length; i < ii; ++i) {
|
for (i = 0, ii = intersectingSegments.length; i < ii; ++i) {
|
||||||
var currSeg = intersectingSegments[i];
|
var currSeg = intersectingSegments[i];
|
||||||
if (currSeg.p0 !== p1 && currSeg.p1 !== p1) {
|
if (currSeg.p0 !== p1 && currSeg.p1 !== p1) {
|
||||||
@@ -1887,7 +1883,7 @@ ol.render.webgl.PolygonReplay.prototype.bridgeHole_ = function(hole, holeMaxX,
|
|||||||
}
|
}
|
||||||
bestPoint = seg.p1;
|
bestPoint = seg.p1;
|
||||||
|
|
||||||
var pointsInTriangle = this.getPointsInTriangle_(p1, p5, seg.p1);
|
var pointsInTriangle = this.getPointsInTriangle_(p1, p5, seg.p1, rtree);
|
||||||
if (pointsInTriangle.length) {
|
if (pointsInTriangle.length) {
|
||||||
var theta = Infinity;
|
var theta = Infinity;
|
||||||
for (i = 0, ii = pointsInTriangle.length; i < ii; ++i) {
|
for (i = 0, ii = pointsInTriangle.length; i < ii; ++i) {
|
||||||
@@ -1910,8 +1906,8 @@ ol.render.webgl.PolygonReplay.prototype.bridgeHole_ = function(hole, holeMaxX,
|
|||||||
var p1Bridge = {x: seg.p1.x, y: seg.p1.y, i: seg.p1.i, reflex: undefined};
|
var p1Bridge = {x: seg.p1.x, y: seg.p1.y, i: seg.p1.i, reflex: undefined};
|
||||||
|
|
||||||
hole.getNextItem().p0 = p0Bridge;
|
hole.getNextItem().p0 = p0Bridge;
|
||||||
this.insertItem_(p1, seg.p1, hole, true);
|
this.insertItem_(p1, seg.p1, hole, rtree);
|
||||||
this.insertItem_(p1Bridge, p0Bridge, hole, true);
|
this.insertItem_(p1Bridge, p0Bridge, hole, rtree);
|
||||||
seg.p1 = p1Bridge;
|
seg.p1 = p1Bridge;
|
||||||
hole.setFirstItem();
|
hole.setFirstItem();
|
||||||
list.concat(hole);
|
list.concat(hole);
|
||||||
@@ -1921,17 +1917,18 @@ ol.render.webgl.PolygonReplay.prototype.bridgeHole_ = function(hole, holeMaxX,
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {ol.structs.LinkedList} list Linked list of the polygon.
|
* @param {ol.structs.LinkedList} list Linked list of the polygon.
|
||||||
|
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.PolygonReplay.prototype.triangulate_ = function(list) {
|
ol.render.webgl.PolygonReplay.prototype.triangulate_ = function(list, rtree) {
|
||||||
var ccw = false;
|
var ccw = false;
|
||||||
var simple = this.isSimple_(list);
|
var simple = this.isSimple_(list, rtree);
|
||||||
var pass = 0;
|
var pass = 0;
|
||||||
|
|
||||||
// Start clipping ears
|
// Start clipping ears
|
||||||
while (list.getLength() > 3) {
|
while (list.getLength() > 3) {
|
||||||
if (simple) {
|
if (simple) {
|
||||||
if (!this.clipEars_(list, simple, ccw)) {
|
if (!this.clipEars_(list, rtree, simple, ccw)) {
|
||||||
if (!this.classifyPoints_(list, ccw)) {
|
if (!this.classifyPoints_(list, rtree, ccw)) {
|
||||||
// We have the wrongly oriented remains of a self-intersecting polygon.
|
// We have the wrongly oriented remains of a self-intersecting polygon.
|
||||||
pass++;
|
pass++;
|
||||||
if (pass > 1) {
|
if (pass > 1) {
|
||||||
@@ -1939,18 +1936,19 @@ ol.render.webgl.PolygonReplay.prototype.triangulate_ = function(list) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ccw = !ccw;
|
ccw = !ccw;
|
||||||
this.classifyPoints_(list, ccw);
|
this.classifyPoints_(list, rtree, ccw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!this.clipEars_(list, simple, ccw)) {
|
if (!this.clipEars_(list, rtree, simple, ccw)) {
|
||||||
// We ran out of ears, try to reclassify.
|
// We ran out of ears, try to reclassify.
|
||||||
if (!this.classifyPoints_(list, ccw)) {
|
if (!this.classifyPoints_(list, rtree, ccw)) {
|
||||||
// We have a bad polygon, try to resolve local self-intersections.
|
// We have a bad polygon, try to resolve local self-intersections.
|
||||||
if (!this.resolveLocalSelfIntersections_(list)) {
|
if (!this.resolveLocalSelfIntersections_(list, rtree)) {
|
||||||
simple = this.isSimple_(list);
|
simple = this.isSimple_(list, rtree);
|
||||||
if (!simple) {
|
if (!simple) {
|
||||||
// We have a really bad polygon, try more time consuming methods.
|
// We have a really bad polygon, try more time consuming methods.
|
||||||
|
this.splitPolygon_(list, rtree);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1970,11 +1968,12 @@ ol.render.webgl.PolygonReplay.prototype.triangulate_ = function(list) {
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {ol.structs.LinkedList} list Linked list of the polygon.
|
* @param {ol.structs.LinkedList} list Linked list of the polygon.
|
||||||
|
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||||
* @param {boolean} simple The polygon is simple.
|
* @param {boolean} simple The polygon is simple.
|
||||||
* @param {boolean} ccw Orientation of the polygon is counter-clockwise.
|
* @param {boolean} ccw Orientation of the polygon is counter-clockwise.
|
||||||
* @return {boolean} There were processed ears.
|
* @return {boolean} There were processed ears.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.PolygonReplay.prototype.clipEars_ = function(list, simple, ccw) {
|
ol.render.webgl.PolygonReplay.prototype.clipEars_ = function(list, rtree, simple, ccw) {
|
||||||
var numIndices = this.indices_.length;
|
var numIndices = this.indices_.length;
|
||||||
var start = list.firstItem();
|
var start = list.firstItem();
|
||||||
var s0 = list.getPrevItem();
|
var s0 = list.getPrevItem();
|
||||||
@@ -1991,8 +1990,8 @@ ol.render.webgl.PolygonReplay.prototype.clipEars_ = function(list, simple, ccw)
|
|||||||
// We might have a valid ear
|
// We might have a valid ear
|
||||||
var diagonalIsInside = ccw ? this.diagonalIsInside_(s3.p1, p2, p1, p0,
|
var diagonalIsInside = ccw ? this.diagonalIsInside_(s3.p1, p2, p1, p0,
|
||||||
s0.p0) : this.diagonalIsInside_(s0.p0, p0, p1, p2, s3.p1);
|
s0.p0) : this.diagonalIsInside_(s0.p0, p0, p1, p2, s3.p1);
|
||||||
if ((simple || this.getIntersections_({p0: p0, p1: p2}).length === 0) &&
|
if ((simple || this.getIntersections_({p0: p0, p1: p2}, rtree).length === 0) &&
|
||||||
diagonalIsInside && this.getPointsInTriangle_(p0, p1, p2, true).length === 0) {
|
diagonalIsInside && this.getPointsInTriangle_(p0, p1, p2, rtree, true).length === 0) {
|
||||||
//The diagonal is completely inside the polygon
|
//The diagonal is completely inside the polygon
|
||||||
if (p0.reflex === false || p2.reflex === false ||
|
if (p0.reflex === false || p2.reflex === false ||
|
||||||
ol.geom.flat.orient.linearRingIsClockwise([s0.p0.x, s0.p0.y, p0.x,
|
ol.geom.flat.orient.linearRingIsClockwise([s0.p0.x, s0.p0.y, p0.x,
|
||||||
@@ -2001,7 +2000,7 @@ ol.render.webgl.PolygonReplay.prototype.clipEars_ = function(list, simple, ccw)
|
|||||||
this.indices_[numIndices++] = p0.i;
|
this.indices_[numIndices++] = p0.i;
|
||||||
this.indices_[numIndices++] = p1.i;
|
this.indices_[numIndices++] = p1.i;
|
||||||
this.indices_[numIndices++] = p2.i;
|
this.indices_[numIndices++] = p2.i;
|
||||||
this.removeItem_(s1, s2, list);
|
this.removeItem_(s1, s2, list, rtree);
|
||||||
if (s2 === start) {
|
if (s2 === start) {
|
||||||
start = s3;
|
start = s3;
|
||||||
}
|
}
|
||||||
@@ -2023,10 +2022,11 @@ ol.render.webgl.PolygonReplay.prototype.clipEars_ = function(list, simple, ccw)
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {ol.structs.LinkedList} list Linked list of the polygon.
|
* @param {ol.structs.LinkedList} list Linked list of the polygon.
|
||||||
|
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||||
* @return {boolean} There were resolved intersections.
|
* @return {boolean} There were resolved intersections.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.PolygonReplay.prototype.resolveLocalSelfIntersections_ = function(
|
ol.render.webgl.PolygonReplay.prototype.resolveLocalSelfIntersections_ = function(
|
||||||
list) {
|
list, rtree) {
|
||||||
var start = list.firstItem();
|
var start = list.firstItem();
|
||||||
list.nextItem();
|
list.nextItem();
|
||||||
var s0 = start;
|
var s0 = start;
|
||||||
@@ -2043,12 +2043,12 @@ ol.render.webgl.PolygonReplay.prototype.resolveLocalSelfIntersections_ = functio
|
|||||||
|
|
||||||
var seg = list.prevItem();
|
var seg = list.prevItem();
|
||||||
list.removeItem();
|
list.removeItem();
|
||||||
this.rtree_.remove(seg);
|
rtree.remove(seg);
|
||||||
s0.p1 = p;
|
s0.p1 = p;
|
||||||
s1.p0 = p;
|
s1.p0 = p;
|
||||||
this.rtree_.update([Math.min(s0.p0.x, s0.p1.x), Math.min(s0.p0.y, s0.p1.y),
|
rtree.update([Math.min(s0.p0.x, s0.p1.x), Math.min(s0.p0.y, s0.p1.y),
|
||||||
Math.max(s0.p0.x, s0.p1.x), Math.max(s0.p0.y, s0.p1.y)], s0);
|
Math.max(s0.p0.x, s0.p1.x), Math.max(s0.p0.y, s0.p1.y)], s0);
|
||||||
this.rtree_.update([Math.min(s1.p0.x, s1.p1.x), Math.min(s1.p0.y, s1.p1.y),
|
rtree.update([Math.min(s1.p0.x, s1.p1.x), Math.min(s1.p0.y, s1.p1.y),
|
||||||
Math.max(s1.p0.x, s1.p1.x), Math.max(s1.p0.y, s1.p1.y)], s1);
|
Math.max(s1.p0.x, s1.p1.x), Math.max(s1.p0.y, s1.p1.y)], s1);
|
||||||
this.indices_[numIndices++] = seg.p0.i;
|
this.indices_[numIndices++] = seg.p0.i;
|
||||||
this.indices_[numIndices++] = seg.p1.i;
|
this.indices_[numIndices++] = seg.p1.i;
|
||||||
@@ -2070,13 +2070,14 @@ ol.render.webgl.PolygonReplay.prototype.resolveLocalSelfIntersections_ = functio
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {ol.structs.LinkedList} list Linked list of the polygon.
|
* @param {ol.structs.LinkedList} list Linked list of the polygon.
|
||||||
|
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||||
* @return {boolean} The polygon is simple.
|
* @return {boolean} The polygon is simple.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.PolygonReplay.prototype.isSimple_ = function(list) {
|
ol.render.webgl.PolygonReplay.prototype.isSimple_ = function(list, rtree) {
|
||||||
var start = list.firstItem();
|
var start = list.firstItem();
|
||||||
var seg = start;
|
var seg = start;
|
||||||
do {
|
do {
|
||||||
if (this.getIntersections_(seg).length) {
|
if (this.getIntersections_(seg, rtree).length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
seg = list.nextItem();
|
seg = list.nextItem();
|
||||||
@@ -2085,6 +2086,50 @@ ol.render.webgl.PolygonReplay.prototype.isSimple_ = function(list) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {ol.structs.LinkedList} list Linked list of the polygon.
|
||||||
|
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.PolygonReplay.prototype.splitPolygon_ = function(list, rtree) {
|
||||||
|
var start = list.firstItem();
|
||||||
|
var s0 = start;
|
||||||
|
do {
|
||||||
|
var intersections = this.getIntersections_(s0, rtree);
|
||||||
|
if (intersections.length) {
|
||||||
|
var s1 = intersections[0];
|
||||||
|
var n = this.vertices_.length / 2;
|
||||||
|
var intersection = this.calculateIntersection_(s0.p0,
|
||||||
|
s0.p1, s1.p0, s1.p1);
|
||||||
|
var p = this.createPoint_(intersection[0], intersection[1], n);
|
||||||
|
var newPolygon = new ol.structs.LinkedList();
|
||||||
|
var newRtree = new ol.structs.RBush();
|
||||||
|
this.insertItem_(p, s0.p1, newPolygon, newRtree);
|
||||||
|
s0.p1 = p;
|
||||||
|
rtree.update([Math.min(s0.p0.x, p.x), Math.min(s0.p0.y, p.y),
|
||||||
|
Math.max(s0.p0.x, p.x), Math.max(s0.p0.y, p.y)], s0);
|
||||||
|
var currItem = list.nextItem();
|
||||||
|
while (currItem !== s1) {
|
||||||
|
this.insertItem_(currItem.p0, currItem.p1, newPolygon, newRtree);
|
||||||
|
rtree.remove(currItem);
|
||||||
|
list.removeItem();
|
||||||
|
currItem = list.getCurrItem();
|
||||||
|
}
|
||||||
|
this.insertItem_(s1.p0, p, newPolygon, newRtree);
|
||||||
|
s1.p0 = p;
|
||||||
|
rtree.update([Math.min(s1.p1.x, p.x), Math.min(s1.p1.y, p.y),
|
||||||
|
Math.max(s1.p1.x, p.x), Math.max(s1.p1.y, p.y)], s1);
|
||||||
|
this.classifyPoints_(list, rtree, false);
|
||||||
|
this.triangulate_(list, rtree);
|
||||||
|
this.classifyPoints_(newPolygon, newRtree, false);
|
||||||
|
this.triangulate_(newPolygon, newRtree);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s0 = list.nextItem();
|
||||||
|
} while (s0 !== start);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {number} x X coordinate.
|
* @param {number} x X coordinate.
|
||||||
@@ -2112,8 +2157,8 @@ ol.render.webgl.PolygonReplay.prototype.createPoint_ = function(x, y, i) {
|
|||||||
* @param {ol.WebglPolygonVertex} p0 First point of segment.
|
* @param {ol.WebglPolygonVertex} p0 First point of segment.
|
||||||
* @param {ol.WebglPolygonVertex} p1 Second point of segment.
|
* @param {ol.WebglPolygonVertex} p1 Second point of segment.
|
||||||
* @param {ol.structs.LinkedList} list Polygon ring.
|
* @param {ol.structs.LinkedList} list Polygon ring.
|
||||||
* @param {boolean=} opt_rtree Insert the segment into the R-Tree.
|
* @param {ol.structs.RBush=} opt_rtree Insert the segment into the R-Tree.
|
||||||
* @return {Object.<string, ol.WebglPolygonVertex>} segment.
|
* @return {ol.WebglPolygonSegment} segment.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.PolygonReplay.prototype.insertItem_ = function(p0, p1, list, opt_rtree) {
|
ol.render.webgl.PolygonReplay.prototype.insertItem_ = function(p0, p1, list, opt_rtree) {
|
||||||
var seg = {
|
var seg = {
|
||||||
@@ -2122,7 +2167,7 @@ ol.render.webgl.PolygonReplay.prototype.insertItem_ = function(p0, p1, list, opt
|
|||||||
};
|
};
|
||||||
list.insertItem(seg);
|
list.insertItem(seg);
|
||||||
if (opt_rtree) {
|
if (opt_rtree) {
|
||||||
this.rtree_.insert([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y),
|
opt_rtree.insert([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y),
|
||||||
Math.max(p0.x, p1.x), Math.max(p0.y, p1.y)], seg);
|
Math.max(p0.x, p1.x), Math.max(p0.y, p1.y)], seg);
|
||||||
}
|
}
|
||||||
return seg;
|
return seg;
|
||||||
@@ -2131,15 +2176,16 @@ ol.render.webgl.PolygonReplay.prototype.insertItem_ = function(p0, p1, list, opt
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {Object.<string, ol.WebglPolygonVertex>} s0 Segment before the remove candidate.
|
* @param {ol.WebglPolygonSegment} s0 Segment before the remove candidate.
|
||||||
* @param {Object.<string, ol.WebglPolygonVertex>} s1 Remove candidate segment.
|
* @param {ol.WebglPolygonSegment} s1 Remove candidate segment.
|
||||||
* @param {ol.structs.LinkedList} list Polygon ring.
|
* @param {ol.structs.LinkedList} list Polygon ring.
|
||||||
|
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.PolygonReplay.prototype.removeItem_ = function(s0, s1, list) {
|
ol.render.webgl.PolygonReplay.prototype.removeItem_ = function(s0, s1, list, rtree) {
|
||||||
list.removeItem();
|
list.removeItem();
|
||||||
s0.p1 = s1.p1;
|
s0.p1 = s1.p1;
|
||||||
this.rtree_.remove(s1);
|
rtree.remove(s1);
|
||||||
this.rtree_.update([Math.min(s0.p0.x, s0.p1.x), Math.min(s0.p0.y, s0.p1.y),
|
rtree.update([Math.min(s0.p0.x, s0.p1.x), Math.min(s0.p0.y, s0.p1.y),
|
||||||
Math.max(s0.p0.x, s0.p1.x), Math.max(s0.p0.y, s0.p1.y)], s0);
|
Math.max(s0.p0.x, s0.p1.x), Math.max(s0.p0.y, s0.p1.y)], s0);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2149,14 +2195,15 @@ ol.render.webgl.PolygonReplay.prototype.removeItem_ = function(s0, s1, list) {
|
|||||||
* @param {ol.WebglPolygonVertex} p0 First point.
|
* @param {ol.WebglPolygonVertex} p0 First point.
|
||||||
* @param {ol.WebglPolygonVertex} p1 Second point.
|
* @param {ol.WebglPolygonVertex} p1 Second point.
|
||||||
* @param {ol.WebglPolygonVertex} p2 Third point.
|
* @param {ol.WebglPolygonVertex} p2 Third point.
|
||||||
|
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||||
* @param {boolean=} opt_reflex Only include reflex points.
|
* @param {boolean=} opt_reflex Only include reflex points.
|
||||||
* @return {Array.<Object.<string, number>>} Points in the triangle.
|
* @return {Array.<ol.WebglPolygonVertex>} Points in the triangle.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.PolygonReplay.prototype.getPointsInTriangle_ = function(p0, p1,
|
ol.render.webgl.PolygonReplay.prototype.getPointsInTriangle_ = function(p0, p1,
|
||||||
p2, opt_reflex) {
|
p2, rtree, opt_reflex) {
|
||||||
var i, ii, j, p;
|
var i, ii, j, p;
|
||||||
var result = [];
|
var result = [];
|
||||||
var segmentsInExtent = this.rtree_.getInExtent([Math.min(p0.x, p1.x, p2.x),
|
var segmentsInExtent = rtree.getInExtent([Math.min(p0.x, p1.x, p2.x),
|
||||||
Math.min(p0.y, p1.y, p2.y), Math.max(p0.x, p1.x, p2.x), Math.max(p0.y,
|
Math.min(p0.y, p1.y, p2.y), Math.max(p0.x, p1.x, p2.x), Math.max(p0.y,
|
||||||
p1.y, p2.y)]);
|
p1.y, p2.y)]);
|
||||||
for (i = 0, ii = segmentsInExtent.length; i < ii; ++i) {
|
for (i = 0, ii = segmentsInExtent.length; i < ii; ++i) {
|
||||||
@@ -2178,14 +2225,15 @@ ol.render.webgl.PolygonReplay.prototype.getPointsInTriangle_ = function(p0, p1,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {Object.<string, ol.WebglPolygonVertex>} segment Segment.
|
* @param {ol.WebglPolygonSegment} segment Segment.
|
||||||
|
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||||
* @param {boolean=} opt_touch Touching segments should be considered an intersection.
|
* @param {boolean=} opt_touch Touching segments should be considered an intersection.
|
||||||
* @return {Array.<Object.<string, ol.WebglPolygonVertex>>} Intersecting segments.
|
* @return {Array.<ol.WebglPolygonSegment>} Intersecting segments.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.PolygonReplay.prototype.getIntersections_ = function(segment, opt_touch) {
|
ol.render.webgl.PolygonReplay.prototype.getIntersections_ = function(segment, rtree, opt_touch) {
|
||||||
var p0 = segment.p0;
|
var p0 = segment.p0;
|
||||||
var p1 = segment.p1;
|
var p1 = segment.p1;
|
||||||
var segmentsInExtent = this.rtree_.getInExtent([Math.min(p0.x, p1.x),
|
var segmentsInExtent = rtree.getInExtent([Math.min(p0.x, p1.x),
|
||||||
Math.min(p0.y, p1.y), Math.max(p0.x, p1.x), Math.max(p0.y, p1.y)]);
|
Math.min(p0.y, p1.y), Math.max(p0.x, p1.x), Math.max(p0.y, p1.y)]);
|
||||||
var result = [];
|
var result = [];
|
||||||
var i, ii;
|
var i, ii;
|
||||||
|
|||||||
@@ -694,6 +694,12 @@ ol.ViewAnimation;
|
|||||||
ol.WebglBufferCacheEntry;
|
ol.WebglBufferCacheEntry;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{p0: ol.WebglPolygonVertex,
|
||||||
|
* p1: ol.WebglPolygonVertex}}
|
||||||
|
*/
|
||||||
|
ol.WebglPolygonSegment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{x: number,
|
* @typedef {{x: number,
|
||||||
* y: number,
|
* y: number,
|
||||||
|
|||||||
Reference in New Issue
Block a user