Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/circle/CesiumCircleOverlayRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { CesiumMapViewHolder } from '../CesiumMapViewHolder';
import { toCesiumColor } from '../color';
import { toCartesian3 } from '../helpers';
import { cesiumEntityId } from '../entityId';
import { CIRCLE_Z_BASE } from '../zOrder';
import { groundZIndex } from '../zOrder';

export class CesiumCircleOverlayRenderer implements CircleOverlayRenderer<Entity> {
constructor(readonly holder: CesiumMapViewHolder) {}
Expand All @@ -29,7 +29,7 @@ export class CesiumCircleOverlayRenderer implements CircleOverlayRenderer<Entity
// No height: the ellipse renders as ground geometry, which is what makes
// Cesium honour zIndex ordering against other overlays (polylines sit in
// a higher band; see zOrder.ts).
entity.ellipse = new EllipseGraphics({ semiMajorAxis: state.radiusMeters, semiMinorAxis: state.radiusMeters, material: toCesiumColor(state.fillColor), outline: false, zIndex: CIRCLE_Z_BASE + (state.zIndex ?? 0) });
entity.ellipse = new EllipseGraphics({ semiMajorAxis: state.radiusMeters, semiMinorAxis: state.radiusMeters, material: toCesiumColor(state.fillColor), outline: false, zIndex: groundZIndex('circle', state.zIndex) });
// Geometry outlines are drawn with WebGL lineWidth, which is capped at
// 1px on effectively every platform, so EllipseGraphics cannot honour
// strokeWidth. Draw the outline as a clamped polyline ring instead —
Expand All @@ -41,7 +41,7 @@ export class CesiumCircleOverlayRenderer implements CircleOverlayRenderer<Entity
material: toCesiumColor(state.strokeColor),
clampToGround: true,
arcType: ArcType.GEODESIC,
zIndex: CIRCLE_Z_BASE + (state.zIndex ?? 0),
zIndex: groundZIndex('circle', state.zIndex),
})
: undefined;
}
Expand Down
6 changes: 5 additions & 1 deletion src/groundimage/CesiumGroundImageOverlayRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Color, Entity, ImageMaterialProperty, Rectangle, RectangleGraphics } fr
import { type GroundImageAddParams, type GroundImageChangeParams, type GroundImageEntity, type GroundImageOverlayRenderer, type GroundImageState } from '@mapconductor/js-sdk-core';
import { CesiumMapViewHolder } from '../CesiumMapViewHolder';
import { cesiumEntityId } from '../entityId';
import { groundZIndex } from '../zOrder';

export class CesiumGroundImageOverlayRenderer implements GroundImageOverlayRenderer<Entity> {
constructor(readonly holder: CesiumMapViewHolder) { }
Expand Down Expand Up @@ -30,7 +31,10 @@ export class CesiumGroundImageOverlayRenderer implements GroundImageOverlayRende
// transparent pixels; `color`'s alpha only scales the overall opacity, not
// the per-pixel alpha, so both are needed.
material: new ImageMaterialProperty({ image: state.imageUrl, color: Color.WHITE.withAlpha(state.opacity), transparent: true }),
height: 0,
// Ground geometry (no height) so Cesium orders it by zIndex with the polygons, circles and
// polylines: under them, in the ground-image band. With `height: 0` it was an ordinary
// primitive drawn after every ground primitive, i.e. over the polygons.
zIndex: groundZIndex('groundImage', 0),
});
}
}
6 changes: 3 additions & 3 deletions src/polygon/CesiumPolygonOverlayRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CesiumMapViewHolder } from '../CesiumMapViewHolder';
import { toCesiumColor } from '../color';
import { pointsToDegrees } from '../helpers';
import { cesiumEntityId } from '../entityId';
import { POLYGON_Z_BASE } from '../zOrder';
import { groundZIndex } from '../zOrder';

// Same segment length react-for-arcgis uses for polygons: coarser than
// polylines so world-scale rings don't densify into huge geometries.
Expand Down Expand Up @@ -60,7 +60,7 @@ export class CesiumPolygonOverlayRenderer implements PolygonOverlayRenderer<Enti
// render rings approaching hemisphere size (world-mask polygons render
// inverted or disappear) — keep mask polygons regional.
arcType: ArcType.RHUMB,
zIndex: POLYGON_Z_BASE + state.zIndex,
zIndex: groundZIndex('polygon', state.zIndex),
});
entity.polyline = state.strokeWidth > 0
? new PolylineGraphics({
Expand All @@ -73,7 +73,7 @@ export class CesiumPolygonOverlayRenderer implements PolygonOverlayRenderer<Enti
// one line. With GEODESIC the outline bowed away from the fill on
// every segment, most visibly on long undensified ones.
arcType: ArcType.RHUMB,
zIndex: POLYGON_Z_BASE + state.zIndex,
zIndex: groundZIndex('polygon', state.zIndex),
})
: undefined;
}
Expand Down
4 changes: 2 additions & 2 deletions src/polyline/CesiumPolylineOverlayRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { toCesiumColor } from '../color';
import { pointsToDegrees } from '../helpers';
import { Cartesian3 } from 'cesium';
import { cesiumEntityId } from '../entityId';
import { POLYLINE_Z_BASE } from '../zOrder';
import { groundZIndex } from '../zOrder';

export class CesiumPolylineOverlayRenderer implements PolylineOverlayRenderer<Entity> {
constructor(readonly holder: CesiumMapViewHolder) {}
Expand Down Expand Up @@ -33,7 +33,7 @@ export class CesiumPolylineOverlayRenderer implements PolylineOverlayRenderer<En
width: state.strokeWidth,
material: toCesiumColor(state.strokeColor),
clampToGround: true,
zIndex: POLYLINE_Z_BASE + state.zIndex,
zIndex: groundZIndex('polyline', state.zIndex),
});
}
}
4 changes: 3 additions & 1 deletion src/raster/CesiumRasterLayerOverlayRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ export class CesiumRasterLayerOverlayRenderer implements RasterLayerOverlayRende
if (this.holder.isDestroyed()) return null;
const layer = new ImageryLayer(provider, { alpha: state.opacity, show: state.visible });
this.holder.map.imageryLayers.add(layer);
this.zIndexes.set(layer, state.zIndex);
// Marker tiles are mounted as a raster. Cesium draws every imagery layer under the ground
// primitives, so they cannot reach the marker band; keep them at least above the app's rasters.
this.zIndexes.set(layer, state.id === 'mc-marker-tiles' ? Number.POSITIVE_INFINITY : state.zIndex);
return layer;
}
}
28 changes: 18 additions & 10 deletions src/zOrder.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
// Cesium orders ground geometry (entities without height / with clampToGround)
// by their zIndex property. Mirror the overlay stacking convention from
// js-sdk-core's controllers — groundImage(2) < circle/polygon(3) < polyline(5)
// < marker(10) — by spreading each overlay type into its own band and adding
// the per-state zIndex within it.
export const OVERLAY_Z_BAND = 1000;
export const GROUND_IMAGE_Z_BASE = 2 * OVERLAY_Z_BAND;
export const CIRCLE_Z_BASE = 3 * OVERLAY_Z_BAND;
export const POLYGON_Z_BASE = 3 * OVERLAY_Z_BAND;
export const POLYLINE_Z_BASE = 5 * OVERLAY_Z_BAND;
import { overlayStackZ } from '@mapconductor/js-sdk-core';

// Cesium orders ground geometry (entities without height / with clampToGround) by their
// zIndex property. Each overlay kind gets its own band from the shared stack
// (js-sdk-core OVERLAY_STACK_ORDER: raster < ground image < polygon < circle < polyline <
// marker), with the per-state zIndex inside it (clamped to ±499 so it cannot cross a band).
//
// Circles used to share the polygons' band (3000), so which one was on top depended on the
// order they were added in.
//
// Rasters are imagery layers and markers are billboards; Cesium draws imagery under every
// ground primitive and billboards over them, which is already the stack's order.
const OVERLAY_Z_BAND = 1000;

/** zIndex for a ground entity of this kind. */
export function groundZIndex(kind: 'groundImage' | 'polygon' | 'circle' | 'polyline', zIndex: number | null | undefined): number {
return overlayStackZ(kind, zIndex, { bandSize: OVERLAY_Z_BAND });
}