SDK JS
    Preparing search index...

    Interface I3sPointLayerOptions

    Configuration for I3sPointLayer. Only id and url are required; a public geographic service renders as GPU dots with nothing else set.

    The two fields that change what you actually see are autoModel (draw each feature as the service's own 3D asset instead of a dot) and labels / labelField (per-feature text billboards). Past those, datum controls the vertical seat and modelMaxDistance with lodBias bound how much of a national-scale service streams and draws. A secured ArcGIS service needs auth.

    interface I3sPointLayerOptions {
        attribution?: string;
        auth?: RequestAuthorizer;
        autoModel?: boolean;
        budget?: { maxBytes?: number; maxPoints?: number };
        center?: [number, number];
        colorMode?: PointColorMode;
        datum?: VerticalDatum;
        decoder?: I3sPointFeatureDecoderLike;
        fixedPx?: number;
        geoidN?: number;
        grid?: number;
        ground?: boolean;
        id: string;
        labelColor?: string;
        labelField?: string;
        labelMaxUnique?: number;
        labelOffsetMeters?: number;
        labelOffsetPx?: number;
        labels?: boolean;
        labelSize?: number;
        labelSizeScale?: number;
        labelStyle?: TextLabelStyle;
        lodBias?: number;
        maxPx?: number;
        minPx?: number;
        model?: string | ArrayBuffer | NormalizedMesh;
        modelLodFalloffDistance?: number;
        modelMaxConcurrentLoads?: number;
        modelMaxDistance?: number;
        modelMinScreenPx?: number;
        modelRotationField?: string;
        modelScale?: number;
        modelScaleBase?: number;
        modelScaleFactor?: number;
        modelScaleField?: string;
        onError?: (error: unknown) => void;
        onLoaded?: () => void;
        onProgress?: (fraction: number) => void;
        opacity?: number;
        pointRadiusM?: number;
        portal?: string;
        requestInit?: RequestInit;
        seams?: GeometrySeams;
        shadows?: boolean;
        smoothModelNormals?: boolean;
        url: string;
        visible?: boolean;
        workers?: boolean;
    }
    Index

    Properties

    attribution?: string
    auth?: RequestAuthorizer

    Request authorizer for secured ArcGIS services. Pass an ESRI authorizer (e.g. getEsriAuthorizer() from @bitruvius/esri-auth, or set one globally via configureEsriAuth() and omit this). Public services need neither this nor requestInit.

    autoModel?: boolean

    Auto symbology*: when no explicit model is set, parse the service's drawingInfo and, if it symbolizes with a 3D PointSymbol3D Object (a glTF "asset" — the Esri norm for trees / turbines), resolve + load that real .glb model and render it instanced per feature, auto-sized by the sizeInfo visual variable. Falls back to GPU dots when there is no resolvable model.

    budget?: { maxBytes?: number; maxPoints?: number }

    Resident memory budget.

    center?: [number, number]

    Scene-anchor center [lng,lat] — pin for a wide-extent root whose OBB center is degenerate.

    colorMode?: PointColorMode

    Initial color mode (default 'height' — feature positions carry no per-point color until symbology lands; height-ramps the dots so they're visible).

    Vertical datum: drop on the map ('basemap'), or place at true absolute height. Default: 'basemap' for a ground-relative service (elevationInfo.mode relativeToGround/ onTheGround), else inherited from the declared vertical CRS (vcsWkid) when a geoid is available, else 'basemap'.

    decoder?: I3sPointFeatureDecoderLike

    Advanced: a custom point decoder (overrides the built-in Draco decoder + the worker pool).

    fixedPx?: number

    Constant on-screen point size (CSS px). Default 3 — feature points are sparse, so a fixed pixel size reads better than physical-radius attenuation.

    geoidN?: number

    Optional — you should not normally need this.* The geoid undulation N (m) at the dataset, used to place absolutely-georeferenced data on mean-sea-level terrain. The SDK resolves it automatically (it fetches the EGM96 grid on demand and samples it at the dataset), so pass this only to override that — e.g. for a dataset referenced to a local vertical datum EGM96 does not model.

    An override shifts placement by the DIFFERENCE between your value and the EGM96 undulation at the dataset — so passing the conventional EGM96 value for your area is a no-op rather than a ~30 m jump.

    grid?: number

    Requantization grid (m) for the i32 position buffer. Default 0.001 (1 mm).

    ground?: boolean

    Auto-ground from the first decoded tile's lowest point (default true).

    id: string

    MapLibre layer id (must be unique within the map).

    labelColor?: string

    Label text COLOUR (any CSS colour, default white). Convenience — overridden by labelStyle.color.

    labelField?: string

    Text labels — field.* Label each feature with the value of this attribute (by name), rasterised into a sprite atlas and drawn as screen-facing billboards over the base render (dots / models / icons). Overrides the service's labelingInfo field. Categorical / small label sets (species, type, class) are ideal; per-feature UNIQUE text at scale (every id) wants an SDF atlas — a follow-up that shares this renderer.

    labelMaxUnique?: number

    Cap on DISTINCT label strings rasterised into the atlas (default 1024). Beyond it, further unique values render with no label (logged once) — the categorical-atlas limit; unbounded unique text is the SDF follow-up.

    labelOffsetMeters?: number

    Extra WORLD-space lift (metres) of labels above their feature, ON TOP OF the per-feature model height (model mode raises each label by its own model height so it clears the model). Default 0.

    labelOffsetPx?: number

    Screen-space lift (CSS px) of labels above their anchor point — the "slightly above" float that keeps the text clear of the feature. Default 8.

    labels?: boolean

    Text labels — master toggle.* false forces labels OFF even when the service declares them; true forces them ON, choosing a field automatically (the service's labelingInfo, else the renderer's own category field — e.g. tree species / furniture type). Omit for the default: labels show when the service declares labelingInfo or a labelField is given, otherwise off.

    labelSize?: number

    Label text SIZE in CSS px (default 14). Convenience for the common case — overridden by an explicit labelStyle.font.

    labelSizeScale?: number

    On-screen size multiplier for label billboards (default 1).

    labelStyle?: TextLabelStyle

    Full text style for labels (font / color / halo / haloWidth / …). Takes precedence over labelSize / labelColor; merged over the service's labelingInfo symbol style, which is merged over the renderer defaults.

    lodBias?: number

    LOD quality bias on maxScreenThreshold (>1 coarser/lighter, <1 sharper). Default 1 in dots mode; 2.6 in model mode (heavy instanced models refine coarser).

    maxPx?: number
    minPx?: number
    model?: string | ArrayBuffer | NormalizedMesh

    Model mode*: render each feature as an instanced 3D MODEL (the Esri ObjectSymbol3DLayer / "models on points" path) instead of GPU dots — a glTF/GLB URL, raw bytes, or a built-in NormalizedMesh. v1 uses a uniform modelScale; per-feature scale/rotation from attributes is a follow-up.

    modelLodFalloffDistance?: number

    Model mode DISTANCE-WEIGHTED LOD: the distance (m) over which the LOD coarsens ~2× — so mid/far features thin out progressively (Esri-style dense-near / sparse-far) instead of loading full density across the whole view. Default 400. Smaller = thins harder + closer (lighter / faster); larger = denser far. 0 disables (uniform LOD).

    modelMaxConcurrentLoads?: number

    Model mode: max concurrent in-flight node loads (fetch → decode → GPU upload). Default: 4 with a main-thread decoder, else max(8, 2 × the worker pool's concurrency) — lower = smoother navigation (less per-frame main-thread work) but slower fill-in; higher = faster fill, more pan jank. (A worker-pooled decoder will lift this constraint.)

    modelMaxDistance?: number

    DISTANCE-LOD cusp.* Max distance (m) at which features load + render; beyond it the engine culls those nodes (so a whole national/global point-feature service doesn't stream + draw out to the frustum far plane / past the horizon — the "everything loads" perf hit). Default: ADAPTIVE — the distance at which a nominal feature would be ~modelMinScreenPx CSS px tall (so it tracks viewport + fov + the asset's height), clamped to a 4 km ceiling. Applies in BOTH model and dots mode. Set a fixed metre value to override.

    modelMinScreenPx?: number

    Cull features once they would be smaller than this many CSS px tall on screen (drives the adaptive modelMaxDistance). Default 5. Larger → cull closer (lighter / faster); smaller → persist farther. Ignored when modelMaxDistance is set.

    modelRotationField?: string

    Model mode: per-feature HEADING attribute (by name, e.g. 'Rotatie', degrees CW from north).

    modelScale?: number

    Uniform model scale (metres) in model mode. Default 1 — multiplies any per-feature scale.

    modelScaleBase?: number
    modelScaleFactor?: number
    modelScaleField?: string

    Model mode: per-feature SCALE attribute (by name, e.g. 'Boomhoogte') → model size = value·modelScaleFactor + modelScaleBase. Sizes each model by a real attribute.

    onError?: (error: unknown) => void
    onLoaded?: () => void
    onProgress?: (fraction: number) => void

    Fired with the working-set load fraction (0–1) as it streams.

    opacity?: number
    pointRadiusM?: number
    portal?: string

    Portal base URL for resolving WELL-KNOWN NAMED web styles — a styleSymbolReference whose styleName (e.g. 'EsriThematicTreesStyle') has no per-layer styleUrl, so its 3D model assets live in an ArcGIS portal item. Default 'https://www.arcgis.com'. Set for an enterprise portal that hosts the style.

    requestInit?: RequestInit

    Static auth/headers escape hatch (e.g. a Bearer token) for tile + metadata fetches. Superseded by auth when both are set.

    seams?: GeometrySeams

    Geometry codec seams (Draco/meshopt/ktx2) if the model GLB is compressed.

    shadows?: boolean

    Start with cast shadows on (model mode only — the tree models cast into the shared cascade atlas alongside any mesh/building datasets). Needs a sun via I3sPointLayer.setSunState; toggle live with I3sPointLayer.setShadows. Default false.

    smoothModelNormals?: boolean

    Recompute CREASE-AWARE smooth per-vertex normals on the auto-resolved model(s) — average the face normals at each shared vertex, but only across faces within a ~60° crease so genuine hard edges (box/furniture corners, cylinder rims) survive. Esri's schematic web-scene models (e.g. the LOD3 thematic trees) ship FLAT per-face normals, so a faithful renderer draws them faceted ("geometry lines" on the low-poly canopy); ArcGIS smooths them at load. Default true (matches Esri; the crease test makes it safe for boxy assets too). Set false to render the authored per-face normals verbatim.

    url: string

    SceneServer or layer URL (…/SceneServer or …/SceneServer/layers/{id}).

    visible?: boolean
    workers?: boolean

    Decode tiles off the main thread in a Web Worker pool (default true) — keeps navigation smooth while tiles stream. Set false to decode on the main thread (e.g. a CSP that blocks workers).