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 Runtime 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
KmlDataset
using the URL to the KML file. Then pass the dataset to theKmlLayer
constructor. - To create a KML layer from a portal item, construct a
PortalItem
with aPortal
and the KML portal item ID. Pass the portal item to theKmlLayer
constructor. - To create a KML layer from a local file, create a
KmlDataset
using the absolute file path to the local KML file. Then pass the dataset to theKmlLayer
constructor. - 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
#include "DisplayKml.h"
#include "ArcGISTiledElevationSource.h"
#include "Scene.h"
#include "SceneQuickView.h"
#include "Viewpoint.h"
#include "Camera.h"
#include "SpatialReference.h"
#include "KmlLayer.h"
#include "KmlDataset.h"
#include "PortalItem.h"
#include <QDir>
#include <QtCore/qglobal.h>
#ifdef Q_OS_IOS
#include <QStandardPaths>
#endif // Q_OS_IOS
using namespace Esri::ArcGISRuntime;
// helper method to get cross platform data path
namespace
{
QString defaultDataPath()
{
QString dataPath;
#ifdef Q_OS_ANDROID
dataPath = "/sdcard";
#elif defined Q_OS_IOS
dataPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
#else
dataPath = QDir::homePath();
#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->setViewpoint(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;
}
}