问题描述
我正在使用开放层,我偶然发现了一个问题。
要进一步说明,请查看下面的示例:
https://openlayers.org/en/latest/examples/feature-move-animation.html
点击开始动画时,标记会移动,但是会保留标记经过的黄线,我想在标记移动时删除标记后面的那条线。
如何使用OpenLayers?
解决方法
从the example referenced开始,一种选择是添加新行Feature
,然后更新其坐标以删除已经遍历的坐标
-
添加新的
Polyline
:// new line feature (polyline) var lineCoords = route.getCoordinates(); var lineFeature = new ol.Feature({ type: 'line',geometry: route.clone() });
-
将新功能添加到矢量层:
var vectorLayer = new ol.layer.Vector({ // VectorLayer({ source: new ol.source.Vector({ // VectorSource({ features: [geoMarker,startMarker,endMarker,lineFeature],
-
在moveFeature函数中,更新线的坐标以删除已经遍历的坐标:
var moveFeature = function (event) { // ... var currentPoint = new ol.geom.Point(routeCoords[index]); coords=routeCoords.slice(index); lineFeature.getGeometry().setCoordinates(coords);
代码段:
// This long string is placed here due to jsFiddle limitations.
// It is usually loaded with AJAX.
var polyline = [
'hldhx@lnau`BCG_EaC??cFjAwDjF??uBlKMd@}@z@??aC^yk@z_@se@b[wFdE??wFfE}N','fIoGxB_I\\gG}@eHoCyTmPqGaBaHOoD\\??yVrGotA|N??o[N_STiwAtEmHGeHcAkiA}^','aMyBiHOkFNoI`CcVvM??gG^gF_@iJwC??eCcA]OoL}DwFyCaCgCcCwDcGwHsSoX??wI_E','kUFmq@hBiOqBgTwS??iYse@gYq\\cp@ce@{vA}s@csJqaE}{@iRaqE{lBeRoIwd@_T{]_','Ngn@{PmhEwaA{SeF_u@kQuyAw]wQeEgtAsZ}LiCarAkVwI}D??_}RcjEinPspDwSqCgs@','sPua@_OkXaMeT_Nwk@ob@gV}TiYs[uTwXoNmT{Uyb@wNg]{Nqa@oDgNeJu_@_G}YsFw]k','DuZyDmm@i_@uyIJe~@jCg|@nGiv@zUi_BfNqaAvIow@dEed@dCcf@r@qz@Egs@{Acu@mC','um@yIey@gGig@cK_m@aSku@qRil@we@{mAeTej@}Tkz@cLgr@aHko@qOmcEaJw~C{w@ka','i@qBchBq@kmBS{kDnBscBnFu_Dbc@_~QHeU`IuyDrC_}@bByp@fCyoA?qMbD}{AIkeAgB','k_A_A{UsDke@gFej@qH{o@qGgb@qH{`@mMgm@uQus@kL{_@yOmd@ymBgwE}x@ouBwtA__','DuhEgaKuWct@gp@cnBii@mlBa_@}|Asj@qrCg^eaC}L{dAaJ_aAiOyjByH{nAuYu`GsAw','Xyn@ywMyOyqD{_@cfIcDe}@y@aeBJmwA`CkiAbFkhBlTgdDdPyiB`W}xDnSa}DbJyhCrX','itAhT}x@bE}Z_@qW_Kwv@qKaaAiBgXvIm}A~JovAxCqW~WanB`XewBbK{_A`K}fBvAmi@','xBycBeCauBoF}}@qJioAww@gjHaPopA_NurAyJku@uGmi@cDs[eRaiBkQstAsQkcByNma','CsK_uBcJgbEw@gkB_@ypEqDoqSm@eZcDwjBoGw`BoMegBaU_`Ce_@_uBqb@ytBwkFqiT_','fAqfEwe@mfCka@_eC_UmlB}MmaBeWkkDeHwqAoX}~DcBsZmLcxBqOwqE_DkyAuJmrJ\\o','~CfIewG|YibQxBssB?es@qGciA}RorAoVajA_nAodD{[y`AgPqp@mKwr@ms@umEaW{dAm','b@umAw|@ojBwzDaaJsmBwbEgdCsrFqhAihDquAi`Fux@}_Dui@_eB_u@guCuyAuiHukA_','lKszAu|OmaA{wKm}@clHs_A_rEahCssKo\\sgBsSglAqk@yvDcS_wAyTwpBmPc|BwZknF','oFscB_GsaDiZmyMyLgtHgQonHqT{hKaPg}Dqq@m~Hym@c`EuiBudIabB{hF{pWifx@snA','w`GkFyVqf@y~BkoAi}Lel@wtc@}`@oaXi_C}pZsi@eqGsSuqJ|Lqeb@e]kgPcaAu}SkDw','zGhn@gjYh\\qlNZovJieBqja@ed@siO{[ol\\kCmjMe\\isHorCmec@uLebB}EqiBaCg}','@m@qwHrT_vFps@kkI`uAszIrpHuzYxx@e{Crw@kpDhN{wBtQarDy@knFgP_yCu\\wyCwy','A{kHo~@omEoYmoDaEcPiuAosDagD}rO{{AsyEihCayFilLaiUqm@_bAumFo}DgqA_uByi','@swC~AkzDlhA}xEvcBa}Cxk@ql@`rAo|@~bBq{@``Bye@djDww@z_C_cAtn@ye@nfC_eC','|gGahH~s@w}@``Fi~FpnAooC|u@wlEaEedRlYkrPvKerBfYs}Arg@m}AtrCkzElw@gjBb','h@woBhR{gCwGkgCc[wtCuOapAcFoh@uBy[yBgr@c@iq@o@wvEv@sp@`FajBfCaq@fIipA','dy@ewJlUc`ExGuaBdEmbBpBssArAuqBBg}@s@g{AkB{bBif@_bYmC}r@kDgm@sPq_BuJ_','s@{X_{AsK_d@eM{d@wVgx@oWcu@??aDmOkNia@wFoSmDyMyCkPiBePwAob@XcQ|@oNdCo','SfFwXhEmOnLi\\lbAulB`X_d@|k@au@bc@oc@bqC}{BhwDgcD`l@ed@??bL{G|a@eTje@','oS~]cLr~Bgh@|b@}Jv}EieAlv@sPluD{z@nzA_]`|KchCtd@sPvb@wSb{@ko@f`RooQ~e','[upZbuIolI|gFafFzu@iq@nMmJ|OeJn^{Qjh@yQhc@uJ~j@iGdd@kAp~BkBxO{@|QsAfY','gEtYiGd]}Jpd@wRhVoNzNeK`j@ce@vgK}cJnSoSzQkVvUm^rSgc@`Uql@xIq\\vIgg@~k','Dyq[nIir@jNoq@xNwc@fYik@tk@su@neB}uBhqEesFjoGeyHtCoD|D}Ed|@ctAbIuOzqB','_}D~NgY`\\um@v[gm@v{Cw`G`w@o{AdjAwzBh{C}`Gpp@ypAxn@}mAfz@{bBbNia@??jI','ab@`CuOlC}YnAcV`@_^m@aeB}@yk@YuTuBg^uCkZiGk\\yGeY}Lu_@oOsZiTe[uWi[sl@','mo@soAauAsrBgzBqgAglAyd@ig@asAcyAklA}qAwHkGi{@s~@goAmsAyDeEirB_{B}IsJ','uEeFymAssAkdAmhAyTcVkFeEoKiH}l@kp@wg@sj@ku@ey@uh@kj@}EsFmG}Jk^_r@_f@m','~@ym@yjA??a@cFd@kBrCgDbAUnAcBhAyAdk@et@??kF}D??OL'
].join('');
var route = /** @type {import("../src/ol/geom/LineString.js").default} */ (new ol.format.Polyline({
factor: 1e6,}).readGeometry(polyline,{
dataProjection: 'EPSG:4326',featureProjection: 'EPSG:3857',}));
var routeCoords = route.getCoordinates();
var routeLength = routeCoords.length;
var routeFeature = new ol.Feature({
type: 'route',geometry: route,});
var lineCoords = route.getCoordinates();
var lineFeature = new ol.Feature({
type: 'line',geometry: route.clone()
});
var geoMarker = /** @type Feature<import("../src/ol/geom/Point").default> */ (new ol.Feature({
type: 'geoMarker',geometry: new ol.geom.Point(routeCoords[0]),}));
var startMarker = new ol.Feature({
type: 'icon',});
var endMarker = new ol.Feature({
type: 'icon',geometry: new ol.geom.Point(routeCoords[routeLength - 1]),});
var styles = {
'line': new ol.style.Style({
stroke: new ol.style.Stroke({
width: 6,color: "blue",}),'route': new ol.style.Style({
stroke: new ol.style.Stroke({
width: 6,color: [237,212,0.8],'icon': new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5,1],src: 'https://openlayers.org/en/v4.6.5/examples/data/icon.png','geoMarker': new ol.style.Style({
image: new ol.style.Circle({ // CircleStyle({
radius: 7,fill: new ol.style.Fill({
color: 'black'
}),stroke: new ol.style.Stroke({
color: 'white',width: 2,};
var animating = false;
var speed,now;
var speedInput = document.getElementById('speed');
var startButton = document.getElementById('start-animation');
var vectorLayer = new ol.layer.Vector({ // VectorLayer({
source: new ol.source.Vector({ // VectorSource({
features: [ /* routeFeature,*/ geoMarker,style: function(feature) {
// hide geoMarker if animation is active
if (animating && feature.get('type') === 'geoMarker') {
return null;
}
return styles[feature.get('type')];
},});
var key = 'otwSpfI7kCJve6AMTcr0';
var attributions =
'<a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> ' +
'<a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>';
var center = [-5639523.95,-3501274.52];
var map = new ol.Map({
target: document.getElementById('map'),view: new ol.View({
center: center,zoom: 10,minZoom: 2,maxZoom: 19,layers: [
new ol.layer.Tile({ // TileLayer({
source: new ol.source.XYZ({
attributions: attributions,url: 'https://api.maptiler.com/maps/hybrid/{z}/{x}/{y}.jpg?key=' + key,tileSize: 512,vectorLayer
],});
var moveFeature = function(event) {
var vectorContext = ol.render.getVectorContext(event);
var frameState = event.frameState;
if (animating) {
var elapsedTime = frameState.time - now;
// here the trick to increase speed is to jump some indexes
// on lineString coordinates
var index = Math.round((speed * elapsedTime) / 1000);
if (index >= routeLength) {
stopAnimation(true);
return;
}
var currentPoint = new ol.geom.Point(routeCoords[index]);
coords = routeCoords.slice(index);
lineFeature.getGeometry().setCoordinates(coords);
var feature = new ol.Feature(currentPoint);
vectorContext.drawFeature(feature,styles.geoMarker);
}
// tell OpenLayers to continue the postrender animation
map.render();
};
function startAnimation() {
if (animating) {
stopAnimation(false);
} else {
animating = true;
now = new Date().getTime();
speed = speedInput.value;
startButton.textContent = 'Cancel Animation';
// hide geoMarker
geoMarker.setStyle(null);
// just in case you pan somewhere else
map.getView().setCenter(center);
vectorLayer.on('postrender',moveFeature);
map.render();
}
}
/**
* @param {boolean} ended end of animation.
*/
function stopAnimation(ended) {
animating = false;
startButton.textContent = 'Start Animation';
// if animation cancelled set the marker at the beginning
var coord = ended ? routeCoords[routeLength - 1] : routeCoords[0];
var geometry = geoMarker.getGeometry();
geometry.setCoordinates(coord);
//remove listener
vectorLayer.un('postrender',moveFeature);
}
startButton.addEventListener('click',startAnimation,false);
html,body {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
.map {
height: 90%;
width: 100%;
}
<link rel="stylesheet" href="https://openlayers.org/en/v6.4.3/css/ol.css" type="text/css">
<!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
<script src="https://openlayers.org/en/v6.4.3/build/ol.js" type="text/javascript"></script>
<div id="map" class="map"></div>
<label for="speed">
speed:
<input id="speed" type="range" min="10" max="999" step="10" value="60">
</label>
<button id="start-animation">Start Animation</button>