我在我的(python)烧瓶应用程序中实现了OpenLayer Marker Animation。
然而,在我用于标记动画的数据集中,我有一条额外的路线,我想要显示动画。
当我添加代码来处理第二个动画时,就像第一个动画的控件被覆盖一样,我不知道如何避免这种情况发生。我已经尝试将所有变量重命名为1和2以避免它们互相覆盖,但由于某种原因,它似乎仍然会覆盖控件。
我创建了this fiddle来说明问题。如果单击Map 1下的开始动画,它将在Map 2上运行动画。我刚刚在我的小提琴中使用了下面的过程,但最初我的代码在for循环中运行两次以提取两个路径然后绘制地图。
Route points for Map 1
Set up Map 1
Bind functions to Map 1 buttons
Route points for Map 2
Set up Map 2
Bind functions to Map 2 buttons
我想我的问题是关于隔离代码和/或绑定。首先,我尝试将函数(moveFeature,startAnimation,stopAnimation)重命名为各自的名称,并添加“1”或“2”。这没有做到这一点,也没有类似地重命名所有变量。
答案 0 :(得分:1)
您正在创建许多具有相同名称的变量。例如,当您覆盖函数StartAnimation时,按钮会在第二个中输入(因为两者都指向一个名为“StartAnimation”的函数)。
为避免这种情况,您必须为每个地图创建不同的变量。这样你可以避免使用无用的代码,并确保每个元素都使用它们应该使用的变量。
我根据您的jsfiddle代码构建了一个示例:
var locations1 = [[53.44241609, 6.84913974], [53.44241894, 6.84913726], [53.44242156, 6.84913385], [53.44242473, 6.84913076], [53.44242859, 6.84912721], [53.44243324, 6.84912446], [53.44243724, 6.84912303], [53.44243994, 6.84912206], [53.44244199, 6.84911994], [53.44244474, 6.84911928], [53.44244757, 6.8491193], [53.44245181, 6.84911968], [53.44245596, 6.84912085], [53.44246139, 6.84912072], [53.4424669, 6.84912142], [53.44247222, 6.84912279], [53.4424778, 6.84912454], [53.44248644, 6.84912644], [53.44249062, 6.84912761], [53.44249409, 6.84913057], [53.44249746, 6.84913362], [53.44250197, 6.84913592], [53.44250901, 6.84913629], [53.44251198, 6.84913792], [53.44251293, 6.84913988], [53.44251458, 6.84914126], [53.44251596, 6.8491434], [53.44251778, 6.84914727], [53.44251988, 6.8491501], [53.44252248, 6.8491531], [53.44252517, 6.84915473], [53.44252316, 6.84915181], [53.44252377, 6.84915124], [53.4425233, 6.84914949], [53.44252341, 6.84914848], [53.44252276, 6.84914827], [53.44252397, 6.84914868], [53.4425216, 6.84914477], [53.44252001, 6.84914287], [53.44252107, 6.84914273], [53.44251986, 6.84913869], [53.44251841, 6.84913463], [53.44251482, 6.84912822], [53.44251525, 6.84912649], [53.4425148, 6.84912465], [53.44251483, 6.84912049], [53.44251625, 6.84911749], [53.44251677, 6.84911403], [53.4425187, 6.84910978], [53.44252028, 6.84910694], [53.44252218, 6.84910622], [53.44252457, 6.84910649], [53.44252783, 6.84910729], [53.44253168, 6.84910888], [53.44253668, 6.84910943], [53.44254088, 6.84910976], [53.44254363, 6.84910898], [53.44254612, 6.84910996], [53.44254803, 6.84910946], [53.44255004, 6.84910945], [53.44255416, 6.84910766], [53.44256019, 6.84910343], [53.44256469, 6.84909908], [53.44256753, 6.84909764], [53.44257106, 6.84909639], [53.44257482, 6.84909654], [53.44257861, 6.84909769]];
var locations2 = [[53.44241609, 6.84913974], [53.44241894, 6.84913726], [53.44242156, 6.84913385], [53.44242473, 6.84913076], [53.44242859, 6.84912721], [53.44243324, 6.84912446], [53.44243724, 6.84912303], [53.44243994, 6.84912206], [53.44244199, 6.84911994], [53.44244474, 6.84911928], [53.44244757, 6.8491193], [53.44245181, 6.84911968], [53.44245596, 6.84912085], [53.44246139, 6.84912072], [53.4424669, 6.84912142], [53.44247222, 6.84912279], [53.4424778, 6.84912454], [53.44248644, 6.84912644], [53.44249062, 6.84912761], [53.44249409, 6.84913057], [53.44249746, 6.84913362], [53.44250197, 6.84913592], [53.44250901, 6.84913629], [53.44251198, 6.84913792], [53.44251293, 6.84913988], [53.44251458, 6.84914126], [53.44251596, 6.8491434], [53.44251778, 6.84914727], [53.44251988, 6.8491501], [53.44252248, 6.8491531], [53.44252517, 6.84915473], [53.44252316, 6.84915181], [53.44252377, 6.84915124], [53.4425233, 6.84914949], [53.44252341, 6.84914848], [53.44252276, 6.84914827], [53.44252397, 6.84914868], [53.4425216, 6.84914477], [53.44252001, 6.84914287], [53.44252107, 6.84914273], [53.44251986, 6.84913869], [53.44251841, 6.84913463], [53.44251482, 6.84912822], [53.44251525, 6.84912649], [53.4425148, 6.84912465], [53.44251483, 6.84912049], [53.44251625, 6.84911749], [53.44251677, 6.84911403], [53.4425187, 6.84910978], [53.44252028, 6.84910694], [53.44252218, 6.84910622], [53.44252457, 6.84910649], [53.44252783, 6.84910729], [53.44253168, 6.84910888], [53.44253668, 6.84910943], [53.44254088, 6.84910976], [53.44254363, 6.84910898], [53.44254612, 6.84910996], [53.44254803, 6.84910946], [53.44255004, 6.84910945], [53.44255416, 6.84910766], [53.44256019, 6.84910343], [53.44256469, 6.84909908], [53.44256753, 6.84909764], [53.44257106, 6.84909639], [53.44257482, 6.84909654], [53.44257861, 6.84909769]];
locations1.map(function(l) {
return l.reverse();
});
locations2.map(function(l) {
return l.reverse();
});
// ---------------------------
//Defining Map 1 and Events
// ---------------------------
var route1 = new ol.geom.LineString(locations1)
.transform('EPSG:4326', 'EPSG:3857');
var routeCoords1 = route1.getCoordinates();
var routeLength1 = routeCoords1.length;
var routeFeature1 = new ol.Feature({
type: 'route',
geometry: route1
});
var geoMarker1 = new ol.Feature({
type: 'geoMarker',
geometry: new ol.geom.Point(routeCoords1[0])
});
var startMarker1 = new ol.Feature({
type: 'icon',
geometry: new ol.geom.Point(routeCoords1[0])
});
var endMarker1 = new ol.Feature({
type: 'icon',
geometry: new ol.geom.Point(routeCoords1[routeLength1 - 1])
});
var styles1 = {
'route': new ol.style.Style({
stroke: new ol.style.Stroke({
width: 6,
color: [237, 212, 0, 0.8]
})
}),
'icon': new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 1],
src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png'
})
}),
'geoMarker': new ol.style.Style({
image: new ol.style.Circle({
radius: 7,
snapToPixel: false,
fill: new ol.style.Fill({
color: 'black'
}),
stroke: new ol.style.Stroke({
color: 'white',
width: 2
})
})
})
};
var animating1 = false;
var speed1, now1;
var speedInput1 = document.getElementById('speed1');
var startButton1 = document.getElementById('start-animation1');
var vectorLayer1 = new ol.layer.Vector({
source: new ol.source.Vector({
features: [routeFeature1, geoMarker1, startMarker1, endMarker1]
}),
style: function(feature) {
// hide geoMarker if animation is active
if (animating1 && feature.get('type') === 'geoMarker') {
return null;
}
return styles1[feature.get('type')];
}
});
var map1 = new ol.Map({
target: document.getElementById('map1'),
loadTilesWhileAnimating: true,
view: new ol.View(),
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
vectorLayer1
]
});
map1.getView().fit(
vectorLayer1.getSource().getExtent(), map1.getSize(),
{padding: [30, 5, 5, 5]});
var center1 = map1.getView().getCenter();
var moveFeature1 = function(event) {
var vectorContext = event.vectorContext;
var frameState = event.frameState;
if (animating1) {
var elapsedTime = frameState.time - now1;
// here the trick to increase speed is to jump some indexes
// on lineString coordinates
var index = Math.round(speed1 * elapsedTime / 1000);
if (index >= routeLength1) {
stopAnimation1(true);
return;
}
var currentPoint = new ol.geom.Point(routeCoords1[index]);
var feature = new ol.Feature(currentPoint);
vectorContext.drawFeature(feature, styles1.geoMarker);
}
// tell OL3 to continue the postcompose animation
map1.render();
};
function startAnimation1() {
if (animating1) {
stopAnimation1(false);
} else {
animating1 = true;
now1 = new Date().getTime();
speed1 = speedInput1.value;
startButton1.textContent = 'Cancel Animation';
// hide geoMarker
geoMarker1.setStyle(null);
// just in case you pan somewhere else
map1.getView().setCenter(center1);
map1.on('postcompose', moveFeature1);
map1.render();
}
}
function stopAnimation1(ended) {
animating1 = false;
startButton1.textContent = 'Start Animation';
// if animation cancelled set the marker at the beginning
var coord = ended ? routeCoords1[routeLength1 - 1] : routeCoords1[0];
/** @type {ol.geom.Point} */
(geoMarker1.getGeometry())
.setCoordinates(coord);
//remove listener
map1.un('postcompose', moveFeature1);
}
startButton1.addEventListener('click', startAnimation1, false);
// ---------------------------
//Defining Map 2 and Events
// ---------------------------
var route2 = new ol.geom.LineString(locations2)
.transform('EPSG:4326', 'EPSG:3857');
var routeCoords2 = route2.getCoordinates();
var routeLength2 = routeCoords2.length;
var routeFeature2 = new ol.Feature({
type: 'route',
geometry: route2
});
var geoMarker2 = new ol.Feature({
type: 'geoMarker',
geometry: new ol.geom.Point(routeCoords2[0])
});
var startMarker2 = new ol.Feature({
type: 'icon',
geometry: new ol.geom.Point(routeCoords2[0])
});
var endMarker2 = new ol.Feature({
type: 'icon',
geometry: new ol.geom.Point(routeCoords2[routeLength2 - 1])
});
var styles2 = {
'route': new ol.style.Style({
stroke: new ol.style.Stroke({
width: 6,
color: [237, 212, 0, 0.8]
})
}),
'icon': new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 1],
src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png'
})
}),
'geoMarker': new ol.style.Style({
image: new ol.style.Circle({
radius: 7,
snapToPixel: false,
fill: new ol.style.Fill({
color: 'black'
}),
stroke: new ol.style.Stroke({
color: 'white',
width: 2
})
})
})
};
var animating2 = false;
var speed2, now2;
var speedInput2 = document.getElementById('speed2');
var startButton2 = document.getElementById('start-animation2');
var vectorLayer2 = new ol.layer.Vector({
source: new ol.source.Vector({
features: [routeFeature2, geoMarker2, startMarker2, endMarker2]
}),
style: function(feature) {
// hide geoMarker if animation is active
if (animating2 && feature.get('type') === 'geoMarker') {
return null;
}
return styles2[feature.get('type')];
}
});
var map2 = new ol.Map({
target: document.getElementById('map2'),
loadTilesWhileAnimating: true,
view: new ol.View(),
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
vectorLayer2
]
});
map2.getView().fit(
vectorLayer2.getSource().getExtent(), map2.getSize(),
{padding: [30, 5, 5, 5]});
var center2 = map2.getView().getCenter();
var moveFeature2 = function(event) {
var vectorContext = event.vectorContext;
var frameState = event.frameState;
if (animating2) {
var elapsedTime = frameState.time - now2;
// here the trick to increase speed is to jump some indexes
// on lineString coordinates
var index = Math.round(speed2 * elapsedTime / 1000);
if (index >= routeLength2) {
stopAnimation2(true);
return;
}
var currentPoint = new ol.geom.Point(routeCoords2[index]);
var feature = new ol.Feature(currentPoint);
vectorContext.drawFeature(feature, styles2.geoMarker);
}
// tell OL3 to continue the postcompose animation
map2.render();
};
function startAnimation2() {
if (animating2) {
stopAnimation2(false);
} else {
animating2 = true;
now2 = new Date().getTime();
speed2 = speedInput2.value;
startButton2.textContent = 'Cancel Animation';
// hide geoMarker
geoMarker2.setStyle(null);
// just in case you pan somewhere else
map2.getView().setCenter(center2);
map2.on('postcompose', moveFeature2);
map2.render();
}
}
function stopAnimation2(ended) {
animating2 = false;
startButton2.textContent = 'Start Animation';
// if animation cancelled set the marker at the beginning
var coord = ended ? routeCoords2[routeLength2 - 1] : routeCoords2[0];
/** @type {ol.geom.Point} */
(geoMarker2.getGeometry())
.setCoordinates(coord);
//remove listener
map2.un('postcompose', moveFeature2);
}
startButton2.addEventListener('click', startAnimation2, false);
<script src="https://openlayers.org/en/v3.20.1/build/ol.js"></script>
<link href="https://openlayers.org/en/v3.20.1/css/ol.css" rel="stylesheet"/>
<h1>
Map 1
</h1>
<div id="map1" class="map"></div>
<label for="speed1">
speed:
<input id="speed1" type="range" min="10" max="999" step="10" value="60">
</label>
<button id="start-animation1">Start Animation</button>
<h1>
Map 2
</h1>
<div id="map2" class="map"></div>
<label for="speed2">
speed:
<input id="speed2" type="range" min="10" max="999" step="10" value="60">
</label>
<button id="start-animation2">Start Animation</button>