import { StyleSet , Theme } from "@here/harp-datasource-protocol" ; import { FeaturesDataSource } from "@here/harp-features-datasource" ; import { MapControls , MapControlsUI } from "@here/harp-map-controls" ; import { CopyrightElementHandler , MapView } from "@here/harp-mapview" ; import { VectorTileDataSource } from "@here/harp-vectortile-datasource" ; import { apikey } from "../config" ; /**
 * In this example we avail ourselves of the [[FeaturesDataSource]] and its `setFromGeoJson` method
 * to read GeoJSON from a file or from a textarea in the page. A default style is applied for all
 * possible geometry types.
 */ export namespace GeoJsonExample { const editorWidth = "550px" ; const customTheme = { extends : "resources/berlin_tilezen_night_reduced.json" , styles : { geojson : getStyleSet ( ) } } ; const map = createBaseMap ( customTheme ) ; setUpFilePicker ( ) ; setUpEditor ( ) ; const featuresDataSource = new FeaturesDataSource ( { styleSetName : "geojson" } ) ; map . addDataSource ( featuresDataSource ) ; function setUpEditor ( ) { const editorInput = document . querySelector ( "#editor textarea" ) as HTMLTextAreaElement ; editorInput . placeholder = `{
    type: "FeatureCollection",
    features:[

    ]
}` ; const updateButton = document . querySelector ( "#editor button" ) as HTMLButtonElement ; updateButton . addEventListener ( "click" , ( ) => { const geojson = JSON . parse ( ( document . querySelector ( "#editor textarea" ) as HTMLTextAreaElement ) . value ) ; featuresDataSource . setFromGeojson ( geojson ) ; } ) ; } function getStyleSet ( ) { return [ { when : "$geometryType == 'polygon'" , technique : "fill" , renderOrder : 10000 , attr : { color : "#7cf" , transparent : true , opacity : 0.8 , lineWidth : 1 , lineColor : "#003344" } } , { when : "$geometryType == 'polygon'" , technique : "solid-line" , renderOrder : 10001 , attr : { color : "#8df" , metricUnit : "Pixel" , lineWidth : 5 } } , { when : "$geometryType == 'point'" , technique : "circles" , renderOrder : 10002 , attr : { size : 10 , color : "#5ad" } } , { when : "$geometryType == 'line'" , technique : "solid-line" , renderOrder : 10000 , attr : { color : "#8df" , metricUnit : "Pixel" , lineWidth : 5 } } ] ; } function processGeoJsonFile ( file ) { const reader = new FileReader ( ) ; reader . onload = ( ) => { ( document . querySelector ( "#editor textarea" ) as HTMLTextAreaElement ) . value = reader . result as string ; featuresDataSource . setFromGeojson ( JSON . parse ( reader . result as string ) ) ; map . update ( ) ; } ; if ( file . type === "application/geo+json" || file . type === "application/json" ) { reader . readAsText ( file ) ; } } function setUpFilePicker ( ) { const input = document . getElementById ( "input" ) as HTMLInputElement ; input . addEventListener ( "change" , e => { const file = input . files ! [ 0 ] ; processGeoJsonFile ( file ) ; } ) ; const overlay = document . getElementById ( "drag-overlay" ) as HTMLDivElement ; window . addEventListener ( "dragover" , e => { e . preventDefault ( ) ; overlay . style . display = "block" ; } ) ; const removeOverlay = ( e ) => { e . preventDefault ( ) ; overlay . style . display = "none" ; } ; overlay . addEventListener ( "dragleave" , removeOverlay ) ; overlay . addEventListener ( "dragend" , removeOverlay ) ; overlay . addEventListener ( "dragexit" , removeOverlay ) ; overlay . addEventListener ( "drop" , e => { removeOverlay ( e ) ; const file = e . dataTransfer ! . files [ 0 ] ; processGeoJsonFile ( file ) ; } , false ) ; } function createBaseMap ( theme ) { document . body . innerHTML += getExampleHTML ( ) ; const canvas = document . getElementById ( "mapCanvas" ) as HTMLCanvasElement ; const mapView = new MapView ( { canvas , theme } ) ; mapView . renderLabels = false ; CopyrightElementHandler . install ( "copyrightNotice" , mapView ) ; const controls = new MapControls ( mapView ) ; const ui = new MapControlsUI ( controls , { projectionSwitch : true } ) ; const width = innerWidth <= 450 ? 0 : Math . min ( parseInt ( editorWidth , undefined ) , innerWidth * 0.4 ) ; ui . domElement . style . right = width + 10 + "px" ; canvas . parentElement ! . appendChild ( ui . domElement ) ; window . addEventListener ( "resize" , ( ) => { const _width = innerWidth <= 450 ? 0 : Math . min ( parseInt ( editorWidth , undefined ) , innerWidth * 0.4 ) ; canvas . className = "full" ; ui . domElement . style . right = _width + 10 + "px" ; mapView . resize ( innerWidth - _width , innerHeight ) ; } ) ; const baseMap = new VectorTileDataSource ( { baseUrl : "https://vector.hereapi.com/v2/vectortiles/base/mc" , authenticationCode : apikey } ) ; mapView . addDataSource ( baseMap ) ; return mapView ; } function getExampleHTML ( ) { return `
            <link href="https://fonts.googleapis.com/css?family=Fira+Sans&amp;display=swap" rel="stylesheet">
            <style>
                :root{
                    --editor-width:${ editorWidth };
                }
                #mapCanvas{
                    top:0;
                    width:calc(100% - var(--editor-width));
                    min-width: 60%;
                }
                #drag-overlay{
                    position:absolute;
                    width:calc(100% - var(--editor-width));
                    min-width: 60%;
                    height: 100%;
                    background: rgba(0,0,0,0.5);
                    display:none
                }
                #drag-dashes{
                    --border-thickness: 9px;
                    --margin:70px;
                    position:absolute;
                    width:calc(100% - var(--margin) * 2 - var(--border-thickness) * 2);
                    height:calc(100% - var(--margin) * 2 - var(--border-thickness) * 2);
                    top:var(--margin);
                    left:var(--margin);
                    border: dashed var(--border-thickness) #fff;
                    border-radius: 25px;
                }
                #editor{
                    font-family: 'Fira Sans', sans-serif;
                    width:var(--editor-width);
                    max-width:40%;
                    right:0;
                    top:0;
                    position:absolute;
                    height:100%;
                    padding:5px;
                    background:hsla(215, 15%, 65%, 1);
                    box-sizing: border-box;
                }
                button{
                    font-family: 'Fira Sans', sans-serif;
                    background: hsla(215, 15%, 17%, 1);
                    height: 21px;
                    border: 0;
                    color: #d2d7de;
                    text-transform: uppercase;
                    cursor: pointer;
                }
                #browse{
                    display:block;
                    position:absolute;
                    right: 5px;
                    top: 5px;
                }
                #editor textarea{
                    font-family: 'Fira Sans', sans-serif;
                    position:absolute;
                    resize: none;
                    width:calc(100% - 10px);
                    height:calc(100% - 36px);
                    padding:0;
                    top:31px;
                    right:5px;
                    border:0
                }
                #info{
                    color: #fff;
                    min-width: 60%;
                    width: calc(100% - var(--editor-width));
                    text-align: center;
                    font-family: monospace;
                    left: 50%;
                    bottom: 10px;
                    font-size: 15px;
                    position: absolute;
                    margin-left: -50%;
                }
                #copyrightNotice{
                    left:0;
                    background:#888;
                    right:inherit;
                }
                @media all and (max-width: 450px) {
                    #editor{
                        display:none;
                    }
                    #mapCanvas, #info, #drag-overlay{
                        width: 100%;
                    }
                }
            </style>
            <div id=editor>
                <button style="left:5px;position:absolute;">Update</button>
                <textarea></textarea>
            </div>

            <input type="file" id="input" style="display: none;" />
            <button id=browse onclick="document.getElementById('input').click();">
                Browse a file
            </button>

            <div id="drag-overlay">
                <div id="drag-dashes"></div>
            </div>
            <p id=info>Drag and drop a GeoJSON or browse a local one.</p>
        ` ; } }