import { GeometryKind } from "@here/harp-datasource-protocol" ; import { Projection } from "@here/harp-geoutils" ; import { setDisplacementMapToMaterial } from "@here/harp-materials" ; import { assert } from "@here/harp-utils" ; import * as THREE from "three" ; import { TileDisplacementMap } from "../DisplacementMap" ; import { ElevationProvider } from "../ElevationProvider" ; import { TextElement } from "../text/TextElement" ; import { Tile , TileObject } from "../Tile" ; param object param displacementMap function overlayObject ( object , displacementMap ) { if ( ! ( "material" in object ) ) { return ; } const setDisplacementMap = setDisplacementMapToMaterial . bind ( null , displacementMap ) ; const material = ( object as any ) . material as THREE . Mesh [ "material" ] ; if ( Array . isArray ( material ) ) { material . forEach ( setDisplacementMap ) ; } else if ( material ) { setDisplacementMap ( material ) ; } } param worldCoords param elevationProvider param displacementMap param projection returns function overlayPosition ( worldCoords , elevationProvider , displacementMap , projection ) { const geoCoords = projection . unprojectPoint ( worldCoords ) ; if ( displacementMap . geoBox . contains ( geoCoords ) ) { geoCoords . altitude = elevationProvider . sampleHeight ( geoCoords , displacementMap ) ; } else { geoCoords . altitude = elevationProvider . getHeight ( geoCoords , displacementMap . tileKey . level ) ; if ( geoCoords . altitude === undefined ) { return false ; } } projection . projectPoint ( geoCoords , worldCoords ) ; return true ; } param path param elevationProvider param displacementMap param projection returns function overlayPath ( path , elevationProvider , displacementMap , projection ) { for ( const position of path ) { if ( ! overlayPosition ( position , elevationProvider , displacementMap , projection ) ) { return false ; } } return true ; } param textElement param elevationProvider param displacementMap param projection export function overlayTextElement ( textElement , elevationProvider , displacementMap , projection ) { assert ( ! textElement . elevated ) ; if ( ! displacementMap ) { return ; } textElement . elevated = textElement . path ? overlayPath ( textElement . path , elevationProvider , displacementMap , projection ) : overlayPosition ( textElement . position , elevationProvider , displacementMap , projection ) ; } param tile export function overlayOnElevation ( tile ) { const elevationProvider = tile . mapView . elevationProvider ; if ( elevationProvider === undefined || tile . objects . length === 0 ) { return ; } const firstObject = tile . objects [ 0 ] ; if ( ! firstObject . userData || ! firstObject . userData . kind || ! firstObject . userData . kind . find ( ( kind ) => { return kind !== GeometryKind . All && kind !== GeometryKind . Terrain ; } ) ) { return ; } const displacementMap = elevationProvider . getDisplacementMap ( tile . tileKey ) ; if ( displacementMap === undefined ) { return ; } for ( const object of tile . objects ) { overlayObject ( object , displacementMap . texture ) ; } }