Click or drag to resize

KmlTourController Class

A KML tour controller, which can be used to control the playback of KML tours.
Inheritance Hierarchy
SystemObject
  Esri.ArcGISRuntime.OgcKmlTourController

Namespace:  Esri.ArcGISRuntime.Ogc
Assembly:  Esri.ArcGISRuntime (in Esri.ArcGISRuntime.dll) Version: 100.7.0.0
Syntax
C#
public sealed class KmlTourController

The KmlTourController type exposes the following members.

Constructors
  NameDescription
Public methodCode exampleKmlTourController
Initializes a new instance of the KmlTourController class.
Public methodKmlTourController(Context)
Initializes a new instance of the KmlTourController class.
Top
Properties
  NameDescription
Public propertyCurrentPosition
Gets the current position of the associated tour.
Public propertyTotalDuration
Gets the total duration of the associated tour.
Public propertyCode exampleTour
Gets the associated KML tour.
Top
Methods
  NameDescription
Public methodCode examplePause
Pauses the associated tour.
Public methodCode examplePlay
Plays the associated tour, which may include audio content.
Public methodCode exampleReset
Resets the associated tour.
Top
Remarks
Use KML tour controller to play, pause or reset a KmlTour. It notifies the application to play sound cues or show/hide balloon popups as specified in a tour playlist. To monitor the status of the tour, see TourStatus of the Tour.
Examples

Android

Example Name: PlayKmlTours

Play tours in KML files.

Code example screen shot.

C#
// Copyright 2019 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.

using Android.App;
using Android.OS;
using Android.Views;
using Android.Widget;
using ArcGISRuntime.Samples.Managers;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Ogc;
using Esri.ArcGISRuntime.UI.Controls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Debug = System.Diagnostics.Debug;

namespace ArcGISRuntimeXamarin.Samples.PlayKmlTours
{
    [Activity (ConfigurationChanges=Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize)]
    [ArcGISRuntime.Samples.Shared.Attributes.Sample(
        "Play a KML tour",
        "Layers",
        "Play tours in KML files.",
        "")]
    [ArcGISRuntime.Samples.Shared.Attributes.OfflineData("f10b1d37fdd645c9bc9b189fb546307c")]
    public class PlayKmlTours : Activity
    {
        // Hold references to the UI controls.
        private SceneView _mySceneView;
        private Button _playButton;
        private Button _pauseButton;
        private Button _resetButton;

        // The KML tour controller provides player controls for KML tours.
        private readonly KmlTourController _tourController = new KmlTourController();

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            Title = "Play a KML tour";

            CreateLayout();
            Initialize();
        }

        private async void Initialize()
        {
            // Load the scene with a basemap and a terrain surface.
            _mySceneView.Scene = new Scene(Basemap.CreateImagery());
            _mySceneView.Scene.BaseSurface.ElevationSources.Add(new ArcGISTiledElevationSource(new Uri("https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer")));

            // Get the URL to the data.
            string filePath = DataManager.GetDataFolder("f10b1d37fdd645c9bc9b189fb546307c", "Esri_tour.kmz");
            Uri kmlUrl = new Uri(filePath);

            // Create the KML dataset and layer.
            KmlDataset dataset = new KmlDataset(kmlUrl);
            KmlLayer layer = new KmlLayer(dataset);

            // Add the layer to the map.
            _mySceneView.Scene.OperationalLayers.Add(layer);

            try
            {
                // Load the dataset.
                await dataset.LoadAsync();

                // Find the first KML tour.
                FindKmlTour(dataset.RootNodes);

                // Handle absence of tour gracefully.
                if (_tourController.Tour == null)
                {
                    throw new InvalidOperationException("No tour found. Can't enable touring for a KML file with no tours.");
                }

                // Listen for changes to the tour status.
                _tourController.Tour.PropertyChanged += Tour_PropertyChanged;

                // Enable the play button.
                _playButton.Enabled = true;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.ToString());
                new AlertDialog.Builder(this).SetMessage(e.ToString()).SetTitle("Error").Show();
            }
        }

        private void FindKmlTour(IEnumerable<KmlNode> rootNodes)
        {
            // Hold a list of nodes to explore.
            Queue<KmlNode> nodesToExplore = new Queue<KmlNode>();

            // Add each root node to the list.
            foreach (KmlNode rootNode in rootNodes)
            {
                nodesToExplore.Enqueue(rootNode);
            }

            // Keep exploring until a tour is found or there are no more nodes.
            while (nodesToExplore.Any())
            {
                // Remove a node from the queue.
                KmlNode currentNode = nodesToExplore.Dequeue();

                // If the node is a tour, use it.
                if (currentNode is KmlTour tourNode)
                {
                    _tourController.Tour = tourNode;
                    return;
                }

                // If the node is a container, add all of its children to the list of nodes to explore.
                if (currentNode is KmlContainer container)
                {
                    foreach (KmlNode node in container.ChildNodes)
                    {
                        nodesToExplore.Enqueue(node);
                    }
                }

                // Otherwise, continue.
            }
        }

        private void Tour_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            // Skip for everything except tour status property changes.
            if (e.PropertyName != nameof(KmlTour.TourStatus))
            {
                return;
            }

            // Set the UI based on the current state of the tour.
            switch (_tourController.Tour.TourStatus)
            {
                case KmlTourStatus.Completed:
                case KmlTourStatus.Initialized:
                    _playButton.Enabled = true;
                    _pauseButton.Enabled = false;
                    break;
                case KmlTourStatus.Paused:
                    _playButton.Enabled = true;
                    _pauseButton.Enabled = false;
                    _resetButton.Enabled = true;
                    break;
                case KmlTourStatus.Playing:
                    _resetButton.Enabled = true;
                    _playButton.Enabled = false;
                    _pauseButton.Enabled = true;
                    break;
            }
        }

        // Play the tour when the button is pressed.
        private void Play_Clicked(object sender, EventArgs e) => _tourController?.Play();

        // Pause the tour when the button is pressed.
        private void Pause_Clicked(object sender, EventArgs e) => _tourController?.Pause();

        // Reset the tour when the button is pressed.
        private void Reset_Clicked(object sender, EventArgs e) => _tourController?.Reset();

        protected override void OnStop()
        {
            base.OnStop();

            // Reset the tour controller when the sample closes - avoids a crash.
            _tourController?.Pause();
            _tourController?.Reset();
        }

        private void CreateLayout()
        {
            // Create a new vertical layout for the app.
            var layout = new LinearLayout(this) {Orientation = Orientation.Vertical};

            // Add a help label.
            TextView helpLabel = new TextView(this);
            helpLabel.Text = "Use the buttons to play the tour. Contains audio. 🎧";
            layout.AddView(helpLabel);

            // Add a row with buttons.
            _playButton = new Button(this) {Text = "Play", Enabled = false};
            _playButton.Click += Play_Clicked;
            _pauseButton = new Button(this) {Text = "Pause", Enabled = false};
            _pauseButton.Click += Pause_Clicked;
            _resetButton = new Button(this) {Text = "Reset", Enabled = false};
            _resetButton.Click += Reset_Clicked;

            LinearLayout rowLayout = new LinearLayout(this) {Orientation = Orientation.Horizontal};

            LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MatchParent,
                ViewGroup.LayoutParams.MatchParent,
                1.0f
            );
            _playButton.LayoutParameters = param;
            _pauseButton.LayoutParameters = param;
            _resetButton.LayoutParameters = param;

            rowLayout.AddView(_playButton);
            rowLayout.AddView(_pauseButton);
            rowLayout.AddView(_resetButton);

            layout.AddView(rowLayout);

            // Add the scene view to the layout.
            _mySceneView = new SceneView(this);
            layout.AddView(_mySceneView);

            // Show the layout in the app.
            SetContentView(layout);
        }
    }
}
Examples

Xamarin Forms Android

Example Name: PlayKmlTours

Play tours in KML files.

Code example screen shot.

C#
// Copyright 2019 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.

using ArcGISRuntime.Samples.Managers;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Ogc;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using Xamarin.Forms;

namespace ArcGISRuntimeXamarin.Samples.PlayKmlTours
{
    [ArcGISRuntime.Samples.Shared.Attributes.Sample(
        "Play a KML tour",
        "Layers",
        "Play tours in KML files.",
        "")]
    [ArcGISRuntime.Samples.Shared.Attributes.OfflineData("f10b1d37fdd645c9bc9b189fb546307c")]
    public partial class PlayKmlTours : ContentPage, IDisposable
    {
        // The KML tour controller provides player controls for KML tours.
        private readonly KmlTourController _tourController = new KmlTourController();

        public PlayKmlTours()
        {
            InitializeComponent();
            Initialize();
        }

        private async void Initialize()
        {
            // Load the scene with a basemap and a terrain surface.
            MySceneView.Scene = new Scene(Basemap.CreateImagery());
            MySceneView.Scene.BaseSurface.ElevationSources.Add(new ArcGISTiledElevationSource(new Uri("https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer")));

            // Get the URL to the data.
            string filePath = DataManager.GetDataFolder("f10b1d37fdd645c9bc9b189fb546307c", "Esri_tour.kmz");
            Uri kmlUrl = new Uri(filePath);

            // Create the KML dataset and layer.
            KmlDataset dataset = new KmlDataset(kmlUrl);
            KmlLayer layer = new KmlLayer(dataset);

            // Add the layer to the map.
            MySceneView.Scene.OperationalLayers.Add(layer);

            try
            {
                // Load the dataset.
                await dataset.LoadAsync();

                // Find the first KML tour.
                FindKmlTour(dataset.RootNodes);

                // Handle absence of tour gracefully.
                if (_tourController.Tour == null)
                {
                    throw new InvalidOperationException("No tour found. Can't enable touring for a KML file with no tours.");
                }

                // Listen for changes to the tour status.
                _tourController.Tour.PropertyChanged += Tour_PropertyChanged;

                // Enable the play button.
                PlayButton.IsEnabled = true;

                // Hide the status bar.
                LoadingStatusBar.IsVisible = false;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.ToString());
                await Application.Current.MainPage.DisplayAlert("Error", e.ToString(), "OK");
            }
        }

        private void FindKmlTour(IEnumerable<KmlNode> rootNodes)
        {
            // Hold a list of nodes to explore.
            Queue<KmlNode> nodesToExplore = new Queue<KmlNode>();

            // Add each root node to the list.
            foreach (KmlNode rootNode in rootNodes)
            {
                nodesToExplore.Enqueue(rootNode);
            }

            // Keep exploring until a tour is found or there are no more nodes.
            while (nodesToExplore.Any())
            {
                // Remove a node from the queue.
                KmlNode currentNode = nodesToExplore.Dequeue();

                // If the node is a tour, use it.
                if (currentNode is KmlTour tour)
                {
                    _tourController.Tour = tour;
                    return;
                }

                // If the node is a container, add all of its children to the list of nodes to explore.
                if (currentNode is KmlContainer container)
                {
                    foreach (KmlNode node in container.ChildNodes)
                    {
                        nodesToExplore.Enqueue(node);
                    }
                }

                // Otherwise, continue.
            }
        }

        private void Tour_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            // Skip for everything except tour status property changes.
            if (e.PropertyName != nameof(KmlTour.TourStatus))
            {
                return;
            }

            // Set the UI based on the current state of the tour.
            switch (_tourController.Tour.TourStatus)
            {
                case KmlTourStatus.Completed:
                case KmlTourStatus.Initialized:
                    PlayButton.IsEnabled = true;
                    PauseButton.IsEnabled = false;
                    break;
                case KmlTourStatus.Paused:
                    PlayButton.IsEnabled = true;
                    PauseButton.IsEnabled = false;
                    ResetButton.IsEnabled = true;
                    break;
                case KmlTourStatus.Playing:
                    ResetButton.IsEnabled = true;
                    PlayButton.IsEnabled = false;
                    PauseButton.IsEnabled = true;
                    break;
            }
        }

        // Play the tour when the button is pressed.
        private void Play_Clicked(object sender, EventArgs e) => _tourController?.Play();

        // Pause the tour when the button is pressed.
        private void Pause_Clicked(object sender, EventArgs e) => _tourController?.Pause();

        // Reset the tour when the button is pressed.
        private void Reset_Clicked(object sender, EventArgs e) => _tourController?.Reset();

        public void Dispose()
        {
            // Reset the tour when the user leaves the sample.
            _tourController?.Pause();
            _tourController?.Reset();
        }
    }
}
XAML
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"             
             xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Xamarin.Forms;assembly=Esri.ArcGISRuntime.Xamarin.Forms"
             xmlns:resources="clr-namespace:Forms.Resources;assembly=ArcGISRuntime"
             x:Class="ArcGISRuntimeXamarin.Samples.PlayKmlTours.PlayKmlTours">
    <RelativeLayout>
        <esriUI:SceneView x:Name="MySceneView" Style="{StaticResource SceneWithFormStyle}"
                        BindingContext="{x:Reference Name=ResponsiveFormContainer}" />
        <resources:ResponsiveFormContainer x:Name="ResponsiveFormContainer">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Label Text="Use the buttons to control the tour. Contains audio. 🎧"
                           Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"
                           Margin="0,0,0,5"
                           />
                <Button x:Name="PlayButton"
                        Grid.Row="1" Grid.Column="0"
                        Text="Play"
                        IsEnabled="False"
                        Clicked="Play_Clicked" />
                <Button x:Name="PauseButton"
                        Grid.Row="1" Grid.Column="1"
                        Margin="5,0,5,0"
                        Text="Pause"
                        IsEnabled="False"
                        Clicked="Pause_Clicked" />
                <Button x:Name="ResetButton"
                        Grid.Row="1" Grid.Column="2"
                        Text="Reset"
                        IsEnabled="False"
                        Clicked="Reset_Clicked" />
                <ActivityIndicator x:Name="LoadingStatusBar"
                                   Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3"
                                   Margin="0,5,0,0"
                                   IsEnabled="True" IsRunning="True"  />
            </Grid>
        </resources:ResponsiveFormContainer>
    </RelativeLayout>
</ContentPage>
See Also
Additional Examples
Hyperlink to ExampleDescription
PlayKmlToursPlay tours in KML files.