diff --git a/public/polylines_with_particles.js b/public/polylines_with_particles.js index d4a4299e6285546a1c04f4c86fe9eee639bf2371..3120c046fb2f638f7b3b6b76db91ba4221a279e2 100644 --- a/public/polylines_with_particles.js +++ b/public/polylines_with_particles.js @@ -39,11 +39,11 @@ $(function () { animation: true, infoBox: true, baseLayerPicker: true, - fullscreenButton: false, - timeline: false, + fullscreenButton: true, + timeline: true, navigationHelpButton: true, navigationInstructionsInitiallyVisible: false, - homeButton: false, + homeButton: true, selectionIndicator: true, geocoder: true, // imageryProviderViewModels: imageryViewModels @@ -138,7 +138,7 @@ $(function () { var Velocity = []; var pt_to_pt_dist = []; var avgVelocity = []; - var czmlArray = []; + function get_date_time_dt(deltaTime) { // deltaTime should be given in SECONDS and is then converted to milliseconds @@ -151,23 +151,31 @@ $(function () { } d3.dsv(",", "results/polylines_with_velocity.csv").then(function (text) { - const particleDuration = 90; // units in seconds the particle / point should take to move from start to finish + const particleDuration = 120; // units in seconds the particle / point should take to move from start to finish //define the czml structure var particle_czml = [ { id: "document", name: "CZML Point - Time Dynamic", version: "1.0", + clock: { + interval: get_date_time_dt(0) + "/" + get_date_time_dt(particleDuration), // This is the time range of our simulation + currentTime: '', // This is the time associated with the start view + currentTime: get_date_time_dt(0), + multiplier: 5, + // range: 'LOOP_STOP', + } }, { id: "point", - availability: - get_date_time_dt(0) + "/" + get_date_time_dt(particleDuration), + availability: get_date_time_dt(0) + "/" + get_date_time_dt(particleDuration), position: { epoch: get_date_time_dt(0), cartographicDegrees: [ // use 4 coordinates / values : (t,x,y,z) or rather (t,lon,lat,alt) ], + //"interpolationAlgorithm": "LAGRANGE", + //"interpolationDegree": 1 }, point: { color: { @@ -181,6 +189,18 @@ $(function () { }, }, ]; + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + let package_time_faktor = 6.0; + + // create an array of deep copies of the original czml data structure, to be modified below. + let czmlArr = []; + for (c=0; c < package_time_faktor; c++){ + czmlArr.push(JSON.parse(JSON.stringify(particle_czml))); + czmlArr[c][1].id = "point_arr_" + String(c); + } + + var temp = text; for (var i = 0; i < temp.length; i++) { @@ -223,6 +243,7 @@ $(function () { // Create and draw a polyline with per vertex colors ///////////////////////////////////////////////// const heightOffset = 120; + for (var line = 0; line < uniqueStreamID.length; line++) { let positions = []; let positionsInDegrees = []; @@ -231,25 +252,29 @@ $(function () { let individual_particle_pt_distance = []; let individual_particle_avg_velo = []; - for (i = sIDidx[line - 1]; i < sIDidx[line] - 1; ++i) { - positions.push( - Cesium.Cartesian3.fromDegrees( + curr_pos = sIDidx[line]; + + for (i = curr_pos; i < streamID.length; ++i) { + if (line === streamID[i]){ + positions.push( + Cesium.Cartesian3.fromDegrees( + pos[i][0], + pos[i][1], + pos[i][2] + heightOffset + ) + ); + positionsInDegrees.push([ pos[i][0], pos[i][1], - pos[i][2] + heightOffset - ) - ); - positionsInDegrees.push([ - pos[i][0], - pos[i][1], - pos[i][2] + heightOffset, - ]); - colors.push( - Cesium.Color.fromBytes(cols[i][0], cols[i][1], cols[i][2], 180) - ); - individual_particle_avg_velo.push(avgVelocity[i]); - individual_particle_pt_distance.push(pt_to_pt_dist[i]); - individual_particle_velo.push(Velocity[i]); + pos[i][2] + heightOffset, + ]); + colors.push( + Cesium.Color.fromBytes(cols[i][0], cols[i][1], cols[i][2], 180) + ); + individual_particle_avg_velo.push(avgVelocity[i]); + individual_particle_pt_distance.push(pt_to_pt_dist[i]); + individual_particle_velo.push(Velocity[i]); + } // if end brace } // For per segment coloring, supply the colors option with // an array of colors for each vertex. Also set the @@ -274,14 +299,15 @@ $(function () { ///////////////////////////////////////////////// let streamDist = individual_particle_pt_distance.reduce(function (a, b) { return a + b; - }, 0); - // console.log(streamDist); + }, 0); + // console.log(streamDist); let t = 0; - let dt = (individual_particle_pt_distance[0] / individual_particle_avg_velo[0])/ 20; - // let dt = streamDist / individual_particle_avg_velo[0] / 500; - let temp_pos = []; - + let dt = (individual_particle_pt_distance[1] / individual_particle_avg_velo[0]) / 20; + // let dt = streamDist / individual_particle_avg_velo[0] / 500; + + ///////////////////////////////////// + var temp_pos = []; for (i = 0; i < positionsInDegrees.length; i++) { if (i === 0) { temp_pos.push( @@ -289,34 +315,62 @@ $(function () { positionsInDegrees[i][0], positionsInDegrees[i][1], positionsInDegrees[i][2] - ); + ); } else { temp_pos.push( t, positionsInDegrees[i][0], positionsInDegrees[i][1], positionsInDegrees[i][2] - ); - dt = individual_particle_pt_distance[i] /individual_particle_avg_velo[i] / 20; + ); + dt = individual_particle_pt_distance[i] /individual_particle_avg_velo[0] / 20; // avg_velo is always the same per streamline // console.log(individual_particle_pt_distance[i] + "/" + individual_particle_avg_velo[i] ); // console.log(dt); } - t += dt; } particle_czml[1].id = "point" + String(line); - particle_czml[1].position.cartographicDegrees = temp_pos; - - // czmlArray.push(particle_czml); + particle_czml[1].position.cartographicDegrees = temp_pos; viewer.dataSources.add(Cesium.CzmlDataSource.load(particle_czml)); - } + + //////////////////////////////////////////////// + dt = (individual_particle_pt_distance[1] / individual_particle_avg_velo[0]) / 20; + for (c=0; c < czmlArr.length ; c++){ + + temp_pos = []; + for (i = 0; i < positionsInDegrees.length; i++) { + if (i === 0) { + temp_pos.push( + t, + positionsInDegrees[i][0], + positionsInDegrees[i][1], + positionsInDegrees[i][2] + ); + } else { + temp_pos.push( + t, + positionsInDegrees[i][0], + positionsInDegrees[i][1], + positionsInDegrees[i][2] + ); + dt = individual_particle_pt_distance[i] /individual_particle_avg_velo[0] / 20; + // console.log(individual_particle_pt_distance[i] + "/" + individual_particle_avg_velo[i] ); + // console.log(dt); + } + + t += dt; + } + czmlArr[c][1].position.cartographicDegrees = temp_pos; + czmlArr[c][1].id = "point_set_" + String(c) + "_" + String(line); + czmlArr[c][1].position.epoch = get_date_time_dt(0); + viewer.dataSources.add(Cesium.CzmlDataSource.load(czmlArr[c])); + } + + + } // end bracket for: for (var line = 0; line < uniqueStreamID.length; line++) { - // for (p = 0; p < czmlArray.length; p++) { - // let temp = czmlArray[p]; - // viewer.dataSources.add(Cesium.CzmlDataSource.load(temp)); - // } - }); + }); // end bracket for: d3.dsv(...).then(... diff --git a/public/polylines_with_particles_backup.js b/public/polylines_with_particles_backup.js new file mode 100644 index 0000000000000000000000000000000000000000..b4c6e27ccdbbd211ea570bb0f5b1fa8299484967 --- /dev/null +++ b/public/polylines_with_particles_backup.js @@ -0,0 +1,520 @@ +$(function () { + Cesium.Ion.defaultAccessToken = + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5ODI4ZTYyZS1mMTg2LTQ5NGEtYjdiOS02ODg2NzVhNjc0MTAiLCJpZCI6MjkwNCwiaWF0IjoxNTM1MTA5OTAzfQ.kyDX_0ScvJBkYnvXI0DW5NfZbiaRL5ezwtAUhxYnk1Y"; + var imageryViewModels = []; + imageryViewModels.push( + new Cesium.ProviderViewModel({ + name: "Sentinel-2", + iconUrl: Cesium.buildModuleUrl( + "Widgets/Images/ImageryProviders/sentinel-2.png" + ), + tooltip: "Sentinel-2 cloudless.", + creationFunction: function () { + return new Cesium.IonImageryProvider({ assetId: 3954 }); + }, + }) + ); + + imageryViewModels.push( + new Cesium.ProviderViewModel({ + name: "Blue Marble", + iconUrl: Cesium.buildModuleUrl( + "Widgets/Images/ImageryProviders/blueMarble.png" + ), + tooltip: "Blue Marble Next Generation July, 2004 imagery from NASA.", + creationFunction: function () { + return new Cesium.IonImageryProvider({ assetId: 3845 }); + }, + }) + ); + + var viewer = new Cesium.Viewer("cesiumContainer", { + imageryProvider: new Cesium.IonImageryProvider({ assetId: 3954 }), + + terrainProvider: new Cesium.CesiumTerrainProvider({ + url: Cesium.IonResource.fromAssetId(1), + }), + scene3DOnly: false, + shouldAnimate: true, + animation: true, + infoBox: true, + baseLayerPicker: true, + fullscreenButton: false, + timeline: false, + navigationHelpButton: true, + navigationInstructionsInitiallyVisible: false, + homeButton: false, + selectionIndicator: true, + geocoder: true, + // imageryProviderViewModels: imageryViewModels + }); + + // var layer = viewer.imageryLayers.addImageryProvider( + // new Cesium.IonImageryProvider({ assetId: 3 }) + // ); + + var imageryLayer = viewer.imageryLayers.addImageryProvider( + new Cesium.IonImageryProvider({ assetId: 3954 }) + ); + + var canvas = viewer.canvas; + canvas.setAttribute("tabindex", "0"); // needed to put focus on the canvas + canvas.addEventListener("click", function () { + canvas.focus(); + }); + canvas.focus(); + var scene = viewer.scene; + + var tileset = viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: "buildingTiles/StoeckachLOD1/tileset.json", + show: true, + }) + ); + + tileset.readyPromise.then(function (tileset) { + return zoomAll(tileset); + }); + + tileset.readyPromise.then(function (tileset) { + var R = 0; // roll + var P = 0; // pitch + var Yaw = 0; // yaw + var height = 53; + var cartographic = Cesium.Cartographic.fromCartesian( + tileset.boundingSphere.center + ); + var surface = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + 0.0 + ); + var offset = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + height + ); + var translation = Cesium.Cartesian3.subtract( + offset, + surface, + new Cesium.Cartesian3() + ); + + //var rotMat = new Cesium.Matrix3(); + var rotation = new Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(Yaw, P, R) + ); + + tileset.modelMatrix = Cesium.Matrix4.fromRotationTranslation( + rotation, + translation + ); + + return zoomAll(tileset); + }); + + viewer.scene.globe.enableLighting = true; // set lighting to true + + var zoomAll = function (tileset) { + return new Promise(function (resolve, reject) { + if (!tileset) { + reject("Tileset is undifined"); + } + viewer.camera.viewBoundingSphere( + tileset.boundingSphere, + new Cesium.HeadingPitchRange(0, -0.5, 1500) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + resolve(); + }); + }; + + ////////////////////////////////////////// + // load streamline data from text file and parse it to polyline with multiple colors. + + var pos = []; + var cols = []; + var streamID = []; + var Velocity = []; + var pt_to_pt_dist = []; + var avgVelocity = []; + var czmlArray = []; + + function get_date_time_dt(deltaTime) { + // deltaTime should be given in SECONDS and is then converted to milliseconds + // set deltaTime to 0 if you want to get current date and time + // set to +60000 to get date and time of 60 seconds = 60000 milliseconds in the future + + return (currentdate = new Date( + new Date().getTime() + deltaTime * 1000 + ).toISOString()); + } + + d3.dsv(",", "results/polylines_with_velocity.csv").then(function (text) { + const particleDuration = 90; // units in seconds the particle / point should take to move from start to finish + //define the czml structure + var particle_czml = [ + { + id: "document", + name: "CZML Point - Time Dynamic", + version: "1.0", + }, + { + id: "point", + availability: + get_date_time_dt(0) + "/" + get_date_time_dt(particleDuration), + position: { + epoch: get_date_time_dt(0), + cartographicDegrees: [ + // use 4 coordinates / values : (t,x,y,z) or rather (t,lon,lat,alt) + ], + }, + point: { + color: { + rgba: [0, 0, 0, 250], + }, + outlineColor: { + rgba: [255, 0, 0, 128], + }, + outlineWidth: 1, + pixelSize: 6, + }, + }, + ]; + + var temp = text; + for (var i = 0; i < temp.length; i++) { + // use i+=7 when parsed as d3.text(...) + pos.push([ + parseFloat(text[i].Lon), + parseFloat(text[i].Lat), + parseFloat(text[i].z), + ]); + cols.push([ + parseInt(text[i].R), + parseInt(text[i].G), + parseInt(text[i].B), + ]); + streamID.push(parseInt(text[i].ID)); + Velocity.push(parseFloat(text[i].velocity)); + avgVelocity.push(parseFloat(text[i].AverageVelocity)); + pt_to_pt_dist.push(parseFloat(text[i].pt_to_pt_dist)); + // use these lines if parsed as text. i.e. using d3.text(...) + //pos.push([parseFloat(temp[i+0]), parseFloat(temp[i+1]), parseFloat(temp[i+2])]); + //colors.push([parseFloat(temp[i+3]),parseFloat(temp[i+4]),parseFloat(temp[i+5])]) + //streamID.push([parseFloat(temp[i+6])]); + } + + const maxID = streamID.reduce(function (a, b) { + return Math.max(a, b); + }); + + //find out the unique ids within the streamID array + const uniqueStreamID = Array.from(new Set(streamID)); // const uniqueStreamID = [...new Set(streamID)]; // same can be done with spread operator + + //get index of each unique id, first element of those + let sIDidx = []; + for (var i = 0; i <= maxID; i++) { + var tmpIdx = streamID.indexOf(i); + if (tmpIdx !== -1) sIDidx.push(tmpIdx); + } + + ///////////////////////////////////////////////// + // Create and draw a polyline with per vertex colors + ///////////////////////////////////////////////// + const heightOffset = 120; + for (var line = 0; line < uniqueStreamID.length; line++) { + let positions = []; + let positionsInDegrees = []; + let colors = []; + let individual_particle_velo = []; + let individual_particle_pt_distance = []; + let individual_particle_avg_velo = []; + + for (i = sIDidx[line - 1]; i < sIDidx[line] - 1; ++i) { + positions.push( + Cesium.Cartesian3.fromDegrees( + pos[i][0], + pos[i][1], + pos[i][2] + heightOffset + ) + ); + positionsInDegrees.push([ + pos[i][0], + pos[i][1], + pos[i][2] + heightOffset, + ]); + colors.push( + Cesium.Color.fromBytes(cols[i][0], cols[i][1], cols[i][2], 180) + ); + individual_particle_avg_velo.push(avgVelocity[i]); + individual_particle_pt_distance.push(pt_to_pt_dist[i]); + individual_particle_velo.push(Velocity[i]); + } + // For per segment coloring, supply the colors option with + // an array of colors for each vertex. Also set the + // colorsPerVertex option to true. + viewer.scene.primitives.add( + new Cesium.Primitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.PolylineGeometry({ + positions: positions, + width: 5.0, + vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT, + colors: colors, + colorsPerVertex: true, + }), + }), + appearance: new Cesium.PolylineColorAppearance(), + }) + ); + + //////////////////////////////////////////////// + // Create and prepare particles for movement + ///////////////////////////////////////////////// + let streamDist = individual_particle_pt_distance.reduce(function (a, b) { + return a + b; + }, 0); + // console.log(streamDist); + + let t = 0; + let dt = (individual_particle_pt_distance[0] / individual_particle_avg_velo[0])/ 20; + // let dt = streamDist / individual_particle_avg_velo[0] / 500; + let temp_pos = []; + + for (i = 0; i < positionsInDegrees.length; i++) { + if (i === 0) { + temp_pos.push( + 0, + positionsInDegrees[i][0], + positionsInDegrees[i][1], + positionsInDegrees[i][2] + ); + } else { + temp_pos.push( + t, + positionsInDegrees[i][0], + positionsInDegrees[i][1], + positionsInDegrees[i][2] + ); + dt = individual_particle_pt_distance[i] /individual_particle_avg_velo[i] / 20; + // console.log(individual_particle_pt_distance[i] + "/" + individual_particle_avg_velo[i] ); + // console.log(dt); + } + + t += dt; + } + particle_czml[1].id = "point" + String(line); + particle_czml[1].position.cartographicDegrees = temp_pos; + + // czmlArray.push(particle_czml); + viewer.dataSources.add(Cesium.CzmlDataSource.load(particle_czml)); + } + + // for (p = 0; p < czmlArray.length; p++) { + // let temp = czmlArray[p]; + // viewer.dataSources.add(Cesium.CzmlDataSource.load(temp)); + // } + + }); + + + + // This adds a large arrow to the viewer. Works fine. for testing + + // var purpleArrow = viewer.entities.add({ + // name: "Purple straight arrow at height", + // polyline: { + // positions: Cesium.Cartesian3.fromDegreesArrayHeights([ + // 9.187290, 48.784567, 400, + // 9.195991, 48.790575, 400 + // ]), + // width: 50, + // arcType: Cesium.ArcType.NONE, + // material: new Cesium.PolylineArrowMaterialProperty( + // Cesium.Color.PURPLE + // ), + // }, + // }); + + // var f = new File([""], "results/singlePolyline.csv", {type: "text/plain", lastModified: Date()}) + + // var temp = text.split(','); + // for(var i = 0; i < temp.length; i+=6) { + // pos.push([parseFloat(temp[i+1]), parseFloat(temp[i+2]), parseFloat(temp[i+3])]); + // colors.push([parseInt(temp[i+4]),parseInt(temp[i+5]),parseInt(temp[i+6])]) + // } + + console.log("Position data imported."); + + //// the following codes will actually generate multicolor polylines + /// just need a away to get the actual data into there... + /// + /// + // for (var line=0; line < 10; line++){ + // // Example 2: Draw a polyline with per vertex colors + // positions = []; + // colors = []; + // for (i = 0; i < 12; ++i) { + // positions.push(Cesium.Cartesian3.fromDegrees(-124.0 + line*5 + 5 * i, 35.0+line)); + // colors.push(Cesium.Color.fromRandom({ alpha: 1.0 })); + // } + // // For per segment coloring, supply the colors option with + // // an array of colors for each vertex. Also set the + // // colorsPerVertex option to true. + // scene.primitives.add( + // new Cesium.Primitive({ + // geometryInstances: new Cesium.GeometryInstance({ + // geometry: new Cesium.PolylineGeometry({ + // positions: positions, + // width: 5.0, + // vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT, + // colors: colors, + // colorsPerVertex: true, + // }), + // }), + // appearance: new Cesium.PolylineColorAppearance(), + // }) + // ); + // } + + // HTML overlay for showing feature name on mouseover + var nameOverlay = document.createElement("div"); + viewer.container.appendChild(nameOverlay); + nameOverlay.className = "backdrop"; + nameOverlay.style.display = "none"; + nameOverlay.style.position = "absolute"; + nameOverlay.style.bottom = "0"; + nameOverlay.style.left = "0"; + nameOverlay.style["pointer-events"] = "none"; + nameOverlay.style.padding = "4px"; + nameOverlay.style.backgroundColor = "green"; + + var scene = viewer.scene; + var longitude; + var latitude; + var fid; + var featuretype; + var gmlid; + var selID = new Array(); + var cnt = 0; + var lastPickedObject; + + var viewModel = { + rightClickAction: "properties", + middleClickAction: "hide", + }; + + Cesium.knockout.track(viewModel); + + var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + + handler.setInputAction(function (movement) { + // makes camera go to a certain position given by the coordinates below + + var feature = viewer.scene.pick(movement.position); + if (!Cesium.defined(feature)) { + console.log("no feature defined"); + return; + } + var propertyNames = feature.getPropertyNames(); + var lat = feature.getProperty("Latitude"); + var lon = feature.getProperty("Longitude"); + var tmp = feature.getProperty("YearOfConstruction"); + + viewer.camera.flyTo({ + destination: Cesium.Cartesian3.fromDegrees(lon, lat, 900), + maximumHeight: 1500.0, + orientation: { + heading: Cesium.Math.toRadians(0.0), + pitch: Cesium.Math.toRadians(-90.0), + roll: Cesium.Math.toRadians(45.0), + }, + duration: 2, + }); + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); + + handler.setInputAction(function (movement) { + var feature = viewer.scene.pick(movement.position); + if (!Cesium.defined(feature)) { + return; + } + var action = viewModel.rightClickAction; + action === "properties"; + printProperties(movement, feature); + }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); + + function printProperties(movement, feature) { + console.log("Properties:"); + var propertyNames = feature.getPropertyNames(); + var length = propertyNames.length; + for (var i = 0; i < length; ++i) { + var propertyName = propertyNames[i]; + if ( + propertyName == "gmlIdALKISLageBezeichnung_1" || + propertyName == "gmlIdALKISLageBezeichnung_2" || + propertyName == "gmlIdALKISLageBezeichnung_3" || + propertyName == "gmlIdALKISLageBezeichnung_4" || + propertyName == "gmlIdALKISLageBezeichnung_5" || + propertyName == "gmlIdALKISLageBezeichnung_6" + ) + console.log(" " + propertyName + ": " + "zensiert"); + else + console.log( + " " + propertyName + ": " + feature.getProperty(propertyName) + ); + } + + // Evaluate feature description + //console.log('Description : ' + tileset.style.meta.description.evaluate(scene.frameState, feature)); + } + + handler.setInputAction(function (movement) { + var feature = viewer.scene.pick(movement.position); + if (!Cesium.defined(feature)) { + return; + } + + var action = viewModel.middleClickAction; + if (action === "hide") { + feature.show = false; + } else { + feature.show = true; + } + }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); + + function showLegend() { + $("#legend").css("display", "block"); + } + function hideLegend() { + $("#legend").css("display", "none"); + } + + // Legend - Colour Table + function emptyColourTable() { + $(".inner").empty(); + } + + function setHeightTable() { + $(".inner").append( + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "
     > 3.5
3
2.5
2
1.5
1
0.5
" + ); + } + + return Cesium.when(tileset.readyPromise).then(function (tileset) { + tileset.style = new Cesium.Cesium3DTileStyle({ + color: "color('white',1)", + }); + showLegend(); + setHeightTable(); + }); + }); + \ No newline at end of file diff --git a/public/polylines_with_particles_backup_2.js b/public/polylines_with_particles_backup_2.js new file mode 100644 index 0000000000000000000000000000000000000000..be11df7bef90d317ab457f7ad23389949c73328a --- /dev/null +++ b/public/polylines_with_particles_backup_2.js @@ -0,0 +1,569 @@ +$(function () { + Cesium.Ion.defaultAccessToken = + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5ODI4ZTYyZS1mMTg2LTQ5NGEtYjdiOS02ODg2NzVhNjc0MTAiLCJpZCI6MjkwNCwiaWF0IjoxNTM1MTA5OTAzfQ.kyDX_0ScvJBkYnvXI0DW5NfZbiaRL5ezwtAUhxYnk1Y"; + var imageryViewModels = []; + imageryViewModels.push( + new Cesium.ProviderViewModel({ + name: "Sentinel-2", + iconUrl: Cesium.buildModuleUrl( + "Widgets/Images/ImageryProviders/sentinel-2.png" + ), + tooltip: "Sentinel-2 cloudless.", + creationFunction: function () { + return new Cesium.IonImageryProvider({ assetId: 3954 }); + }, + }) + ); + + imageryViewModels.push( + new Cesium.ProviderViewModel({ + name: "Blue Marble", + iconUrl: Cesium.buildModuleUrl( + "Widgets/Images/ImageryProviders/blueMarble.png" + ), + tooltip: "Blue Marble Next Generation July, 2004 imagery from NASA.", + creationFunction: function () { + return new Cesium.IonImageryProvider({ assetId: 3845 }); + }, + }) + ); + + var viewer = new Cesium.Viewer("cesiumContainer", { + imageryProvider: new Cesium.IonImageryProvider({ assetId: 3954 }), + + terrainProvider: new Cesium.CesiumTerrainProvider({ + url: Cesium.IonResource.fromAssetId(1), + }), + scene3DOnly: false, + shouldAnimate: true, + animation: true, + infoBox: true, + baseLayerPicker: true, + fullscreenButton: false, + timeline: false, + navigationHelpButton: true, + navigationInstructionsInitiallyVisible: false, + homeButton: false, + selectionIndicator: true, + geocoder: true, + // imageryProviderViewModels: imageryViewModels + }); + + // var layer = viewer.imageryLayers.addImageryProvider( + // new Cesium.IonImageryProvider({ assetId: 3 }) + // ); + + var imageryLayer = viewer.imageryLayers.addImageryProvider( + new Cesium.IonImageryProvider({ assetId: 3954 }) + ); + + var canvas = viewer.canvas; + canvas.setAttribute("tabindex", "0"); // needed to put focus on the canvas + canvas.addEventListener("click", function () { + canvas.focus(); + }); + canvas.focus(); + var scene = viewer.scene; + + var tileset = viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: "buildingTiles/StoeckachLOD1/tileset.json", + show: true, + }) + ); + + tileset.readyPromise.then(function (tileset) { + return zoomAll(tileset); + }); + + tileset.readyPromise.then(function (tileset) { + var R = 0; // roll + var P = 0; // pitch + var Yaw = 0; // yaw + var height = 53; + var cartographic = Cesium.Cartographic.fromCartesian( + tileset.boundingSphere.center + ); + var surface = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + 0.0 + ); + var offset = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + height + ); + var translation = Cesium.Cartesian3.subtract( + offset, + surface, + new Cesium.Cartesian3() + ); + + //var rotMat = new Cesium.Matrix3(); + var rotation = new Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(Yaw, P, R) + ); + + tileset.modelMatrix = Cesium.Matrix4.fromRotationTranslation( + rotation, + translation + ); + + return zoomAll(tileset); + }); + + viewer.scene.globe.enableLighting = true; // set lighting to true + + var zoomAll = function (tileset) { + return new Promise(function (resolve, reject) { + if (!tileset) { + reject("Tileset is undifined"); + } + viewer.camera.viewBoundingSphere( + tileset.boundingSphere, + new Cesium.HeadingPitchRange(0, -0.5, 1500) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + resolve(); + }); + }; + + ////////////////////////////////////////// + // load streamline data from text file and parse it to polyline with multiple colors. + + var pos = []; + var cols = []; + var streamID = []; + var Velocity = []; + var pt_to_pt_dist = []; + var avgVelocity = []; + var czmlArray = []; + + function get_date_time_dt(deltaTime) { + // deltaTime should be given in SECONDS and is then converted to milliseconds + // set deltaTime to 0 if you want to get current date and time + // set to +60000 to get date and time of 60 seconds = 60000 milliseconds in the future + + return (currentdate = new Date( + new Date().getTime() + deltaTime * 1000 + ).toISOString()); + } + + d3.dsv(",", "results/polylines_with_velocity.csv").then(function (text) { + const particleDuration = 90; // units in seconds the particle / point should take to move from start to finish + //define the czml structure + var particle_czml = [ + { + id: "document", + name: "CZML Point - Time Dynamic", + version: "1.0", + }, + { + id: "point", + availability: + get_date_time_dt(0) + "/" + get_date_time_dt(particleDuration), + position: { + epoch: get_date_time_dt(0), + cartographicDegrees: [ + // use 4 coordinates / values : (t,x,y,z) or rather (t,lon,lat,alt) + ], + }, + point: { + color: { + rgba: [0, 0, 0, 250], + }, + outlineColor: { + rgba: [255, 0, 0, 128], + }, + outlineWidth: 1, + pixelSize: 6, + }, + }, + ]; + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + let package_time_faktor = 8.0; + + var particle_czml_2_ = [ + { + id: "document", + name: "CZML Point - Time Dynamic", + version: "1.0", + }, + { + id: "point_set2_", + availability: + get_date_time_dt(0) + "/" + get_date_time_dt( particleDuration), + position: { + epoch: get_date_time_dt(0), + cartographicDegrees: [ + // use 4 coordinates / values : (t,x,y,z) or rather (t,lon,lat,alt) + ], + }, + point: { + color: { + rgba: [0, 0, 0, 250], + }, + outlineColor: { + rgba: [255, 0, 0, 128], + }, + outlineWidth: 1, + pixelSize: 6, + }, + }, + ]; + + var temp = text; + for (var i = 0; i < temp.length; i++) { + // use i+=7 when parsed as d3.text(...) + pos.push([ + parseFloat(text[i].Lon), + parseFloat(text[i].Lat), + parseFloat(text[i].z), + ]); + cols.push([ + parseInt(text[i].R), + parseInt(text[i].G), + parseInt(text[i].B), + ]); + streamID.push(parseInt(text[i].ID)); + Velocity.push(parseFloat(text[i].velocity)); + avgVelocity.push(parseFloat(text[i].AverageVelocity)); + pt_to_pt_dist.push(parseFloat(text[i].pt_to_pt_dist)); + // use these lines if parsed as text. i.e. using d3.text(...) + //pos.push([parseFloat(temp[i+0]), parseFloat(temp[i+1]), parseFloat(temp[i+2])]); + //colors.push([parseFloat(temp[i+3]),parseFloat(temp[i+4]),parseFloat(temp[i+5])]) + //streamID.push([parseFloat(temp[i+6])]); + } + + const maxID = streamID.reduce(function (a, b) { + return Math.max(a, b); + }); + + //find out the unique ids within the streamID array + const uniqueStreamID = Array.from(new Set(streamID)); // const uniqueStreamID = [...new Set(streamID)]; // same can be done with spread operator + + //get index of each unique id, first element of those + let sIDidx = []; + for (var i = 0; i <= maxID; i++) { + var tmpIdx = streamID.indexOf(i); + if (tmpIdx !== -1) sIDidx.push(tmpIdx); + } + + ///////////////////////////////////////////////// + // Create and draw a polyline with per vertex colors + ///////////////////////////////////////////////// + const heightOffset = 120; + for (var line = 0; line < uniqueStreamID.length; line++) { + let positions = []; + let positionsInDegrees = []; + let colors = []; + let individual_particle_velo = []; + let individual_particle_pt_distance = []; + let individual_particle_avg_velo = []; + + for (i = sIDidx[line - 1]; i < sIDidx[line] - 1; ++i) { + positions.push( + Cesium.Cartesian3.fromDegrees( + pos[i][0], + pos[i][1], + pos[i][2] + heightOffset + ) + ); + positionsInDegrees.push([ + pos[i][0], + pos[i][1], + pos[i][2] + heightOffset, + ]); + colors.push( + Cesium.Color.fromBytes(cols[i][0], cols[i][1], cols[i][2], 180) + ); + individual_particle_avg_velo.push(avgVelocity[i]); + individual_particle_pt_distance.push(pt_to_pt_dist[i]); + individual_particle_velo.push(Velocity[i]); + } + // For per segment coloring, supply the colors option with + // an array of colors for each vertex. Also set the + // colorsPerVertex option to true. + viewer.scene.primitives.add( + new Cesium.Primitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.PolylineGeometry({ + positions: positions, + width: 5.0, + vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT, + colors: colors, + colorsPerVertex: true, + }), + }), + appearance: new Cesium.PolylineColorAppearance(), + }) + ); + + //////////////////////////////////////////////// + // Create and prepare particles for movement + ///////////////////////////////////////////////// + let streamDist = individual_particle_pt_distance.reduce(function (a, b) { + return a + b; + }, 0); + // console.log(streamDist); + + let t = 0; + let dt = (individual_particle_pt_distance[0] / individual_particle_avg_velo[0])/ 20; + // let dt = streamDist / individual_particle_avg_velo[0] / 500; + let temp_pos = []; + let temp_pos_2_ = []; + + for (i = 0; i < positionsInDegrees.length; i++) { + if (i === 0) { + temp_pos.push( + 0, + positionsInDegrees[i][0], + positionsInDegrees[i][1], + positionsInDegrees[i][2] + ); + temp_pos_2_.push( + particleDuration/ package_time_faktor, + positionsInDegrees[i][0], + positionsInDegrees[i][1], + positionsInDegrees[i][2] + ); + } else { + temp_pos.push( + t, + positionsInDegrees[i][0], + positionsInDegrees[i][1], + positionsInDegrees[i][2] + ); + temp_pos_2_.push( + particleDuration / package_time_faktor + t, + positionsInDegrees[i][0], + positionsInDegrees[i][1], + positionsInDegrees[i][2] + ); + dt = individual_particle_pt_distance[i] /individual_particle_avg_velo[i] / 20; + // console.log(individual_particle_pt_distance[i] + "/" + individual_particle_avg_velo[i] ); + // console.log(dt); + } + + t += dt; + } + particle_czml[1].id = "point" + String(line); + particle_czml[1].position.cartographicDegrees = temp_pos; + + particle_czml_2_[1].position.cartographicDegrees = temp_pos_2_; + particle_czml_2_[1].id = "point_set2_" + String(line); + + // czmlArray.push(particle_czml); + viewer.dataSources.add(Cesium.CzmlDataSource.load(particle_czml)); + viewer.dataSources.add(Cesium.CzmlDataSource.load(particle_czml_2_)); + } + + // for (p = 0; p < czmlArray.length; p++) { + // let temp = czmlArray[p]; + // viewer.dataSources.add(Cesium.CzmlDataSource.load(temp)); + // } + + }); + + + + // This adds a large arrow to the viewer. Works fine. for testing + + // var purpleArrow = viewer.entities.add({ + // name: "Purple straight arrow at height", + // polyline: { + // positions: Cesium.Cartesian3.fromDegreesArrayHeights([ + // 9.187290, 48.784567, 400, + // 9.195991, 48.790575, 400 + // ]), + // width: 50, + // arcType: Cesium.ArcType.NONE, + // material: new Cesium.PolylineArrowMaterialProperty( + // Cesium.Color.PURPLE + // ), + // }, + // }); + + // var f = new File([""], "results/singlePolyline.csv", {type: "text/plain", lastModified: Date()}) + + // var temp = text.split(','); + // for(var i = 0; i < temp.length; i+=6) { + // pos.push([parseFloat(temp[i+1]), parseFloat(temp[i+2]), parseFloat(temp[i+3])]); + // colors.push([parseInt(temp[i+4]),parseInt(temp[i+5]),parseInt(temp[i+6])]) + // } + + console.log("Position data imported."); + + //// the following codes will actually generate multicolor polylines + /// just need a away to get the actual data into there... + /// + /// + // for (var line=0; line < 10; line++){ + // // Example 2: Draw a polyline with per vertex colors + // positions = []; + // colors = []; + // for (i = 0; i < 12; ++i) { + // positions.push(Cesium.Cartesian3.fromDegrees(-124.0 + line*5 + 5 * i, 35.0+line)); + // colors.push(Cesium.Color.fromRandom({ alpha: 1.0 })); + // } + // // For per segment coloring, supply the colors option with + // // an array of colors for each vertex. Also set the + // // colorsPerVertex option to true. + // scene.primitives.add( + // new Cesium.Primitive({ + // geometryInstances: new Cesium.GeometryInstance({ + // geometry: new Cesium.PolylineGeometry({ + // positions: positions, + // width: 5.0, + // vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT, + // colors: colors, + // colorsPerVertex: true, + // }), + // }), + // appearance: new Cesium.PolylineColorAppearance(), + // }) + // ); + // } + + // HTML overlay for showing feature name on mouseover + var nameOverlay = document.createElement("div"); + viewer.container.appendChild(nameOverlay); + nameOverlay.className = "backdrop"; + nameOverlay.style.display = "none"; + nameOverlay.style.position = "absolute"; + nameOverlay.style.bottom = "0"; + nameOverlay.style.left = "0"; + nameOverlay.style["pointer-events"] = "none"; + nameOverlay.style.padding = "4px"; + nameOverlay.style.backgroundColor = "green"; + + var scene = viewer.scene; + var longitude; + var latitude; + var fid; + var featuretype; + var gmlid; + var selID = new Array(); + var cnt = 0; + var lastPickedObject; + + var viewModel = { + rightClickAction: "properties", + middleClickAction: "hide", + }; + + Cesium.knockout.track(viewModel); + + var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + + handler.setInputAction(function (movement) { + // makes camera go to a certain position given by the coordinates below + + var feature = viewer.scene.pick(movement.position); + if (!Cesium.defined(feature)) { + console.log("no feature defined"); + return; + } + var propertyNames = feature.getPropertyNames(); + var lat = feature.getProperty("Latitude"); + var lon = feature.getProperty("Longitude"); + var tmp = feature.getProperty("YearOfConstruction"); + + viewer.camera.flyTo({ + destination: Cesium.Cartesian3.fromDegrees(lon, lat, 900), + maximumHeight: 1500.0, + orientation: { + heading: Cesium.Math.toRadians(0.0), + pitch: Cesium.Math.toRadians(-90.0), + roll: Cesium.Math.toRadians(45.0), + }, + duration: 2, + }); + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); + + handler.setInputAction(function (movement) { + var feature = viewer.scene.pick(movement.position); + if (!Cesium.defined(feature)) { + return; + } + var action = viewModel.rightClickAction; + action === "properties"; + printProperties(movement, feature); + }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); + + function printProperties(movement, feature) { + console.log("Properties:"); + var propertyNames = feature.getPropertyNames(); + var length = propertyNames.length; + for (var i = 0; i < length; ++i) { + var propertyName = propertyNames[i]; + if ( + propertyName == "gmlIdALKISLageBezeichnung_1" || + propertyName == "gmlIdALKISLageBezeichnung_2" || + propertyName == "gmlIdALKISLageBezeichnung_3" || + propertyName == "gmlIdALKISLageBezeichnung_4" || + propertyName == "gmlIdALKISLageBezeichnung_5" || + propertyName == "gmlIdALKISLageBezeichnung_6" + ) + console.log(" " + propertyName + ": " + "zensiert"); + else + console.log( + " " + propertyName + ": " + feature.getProperty(propertyName) + ); + } + + // Evaluate feature description + //console.log('Description : ' + tileset.style.meta.description.evaluate(scene.frameState, feature)); + } + + handler.setInputAction(function (movement) { + var feature = viewer.scene.pick(movement.position); + if (!Cesium.defined(feature)) { + return; + } + + var action = viewModel.middleClickAction; + if (action === "hide") { + feature.show = false; + } else { + feature.show = true; + } + }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); + + function showLegend() { + $("#legend").css("display", "block"); + } + function hideLegend() { + $("#legend").css("display", "none"); + } + + // Legend - Colour Table + function emptyColourTable() { + $(".inner").empty(); + } + + function setHeightTable() { + $(".inner").append( + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "
     > 3.5
3
2.5
2
1.5
1
0.5
" + ); + } + + return Cesium.when(tileset.readyPromise).then(function (tileset) { + tileset.style = new Cesium.Cesium3DTileStyle({ + color: "color('white',1)", + }); + showLegend(); + setHeightTable(); + }); + }); + \ No newline at end of file