You can create custom TerraExplorer Fusion (TEF) applications by using iframes to embed the TerraExplorer Fusion window in your custom HTML. The TerraExplorer and Fusion APIs, can then be used together with any other script to customize your application. More about: Creating custom tools >
This can be implemented in any of the following scenarios:
- TerraExplorer Fusion is installed under the SkylineGlobe Server folder (single server environment)
- When the host HTML is hosted on a different server in the same network
- In an isolated environment where TerraExplorer Fusion is not part of a broader server installation
Open a TerraExplorer Fusion sample >
Embedding TerraExplorer Fusion in a Single Server Environment (TEF folder is located on the same server as the SGS installation)
Do the following:
- Set Up the iframe: In your HTML file, create the TEF iframe element and link it to the TE.html page. For an example of how TEF functions within an HTML page, execute the sample project by opening ./TEF/custom/sampleTEinIFrame.html in your browser. See below for more information on this file. This sample demonstrates the basic embedding process and interaction capabilities of TerraExplorer Fusion.
<iframe id='tef' src="./TEF/TE.html" class="tef"/>
Embedding TerraExplorer Fusion when the host HTML is Hosted on a Different Server in the Same Network
Do the following:
-
Web.config File:
- For TEF Versions 8.1 and Older: Add the web.config file to the host HTML server. This file is essential for managing cross-origin requests and configuring necessary IIS settings.
- For TEF Version 8.2: The web.config file is already included in the TEF folder, so no additional configuration is needed for this version.
-
For Non-IIS Environments: If you are using a web server other than IIS, you'll need to adapt the settings from the web.config file to your server's configuration file to handle cross-origin requests effectively. The following headers need to be added:
<add name="Cross-Origin-Embedder-Policy" value="require-corp"/>
<add name="Cross-Origin-Resource-Policy" value="cross-origin"/>
<add name="Cross-Origin-Opener-Policy" value="same-origin"/>
-
Set Up the iframe: In your host HTML file, use an iframe to embed TerraExplorer Fusion. Set the src attribute of the iframe to reference the TE.html page via a URL, e.g., https://site/tef/te.html. Include the allow='cross-origin-isolated' attribute in the iframe tag to manage cross-origin access.
<iframe allow='cross-origin-isolated' id='tef' src="https://jon.skyline.co.il/SG/TEF/te.html?roject=..."/>
Embedding TerraExplorer Fusion in an Isolated Environment (TEF folder is located on a different server from the SGS installation)
Do the following:
- TerraExplorer Fusion directory: Copy the .\TEF directory to your server. Place it adjacent to your web application.
-
Web.config File:
- For TEF Versions 8.1 and Older: The web.config file, which configures settings for handling cross-origin requests and other necessary IIS configurations, is not included in the TEF directory. You must add this file to your TEF folder using the attached web.config.
- For TEF Version 8.2: The web.config file is already included in the TEF folder, so no additional configuration is needed for this version.
-
For Non-IIS Environments: Since the provided web.config file is specific to IIS, if you are using a different web server, you will need to configure it to handle cross-origin requests appropriately. The settings in the web.config can serve as a guide for the configurations you might need to apply in your server's respective configuration file. The following headers need to be added:
<add name="Cross-Origin-Embedder-Policy" value="require-corp"/>
<add name="Cross-Origin-Resource-Policy" value="cross-origin"/>
<add name="Cross-Origin-Opener-Policy" value="same-origin"/>
-
Set Up the iframe: In your HTML file, create the TEF iframe element and link it to the TE.html page.
<iframe id='tef' src="./TEF/TE.html" class="tef"/>
To customize Your TerraExplorer Fusion Application (Applicable to All Environments):
- Add custom URL parameters to control different TerraExplorer Fusion characteristics such as the project to load, a custom styling file (css) to hide/restyle GUI elements, start location etc. More about: URL Parameters >
<iframe id='tef' src="./TEF/TE.html?project=https://cloud.skylineglobe.com/SG/demos/projects/TEF_Demo_Project&css=sampleCustomizedGUI" class="tef"/>
- Add the onTEFInit callback function that will be called when TEF initializes. In this callback you can get the TerraExplorer main API interface, SGWorld, and use it to add and control elements in the 3D view:
function onTEFInit(event) {
SGWorld = document.getElementById('tef').contentWindow.SGWorld;
} - Add the onTEFProjectLoaded callback function that will be called when the project is loaded:
function onTEFProjectLoaded(event) {
var position= SGWorld.Creator.CreatePosition (-97.0, 38.0, 100, 0 , -70,0,500);
SGWorld.Navigate.FlyTo (position);
}
sampleTEinIFrame.html
This file is included in the application files of TerraExplorer Fusion under custom (.\custom\sampleTEinIFrame.html). This demo initializes TerraExplorer Fusion and offers three options: Load with GUI, Load without GUI, and Load with Customized GUI.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="../js/jquery-3.6.0.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-aFq/bzH65dt+w6FI2ooMVUpc+21e0SRygnTpmBvdBgSdnuTN7QbdgL+OapgHtvPp" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-qKXV1j0HvMUeCBQ+QVp7JcfGl760yU08IQ+GpUo5hlbpg51QRiuqHAJz8+BrxE/N"
crossorigin="anonymous"></script>
<script language="javascript" src="../Tools/ToolsCommon80.js"></script>
<style>
body {
width: 100%;
height: 100%;
background-color: #DCDCDC;
}
.leftBar {
background-color: beige;
min-height: 80vh;
}
.tef {
width: 100%;
height: 80vh;
background-color: #eeeee4;
}
button {
width: 40%;
height: 60px;
}
div.lead {
margin-left: 10px;
}
.caption{
margin: 0px auto;
width: 35%;
text-align: center;
}
</style>
<script>
var SGWorld = null;
var TEF = null;
$(() => {
TEF = document.getElementById('tef');
});
function onTEFInit(event) {
SGWorld = TEF.contentWindow.SGWorld;
SGWorld.AttachEvent('OnRenderQualityChanged', OnRenderQualityChanged);
}
function onTEFProjectLoaded(event) {
$("#analysisButtons").show();
}
function loadTEF(GUI) {
var guiURL = (GUI) ? "" : "&script=sampleCustomButtons.js&css=sampleCustomButtons";
$("#tef").attr('src', "../te.html?project=https://cloud.skylineglobe.com/sg/demos/projects/TEF_Demo_Project" + guiURL);
}
function loadPartialTEF() {
var guiURL = "&css=sampleCustomizedGUI";
$("#tef").attr('src', "../te.html?project=https://cloud.skylineglobe.com/sg/demos/projects/TEF_Demo_Project" + guiURL);
}
function rotate() {
if (SGWorld === null)
alert("TEF not loaded");
else
SGWorld.Command.Execute(1057, 0);
}
function distance() {
if (SGWorld === null)
alert("TEF not loaded");
else
TEF.contentWindow.analysis.openAnalysisToolURL('./Tools/DistanceMeasurement/distanceMeasurement.html', 'distance', false);
}
function area() {
if (SGWorld === null)
alert("TEF not loaded");
else
TEF.contentWindow.analysis.openAnalysisToolURL('./Tools/AreaMeasurement/AreaMeasurement.html', 'area', false);
}
function volume() {
if (SGWorld === null)
alert("TEF not loaded");
else
TEF.contentWindow.analysis.openAnalysisToolURL('./Tools/Volume/Volume.html', 'volume', false);
}
function profile() {
if (SGWorld === null)
alert("TEF not loaded");
else
TEF.contentWindow.analysis.openAnalysisToolURL('./Tools/TerrainProfile/TerrainProfile.html', 'profile', false);
}
function viewshed() {
if (SGWorld === null)
alert("TEF not loaded");
else
TEF.contentWindow.analysis.openAnalysisToolURL('./Tools/ImageComparison/MeshComparisonPopup.html', 'compare', false);
}
function home() {
if (SGWorld === null)
alert("TEF not loaded");
else
TEF.contentWindow.navigate.home();
}
function OnRenderQualityChanged(quality) {
$("#buffer").text(quality)
return false;
}
function draw(type) {
var position = SGWorld.Window.PixelToWorld(SGWorld.Window.Rect.Width / 2, SGWorld.Window.Rect.Height / 2, 0).Position;
var radius = SGWorld.Navigate.GetPosition(0).DistanceTo(position) / 20;
var group = TEF.contentWindow.projectTree.getMyDataGroup();
switch (type) {
case 0:
SGWorld.Creator.CreateCircle(position, radius, SGWorld.Creator.CreateColor(0, 255, 0, 1), SGWorld.Creator.CreateColor(0, 0, 0, 0), group, "circle");
break;
case 1:
SGWorld.Creator.CreateArrow(position, radius, 4, SGWorld.Creator.CreateColor(0, 255, 0, 1), SGWorld.Creator.CreateColor(0, 0, 0, 0), group, "arrow");
break;
case 2:
SGWorld.Creator.CreateBox(position, radius, radius, radius, SGWorld.Creator.CreateColor(0, 255, 0, 1), SGWorld.Creator.CreateColor(120, 10, 200, 100), group, "box");
break;
default:
break;
}
TEF.contentWindow.projectTree.refreshMyData();
}
</script>
</head>
<body>
<div class="container">
<div class="row">
<div class="jumbotron p-0">
<h1 class="i18n display-4">Header</h1>
<p class="i18n lead">SmallHeader</p>
<hr class="my-4">
<p class="i18n">AboutHeader</p>
</div>
</div>
<div class="row">
<div class="col-3 leftBar">
<p class="caption"><strong><u class="i18n">CaptionGUI</u></strong></p>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="loadTEF(true);">ButtonLoadWithGUI</button>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="loadTEF(false)">ButtonLoadWithoutGUI</button>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="loadPartialTEF()">ButtonLoadPartialGUI</button> <br>
<hr>
<div id="analysisButtons" style="display:none">
<p class="caption"><strong><u class="i18n">CaptionTEFTools</u></strong></p>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="distance();">ButtonDistance</button>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="area();">ButtonArea</button>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="volume();">ButtonVolume</button>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="profile();">ButtonProfile</button>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="viewshed()">ButtonLayerComparison</button>
<hr>
<p class="caption"><strong><u class="i18n">CaptionActions</u></strong></p>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="rotate()">ButtonRotate</button>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="home()">ButtonHome</button>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="draw(0);">ButtonDrawCircle</button>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="draw(1);">ButtonDrawArrow</button>
<button class="i18n btn btn-secondary my-1 mx-md-1 mx-lg-2" onclick="draw(2);">ButtonDrawBox</button>
<hr>
<p class="caption"><strong><u class="i18n">CaptionEvents</u></strong></p>
<div class="lead pl-4">
Quality: <span id="buffer"></span>
</div>
</div>
</div>
<div class="col-8">
<iframe id='tef' src="" class="tef" />
</div>
</div>
</div>
</body>
</html>