Match viewpoint of geo views

View on GitHub

Keep the viewpoints of two views, for example, a map view and a scene view, synchronized with each other.

Image of Match viewpoint of geo views sample

Use case

You might need to synchronize GeoView viewpoints if you had two map views in one application - a main map and an inset. An inset map view could display all the layers at their full extent and contain a hollow rectangular graphic that represents the visible extent of the main map view. As you zoom or pan in the main map view, the extent graphic in the inset map would adjust accordingly.

How to use the sample

Interact with the map view or scene view by zooming or panning. The other map view or scene view will automatically focus on the same viewpoint.

How it works

  1. Use the onNavigatingChanged(perform:) modifier on each of the geo views to determine when they are navigating.
  2. When a given geo view is navigating, use the onViewpointChanged(kind:perform:) modifier to set its new viewpoint on the other geo view's viewpoint.

Relevant API

  • GeoView
  • MapView
  • SceneView
  • Viewpoint

About the data

This application provides two different perspectives of the arcGISImagery basemap, A 2D MapView as well as a 3D SceneView, displayed on top of one another.

Tags

3D, automatic refresh, event, event handler, events, extent, interaction, interactions, pan, zoom

Sample Code

MatchViewpointOfGeoViewsView.swift
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Copyright 2024 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
//
//   https://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.

import ArcGIS
import SwiftUI

struct MatchViewpointOfGeoViewsView: View {
    /// A map with an imagery basemap.
    @State private var map = Map(basemapStyle: .arcGISImagery)

    /// A scene with an imagery basemap.
    @State private var scene = Scene(basemapStyle: .arcGISImagery)

    /// The viewpoint of the map view.
    @State private var mapViewpoint: Viewpoint?

    /// The viewpoint of the scene view.
    @State private var sceneViewpoint: Viewpoint?

    /// A Boolean value indicating whether the map view is currently navigating.
    @State private var mapIsNavigating = false

    /// A Boolean value indicating whether the scene view is currently navigating.
    @State private var sceneIsNavigating = false

    var body: some View {
        VStack(spacing: 0) {
            MapView(map: map, viewpoint: mapViewpoint)
                .onNavigatingChanged { mapIsNavigating = $0 }
                .onViewpointChanged(kind: .centerAndScale) { newViewpoint in
                    // Sets the scene's viewpoint to the map's when the map is navigating,
                    // or when the scene isn't navigating, i.e., when the viewpoint is first set.
                    guard mapIsNavigating || !sceneIsNavigating else { return }
                    sceneViewpoint = newViewpoint
                }

            SceneView(scene: scene, viewpoint: sceneViewpoint)
                .onNavigatingChanged { sceneIsNavigating = $0 }
                .onViewpointChanged(kind: .centerAndScale) { newViewpoint in
                    // Sets the map's viewpoint to the scene's when the scene is navigating.
                    guard sceneIsNavigating else { return }
                    mapViewpoint = newViewpoint
                }
        }
    }
}

#Preview {
    MatchViewpointOfGeoViewsView()
}

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.