如何在OpenLayers中在两个遥远的多边形之间创建飞行动画

问题描述 投票:0回答:1

使用Openlayers(v6.1.1。),我试图在几个多边形之间创建简单的FlyTo动画。当两者之间的距离很小时,FlyTo动画效果很好,但是随着距离的增加,用户体验会下降。

在更大的距离上,我只是看到以低倍缩放快速浏览地图。我尝试了ahocevarthis link答案,但没有达到预期的效果。

按照说明,我将一个中心动画与两个缩放动画组合在一起,并同时启动它们。示例:

let view = map.getView();
let extentOfPolygon = feature.getGeometry().getExtent();
let resolution = view.getResolutionForExtent(extentOfPolygon);
let zoom = view.getZoomForResolution(resolution);
let center = ol.extent.getCenter(extentOfPolygon);

view.animate({
  center: center,
  duration: duration
});
view.animate({
  zoom: zoom - 1,
  duration: duration / 2
}, {
  zoom: zoom,
  duration: duration / 2
});

[FlyTo动画在多边形附近但随着距离增加而工​​作正常,FlyTo动画正在转变为在地图上快速平移。

我已经创建了用于测试目的的小型应用。当我们单击列表项时,地图将进行动画处理并缩放到被单击的字段。例如,当超棒时,另一个场和一个超级场就在附近,而FlyTo动画按预期工作,但是当我们从超级场单击到史诗场(位于最南端时,然后将地图快速平移到位置)。

所以,我的问题是这个。是否有可能独立于多边形位置而对多边形实现相同的FlyTo效果(传单的https://regionbound.com/leaflet-fly-demo设置正确)

这是jsfiddle示例:https://jsfiddle.net/Svinjica/1kjfp4ds/

javascript animation openlayers openlayers-5 openlayers-6
1个回答
0
投票

我认为您需要进一步完善缩放方式。例如,缩小得恰到好处,因此在高峰高度都可以看到起点和终点。您可以通过计算距离并除以地图宽度来做到这一点。对总体上,下变化的持续时间进行一些调整,但不要太大,然后按比例划分上,下持续时间。为了减少初始持续时间(如果当前分辨率已经大于计算出的最高海拔分辨率),持续时间的100%应该向下,并且还应该通过将其拟合到vectorSource范围https://jsfiddle.net/b4mL9s28/8/来打开地图,使其靠近您的地图项

let geojsonData = new ol.format.GeoJSON().readFeatures(fieldData, {
  featureProjection: 'EPSG:3857'
});
let vectorSource = new ol.source.Vector({
  features: geojsonData
});

let vectorLayer = new ol.layer.Vector({
  source: vectorSource
});

var map = new ol.Map({
  target: 'map',
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM()
    }),
    vectorLayer
  ],
  view: new ol.View({
    center: [0, 0],
    zoom: 4
  })
});

map.getView().fit(vectorSource.getExtent());

const duration = 2000;

var featureListElement = document.getElementById("vectorFeatures");

var features = vectorLayer.getSource().getFeatures();
for (let feature of features) {
  let aElement = document.createElement("a");
  aElement.classList.add("list-group-item", "list-group-item-action");
  featureListElement.appendChild(aElement);
  aElement.innerHTML = feature.get("Name");
  aElement.onclick = function() {

    let view = map.getView();
    var extentOfPolygon = feature.getGeometry().getExtent();
    let resolution = view.getResolutionForExtent(extentOfPolygon);
    var center = ol.extent.getCenter(extentOfPolygon);
    var currentCenter = map.getView().getCenter();
    var currentResolution = map.getView().getResolution();
    var distance = Math.sqrt(Math.pow(center[0] - currentCenter[0], 2) + Math.pow(center[1] - currentCenter[1], 2));
    var maxResolution = Math.max(distance/ map.getSize()[0], currentResolution);
    var up = Math.abs(maxResolution - currentResolution);
    var down = Math.abs(maxResolution - resolution);
    var adjustedDuration = duration + Math.sqrt(up + down) * 100;

    view.animate({
      center: center,
      duration: adjustedDuration
    });
    view.animate({
      resolution: maxResolution,
      duration: adjustedDuration * up / (up + down)
    }, {
      resolution: resolution,
      duration: adjustedDuration * down / (up + down)
    });
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.