【问题标题】:Add animated PNG. to polyline in google maps API添加动画PNG。谷歌地图API中的折线
【发布时间】:2019-12-08 04:06:19
【问题描述】:

我正在尝试为多段线上的图标设置动画,如下例所示:https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/overlay-symbol-animate

它可以工作,但我想添加我自己的 PNG 作为动画图标。这是我尝试过的:

        var line = new google.maps.Polyline({
            path: [{ lat: 25.774266, lng: -80.193659 }, { lat: 25.83333, lng: 25.83333 - 77.8999964 }],
            icons: [{
                icon: CruiseShip //This is my .PNG file
            }],
            strokeColor: '#ffffff',
            strokeWeight: 1,
            map: map
        });

        function animateCircle(line) {
            var count = 0;
            window.setInterval(function () {
                count = (count + 1) % 200;

                var icons = line.get('icons');
                icons[0].offset = (count / 2) + '%';
                line.set('icons', icons);
            }, 20);
        }

使用示例中的 lineSymbol 对象确实有效。如何将 .PNG 文件添加到折线而不是 lineSymbol?找不到任何关于此的文档。

【问题讨论】:

标签: google-maps-api-3


【解决方案1】:

您尝试为图标设置动画的方式仅适用于 SVG 符号。

Mike Williams 为 Google Maps Javascript API v2(现已弃用并关闭)编写了一个名为 epoly 的扩展,其中包含方法 .GetPointAtDistance,可用于更新“正常”图标的位置一条折线。

google.maps.geometry.spherical 库中有一个 interpolate 方法可以在两点之间进行插值,但对于大规模特征来说不是很准确。

proof of concept fiddle

代码 sn-p:

// This example creates a 2-pixel-wide red polyline showing the path of
// the first trans-Pacific flight between Oakland, CA, and Brisbane,
// Australia which was made by Charles Kingsford Smith.

function initMap() {
  updatePolylinePrototype();
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 3,
    center: {
      lat: 0,
      lng: -180
    },
    mapTypeId: 'terrain'
  });

  var line = new google.maps.Polyline({
    path: [{
      lat: 25.774266,
      lng: -80.193659
    }, {
      lat: 25.83333,
      lng: 25.83333 - 77.8999964
    }, {
      lat: 28.411413,
      lng: -16.5449611
    }],
    strokeColor: '#ffffff',
    strokeWeight: 1,
    map: map
  });
  var marker = new google.maps.Marker({
    icon: {
      url: "http://earth.google.com/images/kml-icons/track-directional/track-12.png",
      anchor: new google.maps.Point(12, 12),
      scaledSize: new google.maps.Size(24, 24),
    },
    position: line.getPath().getAt(0),
    map: map
  })

  var bounds = new google.maps.LatLngBounds();
  for (var i = 0; i < line.getPath().getLength(); i++) {
    bounds.extend(line.getPath().getAt(i));
  }
  map.fitBounds(bounds);
  animateShip(line, marker);
}

function animateShip(line, marker) {
  var count = 0;
  var lineDistance = 0;
  for (var i = 1; i < line.getPath().getLength(); i++) {
    lineDistance += google.maps.geometry.spherical.computeDistanceBetween(line.getPath().getAt(i - 1), line.getPath().getAt(i))
  }

  window.setInterval(function() {
    count = (count + 1) % 200;

    marker.setPosition(line.GetPointAtDistance(lineDistance - (lineDistance * count / 200)));
  }, 20);
}

function updatePolylinePrototype() {
  // === A method which returns a GLatLng of a point a given distance along the path ===
  // === Returns null if the path is shorter than the specified distance ===
  google.maps.Polyline.prototype.GetPointAtDistance = function(metres) {
    // some awkward special cases
    if (metres == 0) return this.getPath().getAt(0);
    if (metres < 0) return null;
    if (this.getPath().getLength() < 2) return null;
    var dist = 0;
    var olddist = 0;
    for (var i = 1;
      (i < this.getPath().getLength() && dist < metres); i++) {
      olddist = dist;
      dist += google.maps.geometry.spherical.computeDistanceBetween(this.getPath().getAt(i), this.getPath().getAt(i - 1));
    }
    if (dist < metres) {
      return null;
    }
    var p1 = this.getPath().getAt(i - 2);
    var p2 = this.getPath().getAt(i - 1);
    var m = (metres - olddist) / (dist - olddist);
    return new google.maps.LatLng(p1.lat() + (p2.lat() - p1.lat()) * m, p1.lng() + (p2.lng() - p1.lng()) * m);
  }
}
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */

#map {
  height: 100%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=geometry">
</script>

【讨论】:

    猜你喜欢
    • 2013-05-23
    • 2013-07-25
    • 2015-12-12
    • 2015-07-12
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    相关资源
    最近更新 更多