我可以让Google Maps v3独立绘制折线吗?

时间:2014-09-23 13:11:02

标签: javascript google-maps google-maps-api-3 google-polyline

我正在尝试在Google地图(v3 API)上设置跟踪车辆的路径动画。我有4条折线:一条是灰色背景线,用于指示整条路线,另外3条用于指示前一小时的跟踪数据(过去10分钟为红色,10-30分钟为橙色,30-60分钟为黄色) )。

即使我为折线正确设置了zIndex,当我创建新的动画线并破坏旧的动画线时,灰色背景线会与其他线重叠(我在动画期间不会触摸此折线)。 / p>

它还严重降低了动画的性能,如果我禁用灰线,性能就好了。

我相信正在发生的事情是Google地图使用一个画布元素来绘制与该矩形相交的所有折线,因此它必须重绘该矩形中的所有折线,而不仅仅是我动画的那些。有没有办法让Google地图将它们放在单独的图层上,以便只重绘我想要重绘的图层?

更新:我创建了一个表现相当不错的sample,但确实展示了与其他行重叠的背景线。

HTML:

<button>Animate</button> <div id="slider"/>
<div id="map" style="height: 600px; margin-top: 20px;"/>

使用Javascript:

google.maps.LatLng.prototype.destinationPoint = function(brng, dist) {
   dist = dist / 6371;  
   brng = brng.toRad();

   var lat1 = this.lat().toRad(), lon1 = this.lng().toRad();

   var lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist) + 
                        Math.cos(lat1) * Math.sin(dist) * Math.cos(brng));

   var lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(dist) *
                                Math.cos(lat1), 
                                Math.cos(dist) - Math.sin(lat1) *
                                Math.sin(lat2));

   if (isNaN(lat2) || isNaN(lon2)) return null;

   return new google.maps.LatLng(lat2.toDeg(), lon2.toDeg());
}

Number.prototype.toRad = function() {
   return this * Math.PI / 180;
}

Number.prototype.toDeg = function() {
   return this * 180 / Math.PI;
}

var range_lines = {
    red: null,
    orange: null,
    yellow: null
};

var range_colors = {
    red: '#ff0000',
    orange: '#FFA500',
    yellow: '#FFFF00'
};

function onSlide(e, ui) {
    var end_minute = ui.value;
    var start_minute = Math.max(0, end_minute - 60);

    var line_points = [];
    var last_range = null;
    var last_point = null;

    for (var minute = start_minute; minute < end_minute; minute++) {
        var diff = Math.abs(end_minute - minute);
        var range = '';

        if (diff <= 10) {
            range = 'red';
        } else if (diff <= 30) {
            range = 'orange';
        } else {
            range = 'yellow';
        }

        if (range != last_range) {
            renderLine(line_points, last_range);
            line_points = [];
            last_range = range;
        }

        if (points_by_minute.hasOwnProperty(minute)) {
            for (var i = 0; i < points_by_minute[minute].length; i++) {
                line_points.push(points[points_by_minute[minute][i]]);
                last_point = points[points_by_minute[minute][i]];
            }
        }
    }

    marker.setPosition(last_point);
    renderLine(line_points, last_range);
}

function renderLine(line_points, range) {
    var line = new google.maps.Polyline({
        path: line_points,
        strokeColor: range_colors[range],
        strokeWeight: 3,
        map: map,
        zIndex: getZIndex(range)
    });

    if (range_lines[range] != null) {
        range_lines[range].setMap(null);
    }

    range_lines[range] = line;
}

function getZIndex(range) {
    switch (range) {
        case 'yellow':
            return 10;
        case 'orange':
            return 20;
        case 'red':
            return 30;
    }
}

var points = [];
var points_by_minute = {};
var map;
var marker;
var interval;

$(document).ready(function() {
    var start_point = new google.maps.LatLng(51.3767, -0.0960);
    var point = new google.maps.LatLng(51.3767, -0.0960);
    var minute = 0;
    var bearing = 0;
    var bounds = new google.maps.LatLngBounds()

    for (var i = 0; i < 5000; i++) {
        if (Math.random() > 0.5) {
            if (Math.random() > 0.5) {
                bearing += Math.round(Math.random() * 10);
            } else {
                bearing -= Math.round(Math.random() * 10);
            }
        }

        if (i != 0 && i % 12 == 0) {
            minute++;
        }

        if (!points_by_minute.hasOwnProperty(minute)) {
            points_by_minute[minute] = [];
        }

        points_by_minute[minute].push(points.length);

        point = point.destinationPoint(bearing, 0.01);
        points.push(point);
        bounds.extend(point);
    }

    for (var i = 0; i < 5000; i++) {
        if (i != 0 && i % 12 == 0) {
            minute++;
        }

        if (!points_by_minute.hasOwnProperty(minute)) {
            points_by_minute[minute] = [];
        }

        points_by_minute[minute].push(points.length);

        var latJitter = Math.random() / 10000;

        if (Math.random() > 0.5) {
            latJitter = -latJitter;            
        }

        var lngJitter = Math.random() / 10000;

        if (Math.random() > 0.5) {
            lngJitter = -lngJitter;            
        }

        point = new google.maps.LatLng(
            points[4999 - i].lat() + latJitter,
            points[4999 - i].lng() + lngJitter
        );
        points.push(point);
    }

    map = new google.maps.Map($('#map')[0], {
        center: start_point,
        zoom: 8,
        mapTypeId: google.maps.MapTypeId.SATELLITE
    });

    map.fitBounds(bounds);

    $('button').button().click(function() {
        if (interval) clearInterval(interval);

        var value = $('#slider').slider("option", "value");

        if (value == $('#slider').slider("option", "max")) {
            clearInterval(interval);
        }

        $('#slider').slider("option", "value", $('#slider').slider("option", "min"));

        interval = setInterval(animate, 10);
    });

    $('#slider').slider({
        min: 0,
        max: minute++,
        step: 1,
        value: 0,
        change: onSlide
    });

    new google.maps.Polyline({
        path: points,
        strokeColor: '#cccccc',
        strokeWeight: 1.5,
        map: map,
        zIndex: 1
    });

    marker = new google.maps.Marker({
        position: start_point,
        map: map
    });
});

function animate() {
    var value = $('#slider').slider("option", "value");
    value++;
    $('#slider').slider("option", "value", value);
    if (value == $('#slider').slider("option", "max")) {
        clearInterval(interval);
    }
}

0 个答案:

没有答案