如何在页面中添加2个OpenLayer标记动画? Clickevent似乎被覆盖了

时间:2017-01-11 10:24:28

标签: javascript jquery html flask openlayers-3

我在我的(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”。这没有做到这一点,也没有类似地重命名所有变量。

1 个答案:

答案 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:&nbsp;
  <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:&nbsp;
  <input id="speed2" type="range" min="10" max="999" step="10" value="60">
</label>
<button id="start-animation2">Start Animation</button>