Source Code for JavaScript Mapping Tools: wayPoint.js

Source code of a graphical tool for drawing and computing distances over Google maps.

Run Tool | index.html | main.css | formatters.js | geoCircle.js | geoCode.js | geo.js | index.js | mapControls.js | tableManager.js | util.js | wayPoint.js | wayPointsManager.js


// Copyright 2006-2008 (c) Paul Demers  <paul@acscdg.com>

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA., or visit one 
// of the links here:
//  http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
//  http://www.acscdg.com/LICENSE.txt

//////////////////////////////////////////////////////////////////

//
//  map drawing and distance tools.

// Web site with this code running: http://www.acscdg.com/


// Way point object.  Manages a single way point.

// Dependency on other modules:
//  geo.js (for EarthVector)
//  formatters.js
//  Google maps (for geo point object).
//  needs access to the document root.


//
//// Renders a way point into an HTML TR element.
function wayPointToElement(distanceUnits)
{

  var trElement = document.createElement("tr");

  // Allow different formats for odd and even rows, for example to shade them
  //  differently for legibility.  The classes are defined in a CSS file.
  var isEven = (Math.round(this.pointNumber / 2) * 2) == this.pointNumber;
  if (isEven)
    trElement.className = "ptsroweven";
  else
    trElement.className = "ptsrowodd";

  var tdElement;

  var distanceMultiplier = getDistanceMultiplier(distanceUnits);

  tdElement = document.createElement("td");
  tdElement.appendChild(document.createTextNode(this.courseNumber.toString()));
  tdElement.className = "numcol";
  trElement.appendChild(tdElement);  // 0

  tdElement = document.createElement("td");
  tdElement.appendChild(document.createTextNode(this.pointNumber.toString()));
  tdElement.className = "numcol";
  trElement.appendChild(tdElement); // 1

  tdElement = document.createElement("td");
  tdElement.appendChild(document.createTextNode(myLatToString(this.point)));
  tdElement.className = "llcol";
  trElement.appendChild(tdElement);  // 2

  tdElement = document.createElement("td");
  tdElement.appendChild(document.createTextNode(myLngToString(this.point)));
  tdElement.className = "llcol";
  trElement.appendChild(tdElement); // 3

  var distanceString;
  var azimuthString;
  if (this.vectorFromLastPoint == null)
  {
    distanceString = " ";
    azimuthString = " ";
    totalDistanceString = " ";
  }
  else
  {
    distanceString = formatFloat(this.vectorFromLastPoint.distanceNM * distanceMultiplier);
    azimuthString = (Math.round(this.vectorFromLastPoint.azimuthDegrees)).toString();
   totalDistanceString = formatFloat(this.totalDistanceNM * distanceMultiplier);
  }

  tdElement = document.createElement("td");
  tdElement.appendChild(document.createTextNode(distanceString));  // distance
  tdElement.className = "distcol";
  trElement.appendChild(tdElement);  // 4

  tdElement = document.createElement("td");
  tdElement.appendChild(document.createTextNode(azimuthString));  // Azimuth deg.
  tdElement.className = "distcol";
  trElement.appendChild(tdElement);  // 5

  tdElement = document.createElement("td");
  tdElement.appendChild(document.createTextNode(totalDistanceString));  // Total distance.
  tdElement.className = "distcol";
  trElement.appendChild(tdElement);  // 6

  return trElement;
}


//
//// Updates an existing TR element, faster then drawing new.
function wayPointUpdateElement(distanceUnits)
{
  // Replace the lat, lng, az., and dists from a trElement with those from
  //  this waypoint.  used for fast redraws of the table.

  // child 0 is course number.
  // child 1 is point number.
  var tdElement = this.tableRowElement.childNodes[2]; // lat.
  tdElement.replaceChild(document.createTextNode(myLatToString(this.point)), tdElement.childNodes[0]);

  tdElement = this.tableRowElement.childNodes[3]; // lng.
  tdElement.replaceChild(document.createTextNode(myLngToString(this.point)), tdElement.childNodes[0]);

  // since this is assumed to be the same point number,
  //  if vectorFromLastPoint was null before, then it's still null now, so no need to replace spaces.
  if (this.vectorFromLastPoint != null)
  { 
    var distanceMultiplier = getDistanceMultiplier(distanceUnits);

    tdElement = this.tableRowElement.childNodes[4]; // dist
    tdElement.replaceChild(document.createTextNode(
      formatFloat(this.vectorFromLastPoint.distanceNM * distanceMultiplier)), tdElement.childNodes[0]);

    tdElement = this.tableRowElement.childNodes[5]; // azimuth
    tdElement.replaceChild(document.createTextNode(
      Math.round(this.vectorFromLastPoint.azimuthDegrees)), tdElement.childNodes[0]);

    tdElement = this.tableRowElement.childNodes[6]; // total dist.
    tdElement.replaceChild(document.createTextNode(
      formatFloat(this.totalDistanceNM * distanceMultiplier)), tdElement.childNodes[0]);
  }

  return this.tableRowElement;
}


//
////
function wayPointUpdate(map, point, distanceUnits)
{
  if (this.courseLine != null)
  {
    map.removeOverlay(this.courseLine);
    this.courseLine = null;
  }

  // TODO: Check that point is really different.
  this.point = point;

  if (this.lastWayPoint != null)
  {
    var bestCourse = new BestCourse(this.lastWayPoint.point, point);
    this.vectorFromLastPoint = bestCourse.getVector();

    this.totalDistanceNM = this.lastWayPoint.totalDistanceNM + this.vectorFromLastPoint.distanceNM;
    this.courseLine = bestCourse.getLine();
    map.addOverlay(this.courseLine);
  }
  else
  {
    this.totalDistanceNM = 0;
    this.vectorFromLastPoint = null;
    // courseLine set to null, above.
  }

  if (this.tableRowElement != null)
    this.updateElement(distanceUnits);
  else
    this.tableRowElement = this.toElement(distanceUnits);
}


//
////
function WayPoint(map, courseNumber, pointNumber, point, lastWayPoint, distanceUnits)
{
  this.toElement = wayPointToElement;
  this.updateElement = wayPointUpdateElement;
  this.update = wayPointUpdate;

  this.courseNumber = courseNumber;
  this.pointNumber = pointNumber;
  this.lastWayPoint = lastWayPoint;

  this.name = pointNumber.toString();

  this.update(map, point, distanceUnits);
}