+ gLastDrawnPoint = null;
+ gCurPosMapCache = undefined;
+ gTrackContext.clearRect(0, 0, gTrackCanvas.width, gTrackCanvas.height);
+ if (gTrack.length) {
+ for (var i = 0; i < gTrack.length; i++) {
+ drawTrackPoint(gTrack[i].coords.latitude, gTrack[i].coords.longitude,
+ (i + 1 >= gTrack.length));
+ }
+ }
+}
+
+function drawTrackPoint(aLatitude, aLongitude, lastPoint) {
+ var trackpoint = gps2xy(aLatitude, aLongitude);
+ // lastPoint is for optimizing (not actually executing the draw until the last)
+ trackpoint.optimized = (lastPoint === false);
+ var mappos = {x: Math.round((trackpoint.x - gPos.x) / gZoomFactor + gMapCanvas.width / 2),
+ y: Math.round((trackpoint.y - gPos.y) / gZoomFactor + gMapCanvas.height / 2)};
+
+ if (!gLastDrawnPoint || !gLastDrawnPoint.optimized) {
+ gTrackContext.strokeStyle = gTrackColor;
+ gTrackContext.fillStyle = gTrackContext.strokeStyle;
+ gTrackContext.lineWidth = gTrackWidth;
+ gTrackContext.lineCap = "round";
+ gTrackContext.lineJoin = "round";
+ }
+ if (!gLastDrawnPoint || gLastDrawnPoint == trackpoint) {
+ // This breaks optimiziation, so make sure to close path and reset optimization.
+ if (gLastDrawnPoint && gLastDrawnPoint.optimized)
+ gTrackContext.stroke();
+ gTrackContext.beginPath();
+ trackpoint.optimized = false;
+ gTrackContext.arc(mappos.x, mappos.y,
+ gTrackContext.lineWidth, 0, Math.PI * 2, false);
+ gTrackContext.fill();
+ }
+ else {
+ if (!gLastDrawnPoint || !gLastDrawnPoint.optimized) {
+ gTrackContext.beginPath();
+ gTrackContext.moveTo(Math.round((gLastDrawnPoint.x - gPos.x) / gZoomFactor + gMapCanvas.width / 2),
+ Math.round((gLastDrawnPoint.y - gPos.y) / gZoomFactor + gMapCanvas.height / 2));
+ }
+ gTrackContext.lineTo(mappos.x, mappos.y);
+ if (!trackpoint.optimized)
+ gTrackContext.stroke();
+ }
+ gLastDrawnPoint = trackpoint;
+}
+
+function drawCurrentLocation(trackPoint) {
+ var locpoint = gps2xy(trackPoint.coords.latitude, trackPoint.coords.longitude);
+ var circleRadius = Math.round(gCurLocSize / 2);
+ var mappos = {x: Math.round((locpoint.x - gPos.x) / gZoomFactor + gMapCanvas.width / 2),
+ y: Math.round((locpoint.y - gPos.y) / gZoomFactor + gMapCanvas.height / 2)};
+
+ undrawCurrentLocation();
+
+ // Cache overdrawn area.
+ gCurPosMapCache =
+ {point: locpoint,
+ radius: circleRadius,
+ data: gTrackContext.getImageData(mappos.x - circleRadius,
+ mappos.y - circleRadius,
+ circleRadius * 2, circleRadius * 2)};
+
+ gTrackContext.strokeStyle = gCurLocColor;
+ gTrackContext.fillStyle = gTrackContext.strokeStyle;
+ gTrackContext.beginPath();
+ gTrackContext.arc(mappos.x, mappos.y,
+ circleRadius, 0, Math.PI * 2, false);
+ gTrackContext.fill();
+}
+
+function undrawCurrentLocation() {
+ if (gCurPosMapCache) {
+ var oldpoint = gCurPosMapCache.point;
+ var oldmp = {x: Math.round((oldpoint.x - gPos.x) / gZoomFactor + gMapCanvas.width / 2),
+ y: Math.round((oldpoint.y - gPos.y) / gZoomFactor + gMapCanvas.height / 2)};
+ gTrackContext.putImageData(gCurPosMapCache.data,
+ oldmp.x - gCurPosMapCache.radius,
+ oldmp.y - gCurPosMapCache.radius);
+ gCurPosMapCache = undefined;
+ }