UNPKG

@itwin/core-frontend

Version:
127 lines 6.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FeatureGeometryBaseRenderer = void 0; /** Internal implementation of [[FeatureGeometryRenderer]] * @internal */ class FeatureGeometryBaseRenderer { _transform; constructor(world2PixelTransform) { this._transform = world2PixelTransform; } get transform() { return this._transform; } /** * Render a path on the renderer's context. * Note: Inputs are designed based on the PBF format, to avoid any data transformation. * @param geometryLengths Array be used to determine the start and end of each sub-path / rings. (i.e. [5,5] = two rings of 5 vertices) * @param geometryCoords Array that linearly encodes the vertices of each sub-path of a polyline / ring of a polygon * @param fill Indicates if the path should be filled or not. * @param stride Dimension of each vertices (i.e. 2 or 3. 3 could be X,Y,Z, X,YM) Currently 3rd dimension is ignored. */ async renderPath(geometryLengths, geometryCoords, fill, stride, relativeCoords) { if (stride < 2 || stride > 3) { return; } // Keep track of our position in the in the 'coords' array: // Every time we loop on the 'lengths' array, the position // to start reading vertices in the 'coords' must be the sum of all previously read vertices. let coordsOffset = 0; // Begin the path here. // Note: Even though path is closed inside the 'geometryLengths' loop, // it's import to begin the path only once. this.beginPath(); for (const vertexCount of geometryLengths) { let lastPtX = 0, lastPtY = 0; for (let vertexIdx = 0; vertexIdx < vertexCount; vertexIdx++) { let pX = geometryCoords[coordsOffset + (vertexIdx * stride)]; let pY = geometryCoords[coordsOffset + (vertexIdx * stride) + 1]; if (vertexIdx === 0) { // first vertex is always "absolute" and must be drawn as 'moveTo' (i.e. not lineTo) if (relativeCoords) { lastPtX = pX; lastPtY = pY; } if (this._transform) { const transformedPoint = this._transform.multiplyPoint2d({ x: pX, y: pY }); pX = transformedPoint.x; pY = transformedPoint.y; } this.moveTo(pX, pY); } else { // Following vertices are relative to the previous one (sadly not really well documented by ESRI) // typically this happens when 'coordinates quantization' is active (i.e. no client side transformation is needed) if (relativeCoords) { pX = lastPtX = lastPtX + pX; pY = lastPtY = lastPtY + pY; } if (this._transform) { const transformedPoint = this._transform.multiplyPoint2d({ x: pX, y: pY }); pX = transformedPoint.x; pY = transformedPoint.y; } this.lineTo(pX, pY); } } coordsOffset += stride * vertexCount; if (fill) { // ClosePath but do not 'fill' here, only at the very end (otherwise it will mess up holes) this.closePath(); } } if (fill) { await this.fill(); } await this.stroke(); // draw line path or polygon outline } /** * Render a point on the renderer's context. * Note: Inputs are designed based on the PBF format, to avoid any data transformation. * @param geometryLengths Array be used to determine the start and end of each multi-point array, empty for single point. * @param geometryCoords Array that linearly encodes vertices. * @param stride Dimension of each vertices (i.e. 2 or 3. 3 could be X,Y,Z, X,YM) Currently 3rd dimension is ignored. */ async renderPoint(geometryLengths, geometryCoords, stride, relativeCoords) { if (stride < 2 || stride > 3) { return; } let coordsOffset = 0; if (geometryLengths.length === 0) { // Strangely, for points, 'lengths' array is empty, so we assume there is a single vertex in 'coords' array. if (geometryCoords.length >= stride) { if (this._transform) { const transformedPoint = this._transform.multiplyPoint2d({ x: geometryCoords[0], y: geometryCoords[1] }); this.drawPoint(transformedPoint.x, transformedPoint.y); } else { this.drawPoint(geometryCoords[0], geometryCoords[1]); } } } else { // MULTI-POINTS: Needs testing // I assume 'lengths' array will get populated and 'coords' array will look similar to line/polygons. for (const vertexCount of geometryLengths) { let lastPtX = 0, lastPtY = 0; for (let vertexIdx = 0; vertexIdx < vertexCount; vertexIdx++) { let pX = geometryCoords[coordsOffset + (vertexIdx * stride)]; let pY = geometryCoords[coordsOffset + (vertexIdx * stride) + 1]; if (relativeCoords) { pX = lastPtX = lastPtX + pX; pY = lastPtY = lastPtY + pY; } if (this._transform) { const transformedPoint = this._transform.multiplyPoint2d({ x: pX, y: pY }); pX = transformedPoint.x; pY = transformedPoint.y; } this.drawPoint(pX, pY); } coordsOffset += stride * vertexCount; } } await this.finishPoints(); } } exports.FeatureGeometryBaseRenderer = FeatureGeometryBaseRenderer; //# sourceMappingURL=FeatureGeometryRenderer.js.map