import { Theme } from "@here/harp-datasource-protocol" ; import { MapControls , MapControlsUI } from "@here/harp-map-controls" ; import { CopyrightElementHandler , MapView , PickResult } from "@here/harp-mapview" ; import { VectorTileDataSource } from "@here/harp-vectortile-datasource" ; import { apikey } from "../config" ; /**
 * This example showcases how picking works.
 *
 * To enable polygon picking set `gatherFeatureAttributes: true` in
 * [[OmvWithRestClientParams]] or in [[OmvWithCustomDataProvider]].
 * To enable text element picking set `gatherFeatureAttributes: true` in
 * [[OmvWithRestClientParams]] or in [[OmvWithCustomDataProvider]].
 *
 * Now, let's write an event that fires when the user clicks the map canvas:
 * ```typescript
 * [[include:datasource_object_picking_1.ts]]
 * ```
 *
 * All the data handling is covered by the `handlePick` function. Here we find the
 * intersected objects, pick the first one in the array and display its
 * data inside the helper box
 * ```typescript
 * [[include:datasource_object_picking_2.ts]]
 * ```
 */ export namespace PickingExample { document . body . innerHTML += `
        <style>
            #mouse-picked-result{
                position:absolute;
                bottom:5px;
                border-radius: 5px;
                margin-left:10px;
                padding: 9px 12px;
                background: #37afaa;
                display: inline-block;
                visibility: hidden;
                text-align: left;
                right:50px;
            }
            #mapCanvas {
              top: 0;
            }
            #info{
                color: #fff;
                width: 80%;
                left: 50%;
                position: relative;
                margin: 10px 0 0 -40%;
                font-size: 15px;
            }
            @media screen and (max-width: 700px) {
                #info{
                    font-size:11px;
                }
            }
        </style>
        <p id=info>Click/touch a feature on the map to read its data (Land masses are not features).
        </p>
        <pre id="mouse-picked-result"></pre>
    ` ; initializeMapView ( "mapCanvas" ) . catch ( err => { throw err ; } ) ; let lastCanvasPosition ; function getCanvasPosition ( event , canvas ) { const { left , top } = canvas . getBoundingClientRect ( ) ; return { x : event . clientX - Math . floor ( left ) , y : event . clientY - Math . floor ( top ) } ; } function isPick ( eventPosition ) { const MAX_MOVE = 5 ; return ( lastCanvasPosition && Math . abs ( lastCanvasPosition . x - eventPosition . x ) <= MAX_MOVE && Math . abs ( lastCanvasPosition . y - eventPosition . y ) <= MAX_MOVE ) ; } const element = document . getElementById ( "mouse-picked-result" ) as HTMLPreElement ; let current ; function handlePick ( mapViewUsed , x , y ) { let usableIntersections = mapViewUsed . intersectMapObjects ( x , y ) . filter ( item => item . userData !== undefined ) ; if ( usableIntersections . length > 1 ) { usableIntersections = usableIntersections . filter ( item => item !== current ) ; } if ( usableIntersections . length === 0 ) { element . style . visibility = "hidden" ; return ; } current = usableIntersections [ 0 ] ; if ( current . userData ?. name !== undefined ) { mapViewUsed . setDynamicProperty ( "selection" , [ current . userData . name ] ) ; } element . style . visibility = "visible" ; element . innerText = JSON . stringify ( current . userData , undefined , 2 ) ; } /**
     * Creates a new MapView for the HTMLCanvasElement of the given id.
     */ async function initializeMapView ( id ) { const canvas = document . getElementById ( id ) as HTMLCanvasElement ; const selectionTheme = { styles : { tilezen : [ { transient : true , layer : "roads" , when : [ "==" , [ "geometry-type" ] , "LineString" ] , technique : "solid-line" , renderOrder : Number . MAX_SAFE_INTEGER , enabled : [ "in" , [ "get" , "name" ] , [ "get" , "selection" , [ "dynamic-properties" ] ] ] , lineWidth : "2px" } , { transient : true , layer : "landuse" , when : [ "==" , [ "geometry-type" ] , "Polygon" ] , technique : "solid-line" , renderOrder : Number . MAX_SAFE_INTEGER , enabled : [ "in" , [ "get" , "name" ] , [ "get" , "selection" , [ "dynamic-properties" ] ] ] , lineWidth : "2px" } ] } } ; const mapView = new MapView ( { canvas , theme : { extends : [ selectionTheme , "resources/berlin_tilezen_base.json" ] } , enableRoadPicking : true , target : [ - 74.01 , 40.707 ] , zoomLevel : 18 } ) ; CopyrightElementHandler . install ( "copyrightNotice" , mapView ) ; const controls = new MapControls ( mapView ) ; const ui = new MapControlsUI ( controls , { zoomLevel : "input" } ) ; canvas . parentElement ! . appendChild ( ui . domElement ) ; window . addEventListener ( "resize" , ( ) => { mapView . resize ( window . innerWidth , window . innerHeight ) ; } ) ; canvas . addEventListener ( "mousedown" , event => { lastCanvasPosition = getCanvasPosition ( event , canvas ) ; } ) ; canvas . addEventListener ( "touchstart" , event => { if ( event . touches . length !== 1 ) { return ; } lastCanvasPosition = getCanvasPosition ( event . touches [ 0 ] , canvas ) ; } ) ; canvas . addEventListener ( "mouseup" , event => { const canvasPos = getCanvasPosition ( event , canvas ) ; if ( isPick ( canvasPos ) ) { handlePick ( mapView , canvasPos . x , canvasPos . y ) ; } } ) ; canvas . addEventListener ( "touchend" , event => { if ( event . changedTouches . length !== 1 ) { return ; } const canvasPos = getCanvasPosition ( event . changedTouches [ 0 ] , canvas ) ; if ( isPick ( canvasPos ) ) { handlePick ( mapView , canvasPos . x , canvasPos . y ) ; } } ) ; const omvDataSource = new VectorTileDataSource ( { baseUrl : "https://vector.hereapi.com/v2/vectortiles/base/mc" , authenticationCode : apikey , gatherFeatureAttributes : true } ) ; mapView . setDynamicProperty ( "selection" , [ ] ) ; await mapView . addDataSource ( omvDataSource ) ; mapView . update ( ) ; } }