1

The OpenLayers example “Advanced View Positioning” (https://openlayers.org/en/latest/examples/center.html) shows how to create a “view inside a view”.

enter image description here

If you examine the example, it uses a padding passed to view.fit(). The problem I see is that only that function accepts a padding, so the reposition cannot be animated.

Also, if you look at the screenshot, fit operations center the map at point B, but clicking on zoom buttons use point A.

My question is: Is there any way to specify that subview when creating the view so all operations (animate, zoom, fit, etc) would always use point B?

One added problem is that default interactions like Map Rotate (Alt+Shift+mouse) rotates around A, not B. So it would be really helpful to define that subview to affect all view operations automatically, let’s say when opening a side panel, for example.

Ricardo
  • 180
  • 2
  • 12

1 Answers1

1

fit does have duration and easing options, and animate has an anchor option. However there is only one view it's simply the controls which have been moved using CSS, so any other interactions will apply to the full view. But you could base a solution on the shared views example https://openlayers.org/en/v4.6.5/examples/side-by-side.html and have two synchronised maps, use CSS to overflow the outer map (created without controls) to offset its center and overlay it with another map positioned so the centers coincide. This code will position the center towards the bottom right at 2/3 the width and height by extending the outer map by 4/3, with the inner map having 45% the width and height of the full outer map http://mikenunn.16mb.com/demo/view-on-view-br.html

<!doctype html>
<html lang="en">

<head>
  <link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" type="text/css">
  <style>
    html, body {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
        overflow: hidden;
    }
    .map1 {
        position: absolute;
        width: calc(100% *4/3);
        height: calc(100% *4/3);
    }
    .map2 {
        position: absolute;
        left: calc((100% - 45%)/2);
        top: calc((100% - 45%)/2);
        width: 45%;
        height: 45%;
    }
  </style>
  <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
  <title>OpenLayers View on View example</title>
</head>

<body>
  <div id="map1" class="map1"><div id="map2" class="map2"></div></div>
  <script type="text/javascript">

    var source = new ol.source.OSM();

    var map2 = new ol.Map({
        target: 'map2',
        layers: [new ol.layer.Tile({ source: source })],
        view: new ol.View({
            center: ol.proj.fromLonLat([2.3442, 48.8635]),
            zoom: 10
        })
    });

    var map1 = new ol.Map({
        target: 'map1',
        controls: [],
        layers:  [new ol.layer.Tile({ source: source, opacity: 0.6 })],
        view: map2.getView()
    });

    var map1div = document.getElementById("map1");
    var map2div = document.getElementById("map2");
    var map1ov = map1div.getElementsByClassName("ol-overlaycontainer")[1];
    map1ov.appendChild(map2div);

  </script>
</body>

</html>

This CSS would position the center towards the top left at 1/3 the width and height by extending the outer map left and up instead of right and down http://mikenunn.16mb.com/demo/view-on-view-tl.html

.map1 {
    position: absolute;
    width: calc(100% *4/3);
    height: calc(100% *4/3);
    left: calc(100% - 100% *4/3);
    top: calc(100% - 100% *4/3);
}
Mike
  • 16,042
  • 2
  • 14
  • 30
  • Hi Mike, thanks for answering. How is this approach performance wise? – Ricardo Feb 01 '19 at 10:51
  • There would be an overhead in loading data which might never be seen, and duplicating vector layers with many features could also be a performance issue, plus in futures releases maps won't be able to share layers https://github.com/openlayers/openlayers/blob/master/changelog/upgrade-notes.md In that case you could considering using only the partly overflowing large map and reposition any hidden controls into the visible region to resemble a normal map, but that would require extra CSS or code. – Mike Feb 05 '19 at 11:19
  • 1
    Didn’t like the idea for performance reasons so started cheating the center in all calculations. Not a difficult task as almost all functions accept an anchor. The only difficult part was animating a center/zoom, where I directly removed the animation. The problem I see is that you cannot rely in default controls. It’s a pity not having a padding option at the view level for OL to take care of all calculations automatically. – Ricardo Feb 05 '19 at 18:23