Merge pull request #11519 from MoonE/multipoint-draw-only-visible

Do not draw multipoints outside render extent
This commit is contained in:
Andreas Hocevar
2020-09-13 12:03:21 +02:00
committed by GitHub
6 changed files with 105 additions and 101 deletions

View File

@@ -6,7 +6,12 @@ import GeometryType from '../../geom/GeometryType.js';
import Relationship from '../../extent/Relationship.js';
import VectorContext from '../VectorContext.js';
import {asColorLike} from '../../colorlike.js';
import {buffer, clone, coordinateRelationship} from '../../extent.js';
import {
buffer,
clone,
containsCoordinate,
coordinateRelationship,
} from '../../extent.js';
import {
defaultFillStyle,
defaultLineCap,
@@ -139,6 +144,28 @@ class CanvasBuilder extends VectorContext {
});
}
/**
* @param {Array<number>} flatCoordinates Flat coordinates.
* @param {number} stride Stride.
* @protected
* @return {number} My end
*/
appendFlatPointCoordinates(flatCoordinates, stride) {
const extent = this.getBufferedMaxExtent();
const tmpCoord = this.tmpCoordinate_;
const coordinates = this.coordinates;
let myEnd = coordinates.length;
for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
tmpCoord[0] = flatCoordinates[i];
tmpCoord[1] = flatCoordinates[i + 1];
if (containsCoordinate(extent, tmpCoord)) {
coordinates[myEnd++] = tmpCoord[0];
coordinates[myEnd++] = tmpCoord[1];
}
}
return myEnd;
}
/**
* @param {Array<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
@@ -149,7 +176,7 @@ class CanvasBuilder extends VectorContext {
* @protected
* @return {number} My end.
*/
appendFlatCoordinates(
appendFlatLineCoordinates(
flatCoordinates,
offset,
end,
@@ -157,7 +184,8 @@ class CanvasBuilder extends VectorContext {
closed,
skipFirst
) {
let myEnd = this.coordinates.length;
const coordinates = this.coordinates;
let myEnd = coordinates.length;
const extent = this.getBufferedMaxExtent();
if (skipFirst) {
offset += stride;
@@ -174,15 +202,15 @@ class CanvasBuilder extends VectorContext {
nextRel = coordinateRelationship(extent, nextCoord);
if (nextRel !== lastRel) {
if (skipped) {
this.coordinates[myEnd++] = lastXCoord;
this.coordinates[myEnd++] = lastYCoord;
coordinates[myEnd++] = lastXCoord;
coordinates[myEnd++] = lastYCoord;
skipped = false;
}
this.coordinates[myEnd++] = nextCoord[0];
this.coordinates[myEnd++] = nextCoord[1];
skipped = false;
coordinates[myEnd++] = nextCoord[0];
coordinates[myEnd++] = nextCoord[1];
} else if (nextRel === Relationship.INTERSECTING) {
this.coordinates[myEnd++] = nextCoord[0];
this.coordinates[myEnd++] = nextCoord[1];
coordinates[myEnd++] = nextCoord[0];
coordinates[myEnd++] = nextCoord[1];
skipped = false;
} else {
skipped = true;
@@ -194,8 +222,8 @@ class CanvasBuilder extends VectorContext {
// Last coordinate equals first or only one point to append:
if ((closed && skipped) || i === offset + stride) {
this.coordinates[myEnd++] = lastXCoord;
this.coordinates[myEnd++] = lastYCoord;
coordinates[myEnd++] = lastXCoord;
coordinates[myEnd++] = lastYCoord;
}
return myEnd;
}
@@ -211,7 +239,7 @@ class CanvasBuilder extends VectorContext {
drawCustomCoordinates_(flatCoordinates, offset, ends, stride, builderEnds) {
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
const builderEnd = this.appendFlatCoordinates(
const builderEnd = this.appendFlatLineCoordinates(
flatCoordinates,
offset,
end,
@@ -285,12 +313,9 @@ class CanvasBuilder extends VectorContext {
renderer,
inflateCoordinatesArray,
]);
} else if (
type == GeometryType.LINE_STRING ||
type == GeometryType.MULTI_POINT
) {
} else if (type == GeometryType.LINE_STRING) {
flatCoordinates = geometry.getFlatCoordinates();
builderEnd = this.appendFlatCoordinates(
builderEnd = this.appendFlatLineCoordinates(
flatCoordinates,
0,
flatCoordinates.length,
@@ -306,6 +331,19 @@ class CanvasBuilder extends VectorContext {
renderer,
inflateCoordinates,
]);
} else if (type == GeometryType.MULTI_POINT) {
flatCoordinates = geometry.getFlatCoordinates();
builderEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);
if (builderEnd > builderBegin) {
this.instructions.push([
CanvasInstruction.CUSTOM,
builderBegin,
builderEnd,
geometry,
renderer,
inflateCoordinates,
]);
}
} else if (type == GeometryType.POINT) {
flatCoordinates = geometry.getFlatCoordinates();
this.coordinates.push(flatCoordinates[0], flatCoordinates[1]);

View File

@@ -99,25 +99,6 @@ class CanvasImageBuilder extends CanvasBuilder {
this.width_ = undefined;
}
/**
* @param {Array<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {number} end End.
* @param {number} stride Stride.
* @private
* @return {number} My end.
*/
drawCoordinates_(flatCoordinates, offset, end, stride) {
return this.appendFlatCoordinates(
flatCoordinates,
offset,
end,
stride,
false,
false
);
}
/**
* @param {import("../../geom/Point.js").default|import("../Feature.js").default} pointGeometry Point geometry.
* @param {import("../../Feature.js").FeatureLike} feature Feature.
@@ -130,12 +111,7 @@ class CanvasImageBuilder extends CanvasBuilder {
const flatCoordinates = pointGeometry.getFlatCoordinates();
const stride = pointGeometry.getStride();
const myBegin = this.coordinates.length;
const myEnd = this.drawCoordinates_(
flatCoordinates,
0,
flatCoordinates.length,
stride
);
const myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);
this.instructions.push([
CanvasInstruction.DRAW_IMAGE,
myBegin,
@@ -190,12 +166,7 @@ class CanvasImageBuilder extends CanvasBuilder {
const flatCoordinates = multiPointGeometry.getFlatCoordinates();
const stride = multiPointGeometry.getStride();
const myBegin = this.coordinates.length;
const myEnd = this.drawCoordinates_(
flatCoordinates,
0,
flatCoordinates.length,
stride
);
const myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);
this.instructions.push([
CanvasInstruction.DRAW_IMAGE,
myBegin,

View File

@@ -28,7 +28,7 @@ class CanvasLineStringBuilder extends CanvasBuilder {
*/
drawFlatCoordinates_(flatCoordinates, offset, end, stride) {
const myBegin = this.coordinates.length;
const myEnd = this.appendFlatCoordinates(
const myEnd = this.appendFlatLineCoordinates(
flatCoordinates,
offset,
end,

View File

@@ -40,7 +40,7 @@ class CanvasPolygonBuilder extends CanvasBuilder {
for (let i = 0; i < numEnds; ++i) {
const end = ends[i];
const myBegin = this.coordinates.length;
const myEnd = this.appendFlatCoordinates(
const myEnd = this.appendFlatLineCoordinates(
flatCoordinates,
offset,
end,
@@ -57,7 +57,7 @@ class CanvasPolygonBuilder extends CanvasBuilder {
this.hitDetectionInstructions.push(moveToLineToInstruction);
if (stroke) {
// Performance optimization: only call closePath() when we have a stroke.
// Otherwise the ring is closed already (see appendFlatCoordinates above).
// Otherwise the ring is closed already (see appendFlatLineCoordinates above).
this.instructions.push(closePathInstruction);
this.hitDetectionInstructions.push(closePathInstruction);
}
@@ -108,7 +108,7 @@ class CanvasPolygonBuilder extends CanvasBuilder {
const flatCoordinates = circleGeometry.getFlatCoordinates();
const stride = circleGeometry.getStride();
const myBegin = this.coordinates.length;
this.appendFlatCoordinates(
this.appendFlatLineCoordinates(
flatCoordinates,
0,
flatCoordinates.length,

View File

@@ -169,15 +169,20 @@ class CanvasTextBuilder extends CanvasBuilder {
return;
}
let begin = this.coordinates.length;
const coordinates = this.coordinates;
let begin = coordinates.length;
const geometryType = geometry.getType();
let flatCoordinates = null;
let end = 2;
let stride = geometry.getStride();
let i, ii;
if (textState.placement === TextPlacement.LINE) {
if (
textState.placement === TextPlacement.LINE &&
(geometryType == GeometryType.LINE_STRING ||
geometryType == GeometryType.MULTI_LINE_STRING ||
geometryType == GeometryType.POLYGON ||
geometryType == GeometryType.MULTI_POLYGON)
) {
if (!intersects(this.getBufferedMaxExtent(), geometry.getExtent())) {
return;
}
@@ -194,7 +199,7 @@ class CanvasTextBuilder extends CanvasBuilder {
} else if (geometryType == GeometryType.MULTI_POLYGON) {
const endss = /** @type {import("../../geom/MultiPolygon.js").default} */ (geometry).getEndss();
ends = [];
for (i = 0, ii = endss.length; i < ii; ++i) {
for (let i = 0, ii = endss.length; i < ii; ++i) {
ends.push(endss[i][0]);
}
}
@@ -216,10 +221,10 @@ class CanvasTextBuilder extends CanvasBuilder {
} else {
flatEnd = ends[o];
}
for (i = flatOffset; i < flatEnd; i += stride) {
this.coordinates.push(flatCoordinates[i], flatCoordinates[i + 1]);
for (let i = flatOffset; i < flatEnd; i += stride) {
coordinates.push(flatCoordinates[i], flatCoordinates[i + 1]);
}
end = this.coordinates.length;
const end = coordinates.length;
flatOffset = ends[o];
const declutterGroup = this.declutterGroups_
? o === 0
@@ -231,15 +236,11 @@ class CanvasTextBuilder extends CanvasBuilder {
}
this.endGeometry(feature);
} else {
let geometryWidths = null;
if (!textState.overflow) {
geometryWidths = [];
}
const geometryWidths = textState.overflow ? null : [];
switch (geometryType) {
case GeometryType.POINT:
case GeometryType.MULTI_POINT:
flatCoordinates = /** @type {import("../../geom/MultiPoint.js").default} */ (geometry).getFlatCoordinates();
end = flatCoordinates.length;
break;
case GeometryType.LINE_STRING:
flatCoordinates = /** @type {import("../../geom/LineString.js").default} */ (geometry).getFlatMidpoint();
@@ -250,7 +251,6 @@ class CanvasTextBuilder extends CanvasBuilder {
case GeometryType.MULTI_LINE_STRING:
flatCoordinates = /** @type {import("../../geom/MultiLineString.js").default} */ (geometry).getFlatMidpoints();
stride = 2;
end = flatCoordinates.length;
break;
case GeometryType.POLYGON:
flatCoordinates = /** @type {import("../../geom/Polygon.js").default} */ (geometry).getFlatInteriorPoint();
@@ -262,28 +262,23 @@ class CanvasTextBuilder extends CanvasBuilder {
case GeometryType.MULTI_POLYGON:
const interiorPoints = /** @type {import("../../geom/MultiPolygon.js").default} */ (geometry).getFlatInteriorPoints();
flatCoordinates = [];
for (i = 0, ii = interiorPoints.length; i < ii; i += 3) {
for (let i = 0, ii = interiorPoints.length; i < ii; i += 3) {
if (!textState.overflow) {
geometryWidths.push(interiorPoints[i + 2] / this.resolution);
}
flatCoordinates.push(interiorPoints[i], interiorPoints[i + 1]);
}
stride = 2;
end = flatCoordinates.length;
if (end == 0) {
if (flatCoordinates.length === 0) {
return;
}
stride = 2;
break;
default:
}
end = this.appendFlatCoordinates(
flatCoordinates,
0,
end,
stride,
false,
false
);
const end = this.appendFlatPointCoordinates(flatCoordinates, stride);
if (end === begin) {
return;
}
this.saveTextStates_();