同步具有不同中心和旋转的不同地图
Synchronize different maps with different center and rotation
我的用例是我有两个并排的地图,然后用户可以将两个地图独立地移动到两个地图上的不同区域,并在必要时进行旋转。然后,他们按下一个按钮,该按钮将从该点开始在两个地图上同步。
我看到同步如何与相同的视图对象一起工作,但在我的情况下,据我了解,我需要不同的视图对象,因为中心和旋转会发生变化。
如何在两个地图之间共享一个视图,但中心和旋转角度不同?
同步视图更改而不同步视图可以通过侦听更改来完成,但是您需要防止对一个地图的更改更新另一个地图,从而导致对原始地图的进一步更新和无限循环。幸运的是,animate 方法有一个完成回调选项,因此使用它可以在第一个完成之前禁用进一步的更新。 http://mikenunn.16mb.com/demo/sync-changes.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, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.map1 {
width: 50%;
height: 40%;
}
.map2 {
width: 50%;
height: 40%;
}
</style>
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<title>OpenLayers example</title>
</head>
<body>
<div id="map1" class="map1"></div>
<input type="submit" onclick="setSync()" value="Sync">
<input type="submit" onclick="unsetSync()" value="Unsync">
<div id="map2" class="map2"></div>
<script type="text/javascript">
var layer = new ol.layer.Tile({
source: new ol.source.OSM()
});
var map1 = new ol.Map({
target: 'map1',
layers: [layer],
view: new ol.View({
center: [0, 0],
zoom: 1
})
});
var map2 = new ol.Map({
target: 'map2',
layers: [layer],
view: new ol.View({
center: [0, 0],
zoom: 1
})
});
var sync = false;
var dx, dy, dz, dr;
map1.getView().on(['change:center','change:resolution','change:rotation'], function() {
if (sync) {
var center = map1.getView().getCenter();
var zoom = map1.getView().getZoom();
var rotation = map1.getView().getRotation();
sync = false;
map2.getView().animate({
center: [center[0] + dx, center[1] + dy],
zoom: zoom + dz,
rotation: rotation + dr,
duration: 0
}, function() { sync = true; });
}
});
map2.getView().on(['change:center','change:resolution','change:rotation'], function() {
if (sync) {
var center = map2.getView().getCenter();
var zoom = map2.getView().getZoom();
var rotation = map2.getView().getRotation();
sync = false;
map1.getView().animate({
center: [center[0] - dx, center[1] - dy],
zoom: zoom - dz,
rotation: rotation - dr,
duration: 0
}, function() { sync = true; });
}
});
function setSync() {
sync = true;
var center1 = map1.getView().getCenter();
var center2 = map2.getView().getCenter();
dx = center2[0] - center1[0];
dy = center2[1] - center1[1];
var zoom1 = map1.getView().getZoom();
var zoom2 = map2.getView().getZoom();
dz = zoom2 - zoom1;
var rotation1 = map1.getView().getRotation();
var rotation2 = map2.getView().getRotation();
dr = rotation2 - rotation1;
}
function unsetSync() {
sync = false;
}
</script>
</body>
</html>
ol-ext 有一个同步交互可以为您完成这项工作。单击按钮时,您只需将其添加到地图上。
参见示例 http://viglino.github.io/ol-ext/examples/misc/map.interaction.synchronize.html
我的用例是我有两个并排的地图,然后用户可以将两个地图独立地移动到两个地图上的不同区域,并在必要时进行旋转。然后,他们按下一个按钮,该按钮将从该点开始在两个地图上同步。
我看到同步如何与相同的视图对象一起工作,但在我的情况下,据我了解,我需要不同的视图对象,因为中心和旋转会发生变化。
如何在两个地图之间共享一个视图,但中心和旋转角度不同?
同步视图更改而不同步视图可以通过侦听更改来完成,但是您需要防止对一个地图的更改更新另一个地图,从而导致对原始地图的进一步更新和无限循环。幸运的是,animate 方法有一个完成回调选项,因此使用它可以在第一个完成之前禁用进一步的更新。 http://mikenunn.16mb.com/demo/sync-changes.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, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.map1 {
width: 50%;
height: 40%;
}
.map2 {
width: 50%;
height: 40%;
}
</style>
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<title>OpenLayers example</title>
</head>
<body>
<div id="map1" class="map1"></div>
<input type="submit" onclick="setSync()" value="Sync">
<input type="submit" onclick="unsetSync()" value="Unsync">
<div id="map2" class="map2"></div>
<script type="text/javascript">
var layer = new ol.layer.Tile({
source: new ol.source.OSM()
});
var map1 = new ol.Map({
target: 'map1',
layers: [layer],
view: new ol.View({
center: [0, 0],
zoom: 1
})
});
var map2 = new ol.Map({
target: 'map2',
layers: [layer],
view: new ol.View({
center: [0, 0],
zoom: 1
})
});
var sync = false;
var dx, dy, dz, dr;
map1.getView().on(['change:center','change:resolution','change:rotation'], function() {
if (sync) {
var center = map1.getView().getCenter();
var zoom = map1.getView().getZoom();
var rotation = map1.getView().getRotation();
sync = false;
map2.getView().animate({
center: [center[0] + dx, center[1] + dy],
zoom: zoom + dz,
rotation: rotation + dr,
duration: 0
}, function() { sync = true; });
}
});
map2.getView().on(['change:center','change:resolution','change:rotation'], function() {
if (sync) {
var center = map2.getView().getCenter();
var zoom = map2.getView().getZoom();
var rotation = map2.getView().getRotation();
sync = false;
map1.getView().animate({
center: [center[0] - dx, center[1] - dy],
zoom: zoom - dz,
rotation: rotation - dr,
duration: 0
}, function() { sync = true; });
}
});
function setSync() {
sync = true;
var center1 = map1.getView().getCenter();
var center2 = map2.getView().getCenter();
dx = center2[0] - center1[0];
dy = center2[1] - center1[1];
var zoom1 = map1.getView().getZoom();
var zoom2 = map2.getView().getZoom();
dz = zoom2 - zoom1;
var rotation1 = map1.getView().getRotation();
var rotation2 = map2.getView().getRotation();
dr = rotation2 - rotation1;
}
function unsetSync() {
sync = false;
}
</script>
</body>
</html>
ol-ext 有一个同步交互可以为您完成这项工作。单击按钮时,您只需将其添加到地图上。
参见示例 http://viglino.github.io/ol-ext/examples/misc/map.interaction.synchronize.html