Display KML from a URL, portal item, or local KML file.

Use case
Keyhole Markup Language (KML) is a data format used by Google Earth. KML is popular as a transmission format for consumer use and for sharing geographic data between apps. You can use the ArcGIS Maps SDK for Native Apps to display KML files, with full support for a variety of features, including network links, 3D models, screen overlays, and tours.
How to use the sample
Use the drop-down menu to select a source. A KML file from that source will be loaded and displayed in the map.
How it works
- To create a KML layer from a URL, create a
KmlDatasetusing the URL to the KML file. Then pass the dataset to theKmlLayerconstructor. - To create a KML layer from a portal item, construct a
PortalItemwith aPortaland the KML portal item ID. Pass the portal item to theKmlLayerconstructor. - To create a KML layer from a local file, create a
KmlDatasetusing the absolute file path to the local KML file. Then pass the dataset to theKmlLayerconstructor. - Add the layer as an operational layer to the map with
map::operationalLayers()::append(kmlLayer).
Relevant API
- KmlDataset
- KmlLayer
Offline data
To set up the sample’s offline data, see the Use offline data in the samples section of the Qt Samples repository overview.
| Link | Local Location |
|---|---|
| US State Capitals | <userhome>/ArcGIS/Runtime/Data/kml/US_State_Capitals.kml |
About the data
This sample displays three different KML files:
- From URL - this is a map of the significant weather outlook produced by NOAA/NWS. It uses KML network links to always show the latest data.
- From local file - this is a map of U.S. state capitals. It doesn’t define an icon, so the default pushpin is used for the points.
- From portal item - this is a map of U.S. states.
Tags
keyhole, KML, KMZ, OGC
Sample Code
// [WriteFile Name=DisplayKml, Category=Layers]// [Legal]// Copyright 2018 Esri.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// [Legal]
#ifdef PCH_BUILD#include "pch.hpp"#endif // PCH_BUILD
// sample headers#include "DisplayKml.h"
// ArcGIS Maps SDK headers#include "ArcGISTiledElevationSource.h"#include "Camera.h"#include "ElevationSourceListModel.h"#include "KmlDataset.h"#include "KmlLayer.h"#include "LayerListModel.h"#include "MapTypes.h"#include "Point.h"#include "PortalItem.h"#include "Scene.h"#include "SceneQuickView.h"#include "SpatialReference.h"#include "Surface.h"#include "Viewpoint.h"
// Qt headers#include <QFuture>#include <QStandardPaths>#include <QtCore/qglobal.h>
using namespace Esri::ArcGISRuntime;
// helper method to get cross platform data pathnamespace{ QString defaultDataPath() { QString dataPath;
#ifdef Q_OS_IOS dataPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); #else dataPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); #endif
return dataPath; }} // namespace
DisplayKml::DisplayKml(QQuickItem* parent /* = nullptr */): QQuickItem(parent){}
DisplayKml::~DisplayKml() = default;
void DisplayKml::init(){ // Register classes for QML qmlRegisterType<SceneQuickView>("Esri.Samples", 1, 0, "SceneView"); qmlRegisterType<DisplayKml>("Esri.Samples", 1, 0, "DisplayKmlSample");}
void DisplayKml::componentComplete(){ QQuickItem::componentComplete();
// Create a scene and give it to the SceneView m_sceneView = findChild<SceneQuickView*>("sceneView"); m_scene = new Scene(BasemapStyle::ArcGISImagery, this); Surface* surface = new Surface(this); surface->elevationSources()->append( new ArcGISTiledElevationSource( QUrl("https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer"), this)); m_scene->setBaseSurface(surface); m_sceneView->setArcGISScene(m_scene);
// Create a viewpoint const Point pt(-98, 39, SpatialReference::wgs84()); constexpr int scale = 10000000; const Camera camera(pt, scale, 0, 0, 0); m_viewpoint = Viewpoint(pt, scale, camera);}
void DisplayKml::createFromUrl(){ clearLayers();
// Create the Dataset from an Online URL m_kmlDataset = new KmlDataset(QUrl("https://www.wpc.ncep.noaa.gov/kml/noaa_chart/WPC_Day1_SigWx.kml"), this);
// Create the Layer m_kmlLayer = new KmlLayer(m_kmlDataset, this);
// Add the layer to the scene addLayerToScene(m_kmlLayer);}
void DisplayKml::createFromFile(){ clearLayers();
// Create the Dataset from a local file const QString dataPath = defaultDataPath() + "/ArcGIS/Runtime/Data/kml/"; m_kmlDataset = new KmlDataset(QUrl(dataPath + "US_State_Capitals.kml"), this);
// Create the Layer m_kmlLayer = new KmlLayer(m_kmlDataset, this);
// Add the layer to the scene addLayerToScene(m_kmlLayer);}
void DisplayKml::createFromPortalItem(){ clearLayers();
// Create the PortalItem m_portalItem = new PortalItem(QStringLiteral("9fe0b1bfdcd64c83bd77ea0452c76253"), this);
// Create the Layer m_kmlLayer = new KmlLayer(m_portalItem, this);
// Add the layer to the scene addLayerToScene(m_kmlLayer);}
void DisplayKml::addLayerToScene(KmlLayer* layer){ if (!m_scene) return;
m_scene->operationalLayers()->append(layer);
if (m_viewpoint.isEmpty()) return;
m_sceneView->setViewpointAsync(m_viewpoint);}
void DisplayKml::clearLayers(){ if (!m_scene) return;
// remove the layers m_scene->operationalLayers()->clear();
// clean up the kml datasets if (m_kmlDataset) { delete m_kmlDataset; m_kmlDataset = nullptr; }
// clean up the portal items if (m_portalItem) { delete m_portalItem; m_portalItem = nullptr; }
// clean up the kml layers if (m_kmlLayer) { delete m_kmlLayer; m_kmlLayer = nullptr; }}// [WriteFile Name=DisplayKml, Category=Layers]// [Legal]// Copyright 2018 Esri.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// [Legal]
#ifndef DISPLAYKML_H#define DISPLAYKML_H
// ArcGIS Maps SDK headers#include "Viewpoint.h"
// Qt headers#include <QQuickItem>
namespace Esri::ArcGISRuntime{class SceneQuickView;class Scene;class KmlLayer;class KmlDataset;class PortalItem;}
class DisplayKml : public QQuickItem{ Q_OBJECT
public: explicit DisplayKml(QQuickItem* parent = nullptr); ~DisplayKml() override;
void componentComplete() override; static void init();
Q_INVOKABLE void createFromUrl(); Q_INVOKABLE void createFromFile(); Q_INVOKABLE void createFromPortalItem();
private: Esri::ArcGISRuntime::SceneQuickView* m_sceneView = nullptr; Esri::ArcGISRuntime::Scene* m_scene = nullptr; Esri::ArcGISRuntime::Viewpoint m_viewpoint; Esri::ArcGISRuntime::KmlDataset* m_kmlDataset = nullptr; Esri::ArcGISRuntime::KmlLayer* m_kmlLayer = nullptr; Esri::ArcGISRuntime::PortalItem* m_portalItem = nullptr;
void addLayerToScene(Esri::ArcGISRuntime::KmlLayer* layer); void clearLayers();};
#endif // DISPLAYKML_H// [WriteFile Name=DisplayKml, Category=Layers]// [Legal]// Copyright 2018 Esri.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// [Legal]
import QtQuickimport QtQuick.Controlsimport Esri.Samples
DisplayKmlSample { id: rootRectangle clip: true width: 800 height: 600
SceneView { objectName: "sceneView" anchors.fill: parent
Component.onCompleted: { // Set the focus on SceneView to initially enable keyboard navigation forceActiveFocus(); } }
ComboBox { id: comboBox anchors { right: parent.right top: parent.top margins: 5 }
// Add a background to the ComboBox Rectangle { anchors.fill: parent radius: 10 // Make the rectangle visible if a dropdown indicator exists // An indicator only exists if a theme is set visible: parent.indicator border.width: 1 }
property int modelWidth: 0 width: modelWidth + leftPadding + rightPadding + (indicator ? indicator.width : 10)
model: ["URL", "Local file", "Portal Item"]
onCurrentIndexChanged: { // create the Layer if (currentIndex === 0) createFromUrl(); else if (currentIndex === 1) createFromFile(); else createFromPortalItem(); }
Component.onCompleted : { for (let i = 0; i < model.length; ++i) { metrics.text = model[i]; modelWidth = Math.max(modelWidth, metrics.width); } currentIndexChanged(); }
TextMetrics { id: metrics font: comboBox.font } }}// [Legal]// Copyright 2018 Esri.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// [Legal]
// sample headers#include "DisplayKml.h"
// ArcGIS Maps SDK headers#include "ArcGISRuntimeEnvironment.h"
// Qt headers#include <QCommandLineParser>#include <QDir>#include <QGuiApplication>#include <QQmlEngine>#include <QQuickView>#include <QSurfaceFormat>
// Platform specific headers#ifdef Q_OS_WIN#include <Windows.h>#endif
#define STRINGIZE(x) #x#define QUOTE(x) STRINGIZE(x)
int main(int argc, char *argv[]){ Esri::ArcGISRuntime::ArcGISRuntimeEnvironment::setUseLegacyAuthentication(false);#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) // Linux requires 3.2 OpenGL Context // in order to instance 3D symbols QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); fmt.setVersion(3, 2); QSurfaceFormat::setDefaultFormat(fmt);#endif
QGuiApplication app(argc, argv); app.setApplicationName(QString("DisplayKml"));
// Use of ArcGIS location services, such as basemap styles, geocoding, and routing services, // requires an access token. For more information see // https://links.esri.com/arcgis-runtime-security-auth.
// The following methods grant an access token:
// 1. User authentication: Grants a temporary access token associated with a user's ArcGIS account. // To generate a token, a user logs in to the app with an ArcGIS account that is part of an // organization in ArcGIS Online or ArcGIS Enterprise.
// 2. API key authentication: Get a long-lived access token that gives your application access to // ArcGIS location services. Go to the tutorial at https://links.esri.com/create-an-api-key. // Copy the API Key access token.
const QString accessToken = QString("");
if (accessToken.isEmpty()) { qWarning() << "Use of ArcGIS location services, such as the basemap styles service, requires" << "you to authenticate with an ArcGIS account or set the API Key property."; } else { Esri::ArcGISRuntime::ArcGISRuntimeEnvironment::setApiKey(accessToken); }
// Initialize the sample DisplayKml::init();
// Initialize application view QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView);
QString arcGISRuntimeImportPath = QUOTE(ARCGIS_RUNTIME_IMPORT_PATH);
#if defined(LINUX_PLATFORM_REPLACEMENT) // on some linux platforms the string 'linux' is replaced with 1 // fix the replacement paths which were created QString replaceString = QUOTE(LINUX_PLATFORM_REPLACEMENT); arcGISRuntimeImportPath = arcGISRuntimeImportPath.replace(replaceString, "linux", Qt::CaseSensitive);#endif
// Add the import Path view.engine()->addImportPath(QDir(QCoreApplication::applicationDirPath()).filePath("qml")); // Add the Runtime and Extras path view.engine()->addImportPath(arcGISRuntimeImportPath);
// Set the source view.setSource(QUrl("qrc:/Samples/Layers/DisplayKml/DisplayKml.qml"));
view.show();
return app.exec();}