Добавление изображения вместе с анимированной строкой - PullRequest
0 голосов
/ 11 апреля 2019

Я пытаюсь добавить стиль изображения / значка вдоль анимируемой строки, но стиль изображения / значка не добавляется.

Вот мой стиль для линии

var lineStyle = new ol.style.Style({
    image: new ol.style.Icon(({
        opacity: 1,
        size: 20,
        src: '/Images/Leaflet.custom.marker/red_animation_marker.png'
    })),
    stroke: new ol.style.Stroke({
        color: 'black',
        width: 5,
        lineDash: [10,5],
    })
});

См. Следующую ссылку анимацию строки для получения токового выхода.

То, чего я пытаюсь добиться, - это наличие маркера или указателя в начале строки, который будет указывать, что линия следует за определеннымпуть, значок стрелки или стиль.

1 Ответ

1 голос
/ 11 апреля 2019

Вам необходим отдельный стиль для значка, который включает в себя геометрию (которая будет текущей точкой на линии). Вы также можете рассчитать угол, чтобы выровнять значок на основе этой и предыдущей точки.

var blue = new ol.style.Style({
  stroke: new ol.style.Stroke({
width: 6,
color: 'blue'
  })
});

var red = new ol.style.Style({
  stroke: new ol.style.Stroke({
width: 2,
color: 'red'
  })
});

var style = function(feature) {
  var styles = [red];
  coords = feature.getGeometry().getCoordinates().slice(-2);
  styles.push(
new ol.style.Style({
  geometry: new ol.geom.Point(coords[1]),
  image: new ol.style.Icon({
    src: 'https://cdn1.iconfinder.com/data/icons/basic-ui-elements-color-round/3/19-32.png',
    rotation: Math.atan2(coords[1][0]-coords[0][0], coords[1][1]-coords[0][1])
  })
})
  )
  return styles;
}

var raster = new ol.layer.Tile({
  source: new ol.source.OSM()
});

var vector = new ol.layer.Vector({
  source: new ol.source.Vector(),
  style: blue
});

var map = new ol.Map({
  layers: [raster, vector],
  target: 'map',
  view: new ol.View()
});

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://raw.githubusercontent.com/IvanSanchez/Leaflet.Polyline.SnakeAnim/master/route.js');
xhr.onload = function() {
  // read the route coordinates
  eval(xhr.responseText);
  // reverse the route
  var geom = new ol.geom.LineString(route.reverse());
  // change Lat/Lon to Lon/Lat
  geom.applyTransform(function(c){ return c.reverse(); });
  geom.transform('EPSG:4326', map.getView().getProjection());
  vector.getSource().addFeature(new ol.Feature(geom));  

  map.getView().fit(geom, { size: map.getSize() });
  var snake = new ol.Feature();
  snake.setStyle(style);
  vector.getSource().addFeature(snake);
  var snakeKey = animate_line(snake, geom, 30000, red);

  map.once('singleclick', function() {
ol.Observable.unByKey(snakeKey);
vector.getSource().removeFeature(snake);
  });

}
xhr.send();

function animate_line(feature, linestring, duration, completionStyle) {

  var length = linestring.getLength();
  var length_shown = 0;

  var coords = linestring.getCoordinates();
  var coords_shown = [coords[0], coords[0]];
  var geom_shown = new ol.geom.LineString(coords_shown);
  feature.setGeometry(geom_shown);

  var coordcount = 1;
  var start = new Date().getTime();
  var listenerKey = map.on('postcompose', animate);

  function animate() {

var elapsed = new Date().getTime() - start;
var toAdd = length*elapsed/duration - length_shown;
var point = linestring.getCoordinateAt(Math.min(elapsed/duration, 1));

// restart from last intermediate point and remove it
var newPart = new ol.geom.LineString(coords_shown.slice(-1));
coords_shown.pop();

// add vertices until required length exceeded
while (coordcount < coords.length && newPart.getLength() <= toAdd) {
  newPart.appendCoordinate(coords[coordcount]);
  coords_shown.push(coords[coordcount]);
  coordcount++;
}

// replace overrun vertex with intermediate point
coords_shown.pop();
coordcount--;
coords_shown.push(point);

geom_shown.setCoordinates(coords_shown);
length_shown += toAdd;

if (elapsed > duration) {
  feature.setStyle(completionStyle);
  ol.Observable.unByKey(listenerKey);
}
map.render();

  }

  return listenerKey;

}

/*
draw = new ol.interaction.Draw({
  source: vector.getSource(),
  type: 'LineString'
});

draw.on('drawend',function(evt){
  geom = evt.feature.getGeometry();
  evt.feature.setGeometry(undefined);
  animate_line(evt.feature, geom, 6000);
});
map.addInteraction(draw);
*/
html, body, .map {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id="map" class="map"></div>

Тот же фрагмент плюс несколько полигонов:

var blue = new ol.style.Style({
  stroke: new ol.style.Stroke({
width: 6,
color: 'blue'
  })
});

var red = new ol.style.Style({
  stroke: new ol.style.Stroke({
width: 2,
color: 'red'
  })
});

var style = function(feature) {
  var styles = [red];
  coords = feature.getGeometry().getCoordinates().slice(-2);
  styles.push(
new ol.style.Style({
  geometry: new ol.geom.Point(coords[1]),
  image: new ol.style.Icon({
    src: 'https://cdn1.iconfinder.com/data/icons/basic-ui-elements-color-round/3/19-32.png',
    rotation: Math.atan2(coords[1][0]-coords[0][0], coords[1][1]-coords[0][1])
  })
})
  )
  return styles;
}

var raster = new ol.layer.Tile({
  source: new ol.source.OSM()
});

var vector = new ol.layer.Vector({
  source: new ol.source.Vector(),
  style: function(feature) {
if (feature.getGeometry().getType() == 'Polygon') {
  return feature.get('reached') ? red : [];
}
return blue
  }
});

var map = new ol.Map({
  layers: [raster, vector],
  target: 'map',
  view: new ol.View()
});

var poly = new ol.geom.Polygon([[[0,40], [10,60], [20,40], [10,20], [0,40]]]);
var polygons = [];
for (var i=0; i<4; i++) {
  var poly2 = poly.clone();
  poly2.translate(i*30, 0);
  polygons.push(new ol.Feature(poly2.transform('EPSG:4326', map.getView().getProjection())));
}
vector.getSource().addFeatures(polygons);

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://raw.githubusercontent.com/IvanSanchez/Leaflet.Polyline.SnakeAnim/master/route.js');
xhr.onload = function() {
  // read the route coordinates
  eval(xhr.responseText);
  // reverse the route
  var geom = new ol.geom.LineString(route.reverse());
  // change Lat/Lon to Lon/Lat
  geom.applyTransform(function(c){ return c.reverse(); });
  geom.transform('EPSG:4326', map.getView().getProjection());
  vector.getSource().addFeature(new ol.Feature(geom));  

  map.getView().fit(geom, { size: map.getSize() });
  var snake = new ol.Feature();
  snake.setStyle(style);
  vector.getSource().addFeature(snake);
  var snakeKey = animate_line(snake, geom, 30000, red);

  map.once('singleclick', function() {
ol.Observable.unByKey(snakeKey);
vector.getSource().removeFeature(snake);
  });

}
xhr.send();

function animate_line(feature, linestring, duration, completionStyle) {

  var length = linestring.getLength();
  var length_shown = 0;

  var coords = linestring.getCoordinates();
  var coords_shown = [coords[0], coords[0]];
  var geom_shown = new ol.geom.LineString(coords_shown);
  feature.setGeometry(geom_shown);

  var coordcount = 1;
  var start = new Date().getTime();
  var listenerKey = map.on('postcompose', animate);

  function animate() {

var elapsed = new Date().getTime() - start;
var toAdd = length*elapsed/duration - length_shown;
var point = linestring.getCoordinateAt(Math.min(elapsed/duration, 1));

for (var i=0; i<polygons.length; i++) {
   if (!polygons[i].get('reached') && polygons[i].getGeometry().intersectsCoordinate(point)) {
     polygons[i].set('reached', true);
   }
}

// restart from last intermediate point and remove it
var newPart = new ol.geom.LineString(coords_shown.slice(-1));
coords_shown.pop();

// add vertices until required length exceeded
while (coordcount < coords.length && newPart.getLength() <= toAdd) {
  newPart.appendCoordinate(coords[coordcount]);
  coords_shown.push(coords[coordcount]);
  coordcount++;
}

// replace overrun vertex with intermediate point
coords_shown.pop();
coordcount--;
coords_shown.push(point);

geom_shown.setCoordinates(coords_shown);
length_shown += toAdd;

if (elapsed > duration) {
  feature.setStyle(completionStyle);
  ol.Observable.unByKey(listenerKey);
}
map.render();

  }

  return listenerKey;

}
html, body, .map {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id="map" class="map"></div>
...