Skip To Content ArcGIS for Developers Sign In Dashboard

ArcGIS Runtime SDK for .NET

Distance composite scene symbol

This code sample is available for these platforms:
View Sample on GitHub

Change a graphic's symbol based on the camera's proximity to it.

screenshot

How to use the sample

The sample starts looking at a plane. Zoom out from the plane to see it turn into a cone. Keeping zooming out and it will turn into a point.

How it works

  1. Create a GraphicsOverlay object and add it to a SceneView object.
  2. Create a DistanceCompositeSceneSymbol object.
  3. Create DistanceSymbolRange objects specifying a Symbol and the min and max distance within which the symbol should be visible.
  4. Add the ranges to the range collection of the distance composite scene symbol.
  5. Create a Graphic object with the distance composite scene symbol at a location and add it to the graphics overlay.

Relevant API

  • DistanceCompositeSceneSymbol
  • Range
  • RangeCollection

Tags

3D, DistanceCompositeSceneSymbol, DistanceSymbolRange, SimpleMarkerSceneSymbol, graphic

Sample Code

<UserControl
    x:Class="ArcGISRuntime.UWP.Samples.UseDistanceCompositeSym.UseDistanceCompositeSym"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:esriUI="using:Esri.ArcGISRuntime.UI.Controls">

    <Grid>
        <esriUI:SceneView x:Name="MySceneView"/>
    </Grid>
</UserControl>
// Copyright 2017 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.Geometry;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Symbology;
using Esri.ArcGISRuntime.UI;
using System;
using System.Drawing;
using System.Threading.Tasks;
using Windows.UI.Popups;

namespace ArcGISRuntime.UWP.Samples.UseDistanceCompositeSym
{
    [ArcGISRuntime.Samples.Shared.Attributes.Sample(
        "Distance composite symbol",
        "Symbology",
        "This sample demonstrates how to create a `DistanceCompositeSceneSymbol` with unique marker symbols to display at various distances from the camera.",
        "1. When the Scene initially loads, you will be looking at a point graphic symbolized with a 3D model symbol (airplane).\n2. Zoom away slightly from the graphic and the symbol will change to a blue 3D cone symbol (pointing in the direction of flight).\n3. Zoom farther from the graphic and the symbol will change to a blue circle marker symbol.")]
    [ArcGISRuntime.Samples.Shared.Attributes.OfflineData("681d6f7694644709a7c830ec57a2d72b")]
    public sealed partial class UseDistanceCompositeSym
    {
        public UseDistanceCompositeSym()
        {
            InitializeComponent();

            // Create the Scene, basemap, graphic, and composite symbol.
            Initialize();
        }

        private async void Initialize()
        {
            try
            {
                // Create a new Scene with an imagery basemap.
                Scene myScene = new Scene(Basemap.CreateImagery());

                // Add the Scene to the SceneView.
                MySceneView.Scene = myScene;

                // Create a new GraphicsOverlay and add it to the SceneView.
                GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
                graphicsOverlay.SceneProperties.SurfacePlacement = SurfacePlacement.Relative;
                MySceneView.GraphicsOverlays.Add(graphicsOverlay);

                // Call a function to create a new distance composite symbol with three ranges.
                DistanceCompositeSceneSymbol compositeSymbol = await CreateCompositeSymbol();

                // Create a new point graphic with the composite symbol, add it to the graphics overlay.
                MapPoint locationPoint = new MapPoint(-2.708471, 56.096575, 5000, SpatialReferences.Wgs84);
                Graphic pointGraphic = new Graphic(locationPoint, compositeSymbol);
                graphicsOverlay.Graphics.Add(pointGraphic);

                // Add an orbit camera controller to lock the camera to the graphic.
                OrbitGeoElementCameraController cameraController = new OrbitGeoElementCameraController(pointGraphic, 20)
                {
                    CameraPitchOffset = 80,
                    CameraHeadingOffset = -30
                };
                MySceneView.CameraController = cameraController;
            }
            catch (Exception e)
            {
                MessageDialog dialog = new MessageDialog(e.ToString(), "Error");
                await dialog.ShowAsync();
            }
        }

        private async Task<DistanceCompositeSceneSymbol> CreateCompositeSymbol()
        {
            // Get the path to the 3D model.
            string modelPath = GetModelPath();

            // Create three symbols for displaying a feature according to its distance from the camera.
            // First, a 3D model symbol (airplane) for when the camera is near the feature.
            ModelSceneSymbol plane3DSymbol = await ModelSceneSymbol.CreateAsync(new Uri(modelPath), 1.0);

            // 3D (blue cone) symbol for when the feature is at an intermediate range.
            SimpleMarkerSceneSymbol coneSym = new SimpleMarkerSceneSymbol(SimpleMarkerSceneSymbolStyle.Cone, Color.LightSkyBlue, 15, 6, 3, SceneSymbolAnchorPosition.Center)
            {
                // The cone will point in the same direction as the plane.
                Pitch = -90
            };

            // Simple marker symbol (circle) when the feature is far from the camera.
            SimpleMarkerSymbol markerSym = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Circle, Color.LightSkyBlue, 10.0);

            // Create three new ranges for displaying each symbol.
            DistanceSymbolRange closeRange = new DistanceSymbolRange(plane3DSymbol, 0, 100);
            DistanceSymbolRange midRange = new DistanceSymbolRange(coneSym, 100, 500);
            DistanceSymbolRange farRange = new DistanceSymbolRange(markerSym, 500, 0);

            // Create a new DistanceCompositeSceneSymbol and add the ranges.
            DistanceCompositeSceneSymbol compositeSymbol = new DistanceCompositeSceneSymbol();
            compositeSymbol.Ranges.Add(closeRange);
            compositeSymbol.Ranges.Add(midRange);
            compositeSymbol.Ranges.Add(farRange);

            // Return the new composite symbol.
            return compositeSymbol;
        }

        private static string GetModelPath()
        {
            return DataManager.GetDataFolder("681d6f7694644709a7c830ec57a2d72b", "Bristol.dae");
        }
    }
}