2020-07-29 15:05:19 +02:00
import Translations from "./UI/i18n/Translations" ;
import { TabbedComponent } from "./UI/Base/TabbedComponent" ;
import { ShareScreen } from "./UI/ShareScreen" ;
import { FixedUiElement } from "./UI/Base/FixedUiElement" ;
2020-10-02 19:00:24 +02:00
import CheckBox from "./UI/Input/CheckBox" ;
2020-07-29 15:05:19 +02:00
import Combine from "./UI/Base/Combine" ;
import { UIElement } from "./UI/UIElement" ;
2020-07-29 15:48:21 +02:00
import { MoreScreen } from "./UI/MoreScreen" ;
2020-07-30 00:59:08 +02:00
import { FilteredLayer } from "./Logic/FilteredLayer" ;
2020-09-25 21:58:29 +02:00
import { Basemap } from "./Logic/Leaflet/Basemap" ;
2020-10-02 19:00:24 +02:00
import State from "./State" ;
2020-07-31 01:45:54 +02:00
import { WelcomeMessage } from "./UI/WelcomeMessage" ;
2020-07-31 04:58:58 +02:00
import { LayerSelection } from "./UI/LayerSelection" ;
2020-07-31 17:38:03 +02:00
import { VariableUiElement } from "./UI/Base/VariableUIElement" ;
2020-10-19 12:08:42 +02:00
import { UpdateFromOverpass } from "./Logic/UpdateFromOverpass" ;
2020-08-17 17:23:15 +02:00
import { UIEventSource } from "./Logic/UIEventSource" ;
import { QueryParameters } from "./Logic/Web/QueryParameters" ;
2020-08-26 15:36:04 +02:00
import { PersonalLayersPanel } from "./Logic/PersonalLayersPanel" ;
2020-08-31 02:59:47 +02:00
import Locale from "./UI/i18n/Locale" ;
2020-09-07 02:25:45 +02:00
import { StrayClickHandler } from "./Logic/Leaflet/StrayClickHandler" ;
import { SimpleAddUI } from "./UI/SimpleAddUI" ;
import { CenterMessageBox } from "./UI/CenterMessageBox" ;
import { AllKnownLayouts } from "./Customizations/AllKnownLayouts" ;
import { TagUtils } from "./Logic/Tags" ;
import { UserBadge } from "./UI/UserBadge" ;
import { SearchAndGo } from "./UI/SearchAndGo" ;
import { FullScreenMessageBox } from "./UI/FullScreenMessageBoxHandler" ;
import { GeoLocationHandler } from "./Logic/Leaflet/GeoLocationHandler" ;
import { LocalStorageSource } from "./Logic/Web/LocalStorageSource" ;
2020-09-15 00:25:25 +02:00
import { Utils } from "./Utils" ;
2020-09-25 21:58:29 +02:00
import BackgroundSelector from "./UI/BackgroundSelector" ;
2020-09-28 00:30:39 +02:00
import AvailableBaseLayers from "./Logic/AvailableBaseLayers" ;
2020-10-14 12:15:09 +02:00
import { FeatureInfoBox } from "./UI/Popup/FeatureInfoBox" ;
2020-11-06 01:58:26 +01:00
import Svg from "./Svg" ;
import Link from "./UI/Base/Link" ;
2020-11-11 16:23:49 +01:00
import * as personal from "./assets/themes/personalLayout/personalLayout.json"
import LayoutConfig from "./Customizations/JSON/LayoutConfig" ;
2020-11-17 02:22:48 +01:00
import * as L from "leaflet" ;
import { Img } from "./UI/Img" ;
import { UserDetails } from "./Logic/Osm/OsmConnection" ;
2020-07-29 15:05:19 +02:00
export class InitUiElements {
2020-09-15 02:29:31 +02:00
private static setupAllLayerElements() {
// ------------- Setup the layers -------------------------------
InitUiElements . InitLayers ( ) ;
InitUiElements . InitLayerSelection ( ) ;
// ------------------ Setup various other UI elements ------------
InitUiElements . OnlyIf ( State . state . featureSwitchAddNew , ( ) = > {
let presetCount = 0 ;
for ( const layer of State . state . filteredLayers . data ) {
for ( const preset of layer . layerDef . presets ) {
presetCount ++ ;
}
}
if ( presetCount == 0 ) {
return ;
}
new StrayClickHandler ( ( ) = > {
return new SimpleAddUI ( ) ;
}
) ;
} ) ;
new CenterMessageBox ( ) . AttachTo ( "centermessage" ) ;
}
2020-11-11 16:23:49 +01:00
static InitAll ( layoutToUse : LayoutConfig , layoutFromBase64 : string , testing : UIEventSource < string > , layoutName : string ,
2020-09-15 02:29:31 +02:00
layoutDefinition : string = "" ) {
2020-09-07 02:25:45 +02:00
if ( layoutToUse === undefined ) {
console . log ( "Incorrect layout" )
2020-09-15 00:25:25 +02:00
new FixedUiElement ( "Error: incorrect layout <i>" + layoutName + "</i><br/><a href='https://pietervdvn.github.io/MapComplete/index.html'>Go back</a>" ) . AttachTo ( "centermessage" ) . onClick ( ( ) = > {
2020-09-07 02:25:45 +02:00
} ) ;
throw "Incorrect layout"
}
2020-09-15 00:25:25 +02:00
console . log ( "Using layout: " , layoutToUse . id , "LayoutFromBase64 is " , layoutFromBase64 ) ;
2020-09-07 02:25:45 +02:00
State . state = new State ( layoutToUse ) ;
2020-09-15 00:25:25 +02:00
// This 'leaks' the global state via the window object, useful for debugging
// @ts-ignore
window . mapcomplete_state = State . state ;
2020-09-07 02:25:45 +02:00
if ( layoutToUse . hideFromOverview ) {
State . state . osmConnection . GetPreference ( "hidden-theme-" + layoutToUse . id + "-enabled" ) . setData ( "true" ) ;
}
if ( layoutFromBase64 !== "false" ) {
2020-09-15 02:29:31 +02:00
State . state . layoutDefinition = layoutDefinition ;
console . log ( "Layout definition:" , Utils . EllipsesAfter ( State . state . layoutDefinition , 100 ) )
2020-09-07 02:25:45 +02:00
if ( testing . data !== "true" ) {
State . state . osmConnection . OnLoggedIn ( ( ) = > {
State . state . osmConnection . GetLongPreference ( "installed-theme-" + layoutToUse . id ) . setData ( State . state . layoutDefinition ) ;
} )
} else {
console . warn ( "NOT saving custom layout to OSM as we are tesing -> probably in an iFrame" )
}
}
InitUiElements . InitBaseMap ( ) ;
new FixedUiElement ( "" ) . AttachTo ( "decoration-desktop" ) ; // Remove the decoration
2020-09-15 02:29:31 +02:00
InitUiElements . setupAllLayerElements ( ) ;
2020-09-07 02:25:45 +02:00
2020-11-14 02:54:33 +01:00
if ( layoutToUse . customCss !== undefined ) {
2020-11-14 03:26:09 +01:00
Utils . LoadCustomCss ( layoutToUse . customCss ) ;
2020-11-14 02:54:33 +01:00
}
2020-09-07 02:25:45 +02:00
function updateFavs() {
const favs = State . state . favouriteLayers . data ? ? [ ] ;
2020-11-11 16:23:49 +01:00
layoutToUse . layers . splice ( 0 , layoutToUse . layers . length ) ;
2020-09-07 02:25:45 +02:00
for ( const fav of favs ) {
const layer = AllKnownLayouts . allLayers [ fav ] ;
if ( ! ! layer ) {
layoutToUse . layers . push ( layer ) ;
}
for ( const layouts of State . state . installedThemes . data ) {
for ( const layer of layouts . layout . layers ) {
if ( typeof layer === "string" ) {
continue ;
}
if ( layer . id === fav ) {
layoutToUse . layers . push ( layer ) ;
}
}
}
}
2020-09-15 02:29:31 +02:00
InitUiElements . setupAllLayerElements ( ) ;
2020-09-07 02:25:45 +02:00
State . state . layerUpdater . ForceRefresh ( ) ;
2020-09-15 02:29:31 +02:00
State . state . layoutToUse . ping ( ) ;
2020-09-07 02:25:45 +02:00
}
2020-11-17 02:22:48 +01:00
2020-11-11 16:23:49 +01:00
if ( layoutToUse . id === personal . id ) {
2020-09-07 02:25:45 +02:00
State . state . favouriteLayers . addCallback ( updateFavs ) ;
State . state . installedThemes . addCallback ( updateFavs ) ;
}
/ * *
* Show the questions and information for the selected element
* This is given to the div which renders fullscreen on mobile devices
* /
State . state . selectedElement . addCallback ( ( feature ) = > {
2020-11-17 02:22:48 +01:00
if ( feature === undefined ) {
State . state . fullScreenMessage . setData ( undefined ) ;
}
2020-11-18 13:41:31 +01:00
if ( feature ? . properties === undefined ) {
2020-09-07 02:25:45 +02:00
return ;
}
2020-11-15 01:16:35 +01:00
const data = feature . properties ;
2020-09-07 02:25:45 +02:00
// Which is the applicable set?
for ( const layer of layoutToUse . layers ) {
if ( typeof layer === "string" ) {
continue ;
}
2020-10-27 01:01:34 +01:00
const applicable = layer . overpassTags . matches ( TagUtils . proprtiesToKV ( data ) ) ;
2020-11-17 02:22:48 +01:00
if ( ! applicable ) {
continue ;
}
2020-11-18 13:41:31 +01:00
if ( ( layer . title ? ? null ) === null && layer . tagRenderings . length === 0 ) {
2020-11-17 02:22:48 +01:00
continue ;
2020-09-07 02:25:45 +02:00
}
2020-11-17 02:22:48 +01:00
// This layer is the layer that gives the questions
const featureBox = new FeatureInfoBox (
State . state . allElements . getElement ( data . id ) ,
layer
) ;
State . state . fullScreenMessage . setData ( featureBox ) ;
break ;
2020-09-07 02:25:45 +02:00
}
}
) ;
InitUiElements . OnlyIf ( State . state . featureSwitchUserbadge , ( ) = > {
new UserBadge ( ) . AttachTo ( 'userbadge' ) ;
} ) ;
InitUiElements . OnlyIf ( ( State . state . featureSwitchSearch ) , ( ) = > {
new SearchAndGo ( ) . AttachTo ( "searchbox" ) ;
} ) ;
new FullScreenMessageBox ( ( ) = > {
State . state . selectedElement . setData ( undefined )
} ) . AttachTo ( "messagesboxmobile" ) ;
InitUiElements . OnlyIf ( State . state . featureSwitchWelcomeMessage , ( ) = > {
InitUiElements . InitWelcomeMessage ( )
} ) ;
if ( ( window != window . top && ! State . state . featureSwitchWelcomeMessage . data ) || State . state . featureSwitchIframe . data ) {
const currentLocation = State . state . locationControl ;
const url = ` ${ window . location . origin } ${ window . location . pathname } ?z= ${ currentLocation . data . zoom } &lat= ${ currentLocation . data . lat } &lon= ${ currentLocation . data . lon } ` ;
2020-11-06 01:58:26 +01:00
const content = new Link ( Svg . pop_out_ui ( ) . SetClass ( "iframe-escape" ) , url , true ) ;
new FixedUiElement ( content . Render ( ) ) . AttachTo ( "help-button-mobile" )
content . AttachTo ( "messagesbox" ) ;
2020-09-07 02:25:45 +02:00
}
2020-11-17 02:22:48 +01:00
State . state . osmConnection . userDetails . map ( ( userDetails : UserDetails ) = > userDetails ? . home )
. addCallbackAndRun ( home = > {
if ( home === undefined ) {
return ;
}
const color = getComputedStyle ( document . body ) . getPropertyValue ( "--subtle-detail-color" )
const icon = L . icon ( {
iconUrl : Img.AsData ( Svg . home_white_bg . replace ( /#ffffff/g , color ) ) ,
iconSize : [ 30 , 30 ] ,
iconAnchor : [ 15 , 15 ]
} ) ;
const marker = L . marker ( [ home . lat , home . lon ] , { icon : icon } )
marker . addTo ( State . state . bm . map )
} ) ;
2020-09-07 02:25:45 +02:00
2020-10-06 01:37:02 +02:00
new GeoLocationHandler ( )
. SetStyle ( ` position:relative;display:block;border: solid 2px #0005;cursor: pointer; z-index: 999; /*Just below leaflets zoom*/background-color: white;border-radius: 5px;width: 43px;height: 43px; ` )
. AttachTo ( "geolocate-button" ) ;
2020-09-07 02:25:45 +02:00
State . state . locationControl . ping ( ) ;
2020-10-27 01:01:34 +01:00
}
2020-11-11 16:23:49 +01:00
2020-09-07 02:25:45 +02:00
static LoadLayoutFromHash ( userLayoutParam : UIEventSource < string > ) {
try {
let hash = location . hash . substr ( 1 ) ;
const layoutFromBase64 = userLayoutParam . data ;
// layoutFromBase64 contains the name of the theme. This is partly to do tracking with goat counter
const dedicatedHashFromLocalStorage = LocalStorageSource . Get ( "user-layout-" + layoutFromBase64 . replace ( " " , "_" ) ) ;
if ( dedicatedHashFromLocalStorage . data ? . length < 10 ) {
dedicatedHashFromLocalStorage . setData ( undefined ) ;
}
const hashFromLocalStorage = LocalStorageSource . Get ( "last-loaded-user-layout" ) ;
if ( hash . length < 10 ) {
hash = dedicatedHashFromLocalStorage . data ? ? hashFromLocalStorage . data ;
} else {
console . log ( "Saving hash to local storage" )
hashFromLocalStorage . setData ( hash ) ;
dedicatedHashFromLocalStorage . setData ( hash ) ;
}
2020-11-11 16:23:49 +01:00
const layoutToUse = new LayoutConfig ( JSON . parse ( atob ( hash ) ) ) ;
2020-09-07 02:25:45 +02:00
userLayoutParam . setData ( layoutToUse . id ) ;
return layoutToUse ;
} catch ( e ) {
new FixedUiElement ( "Error: could not parse the custom layout:<br/> " + e ) . AttachTo ( "centermessage" ) ;
throw e ;
}
}
2020-07-30 00:59:08 +02:00
static OnlyIf ( featureSwitch : UIEventSource < boolean > , callback : ( ) = > void ) {
2020-07-29 15:05:19 +02:00
featureSwitch . addCallback ( ( ) = > {
2020-07-30 00:59:08 +02:00
if ( featureSwitch . data ) {
callback ( ) ;
2020-07-29 15:05:19 +02:00
}
} ) ;
2020-07-30 00:59:08 +02:00
if ( featureSwitch . data ) {
2020-07-29 15:05:19 +02:00
callback ( ) ;
}
}
2020-07-31 01:45:54 +02:00
private static CreateWelcomePane() {
2020-07-29 15:05:19 +02:00
2020-07-31 01:45:54 +02:00
const layoutToUse = State . state . layoutToUse . data ;
2020-07-31 16:17:16 +02:00
let welcome : UIElement = new WelcomeMessage ( ) ;
2020-11-11 16:23:49 +01:00
if ( layoutToUse . id === personal . id ) {
2020-08-26 15:36:04 +02:00
welcome = new PersonalLayersPanel ( ) ;
2020-07-31 16:17:16 +02:00
}
2020-08-07 00:45:33 +02:00
const tabs = [
2020-11-05 12:28:02 +01:00
{ header : ` <img src=' ${ layoutToUse . icon } '> ` , content : welcome } ,
2020-11-06 01:58:26 +01:00
{
header : Svg.osm_logo_img ,
content : Translations.t.general.openStreetMapIntro as UIElement
} ,
2020-08-07 00:45:33 +02:00
]
if ( State . state . featureSwitchShareScreen . data ) {
2020-11-14 02:54:33 +01:00
tabs . push ( { header : Svg.share , content : new ShareScreen ( ) } ) ;
2020-08-07 00:45:33 +02:00
}
2020-09-05 01:40:43 +02:00
if ( State . state . featureSwitchMoreQuests . data ) {
2020-08-25 00:20:20 +02:00
tabs . push ( {
2020-11-06 01:58:26 +01:00
header : Svg.add_img ,
2020-10-18 00:28:51 +02:00
content : new MoreScreen ( )
2020-08-25 00:20:20 +02:00
} ) ;
2020-08-07 00:45:33 +02:00
}
2020-09-05 01:40:43 +02:00
tabs . push ( {
2020-11-14 02:54:33 +01:00
header : Svg.help ,
2020-09-05 01:40:43 +02:00
content : new VariableUiElement ( State . state . osmConnection . userDetails . map ( userdetails = > {
if ( userdetails . csCount < State . userJourney . mapCompleteHelpUnlock ) {
return ""
}
2020-11-15 16:08:17 +01:00
return new Combine ( [ Translations . t . general . aboutMapcomplete , "<br/>Version " + State . vNumber ] ) . Render ( ) ;
2020-09-05 01:40:43 +02:00
} , [ Locale . language ] ) )
}
) ;
2020-07-29 15:05:19 +02:00
2020-09-05 01:40:43 +02:00
2020-09-12 23:15:17 +02:00
return new TabbedComponent ( tabs , State . state . welcomeMessageOpenedTab )
. ListenTo ( State . state . osmConnection . userDetails ) ;
2020-07-29 15:48:21 +02:00
}
2020-07-31 01:45:54 +02:00
static InitWelcomeMessage() {
2020-07-29 15:48:21 +02:00
2020-07-31 01:45:54 +02:00
const fullOptions = this . CreateWelcomePane ( ) ;
2020-07-29 15:48:21 +02:00
2020-11-14 02:54:33 +01:00
const help = Svg . help_svg ( ) . SetClass ( "open-welcome-button" ) ;
const close = Svg . close_svg ( ) . SetClass ( "close-welcome-button" ) ;
2020-07-29 18:35:46 +02:00
const checkbox = new CheckBox (
2020-07-29 15:05:19 +02:00
new Combine ( [
2020-11-06 01:58:26 +01:00
close ,
fullOptions
. SetClass ( "welcomeMessage" )
. onClick ( ( ) = > { /*Catch the click*/
} ) ] ) ,
help
2020-07-29 15:05:19 +02:00
, true
) . AttachTo ( "messagesbox" ) ;
2020-07-31 01:45:54 +02:00
const openedTime = new Date ( ) . getTime ( ) ;
State . state . locationControl . addCallback ( ( ) = > {
if ( new Date ( ) . getTime ( ) - openedTime < 15 * 1000 ) {
2020-09-12 23:15:17 +02:00
// Don't autoclose the first 15 secs when the map is moving
2020-07-29 18:35:46 +02:00
return ;
}
checkbox . isEnabled . setData ( false ) ;
} )
2020-07-29 15:05:19 +02:00
2020-11-17 02:22:48 +01:00
State . state . selectedElement . addCallback ( ( ) = > {
checkbox . isEnabled . setData ( false ) ;
} )
2020-07-29 15:05:19 +02:00
2020-07-31 01:45:54 +02:00
const fullOptions2 = this . CreateWelcomePane ( ) ;
State . state . fullScreenMessage . setData ( fullOptions2 )
2020-11-06 01:58:26 +01:00
2020-11-14 02:54:33 +01:00
Svg . help_svg ( )
2020-11-06 01:58:26 +01:00
. SetClass ( "open-welcome-button" )
. SetClass ( "shadow" )
. onClick ( ( ) = > {
State . state . fullScreenMessage . setData ( fullOptions2 )
} ) . AttachTo ( "help-button-mobile" ) ;
2020-07-29 15:05:19 +02:00
2020-07-30 00:59:08 +02:00
}
2020-08-31 02:59:47 +02:00
2020-09-13 03:29:44 +02:00
private static GenerateLayerControlPanel() {
2020-09-27 23:37:47 +02:00
let layerControlPanel : UIElement = undefined ;
2020-11-11 16:23:49 +01:00
if ( State . state . layoutToUse . data . enableBackgroundLayerSelection ) {
2020-09-28 00:30:39 +02:00
layerControlPanel = new BackgroundSelector ( ) ;
2020-09-27 23:37:47 +02:00
layerControlPanel . SetStyle ( "margin:1em" ) ;
layerControlPanel . onClick ( ( ) = > { } ) ;
}
2020-07-31 16:17:16 +02:00
if ( State . state . filteredLayers . data . length > 1 ) {
2020-09-13 03:29:44 +02:00
const layerSelection = new LayerSelection ( ) ;
2020-09-27 23:37:47 +02:00
layerSelection . onClick ( ( ) = > {
} ) ;
layerControlPanel = new Combine ( [ layerSelection , "<br/>" , layerControlPanel ] ) ;
2020-07-31 04:58:58 +02:00
}
2020-09-13 03:29:44 +02:00
return layerControlPanel ;
}
2020-07-31 04:58:58 +02:00
2020-09-13 03:29:44 +02:00
static InitLayerSelection() {
2020-07-31 04:58:58 +02:00
InitUiElements . OnlyIf ( State . state . featureSwitchLayers , ( ) = > {
2020-09-28 00:30:39 +02:00
const layerControlPanel = this . GenerateLayerControlPanel ( ) ;
if ( layerControlPanel === undefined ) {
return ;
}
2020-11-15 01:20:30 +01:00
layerControlPanel . SetStyle ( "display:block;padding:0.75em;border-radius:1em;" ) ;
2020-11-14 02:54:33 +01:00
const closeButton = Svg . close_svg ( ) . SetClass ( "layer-selection-toggle" ) . SetStyle ( " background: var(--subtle-detail-color);" )
2020-09-13 03:29:44 +02:00
const checkbox = new CheckBox (
new Combine ( [
closeButton ,
layerControlPanel ] ) . SetStyle ( "display:flex;flex-direction:row;" )
2020-09-17 20:59:05 +02:00
. SetClass ( "hidden-on-mobile" )
2020-09-13 03:29:44 +02:00
,
2020-11-14 02:54:33 +01:00
Svg . layers_svg ( ) . SetClass ( "layer-selection-toggle" ) ,
2020-09-17 23:53:57 +02:00
State . state . layerControlIsOpened
2020-08-22 13:02:31 +02:00
) ;
2020-11-06 01:58:26 +01:00
checkbox . AttachTo ( "layer-selection" ) ;
2020-09-13 03:29:44 +02:00
2020-07-31 04:58:58 +02:00
State . state . bm . Location . addCallback ( ( ) = > {
2020-09-13 03:29:44 +02:00
// Close the layer selection when the map is moved
2020-07-31 04:58:58 +02:00
checkbox . isEnabled . setData ( false ) ;
} ) ;
2020-09-13 03:29:44 +02:00
const fullScreen = this . GenerateLayerControlPanel ( ) ;
checkbox . isEnabled . addCallback ( isEnabled = > {
if ( isEnabled ) {
State . state . fullScreenMessage . setData ( fullScreen ) ;
}
} )
State . state . fullScreenMessage . addCallbackAndRun ( latest = > {
if ( latest === undefined ) {
checkbox . isEnabled . setData ( false ) ;
}
} )
2020-07-31 04:58:58 +02:00
} ) ;
}
2020-11-06 01:58:26 +01:00
static CreateAttribution() {
return new VariableUiElement (
2020-07-31 17:38:03 +02:00
State . state . locationControl . map ( ( location ) = > {
2020-11-06 01:58:26 +01:00
const mapComplete = new Link ( ` Mapcomplete ${ State . vNumber } ` , 'https://github.com/pietervdvn/MapComplete' , true ) ;
const reportBug = new Link ( Svg . bug_img , "https://github.com/pietervdvn/MapComplete/issues" , true ) ;
2020-09-17 19:24:57 +02:00
const layoutId = State . state . layoutToUse . data . id ;
const osmChaLink = ` https://osmcha.org/?filters=%7B%22comment%22%3A%5B%7B%22label%22%3A%22%23 ${ layoutId } %22%2C%22value%22%3A%22%23 ${ layoutId } %22%7D%5D%2C%22date__gte%22%3A%5B%7B%22label%22%3A%222020-07-05%22%2C%22value%22%3A%222020-07-05%22%7D%5D%2C%22editor%22%3A%5B%7B%22label%22%3A%22MapComplete%22%2C%22value%22%3A%22MapComplete%22%7D%5D%7D `
2020-11-06 01:58:26 +01:00
const stats = new Link ( Svg . statistics_img , osmChaLink , true )
let editHere : ( UIElement | string ) = "" ;
2020-07-31 17:38:03 +02:00
if ( location !== undefined ) {
2020-11-06 01:58:26 +01:00
const idLink = ` https://www.openstreetmap.org/edit?editor=id#map= ${ location . zoom } / ${ location . lat } / ${ location . lon } `
editHere = new Link ( Svg . pencil_img , idLink , true ) ;
2020-07-31 17:38:03 +02:00
}
2020-11-06 01:58:26 +01:00
let editWithJosm : ( UIElement | string ) = ""
if ( location !== undefined &&
2020-09-22 00:22:50 +02:00
State . state . osmConnection !== undefined &&
State . state . bm !== undefined &&
2020-11-06 01:58:26 +01:00
State . state . osmConnection . userDetails . data . csCount >= State . userJourney . tagsVisibleAndWikiLinked ) {
2020-09-22 01:15:13 +02:00
const bounds = ( State . state . bm as Basemap ) . map . getBounds ( ) ;
const top = bounds . getNorth ( ) ;
const bottom = bounds . getSouth ( ) ;
const right = bounds . getEast ( ) ;
const left = bounds . getWest ( ) ;
const josmLink = ` http://127.0.0.1:8111/load_and_zoom?left= ${ left } &right= ${ right } &top= ${ top } &bottom= ${ bottom } `
2020-11-06 01:58:26 +01:00
editWithJosm = new Link ( Svg . josm_logo_img , josmLink , true ) ;
2020-09-22 00:22:50 +02:00
}
2020-09-27 01:38:51 +02:00
return new Combine ( [ mapComplete , reportBug , " | " , stats , " | " , editHere , editWithJosm ] ) . Render ( ) ;
2020-07-31 17:38:03 +02:00
2020-09-22 00:22:50 +02:00
} , [ State . state . osmConnection . userDetails ] )
2020-11-06 01:58:26 +01:00
) . SetClass ( "map-attribution" )
}
static InitBaseMap() {
const bm = new Basemap ( "leafletDiv" , State . state . locationControl , this . CreateAttribution ( ) ) ;
2020-08-08 02:16:42 +02:00
State . state . bm = bm ;
2020-11-17 02:22:48 +01:00
bm . map . on ( "popupclose" , ( ) = > {
State . state . selectedElement . setData ( undefined )
} )
2020-10-19 12:08:42 +02:00
State . state . layerUpdater = new UpdateFromOverpass ( State . state ) ;
2020-09-28 00:30:39 +02:00
State . state . availableBackgroundLayers = new AvailableBaseLayers ( State . state ) . availableEditorLayers ;
2020-11-13 23:58:11 +01:00
const queryParam = QueryParameters . GetQueryParameter ( "background" , State . state . layoutToUse . data . defaultBackgroundId , "The id of the background layer to start with" ) ;
2020-09-28 00:30:39 +02:00
2020-11-06 01:58:26 +01:00
queryParam . addCallbackAndRun ( ( selectedId : string ) = > {
2020-09-28 00:30:39 +02:00
const available = State . state . availableBackgroundLayers . data ;
for ( const layer of available ) {
if ( layer . id === selectedId ) {
State . state . bm . CurrentLayer . setData ( layer ) ;
}
}
} )
State . state . bm . CurrentLayer . addCallbackAndRun ( currentLayer = > {
queryParam . setData ( currentLayer . id ) ;
} ) ;
2020-08-08 02:16:42 +02:00
2020-07-31 17:38:03 +02:00
}
2020-07-30 00:59:08 +02:00
2020-07-31 16:17:16 +02:00
static InitLayers() {
2020-07-30 00:59:08 +02:00
const flayers : FilteredLayer [ ] = [ ]
2020-07-31 01:45:54 +02:00
const state = State . state ;
2020-09-05 15:27:35 +02:00
2020-07-31 01:45:54 +02:00
for ( const layer of state . layoutToUse . data . layers ) {
2020-09-05 15:27:35 +02:00
if ( typeof ( layer ) === "string" ) {
throw "Layer " + layer + " was not substituted" ;
2020-08-31 02:59:47 +02:00
}
2020-07-30 00:59:08 +02:00
2020-11-17 02:22:48 +01:00
let generateContents = ( tags : UIEventSource < any > ) = > new FeatureInfoBox ( tags , layer ) ;
if ( layer . title === undefined && ( layer . tagRenderings ? ? [ ] ) . length === 0 ) {
generateContents = undefined ;
}
const flayer : FilteredLayer = new FilteredLayer ( layer , generateContents ) ;
2020-07-30 00:59:08 +02:00
flayers . push ( flayer ) ;
2020-08-08 02:16:42 +02:00
2020-11-16 01:59:30 +01:00
QueryParameters . GetQueryParameter ( "layer-" + layer . id , "true" , "Wehter or not layer " + layer . id + " is shown" )
2020-08-08 02:16:42 +02:00
. map < boolean > ( ( str ) = > str !== "false" , [ ] , ( b ) = > b . toString ( ) )
. syncWith (
flayer . isDisplayed
)
2020-07-30 00:59:08 +02:00
}
2020-07-31 16:17:16 +02:00
State . state . filteredLayers . setData ( flayers ) ;
2020-07-29 15:05:19 +02:00
}
}