Skip to content

Commit d8160cc

Browse files
mpulkki-mapboxgithub-actions[bot]
authored andcommitted
Fix guard rails on features with split geometry
GitOrigin-RevId: 74ab821553a64b277b890a86ad5a4f2a84c8074a
1 parent bc3b02d commit d8160cc

File tree

4 files changed

+54
-84
lines changed

4 files changed

+54
-84
lines changed

3d-style/elevation/elevated_structures.ts

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import assert from 'assert';
22
import Point from "@mapbox/point-geometry";
3-
import {ElevationPolygons, ElevationPortalGraph, type ElevationPortalEdge, type ElevationPortalType, type LeveledPolygon} from "./elevation_graph";
3+
import {ElevationPortalGraph, type ElevationPortalEdge, type ElevationPortalType} from "./elevation_graph";
44
import {vec2, vec3} from "gl-matrix";
55
import {tileToMeter} from '../../src/geo/mercator_coordinate';
66
import EXTENT from '../../src/style-spec/data/extent';
@@ -167,7 +167,6 @@ export class ElevatedStructures {
167167
shadowCasterSegments: SegmentVector | undefined;
168168

169169
unevaluatedPortals = new ElevationPortalGraph();
170-
portalPolygons = new ElevationPolygons();
171170

172171
// Tracks the rail/tunnel mesh same-feature vertex sections
173172
// (within ElevatedStructure::vertexPositions).
@@ -276,60 +275,62 @@ export class ElevatedStructures {
276275
}
277276
}
278277

279-
addPortalCandidates(id: number, polygon: Point[][], isTunnel: boolean, elevation: ElevationFeature, zLevel: number) {
280-
if (polygon.length === 0) return;
281-
282-
const leveledPoly: LeveledPolygon = {geometry: polygon, zLevel};
283-
this.portalPolygons.add(id, leveledPoly);
278+
addPortalCandidates(id: number, polygons: Point[][][], isTunnel: boolean, elevation: ElevationFeature, zLevel: number) {
279+
if (polygons.length === 0) return;
284280

285281
const pointsEqual = (a: Point, b: Point) => a.x === b.x && a.y === b.y;
286282

287-
// Each edge of the exterior ring is a potential portal
288-
const exterior = polygon[0];
289-
assert(exterior.length > 1 && pointsEqual(exterior[0], exterior[exterior.length - 1]));
290-
291283
this.vertexHashLookup.clear();
292284

293-
let prevEdgeHash = ElevatedStructures.computeEdgeHash(exterior[exterior.length - 2], exterior[exterior.length - 1]);
285+
for (const polygon of polygons) {
286+
if (polygon.length === 0) {
287+
continue;
288+
}
289+
// Each edge of the exterior ring is a potential portal
290+
const exterior = polygon[0];
291+
assert(exterior.length > 1 && pointsEqual(exterior[0], exterior[exterior.length - 1]));
292+
293+
let prevEdgeHash = ElevatedStructures.computeEdgeHash(exterior[exterior.length - 2], exterior[exterior.length - 1]);
294294

295-
for (let i = 0; i < exterior.length - 1; i++) {
296-
const a = exterior[i + 0];
297-
const b = exterior[i + 1];
295+
for (let i = 0; i < exterior.length - 1; i++) {
296+
const a = exterior[i + 0];
297+
const b = exterior[i + 1];
298298

299-
const vavb = vec2.fromValues(b.x - a.x, b.y - a.y);
300-
const length = vec2.length(vavb);
299+
const vavb = vec2.fromValues(b.x - a.x, b.y - a.y);
300+
const length = vec2.length(vavb);
301301

302-
if (length === 0) continue;
302+
if (length === 0) continue;
303303

304-
let type: ElevationPortalType = 'unevaluated';
304+
let type: ElevationPortalType = 'unevaluated';
305305

306-
// "Entrance" portals are entry & exit points for the polygons
307-
// from ground level
308-
const ha = elevation.pointElevation(a);
309-
const hb = elevation.pointElevation(b);
310-
const onGround = Math.abs(ha) < 0.01 && Math.abs(hb) < 0.01;
306+
// "Entrance" portals are entry & exit points for the polygons
307+
// from ground level
308+
const ha = elevation.pointElevation(a);
309+
const hb = elevation.pointElevation(b);
310+
const onGround = Math.abs(ha) < 0.01 && Math.abs(hb) < 0.01;
311311

312-
if (onGround) {
313-
type = 'entrance';
314-
} else {
315-
// Portals on tile borders describes connectivity between tiles
316-
if (this.isOnBorder(a.x, b.x) || this.isOnBorder(a.y, b.y)) {
317-
type = 'border';
312+
if (onGround) {
313+
type = 'entrance';
314+
} else {
315+
// Portals on tile borders describes connectivity between tiles
316+
if (this.isOnBorder(a.x, b.x) || this.isOnBorder(a.y, b.y)) {
317+
type = 'border';
318+
}
318319
}
319-
}
320320

321-
const edgeHash = ElevatedStructures.computeEdgeHash(a, b);
322-
this.unevaluatedPortals.portals.push({
323-
connection: {a: id, b: undefined}, va: a, vb: b, vab: vavb, length, hash: edgeHash, isTunnel, type
324-
});
321+
const edgeHash = ElevatedStructures.computeEdgeHash(a, b);
322+
this.unevaluatedPortals.portals.push({
323+
connection: {a: id, b: undefined}, va: a, vb: b, vab: vavb, length, hash: edgeHash, isTunnel, type
324+
});
325325

326-
// Construct a lookup table where vertex position maps to hashes of edges it's connected to
327-
const posHash = ElevatedStructures.computePosHash(a);
326+
// Construct a lookup table where vertex position maps to hashes of edges it's connected to
327+
const posHash = ElevatedStructures.computePosHash(a);
328328

329-
assert(!this.vertexHashLookup.has(posHash));
330-
this.vertexHashLookup.set(posHash, {prev: prevEdgeHash, next: edgeHash});
329+
assert(!this.vertexHashLookup.has(posHash));
330+
this.vertexHashLookup.set(posHash, {prev: prevEdgeHash, next: edgeHash});
331331

332-
prevEdgeHash = edgeHash;
332+
prevEdgeHash = edgeHash;
333+
}
333334
}
334335
}
335336

3d-style/elevation/elevation_graph.ts

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,6 @@ export interface ElevationPortalEdge {
2424
type: ElevationPortalType;
2525
}
2626

27-
export type LeveledPolygon = {
28-
geometry: Point[][];
29-
zLevel: number;
30-
};
31-
32-
export class ElevationPolygons {
33-
polygons: Map<number, Array<LeveledPolygon>> = new Map();
34-
35-
add(key: number, ...values: LeveledPolygon[]) {
36-
const poly = this.polygons.get(key);
37-
if (!poly) {
38-
this.polygons.set(key, values);
39-
} else {
40-
poly.push(...values);
41-
}
42-
}
43-
44-
merge(elevationPolygons: ElevationPolygons) {
45-
for (const [key, value] of elevationPolygons.polygons) {
46-
this.add(key, ...value);
47-
}
48-
}
49-
}
50-
5127
export class ElevationPortalGraph {
5228
portals: ElevationPortalEdge[] = [];
5329

@@ -136,4 +112,3 @@ export class ElevationPortalGraph {
136112
}
137113

138114
register(ElevationPortalGraph, 'ElevationPortalGraph');
139-
register(ElevationPolygons, "ElevationPolygons");

src/data/bucket/fill_bucket.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import type {TileTransform} from '../../geo/projection/tile_transform';
4040
import type {VectorTileLayer} from '@mapbox/vector-tile';
4141
import type {TileFootprint} from '../../../3d-style/util/conflation';
4242
import type {TypedStyleLayer} from '../../style/style_layer/typed_style_layer';
43-
import type {ElevationPolygons, ElevationPortalGraph} from '../../../3d-style/elevation/elevation_graph';
43+
import type {ElevationPortalGraph} from '../../../3d-style/elevation/elevation_graph';
4444
import type {ImageId} from '../../style-spec/expression/types/image_id';
4545
import type {GlobalProperties} from "../../style-spec/expression";
4646
import type {LUT} from '../../util/lut';
@@ -301,10 +301,6 @@ class FillBucket implements Bucket {
301301
return this.elevatedStructures ? this.elevatedStructures.unevaluatedPortals : undefined;
302302
}
303303

304-
getElevationPolygons(): ElevationPolygons | undefined {
305-
return this.elevatedStructures ? this.elevatedStructures.portalPolygons : undefined;
306-
}
307-
308304
setEvaluatedPortalGraph(graph: ElevationPortalGraph, vtLayer: VectorTileLayer, canonical: CanonicalTileID, availableImages: ImageId[], brightness: number) {
309305
if (this.elevatedStructures) {
310306
this.elevatedStructures.construct(graph);
@@ -354,14 +350,12 @@ class FillBucket implements Bucket {
354350

355351
// Create "elevated structures" for polygons using "road" elevation mode that
356352
// contains additional bridge and tunnel geometries for rendering. Additive "markup" features are
357-
// stacked on top of another elevated layers and do not need these structures of their own
358-
for (const polygon of elevated.polygons) {
359-
// Overlapping edges between adjacent polygons form "portals", i.e. entry & exit points
360-
// useful for traversing elevated polygons
361-
this.elevatedStructures.addPortalCandidates(
362-
elevated.elevationFeature.id, polygon, isTunnel, elevated.elevationFeature, zLevel
363-
);
364-
}
353+
// stacked on top of another elevated layers and do not need these structures of their own.
354+
// Overlapping edges between adjacent polygons form "portals", i.e. entry & exit points
355+
// useful for traversing elevated polygons
356+
this.elevatedStructures.addPortalCandidates(
357+
elevated.elevationFeature.id, elevated.polygons, isTunnel, elevated.elevationFeature, zLevel
358+
);
365359
}
366360

367361
if (elevated.elevationFeature.constantHeight == null) {

test/unit/elevation/elevated_structures.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@ import type {Bounds} from '../../../src/style-spec/util/geometry_util';
1111
describe('ElevatedStructures', () => {
1212
test('#getUnevaluatedPortals', () => {
1313
// Entry & exit ramps and a tunnel section
14-
const leftRamp: Point[][] = [
14+
const leftRamp: Point[][][] = [[
1515
[new Point(1, 1), new Point(3, 1), new Point(3, 4), new Point(1, 4), new Point(1, 1)]
16-
];
16+
]];
1717

18-
const middleRamp: Point[][] = [
18+
const middleRamp: Point[][][] = [[
1919
[new Point(3, 1), new Point(6, 1), new Point(6, 4), new Point(3, 4), new Point(3, 1)],
2020
[new Point(4, 2), new Point(4, 3), new Point(5, 3), new Point(5, 2), new Point(4, 2)]
21-
];
21+
]];
2222

23-
const rightRamp: Point[][] = [
23+
const rightRamp: Point[][][] = [[
2424
[new Point(6, 1), new Point(8, 1), new Point(8, 4), new Point(6, 4), new Point(6, 1)]
25-
];
25+
]];
2626

2727
// Mock elevation feature
2828
const vertices: Vertex[] = [

0 commit comments

Comments
 (0)