From 4d77ad0ab5b28b4fd33bb21dee7ec2d23199e542 Mon Sep 17 00:00:00 2001
From: amadmate <82boma1bif@hft-stuttgart.de>
Date: Wed, 12 Jan 2022 20:18:15 +0100
Subject: [PATCH] check for hash on pageload

---
 public/js/connectToAPI.js | 548 +++++++++++++++++++++++++-------------
 public/main.html          |  14 +-
 2 files changed, 381 insertions(+), 181 deletions(-)

diff --git a/public/js/connectToAPI.js b/public/js/connectToAPI.js
index c3d879b..96c395b 100644
--- a/public/js/connectToAPI.js
+++ b/public/js/connectToAPI.js
@@ -1,5 +1,13 @@
 var coordinatesBB = []
-var url = "https://simstadt-api.iaf-ex.hft-stuttgart.de:8080/workflow/execute"
+//var url = "https://simstadt-api.iaf-ex.hft-stuttgart.de:8080/workflow/execute" //old link
+var url = "http://vm24.fkc.hft-stuttgart.de:8082/workflow/execute" // URL to API
+var url2 = "http://vm24.fkc.hft-stuttgart.de:8082/workflow/timedShadowValueByDay/"
+var pvURL = "http://vm24.fkc.hft-stuttgart.de:8082/workflow/readPVPotential"
+
+/*TODO#1:   -get current data from the api and create local test data (apiData foler)
+            -add connection handeling  (error messages when there isnt a connection and then using the local test data)
+*/
+var localShadowData = "/3dclient4simstadtapi/public/test/APIdata/shadowData.json"
 
 var buildingFunctionSort
 var constructionYearSortPick
@@ -8,6 +16,65 @@ var heatedVolumeSortPick
 var totalSurfaceAreaSortPick
 var roofTypeSortPick
 var uValueSortPick
+var shadowdata
+
+
+async function fetchPvPotentialJSON() {    
+    var bottomLat = coordinatesBB[1]
+    var leftLng = coordinatesBB[0]
+    var rightLng = coordinatesBB[2]
+    var topLat = coordinatesBB[3]
+
+    const response = await fetch(pvURL,  {
+        method: "POST",
+        body: JSON.stringify({
+            "boundingBox": {
+                "bottomLat": bottomLat, //48.779004965,
+                "leftLng": leftLng,     //9.1686843081,
+                "lodType": "LOD2",
+                "rightLng": rightLng,   //9.175336684,
+                "topLat": topLat        //48.7822869656
+              },
+              "cityGMLRef": "campusLOD2"
+        }),
+        headers: {
+            "Content-Type": "application/json",
+            "Authorization": "Basic YWRtaW46YWRtaW4xMjM="
+        }
+    })
+
+    const data = await response.json();
+    return data
+}
+
+async function fetchshadowDataJSON() {
+    var bottomLat = coordinatesBB[1]
+    var leftLng = coordinatesBB[0]
+    var rightLng = coordinatesBB[2]
+    var topLat = coordinatesBB[3]//
+    var day = "1";
+    const response = await fetch(url2 + day,  {
+        method: "POST",
+        body: JSON.stringify({
+            "boundingBox": {
+                "bottomLat": bottomLat, //48.779004965,
+                "leftLng": leftLng,     //9.1686843081,
+                "lodType": "LOD2",
+                "rightLng": rightLng,   //9.175336684,
+                "topLat": topLat        //48.7822869656
+            },
+            "cityGMLRef": "campusLOD2"
+        }),
+        headers: {
+            "Content-Type": "application/json",
+            "Authorization": "Basic YWRtaW46YWRtaW4xMjM="
+        }
+    })
+
+    const data = await response.json();
+    return data
+}
+
 
 async function fetchDataJSON() {
     var bottomLat = coordinatesBB[1]
@@ -15,7 +82,7 @@ async function fetchDataJSON() {
     var rightLng = coordinatesBB[2]
     var topLat = coordinatesBB[3]//
 
-    const response = await fetch(url, {
+const response = await fetch(url, {
         method: "POST",
         body: JSON.stringify({
             "boundingBox": {
@@ -25,7 +92,7 @@ async function fetchDataJSON() {
                 "rightLng": rightLng,   //9.175336684,
                 "topLat": topLat        //48.7822869656
             },
- //           "cityGMLRef": "campus",
+            "cityGMLRef": "campusLOD2",
             "interestedAttributes": [
                 "uValue",
                 "volume",
@@ -37,7 +104,7 @@ async function fetchDataJSON() {
                 "monthlyCooling",
                 "pvPotential",
                 "roofType",
-                "totalSurfaceArea"
+                "totalSurfaceArea"                
             ],
             "properies": {
                 "physicsUseScenario": false
@@ -51,181 +118,222 @@ async function fetchDataJSON() {
     const data = await response.json()
     return data
 }
+
 document.getElementById("loader").style.visibility = "hidden"
 
+async function getLocalShadowdata(){
+    // gets the response from the api and put it inside a constant
+    const response = await fetch(localShadowData);
+    //the response have to be converted to json type file, so it can be used
+     const data = await response.json();
+    console.log(data)
+   // shadowData=data;
+    return data;
+  }
+
 function processData() {
     console.log(coordinatesBB)
     console.log("Waiting for data....")
 
-    fetchDataJSON().then(data => {
-        console.log(data);
-        document.getElementById("cesiumContainer").style.opacity = "1";
-        document.getElementById("loader").style.visibility = "hidden"
-        console.log("....received data")
+    timeout(25000, fetchshadowDataJSON()).then((response)=>{        
+        console.log(response)  
+        shadowdata = response  ;                     
+        }).catch((error)=>{ //catching the error(no connection)/ timeout and displaying an alert for the user
+     //  shadowdata=  getLocalShadowdata();
+        console.log(shadowdata);
+        //loadLocalAPIshadowData here...
+    }) 
+
+    timeout(10000,  fetchPvPotentialJSON()).then((response)=>{        
+        console.log(response)                
+     }).catch((error) => {
+        console.log(error)
+    }) 
+    
+    
+    timeout(10000,  fetchDataJSON()).then((response)=>{        
+        calculateData(response);                      
+     }).catch((error) => {
+        console.log(error)
+        /*
+        fetch("/3dclient4simstadtapi/public/test/APIdata/buildingInformation.json")
+        .then(response => response.text())
+        .then(text => calculateData( JSON.parse(text)))
+        */
+    })
 
-        var buildingsMAP = new Map()
+          
 
-        data.buildings.forEach(bu => {
+   
+}
 
-            var partsArray = []
-            var surefacesArray = []
 
-            bu.parts.forEach(p =>
-                p.surfaces.forEach(s =>
-                    surefacesArray.push(new Surface(s.id,
-                        s.attributes.uValue,
-                        s.attributes.totalSurfaceArea))))
 
-            bu.parts.forEach(p => partsArray.push(new Part(p.id,
-                surefacesArray,
-                p.attributes.volume,
-                p.attributes.height,
-                p.attributes.heatedVolume,
-                p.attributes.yearOfConstruction,
-                p.attributes.buildingFunction,
-                p.attributes.monthlyHeating,
-                p.attributes.monthlyCooling,
-                p.attributes.roofType)))
+function calculateData(data){
+    console.log(data);
+    document.getElementById("cesiumContainer").style.opacity = "1";
+    document.getElementById("loader").style.visibility = "hidden"
+    console.log("....received data")
 
-            buildingsMAP.set(bu.id, new Building(bu.id, partsArray))  //puts buildings with parts and surfaces in a map
+    var buildingsMAP = new Map()
 
-        })
+    data.buildings.forEach(bu => {
 
-        var partHeightMAP = new Map()
-        var partVolumeMAP = new Map()
-        var partHeatedVolumeMAP = new Map()
-        var partConstructionYearMAP = new Map()
-        var partBuildingTypeMAP = new Map()
-        var partMonthlyHeatingMAP = new Map()
-        var partMonthlyCoolingMAP = new Map()
-        var surfaceUValueMAP = new Map()
-        var partRoofTypeMAP = new Map()
-        var surfaceTotalSurfaceAreaMAP = new Map()
-
-        //fill height, heated volume and construction year map
-        buildingsMAP.forEach(b => {
-            b.parts.forEach(part => {
-                if (part.height !== undefined) {
-                    partHeightMAP.set(part.id, part.height)
-                }
-                if (part.volume !== undefined) {
-                    partVolumeMAP.set(part.id, part.volume)
-                }
-                if (part.heatedVolume !== undefined) {
-                    partHeatedVolumeMAP.set(part.id, part.heatedVolume)
-                }
-                if (part.yearOfConstruction !== undefined && part.yearOfConstruction <= "2020") {
-                    partConstructionYearMAP.set(part.id, part.yearOfConstruction)
-                }
-                if (part.buildingFunction !== undefined) {
-                    partBuildingTypeMAP.set(part.id, part.buildingFunction)
-                }
-                if (part.monthlyHeating !== undefined) {
-                    partMonthlyHeatingMAP.set(part.id, part.monthlyHeating)
-                }
-                if (part.monthlyCooling !== undefined) {
-                    partMonthlyCoolingMAP.set(part.id, part.monthlyCooling)
-                }
-                if (part.roofType !== undefined) {
-                    partRoofTypeMAP.set(part.id, part.roofType)
+        var partsArray = []
+        var surefacesArray = []
+
+        bu.parts.forEach(p =>
+            p.surfaces.forEach(s =>
+                surefacesArray.push(new Surface(s.id,
+                    s.attributes.uValue,
+                    s.attributes.totalSurfaceArea))))
+
+        bu.parts.forEach(p => partsArray.push(new Part(p.id,
+            surefacesArray,
+            p.attributes.volume,
+            p.attributes.height,
+            p.attributes.heatedVolume,
+            p.attributes.yearOfConstruction,
+            p.attributes.buildingFunction,
+            p.attributes.monthlyHeating,
+            p.attributes.monthlyCooling,
+            p.attributes.roofType)))
+
+        buildingsMAP.set(bu.id, new Building(bu.id, partsArray))  //puts buildings with parts and surfaces in a map
+
+    })
+
+    var partHeightMAP = new Map()
+    var partVolumeMAP = new Map()
+    var partHeatedVolumeMAP = new Map()
+    var partConstructionYearMAP = new Map()
+    var partBuildingTypeMAP = new Map()
+    var partMonthlyHeatingMAP = new Map()
+    var partMonthlyCoolingMAP = new Map()
+    var surfaceUValueMAP = new Map()
+    var partRoofTypeMAP = new Map()
+    var surfaceTotalSurfaceAreaMAP = new Map()
+
+    //fill height, heated volume and construction year map
+    buildingsMAP.forEach(b => {
+        b.parts.forEach(part => {
+            if (part.height !== undefined) {
+                partHeightMAP.set(part.id, part.height)
+            }
+            if (part.volume !== undefined) {
+                partVolumeMAP.set(part.id, part.volume)
+            }
+            if (part.heatedVolume !== undefined) {
+                partHeatedVolumeMAP.set(part.id, part.heatedVolume)
+            }
+            if (part.yearOfConstruction !== undefined && part.yearOfConstruction <= "2020") {
+                partConstructionYearMAP.set(part.id, part.yearOfConstruction)
+            }
+            if (part.buildingFunction !== undefined) {
+                partBuildingTypeMAP.set(part.id, part.buildingFunction)
+            }
+            if (part.monthlyHeating !== undefined) {
+                partMonthlyHeatingMAP.set(part.id, part.monthlyHeating)
+            }
+            if (part.monthlyCooling !== undefined) {
+                partMonthlyCoolingMAP.set(part.id, part.monthlyCooling)
+            }
+            if (part.roofType !== undefined) {
+                partRoofTypeMAP.set(part.id, part.roofType)
+            }
+            part.surfaces.forEach(s => {
+                if (s.uValue !== undefined) {
+                    surfaceUValueMAP.set(s.id, s.uValue)
                 }
-                part.surfaces.forEach(s => {
-                    if (s.uValue !== undefined) {
-                        surfaceUValueMAP.set(s.id, s.uValue)
-                    }
-                })
-                //totalSurfaceArea
-                surfaceTotalSurfaceAreaMAP.set(part.id, part.surfaces)
             })
+            //totalSurfaceArea
+            surfaceTotalSurfaceAreaMAP.set(part.id, part.surfaces)
         })
+    })
 
-        //sort maps
-        const heightSort = new Map([...partHeightMAP.entries()].sort((a, b) => b[1] - a[1]));
-        const heatedVolumeSort = new Map([...partHeatedVolumeMAP.entries()].sort((a, b) => b[1] - a[1]));
-        const constructionYearSort = new Map([...partConstructionYearMAP.entries()].sort((a, b) => a[1] - b[1]));
-        const uValueSort = new Map([...surfaceUValueMAP.entries()].sort((a, b) => b[1] - a[1]));
-
-        //for Properties Single Buildings
-        buildingFunctionSortPick = new Map([...partBuildingTypeMAP.entries()].sort((a, b) => b[1] - a[1]));
-        constructionYearSortPick = new Map([...partConstructionYearMAP.entries()].sort((a, b) => a[1] - b[1]));
-        heightSortPick = new Map([...partHeightMAP.entries()].sort((a, b) => b[1] - a[1]));
-        heatedVolumeSortPick = new Map([...partHeatedVolumeMAP.entries()].sort((a, b) => b[1] - a[1]));
-        totalSurfaceAreaSortPick = new Map([...surfaceTotalSurfaceAreaMAP.entries()].sort((a, b) => b[1] - a[1]));
-        roofTypeSortPick = new Map([...partRoofTypeMAP.entries()].sort((a, b) => b[1] - a[1]));
-        uValueSortPick = new Map([...surfaceUValueMAP.entries()].sort((a, b) => b[1] - a[1]));
-
-
-        //fill arrays needed for charts
-        heightSort.forEach((value, key) => addHeightInfosToArrays(key, value))
-        heatedVolumeSort.forEach((value, key) => addHeatedVolumeInfosToArrays(key, value))
-        constructionYearSort.forEach((value) => yearOfConstructionValues.push(value))
-        partBuildingTypeMAP.forEach((value) => buildingTypeValues.push(value))
-        partMonthlyHeatingMAP.forEach((valueArray, key) => yearlyHeatingDemand(key, valueArray))
-        partMonthlyCoolingMAP.forEach((valueArray, key) => yearlyCoolingDemand(key, valueArray))
-        uValueSort.forEach((value, key) => {
-            uValueSurfaces(key, value)
-            uValuesAll.push(value)
-        })
+    //sort maps
+    const heightSort = new Map([...partHeightMAP.entries()].sort((a, b) => b[1] - a[1]));
+    const heatedVolumeSort = new Map([...partHeatedVolumeMAP.entries()].sort((a, b) => b[1] - a[1]));
+    const constructionYearSort = new Map([...partConstructionYearMAP.entries()].sort((a, b) => a[1] - b[1]));
+    const uValueSort = new Map([...surfaceUValueMAP.entries()].sort((a, b) => b[1] - a[1]));
+
+    //for Properties Single Buildings
+    buildingFunctionSortPick = new Map([...partBuildingTypeMAP.entries()].sort((a, b) => b[1] - a[1]));
+    constructionYearSortPick = new Map([...partConstructionYearMAP.entries()].sort((a, b) => a[1] - b[1]));
+    heightSortPick = new Map([...partHeightMAP.entries()].sort((a, b) => b[1] - a[1]));
+    heatedVolumeSortPick = new Map([...partHeatedVolumeMAP.entries()].sort((a, b) => b[1] - a[1]));
+    totalSurfaceAreaSortPick = new Map([...surfaceTotalSurfaceAreaMAP.entries()].sort((a, b) => b[1] - a[1]));
+    roofTypeSortPick = new Map([...partRoofTypeMAP.entries()].sort((a, b) => b[1] - a[1]));
+    uValueSortPick = new Map([...surfaceUValueMAP.entries()].sort((a, b) => b[1] - a[1]));
+
+
+    //fill arrays needed for charts
+    heightSort.forEach((value, key) => addHeightInfosToArrays(key, value))
+    heatedVolumeSort.forEach((value, key) => addHeatedVolumeInfosToArrays(key, value))
+    constructionYearSort.forEach((value) => yearOfConstructionValues.push(value))
+    partBuildingTypeMAP.forEach((value) => buildingTypeValues.push(value))
+    partMonthlyHeatingMAP.forEach((valueArray, key) => yearlyHeatingDemand(key, valueArray))
+    partMonthlyCoolingMAP.forEach((valueArray, key) => yearlyCoolingDemand(key, valueArray))
+    uValueSort.forEach((value, key) => {
+        uValueSurfaces(key, value)
+        uValuesAll.push(value)
+    })
 
-        partMonthlyHeatingMAP.forEach((value, key) => addmonthlyHeatingInfosToArrays(key, value))
-        partMonthlyCoolingMAP.forEach((value, key) => addmonthlyCoolingInfosToArrays(key, value))
-        partVolumeMAP.forEach((value, key) => addVolumeValues(key, value))
-
-        //calculates year of construction frequency
-        yearFrequency()
-
-        //calculates building type frequency
-        buildingTypeFrequency()
-
-        //calculates uValue frequency
-        uValueFrequency()
-
-        //sorts yearly heating & cooling demand for charts
-        sortMap()
-
-        //disables attributes in chart without values
-        availableAttributes()
-
-        //color buildings with heating demand
-        document.getElementById("checkbox2").addEventListener("change", function () {
-            if (this.checked) {
-                tileContent.forEach(t => {
-                    let tileID = t.getProperty("gml_parent_id")
-                    let tileColor = heatingIDColorMAP.get(tileID)
-                    if (tileColor !== undefined) {
-                        t.color = Cesium.Color.fromCssColorString(tileColor)
-                    } else {
-                        t.color = new Cesium.Color(1, 1, 1, 1)
-                    }
-                })
-                console.log("colored")
-            } else {
-                tileContent.forEach(t => t.color = new Cesium.Color(1, 1, 1, 1))
-                console.log("not colored")
-            }
-        })
+    partMonthlyHeatingMAP.forEach((value, key) => addmonthlyHeatingInfosToArrays(key, value))
+    partMonthlyCoolingMAP.forEach((value, key) => addmonthlyCoolingInfosToArrays(key, value))
+    partVolumeMAP.forEach((value, key) => addVolumeValues(key, value))
 
-        //color surfaces with uValue
-        document.getElementById("checkbox1").addEventListener("change", function () {
-            if (this.checked) {
-                tileContent.forEach(t => {
-                    let tileID = t.getProperty("gml_id")
-                    let tileColor = surfaceIDColorMAP.get(tileID)
-                    if (tileColor !== undefined) {
-                        t.color = Cesium.Color.fromCssColorString(tileColor)
-                    } else {
-                        t.color = new Cesium.Color(1, 1, 1, 1)
-                    }
-                })
-                console.log("colored")
-            } else {
-                tileContent.forEach(t => t.color = new Cesium.Color(1, 1, 1, 1))
-                console.log("not colored")
-            }
-        })
+    //calculates year of construction frequency
+    yearFrequency()
+
+    //calculates building type frequency
+    buildingTypeFrequency()
+
+    //calculates uValue frequency
+    uValueFrequency()
+
+    //sorts yearly heating & cooling demand for charts
+    sortMap()
+
+    //disables attributes in chart without values
+    availableAttributes()
 
-    }).catch((err) => {
-        console.log(err)
+    //color buildings with heating demand
+    document.getElementById("checkbox2").addEventListener("change", function () {
+        if (this.checked) {
+            tileContent.forEach(t => {
+                let tileID = t.getProperty("gml_parent_id")
+                let tileColor = heatingIDColorMAP.get(tileID)
+                if (tileColor !== undefined) {
+                    t.color = Cesium.Color.fromCssColorString(tileColor)
+                } else {
+                    t.color = new Cesium.Color(1, 1, 1, 1)
+                }
+            })
+            console.log("colored")
+        } else {
+            tileContent.forEach(t => t.color = new Cesium.Color(1, 1, 1, 1))
+            console.log("not colored")
+        }
+    })
+
+    //color surfaces with uValue
+    document.getElementById("checkbox1").addEventListener("change", function () {
+        if (this.checked) {
+            tileContent.forEach(t => {
+                let tileID = t.getProperty("gml_id")
+                let tileColor = surfaceIDColorMAP.get(tileID)
+                if (tileColor !== undefined) {
+                    t.color = Cesium.Color.fromCssColorString(tileColor)
+                } else {
+                    t.color = new Cesium.Color(1, 1, 1, 1)
+                }
+            })
+            console.log("colored")
+        } else {
+            tileContent.forEach(t => t.color = new Cesium.Color(1, 1, 1, 1))
+            console.log("not colored")
+        }
     })
 }
 
@@ -282,31 +390,109 @@ window.onclick = function (event) {
     }
 }
 
-var tileData = null
-var tileset = null
+//-------------------------------------------------------------------------------
+var tileData = null;
+var tileset = null;
+//var tilesetURL = 'http://vm24.fkc.hft-stuttgart.de:8081/CampusLOD2Old/tileset.json';
+var tilesetURL = 'http://vm24.fkc.hft-stuttgart.de:8081/CampusLOD2/tileset.json';
+var tilesetURLb1 = 'http://vm24.fkc.hft-stuttgart.de:8081/Baue/bau1u3.json';
+var tilesetURLb2 = 'http://vm24.fkc.hft-stuttgart.de:8081/Baue/bau2.json';
+var tilesetURLb4 = 'http://vm24.fkc.hft-stuttgart.de:8081/Baue/bau4.json';
+var tilesetURLb5 = 'http://vm24.fkc.hft-stuttgart.de:8081/Baue/bau5.json';
+var tilesetURLb6 = 'http://vm24.fkc.hft-stuttgart.de:8081/Baue/bau6.json';
+var tilesetURLb7 = 'http://vm24.fkc.hft-stuttgart.de:8081/Baue/bau7.json';
+var tilesetURLb8 = 'http://vm24.fkc.hft-stuttgart.de:8081/Baue/bau8.json';
+
+var localTestTileset = 'test/gmlTileset_v1.json';
+var localB1 = 'test/bau1u3.json';
+var localB2 = 'test/bau2.json';
+var localB4 = 'test/bau4.json';
+var localB5 = 'test/bau5.json';
+var localB6 = 'test/bau6.json';
+var localB7 = 'test/bau7.json';
+var localB8 = 'test/bau8.json';
+
+
+function timeout(ms, promise) {
+    return new Promise(function(resolve, reject) {
+      setTimeout(function() {
+        reject(new Error("timeout"))
+      }, ms)
+      promise.then(resolve, reject)
+    })
+}
+
+function pageLoad() {
+    if (window.location.hash === "#load-bau1") {
+       loadAndZoomToTileset(tilesetURLb1);
+    }if (window.location.hash === "#load-bau2") {
+        loadAndZoomToTileset(tilesetURLb2);
+     }if (window.location.hash === "#load-bau4") {
+        loadAndZoomToTileset(tilesetURLb4);
+     }if (window.location.hash === "#load-bau5") {
+        loadAndZoomToTileset(tilesetURLb5);
+     }if (window.location.hash === "#load-bau6") {
+        loadAndZoomToTileset(tilesetURLb6);
+     }if (window.location.hash === "#load-bau7") {
+        loadAndZoomToTileset(tilesetURLb7);
+     }if (window.location.hash === "#load-bau8") {
+        loadAndZoomToTileset(tilesetURLb8);
+     }
+}
+
+//fetching the tileset and handling the connection
+async function fetchTileset(){   
+    timeout(1000, fetch(tilesetURL)).then((response)=>{        
+        loadAndZoomToTileset(tilesetURL);                          
+     }).catch((error)=>{ //catching the error(no connection)/ timeout and displaying an alert for the user
+        //var errorString = error["stack"]+"\n"+error["message"]; // formatting the error array
+        swal({text:"Could not connect to Server. Using now: local data",icon:"info" } );  
+        console.log("Using local test data");
+        loadAndZoomToTileset(localTestTileset); //TODO#3: fix the link so the local tileset can be loaded
+    }) 
+}
+
+
+
+/*
+    NOTE #1:    -load the models but the are in the too high in the "air"
+                -building view doesn´t work because all buildings are grouped together
+                -surfaces are also broken
+
+            -->this fixme is the problem of the backendteam !
 
-fetch('https://boxofcare.de/3DContainerTile/collections/')
-    .then(response => response.json())
-    .then(data => {
-        tileData = data
-    });
+    ? maybe add old menu back and the option to also load the new ones 
+    
+*/
 
-function loadTileset() {
-    viewer.scene.primitives.remove(tileset)
-    tileContent = []
+
+//loads tileset after submit button is clicked
+function loadTileset() {    
+    viewer.scene.primitives.remove(tileset);
+    tileContent = [];
     modal.style.display = "block";
-    console.log(tileData)
+    
+    fetchTileset();
+    
+    //var userurl = document.getElementById("3Durl").value;   //returns the chosen area from the dropdown    
+}
+//loads the tileset from the url into the cesium viewer and zooms to it
 
-    var userurl = document.getElementById("3Durl").value;
+function loadAndZoomToTileset(url){
+    tileset=viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
+        
+        url: url
+    }));
+    
 
-    tileData.collections.forEach(c => {
-        if (userurl === 'hftcampus' && c.id === "HftCampus") useContent(c.content)
-        if (userurl === 'paderborn' && c.id === "Paderborn") useContent(c.content)
-    })
+    viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0, -0.5, 0));
+            modal.style.display = "none";
+            saveTilesetContent(tileset)
+            deleteTilesetButtons()
 }
 
-function useContent(content) {
 
+function useContent(content) {
     content.forEach(cont => {
         var element = document.createElement("input")
         element.type = "button"
@@ -341,9 +527,13 @@ function saveTilesetContent(tileset) {
 function deleteTilesetButtons() {
     var x = document.getElementsByName("individualTileset")
     var len = x.length
-
-    parentNode = x[0].parentNode;
-    for (var i = 0; i < len; i++) {
-        parentNode.removeChild(x[0]);
+    
+    //checking if there are even tileset to delete
+    if(x.length>0){
+        parentNode = x[0].parentNode;
+        for (var i = 0; i < len; i++) {
+            parentNode.removeChild(x[0]);
+        }
     }
+   
 }
diff --git a/public/main.html b/public/main.html
index 5a536f0..afbfcf2 100644
--- a/public/main.html
+++ b/public/main.html
@@ -36,6 +36,7 @@
 	</style>
 	<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
 	<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/2.1.2/sweetalert.min.js" integrity="sha512-AA1Bzp5Q0K1KanKKmvN/4d3IRKVlv9PYgwFPvm32nPO6QS8yH1HO7LbgB1pgiOxPtfeg5zEn2ba64MUcqJx6CA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
+	<!-- TODO: maybe add this to a external js file -->
 	<script type="text/javascript">
 		var arrLang = {
 			'en': {
@@ -124,7 +125,7 @@
 	</script>
 </head>
 
-<body>
+<body onload="pageLoad()">
 	<a href="https://www.hft-stuttgart.de/" target="_blank">
 		<div class="credit"></div>
 	</a>
@@ -211,7 +212,7 @@
 	</div>
 
 	<div class="hilfe">
-        <p> <a href="/pdf/Benutzerhandbuch.pdf" target="_blank"><button class="lang" id="Handbuch"  key="userguide">User Guide</button></a></p>
+        <p> <a href="/3dclient4simstadtapi/public/pdf/Benutzerhandbuch.pdf" target="_blank"><button class="lang" id="Handbuch"  key="userguide">User Guide</button></a></p>
     </div>
 
 	<!--Sidebar-->
@@ -241,9 +242,15 @@
 						<input id="building" type="radio" name="credit-card" value="building" checked>
 						<div class="lang" key="buildingview">Building-View</div>
 						<label class="drinkcard-cc building" for="building"></label>
+						
 						<input id="surface" type="radio" name="credit-card" value="surface">
 						<div class="lang" key="surfaceview">Surface-View</div>
 						<label class="drinkcard-cc surface" for="surface"></label>
+
+						<input id="roof" type="radio" name="credit-card" value="roof">
+						<div class="lang" key="roofview">Roof-View</div>
+						<label class="drinkcard-cc surface" for="roof"></label>
+
 					</div>
 				</div>
 				<!--Chartbutton-->
@@ -336,6 +343,9 @@
 		<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"
 			integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous">
 		</script>
+
+		<script type="text/javascript" src="js/shadowPalette.js"></script>
+
 		<script type="text/javascript" src="js/sidebar.js"></script>
 		<script type="text/javascript" src="js/globe.js"></script>
 		<script type="text/javascript" src="js/areaCharts.js"></script>
-- 
GitLab