import { GeoCoordinates } from "@here/harp-geoutils" ; import { MapControls , MapControlsUI } from "@here/harp-map-controls" ; import { CopyrightElementHandler , MapView , MapViewUtils } from "@here/harp-mapview" ; import { APIFormat , AuthenticationMethod , VectorTileDataSource } from "@here/harp-vectortile-datasource" ; import { apikey , copyrightInfo } from "../config" ; /**
 * An example showing triple map view build with 3 [[MapView]]s each with a different theme and/or
 * datasource.
 *
 * Creates 3 views with their own MapView and MapControl as WebTileDataSourceOptions:
 * ```typescript
 * [[include:harp_gl_multiview_tripleView_1.ts]]
 * ```
 *
 * Create 3 separate [[MapView]]s and datasources that will populate them.
 * ```typescript
 * [[include:harp_gl_multiview_tripleView_2.ts]]
 * ```
 * After adding the MapViews and their dedicated datasources (each one possibly with different
 * theme, added event handlers to sync between them [[MapView]]s:
 * ```typescript
 * [[include:harp_gl_multiview_tripleView_3.ts]]
 * ```
 */ export namespace TripleViewExample { document . body . innerHTML += getExampleHTML ( ) ; const numberOfSyncXViews = 3 ; const numberOfSyncYViews = 1 ; interface ViewControlPair { mapView : MapView ; mapControls : MapControls ; } function setupSyncViewsGrid ( mapView , gridPosX , gridPosY ) { const winW = window . innerWidth ; const winH = window . innerHeight ; const chunkW = window . innerWidth / numberOfSyncXViews ; const chunkH = window . innerHeight / numberOfSyncYViews ; mapView . forceCameraAspect = winW / winH ; if ( gridPosX !== 1 ) { mapView . resize ( chunkW , chunkH ) ; mapView . camera . setViewOffset ( winW , winH , gridPosX * chunkW , gridPosY * chunkH , chunkW , chunkH ) ; } else { mapView . resize ( winW , winH ) ; } } function initMapView ( id , gridPositionX , gridPositionY , theme , decoderUrl ) { const canvas = document . getElementById ( id ) as HTMLCanvasElement ; const mapView = new MapView ( { canvas , theme , decoderUrl } ) ; CopyrightElementHandler . install ( "copyrightNotice" , mapView ) ; const mapControls = new MapControls ( mapView ) ; if ( gridPositionX === 1 ) { const ui = new MapControlsUI ( mapControls ) ; canvas . parentElement ! . appendChild ( ui . domElement ) ; } const frankfurt = new GeoCoordinates ( 50.1125867 , 8.6720831 ) ; mapView . lookAt ( { target : frankfurt , zoomLevel : 18 , tilt : 45 , heading : 200 } ) ; mapView . zoomLevel = 16.2 ; setupSyncViewsGrid ( mapView , gridPositionX , gridPositionY ) ; window . addEventListener ( "resize" , ( ) => { setupSyncViewsGrid ( mapView , gridPositionX , gridPositionY ) ; } ) ; return { mapView , mapControls } ; } const mapViews = { view1 : initMapView ( "mapCanvas" , 0 , 0 , "./resources/berlin_tilezen_base.json" , "./decoder.bundle.js" ) , view2 : initMapView ( "mapCanvas2" , 1 , 0 , "./resources/berlin_tilezen_night_reduced.json" , "./decoder.bundle.js" ) , view3 : initMapView ( "mapCanvas3" , 2 , 0 , "./resources/berlin_tilezen_day_reduced.json" , "./decoder.bundle.js" ) } ; const xyzDataSourceParams = { baseUrl : "https://vector.hereapi.com/v2/vectortiles/base/mc" , apiFormat : APIFormat . XYZOMV , styleSetName : "tilezen" , authenticationCode : apikey , authenticationMethod : { method : AuthenticationMethod . QueryString , name : "apikey" } , copyrightInfo } ; const dataSources = { omvDataSource1 : new VectorTileDataSource ( xyzDataSourceParams ) , omvDataSource2 : new VectorTileDataSource ( xyzDataSourceParams ) , omvDataSource3 : new VectorTileDataSource ( xyzDataSourceParams ) } ; mapViews . view1 . mapView . addDataSource ( dataSources . omvDataSource1 ) ; mapViews . view2 . mapView . addDataSource ( dataSources . omvDataSource2 ) ; mapViews . view3 . mapView . addDataSource ( dataSources . omvDataSource3 ) ; const syncMapViews = ( srcView , destView ) => { const ypr = srcView . mapControls . attitude ; MapViewUtils . setRotation ( destView . mapView , ypr . yaw , ypr . pitch ) ; destView . mapView . camera . position . copy ( srcView . mapView . camera . position ) ; destView . mapControls . cameraHeight = srcView . mapControls . cameraHeight ; destView . mapView . camera . aspect = numberOfSyncXViews ; destView . mapView . camera . updateProjectionMatrix ( ) ; destView . mapView . update ( ) ; } ; mapViews . view2 . mapControls . addEventListener ( "update" , ( ) => { syncMapViews ( mapViews . view2 , mapViews . view1 ) ; syncMapViews ( mapViews . view2 , mapViews . view3 ) ; } ) ; function getExampleHTML ( ) { return `
            <style>
                .themeName {
                    font-weight: bold;
                    padding: 1em;
                    position: absolute
                    margin-bottom: 0.5em;
                    margin: 0 auto;
                    width: 33%;
                    text-align:center;
                    text-transform:uppercase;
                    font-family: 'Fira Sans', sans-serif;
                }

                .titleRow
                {
                    display: table;
                    table-layout: fixed;
                    width: 100%;
                }

                #mapTheme1,#mapTheme2,#mapTheme3 {
                    background: hsl(218, 17%, 18%);
                    color: hsl(218, 17%, 85%);
                    display: table-cell;
                    left: 66%;
                }

                #mapCanvas {
                    border: 0px;
                    height: 100%;
                    left: 0;
                    overflow: hidden;
                    position: absolute;
                    pointer-events:none;
                    width: calc(100%/3);
                    z-index: -1
                }

                #mapCanvas2 {
                    border: 0px;
                    height: 100%;
                    left: 0;
                    overflow: hidden;
                    position: absolute;
                    width: 100%;
                    z-index: -2
                }

                #mapCanvas3 {
                    border: 0px;
                    height: 100%;
                    left: 66.6%;
                    pointer-events:none;
                    overflow: hidden;
                    position: absolute;
                    width: calc(100%/3);
                    z-index: -1
                }

            </style>

            <canvas id="mapCanvas2"></canvas>
            <canvas id="mapCanvas3"></canvas>
            <div class="titleRow">
                <div class="themeName" id="mapTheme1">
                    Base theme
                </div>
                <div class="themeName" id="mapTheme2">
                    Night reduced theme
                </div>
                <div class="themeName" id="mapTheme3">
                    Day reduced theme
                </div>
            </div>
        ` ; } }