Math.abs(endValue-value)) {
closestIndex = endIndex;
} else {
closestIndex = startIndex;
}
return closestIndex;
}
var midIndex : int = (endIndex + startIndex) / 2;
var midValue : Number = elevationData[midIndex].x;
if (midValue > value) {
return binarySearch(value, startIndex, midIndex-1);
} else if (midValue < value) {
return binarySearch(value, midIndex+1, endIndex);
} else {
return midIndex;
}
}
private function chartToolTip(e:HitData) : String {
var nf : NumberFormatter = new NumberFormatter();
nf.precision = 2;
var s:String;
s = "" + LineSeries(e.element).displayName + "\n";
s += "Distance: " + nf.format(e.item.x) + " miles\n";
s += "Time: " + nf.format(e.item.time) + " decimal hours\n";
s += "Elevation: " + nf.format(e.item.y) + " feet\n";
nf.precision = 4;
s += "Latitude: " + nf.format(e.item.lat) + " degrees\n";
s += "Longitude: " + nf.format(e.item.lon) + " degrees\n";
var u:URLRequest = new URLRequest("javascript:centerMap('" + e.item.lat + "','" + e.item.lon + "')");
navigateToURL(u,"_self");
return s;
}
private function distance(point1: Object, point2 : Object) : Number {
var lat1 : Number;
var lat2 : Number;
var lon1 : Number;
var lon2 : Number;
if (point1 == null) return 0;
// convert degrees to radians
lat1 = point1.lat * Math.PI / 180.0;
lat2 = point2.lat * Math.PI / 180.0;
lon1 = point1.lon * Math.PI / 180.0;
lon2 = point2.lon * Math.PI / 180.0;
// radius of earth in Kilometers converted to miles
var radius : Number = 6378.1 * 0.621371192;
var latDist : Number = lat2 - lat1;
var lonDist : Number = lon2 - lon1;
var sinLatDist : Number = Math.sin(latDist/2.0);
var sinLonDist : Number = Math.sin(lonDist / 2.0);
var a : Number = sinLatDist * sinLatDist + Math.cos(lat1) * Math.cos(lat2) * sinLonDist * sinLonDist;
var c : Number = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var distance : Number = radius * c;
return distance;
}
private var gpx:XML = new XML();
private var myLoader:URLLoader;
private function loadData() : void {
var myXMLURL:URLRequest = new URLRequest(gpxUrl);
myLoader = new URLLoader(myXMLURL);
myLoader.addEventListener("complete", xmlLoaded);
var u:URLRequest = new URLRequest("javascript:getGpxDistance()");
navigateToURL(u,"_self");
}
[Bindable]
public var computedDistance : Number = 0;
[Bindable]
public var computedDistanceLabel : String = "";
private function xmlLoaded(evtObj:Event) : void {
gpx = XML(myLoader.data);
trace("Data loaded:" + gpxUrl);
var ed : ArrayCollection = new ArrayCollection();
var firstTimePoint : Number = 0;
var prevItem : Object;
for each (var trkpt:XML in gpx..trkpt) {
var item : Object = new Object();
var ele : Number = Number(trkpt.ele);
if (elevationMin == -1 ) {
elevationMin = ele;
} else {
elevationMin = Math.min(elevationMin, ele);
}
if (elevationMax == -1) {
elevationMax = ele;
} else {
elevationMax = Math.max(elevationMax, ele);
}
var time : String = trkpt.time;
var dt : Number = getDecimalTime(time);
if (firstTimePoint == 0) {
firstTimePoint = dt;
}
dt -= firstTimePoint;
if (timeMin == -1) {
timeMin = dt;
} else {
timeMin = Math.min(dt, timeMin);
}
if (timeMax == -1) {
timeMax = dt;
} else {
timeMax = Math.max(dt, timeMax);
}
var lat : String = trkpt.@lat;
var lon : String = trkpt.@lon;
item.time = dt;
// convert meters to feet
item.y = ele * 3.28;
item.lat = lat;
item.lon = lon;
item.x = distance(prevItem, item);
computedDistance += item.x;
item.x = computedDistance;
ed.addItem(item);
prevItem = item;
trace(item.x + ", " + item.y + ", " + item.time);
}
// convert meters to feet
elevationMax *= 3.28;
elevationMin *= 3.28;
var minPoint : Object = new Object();
var maxPoint : Object = new Object();
minPoint.x = 0; //timeMax;
minPoint.y = 0;
maxPoint.x = 0; //timeMax;
maxPoint.y = elevationMax;
timeLineData.addItem(minPoint);
timeLineData.addItem(maxPoint);
var nf : NumberFormatter = new NumberFormatter();
nf.precision = 2;
minElevationLabel = "Min. Elevation: " + nf.format(elevationMin) + " feet";
maxElevationLabel = "Max. Elevation: " + nf.format(elevationMax) + " feet";
elevationData = ed;
computedDistanceLabel = "Distance: " + nf.format(computedDistance) + " miles";
}
private function getDecimalTime(date:String) : Number {
var hour : int = Number(date.substr(11,2));
var minute : int = Number(date.substr(14,2));
var second : int = Number(date.substr(17,2));
var decimalTime : Number = hour + minute/60 + second/3600;
return decimalTime;
}
private var elevationChartLength : int = elevationData.toArray().length - 1;
private function animate() : void {
var timer : Timer = new Timer(elevationChartLength);
timer.addEventListener("timer", onTimer);
timer.start();
}
public function onTimer(event:TimerEvent) : void {
var i : int = event.target.currentCount - 1;
var v : String = elevationData.getItemAt(i)["x"];
sliderMove(v);
}
[Bindable]
private var routeTitle : String = "";
private var gpxUrl : String;
public function setGpxDataSource(value:String, title:String):void {
gpxUrl = value;
routeTitle = title;
loadData();
}
[Bindable]
private var gpxDistance : Number;
[Bindable]
private var gpxDistanceLabel : String;
public function setGpxDistance(value : Number) : void {
gpxDistance = value * 0.0006
var nf : NumberFormatter = new NumberFormatter();
nf.precision = 2;
gpxDistanceLabel = "Google Distance: " + nf.format(gpxDistance) + " miles";
}
public function initApp() : void {
ExternalInterface.addCallback("setDataSource", setGpxDataSource);
ExternalInterface.addCallback("setDistance", setGpxDistance);
var u:URLRequest = new URLRequest("javascript:getGpxUrl()");
navigateToURL(u,"_self");
slider.callback = sliderMove;
}
public function sliderChange(event: Event) : void {
sliderMove(event.currentTarget.value);
}
public function startPlayer(goback: Boolean) : void {
pauseButton.enabled = true;
pauseButton.visible = true;
resumeButton.visible = false;
myMove.play(null, goback);
}
public function stopPlayer() : void {
pauseButton.enabled = true;
pauseButton.visible = true;
resumeButton.visible = false;
myMove.pause();
myMove.play(null, true);
}
public function pausePlayer() : void {
pauseButton.visible = false;
resumeButton.visible = true;
resumeButton.enabled = true;
myMove.pause();
}
public function resumePlayer() : void {
pauseButton.visible = true;
resumeButton.visible = false;
pauseButton.enabled = true;
myMove.resume();
}
]]>