How to make overview map sync with main map

1120
7
Jump to solution
03-18-2021 12:39 PM
JustinBridwell2
Occasional Contributor II

I have created an overview map widget for my web app. I am using the `arcGIS API for Javascript` version 4.17. My overview map is separate from my main map as I don't want to bring in all the layers from my main map in the overview. I have basically followed the API documentation as a guide

// Create Maps
var map = new Map({
    basemap: "streets-vector",
    layers: [GA_Layers, study_layer]
});

// Create another Map, to be used in the overview "view"
const overviewMap = new Map({
    basemap: "topo-vector"
});

// Create Map Views. Add the map to a MapView
const view = new MapView({
    container: "viewDiv",
    map: map,
    center: [-83.9073, 30.8417], 
    zoom: 9,
    highlightOptions: {
        color: "red"
    },
    popup: {
        actions: [],
        dockEnabled: true,
        dockOptions: {
            buttonEnabled: true,
            breakpoint: false
        }
    }
});

// Create the MapView for overview map
var overView = new MapView({
    container: "overviewDiv",
    map: overviewMap,
    constraints: {
        rotationEnabled: false
    }
});

I then create some code to `sync` the overview map zoo, center, and scale to the main view map. However, this does not work.

overView.when(function () {
    view.when(function () {
        setup();
    });
});

function setup() {
    const extent3Dgraphic = new Graphic({
        geometry: null,
        symbol: {
            type: "simple-fill",
            color: [0, 0, 0, 0.5],
            outline: null
        }
});
overView.graphics.add(extent3Dgraphic);

watchUtils.init(view, "extent", function (extent) {
// Sync the overview map location
// whenever the 3d view is stationary
    if (view.stationary) {
        overView
        .goTo({
            center: view.center,
            zoom: view.zoom,
            scale:
               view.scale *
               2 *
               Math.max(
               view.width / overView.width,
               view.height / overView.height
        )
    })
    .catch(function (error) {
// ignore goto-interrupted errors
        if (error.name !== "view:goto-interrupted") {
            console.error(error);
        }
    });
}
    extent3Dgraphic.geometry = extent;
    });
}

Essentially, the overview map is not syncing with the main map and doesn't pan or zoom with it after launch. Any ideas as to what I am doing wrong here?

sync_map.PNG

Tags (3)
0 Kudos
1 Solution

Accepted Solutions
JustinBridwell2
Occasional Contributor II

OK, I got it working. I have removed the `if` part and it seems to be working fine. Thanks for the assist @KenBuja , it was totally the .stationary != true that threw everything off.

watchUtils.init(view, "extent", function (extent) {
    // Sync the overview map location
    // whenever the 3d view is stationary
    console.log(view.stationary);
    //if (view.stationary) {
    overView
        .goTo({
            center: view.center,
            zoom: view.zoom,
            scale:
                view.scale *
                2 *
                Math.max(view.width / overView.width, view.height / overView.height)
        })
        .catch(function (error) {
        // ignore goto-interrupted errors
            if (error.name !== "view:goto-interrupted") {
                console.error(error);
            }
         });
    //} 
        extent3Dgraphic.geometry = extent;
});

View solution in original post

7 Replies
KenBuja
MVP Honored Contributor

Did you look at this sample that shows how to synchronize two views? It's an exact sync of the two views, but you should be able to use the technique to have different scales but the same center point.

JustinBridwell2
Occasional Contributor II

This seemed to work for syncing the views, but I can't figure out how to get the extent 3D graphic ( the opaque rectangle that shows the extent) to work inside the sync. Any ideas about that?

0 Kudos
KenBuja
MVP Honored Contributor

There appears to be a bug in the MapView stationary property. It never gets set to true after panning/zooming stops. If you change it to a SceneView, that property does change from false when you're panning/zooming to true when it stops. You can see this by adding the console.log into your code

watchUtils.init(mainView, "extent", function(extent){
  // Sync the overview map location
  // whenever the 3d view is stationary
  console.log(mainView.stationary); //this is the added line
  if (mainView.stationary) {

 

KenBuja
MVP Honored Contributor

One way around that could use the monitor the LayerView's updating property and when it is false, run your code to set the graphic. Take a look at this blog that gives an example of this.

JustinBridwell2
Occasional Contributor II

This is exactly the problem. So, since I am not using the 3D SceneView, how to I overcome this issue. Should I simply remove the `if`(view.stattionary) {}` part? I still need that extent to set

    `extent3Dgraphic.geometry = extent;`

0 Kudos
KenBuja
MVP Honored Contributor

That's where you could substitute using the LayerView updating property. You could get the view's extent after it's finished updating and use that for the graphic's geometry.

You should open a support issue on the stationary property, if you are able, to see if it's an actual bug or expected behavior. If it's expected, then the documentation should be changed.

JustinBridwell2
Occasional Contributor II

OK, I got it working. I have removed the `if` part and it seems to be working fine. Thanks for the assist @KenBuja , it was totally the .stationary != true that threw everything off.

watchUtils.init(view, "extent", function (extent) {
    // Sync the overview map location
    // whenever the 3d view is stationary
    console.log(view.stationary);
    //if (view.stationary) {
    overView
        .goTo({
            center: view.center,
            zoom: view.zoom,
            scale:
                view.scale *
                2 *
                Math.max(view.width / overView.width, view.height / overView.height)
        })
        .catch(function (error) {
        // ignore goto-interrupted errors
            if (error.name !== "view:goto-interrupted") {
                console.error(error);
            }
         });
    //} 
        extent3Dgraphic.geometry = extent;
});