Introduction
We'll walk through the process of integrating a CesiumJS sample into a WPF (Windows Presentation Foundation) application. CesiumJS is an open-source JavaScript library for creating 3D globes and maps. By embedding CesiumJS within a WPF application, you can leverage its powerful geospatial visualization capabilities alongside the rich UI features of WPF.
Prerequisites
- Basic understanding of WPF and C# programming.
- Visual Studio is installed on your machine.
- Basic knowledge of HTML, JavaScript, and CesiumJS.
Integrating CesiumJS into a web application
Integrating CesiumJS into a web application presents a significant challenge due to its sophisticated 3D rendering and geographic data visualization capabilities. This project offers a comprehensive solution to streamline your development process. If you encounter any reference-related issues during implementation, we recommend installing the 'CefSharp.Wpf' NuGet package to address them efficiently.
This example showcases the functionality for users to inject KML files into the Cesium map. Additionally, it demonstrates how users can define location points on the map, create lines between two specified location points, focus the camera on specific areas of the Cesium map, and manage the loading and removal of KML files from the map.
Project setup
- Create a new WPF project in Visual Studio.
- Install the CefSharp.Wpf NuGet package to enable embedding Chromium (CEF) browser in your WPF application. CefSharp is a .NET wrapper for the Chromium Embedded Framework.
- Ensure that your project targets the .NET Framework version compatible with CefSharp.

Embedding CesiumJS
- Download the CesiumJS library from the official website or include it from a CDN.
- Create an HTML file (`cesium.html`) and include the necessary CesiumJS scripts and stylesheets.
- Write the JavaScript code to initialize the Cesium viewer and display the desired map or globe.
Integrating HTML into WPF
Add a `WebView` control to your WPF window. This control will host the Chromium browser.
Load the `cesium.html` file into the `WebView` control using the `LoadHtml` or `Load` method.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- Include the CesiumJS JavaScript and CSS files -->
<script src="https://cesium.com/downloads/cesiumjs/releases/1.108/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.108/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<style>
/* Set the map container's dimensions */
#cesiumContainer {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="loader-overlay" id="loader" style="z-index:99999">
<div class="loader"></div>
</div>
<div id="cesiumContainer" class="fullSize"></div>
</body>
</html>
.loader {
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<script>
// Function to show the loader
function showLoader() {
var loader = document.getElementById("loader");
loader.style.display = "flex"; // Show the loader
}
// Function to hide the loader
function hideLoader() {
var loader = document.getElementById("loader");
loader.style.display = "none"; // Hide the loader
}
function GetPinString(selectId) {
var retString = "";
switch (selectId) {
case 1:
retString = "data:image/png;base64,iVBORw0K**CC";
break; //Blue Pin
case 2:
retString = "data:image/png;base64,iVBORw**K5CYII=";
break; //Pink Pin
case 3:
retString = "data:image/png;base64,iVBORw0KGgo**5CYII=";
break; //Red Pin
default:
}
return retString;
}
function SetPolygonColor(type) {
var polygonLineTypeColor = null;
switch (type) {
case 1:
polygonLineTypeColor = Cesium.Color.RED;
break;
case 2:
polygonLineTypeColor = Cesium.Color.BLUE;
break;
case 3:
polygonLineTypeColor = Cesium.Color.MAGENTA;
break;
default:
polygonLineTypeColor = Cesium.Color.ORANGE;
}
return polygonLineTypeColor;
}
</script>
<script src="Javascript/CesiumJsMapImplementation.js"></script>
<script>
var cesiumViewer = null;
const kmlString = '';
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI**CHqSUFaF8';
document.addEventListener("DOMContentLoaded", function () {
showLoader();
var viewer = new Cesium.Viewer('cesiumContainer'); // Default 3D mode
// Call the C# function to retrieve the KML string asynchronously
var animationContainer = document.querySelector('.cesium-viewer-animationContainer');
if (animationContainer) {
animationContainer.parentNode.removeChild(animationContainer);
}
var divToRemove = document.querySelector('.cesium-viewer-timelineContainer');
if (divToRemove) {
divToRemove.parentNode.removeChild(divToRemove);
}
var divToRemove = document.querySelector('.cesium-widget-credits');
if (divToRemove) {
divToRemove.parentNode.removeChild(divToRemove);
}
cesiumViewer = viewer;
var iframe = document.getElementsByClassName('cesium-infoBox-iframe')[0];
iframe.setAttribute('sandbox', 'allow-same-origin allow-scripts allow-popups allow-forms');
setTimeout(function () {
var loader = document.getElementById("loader");
loader.style.display = "none";
}, 10000);
});
//Remove entire datascources from cesiumJs map
function ReceiveKMLData(kmlString, kmlDocId) {
RunKmlData(kmlString, kmlDocId);
}
//Hide show full screen
function toggleFullscreenContainer() {
var element = document.querySelector('.cesium-viewer-fullscreenContainer');
if (element.style.display === 'none') {
element.style.display = 'block'; // Show the element
} else {
element.style.display = 'none'; // Hide the element
}
}
//Hide show top toolbar
function toggleCesiumTopToolBar() {
var element = document.querySelector('.cesium-viewer-toolbar');
if (element.style.display === 'none') {
element.style.display = 'block'; // Show the element
} else {
element.style.display = 'none'; // Hide the element
}
}
//Add placemark dynamically on cesiumjs map as a point
function AddDynamicLocationPoint(name, longitude, latitude) {
const citizensBankPark = cesiumViewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
point: {
pixelSize: 15,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
},
label: {
text: name,
font: "bold 12pt Time New Roman",
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
scale: 1.0,
outlineWidth: 2,
fillColor: Cesium.Color.BLUE, // Set the label fill color
outlineColor: Cesium.Color.WHITE,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, -15), // Adjust the offset to your preference
},
});
}
//Add placemark on a cesiumjs map as a Pin
function AddDynamicLocationBillBoard(name, longitude, latitude, pinType) {
let pintTypeImage = GetPinString(pinType);
const citizensBankPark = cesiumViewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
//billboard location as a pin
billboard: {
image: pintTypeImage,
width: 32,
height: 32,
},
label: {
text: name,
font: "bold 12pt Time New Roman",
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
scale: 1.0,
outlineWidth: 2,
fillColor: Cesium.Color.BLUE, // Set the label fill color
outlineColor: Cesium.Color.WHITE,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, -15), // Adjust the offset to your preference
},
});
}
/*Procedure for Managing Camera Control on a Map*/
function HandleCameraPositionInMap(longitude, latitude, height, heading, pitch, roll) {
cesiumViewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height), //Specify the longitude, latitude, and altitude of the camera.
orientation: { //Adjust the camera's orientation
heading: Cesium.Math.toRadians(heading),
pitch: Cesium.Math.toRadians(pitch),
roll: roll,
},
});
}
function AddLinesBetweenTwoLocation(longitude1, latitude1, longitude2, latitude2, polygonLineType) {
var startLocation = Cesium.Cartesian3.fromDegrees(longitude1, latitude1);
var endLocation = Cesium.Cartesian3.fromDegrees(longitude2, latitude2);
var polygonLineTypeColor = SetPolygonColor(polygonLineType);
cesiumViewer.entities.add({
polyline: {
positions: [startLocation, endLocation],
outlineWidth: 3,
outlineColor: Cesium.Color.BLACK,
glowPower: 0.2,
width: 5,
outline: true,
material: polygonLineTypeColor
},
});
}
/*Procedure to load KML file on a Map*/
function RunKmlData(kmlContent, kmlDocId) {
var options = {
camera: cesiumViewer.scene.camera,
canvas: cesiumViewer.scene.canvas,
clampToGround: true
};
var parser = new DOMParser();
var kmlDoc = parser.parseFromString(kmlContent, "text/xml");
var dataSource = new Cesium.KmlDataSource();
cesiumViewer.zoomTo(cesiumViewer.dataSources.add(dataSource.load(kmlDoc, options)))
dataSource.id = kmlDocId;
}
//Remove All datasource from cesiumJs map
function RemoveAllDatasource() {
cesiumViewer.dataSources.removeAll(); // This clears all loaded data sources, including KML
}
/*Unload specific KMl file from MAP*/
function UnloadKML(kmlDocsourceId) {
var kmlDataSource = cesiumViewer.dataSources;
cesiumViewer.dataSources._dataSources.forEach(function (dataSource) {
if (dataSource.id == kmlDocsourceId) {
cesiumViewer.dataSources.remove(dataSource);
}
});
}
</script>



Chris SammonsPosted Mar 18, 2025, 7:02 PM
Hope this message finds you well. I'm working on creating my own sample application that utilizes CesiumJS in a WPF application. Unfortunately, I'm unable to follow the source code link above. It says that it is not found. Do you happen to have this source that you can re-post an active link or zip and attach to this article? It would be greatly appreciated. Thanks!