/// <summary>
 /// get a location from a system.drawing point
 /// </summary>
 public Location getLocation(Point pt)
 {
     Location wpt = new Location();
     wpt.Easting = pt.X * _horizontalScale + _horizontalOffset;
     wpt.Northing = pt.Y * _verticalScale + _verticalOffset;
     return wpt;
 }
 public GpxParser(string fileName, TrackPath path)
 {
     try {
         StreamReader sr = new StreamReader(fileName);
         string file = sr.ReadToEnd();
         sr.Close();
         _doc = new XmlDocument();
         _doc.LoadXml(file);
         XmlNode node = _doc.ChildNodes[0];
         foreach (XmlNode n in _doc.ChildNodes) {
             if (n.Name == "gpx") { node = n; break; }
         }
         foreach (XmlNode n in node) {
             if (n.Name == "trk") { node = n; break; }
         }
         foreach (XmlNode n in node) {
             if (n.Name == "trkseg") { node = n; break; }
         }
         foreach (XmlNode n in node.ChildNodes) {
             if (n.Name == "trkpt") {
                 Location loc = new Location(double.Parse(n.Attributes[0].Value)
                 , double.Parse(n.Attributes[1].Value));
                 loc.Elevation = double.Parse(n.FirstChild.InnerText);
                 path.Locations.Add(loc);
             }
         }
         _status = "Read " + path.Locations.Count + " Locations";
     } catch (Exception e) {
         //_status = e.Message;
         _status = "Parsing error, cannot read input file.";
         path.Locations.Clear();
     }
 }
 /// <summary>
 /// constructor for directions generator
 /// </summary>
 /// <summary>
 ///computes the average of a list of locations
 /// </summary>
 public static Location averageLocations(List<Location> list)
 {
     double lat = 0.0, lon = 0.0, east = 0.0
         , north = 0.0, dist = 0.0, ele = 0.0;
     int index = 0;
     foreach (Location wpt in list) {
         lat += wpt.Lat;
         lon += wpt.Lon;
         east += wpt.Easting;
         north += wpt.Northing;
         dist += wpt.Distance;
         ele += wpt.Elevation;
         index += wpt.Index;
     }
     Location temp = new Location();
     temp.Lat = lat / (double)(list.Count);
     temp.Lon = lon / (double)(list.Count);
     temp.Easting = east / (double)(list.Count);
     temp.Northing = north / (double)(list.Count);
     temp.Distance = dist / (double)(list.Count);
     temp.Elevation = ele / (double)(list.Count);
     temp.Index = (int)(Math.Round((double)index / (double)(list.Count)));
     temp.Zone = list[0].Zone;
     return temp;
 }
 /// <summary>
 /// constructor called when a deep copy is required
 /// </summary>
 public Address(Address a)
 {
     _address = a._address;
     _geocodedLocation = a._geocodedLocation;
     _gpxLocation = a._gpxLocation;
     _status = a._status;
     _streetName = a._streetName;
     _xml = a._xml;
 }
 public static PointOfInterest createPointOfInterest(Location loc, List<Address> addresses)
 {
     Address ca = findNearestAddress(loc, addresses);
     //more options exist, for doing this
     PointOfInterest p = new PointOfInterest(loc, ca, ca, ca);
     p.TurnDirection = "POI";
     p.Locs[2].StreetName = "description of POI";
     return p;
 }
 /// <summary>
 /// constructor called when a location has been reverse geocoded
 /// from a web service (not from the cache)
 /// </summary>
 public Address(string doc, Location gpxLoc)
 {
     _xml = doc;
     if (_xml.Contains("xml"))
         parseDocument();
     _gpxLocation = gpxLoc;
     Easting = gpxLoc.Easting;
     Northing = gpxLoc.Northing;
 }
 public void drawLocations(ref Image map, Location[] points)
 {
     Graphics g = Graphics.FromImage(map);
     SolidBrush sb = new SolidBrush(Color.Blue);
     Point pt;
     for (int i = 0; i < points.Length; i++) {
         pt = _fd.getPoint(points[i]);
         g.FillEllipse(sb, pt.X - 2, pt.Y - 2, 4, 4);
     }
 }
 public void drawBeginAndEndPoints(ref Image map, Location begin, Location end)
 {
     Graphics g = Graphics.FromImage(map);
     Font f = new Font(FontFamily.GenericMonospace, 12, FontStyle.Bold);
     SolidBrush sbB = new SolidBrush(Color.Green);
     SolidBrush sbE = new SolidBrush(Color.DarkRed);
     Point ptB;
     ptB = _fd.getPoint(begin);
     g.FillEllipse(sbB, ptB.X - 5, ptB.Y - 5, 10, 10);
     g.DrawString("B", f, sbB, ptB);
     Point ptE;
     ptE = _fd.getPoint(end);
     g.FillEllipse(sbE, ptE.X - 5, ptE.Y - 5, 10, 10);
     g.DrawString("E", f, sbE, ptE);
 }
 static Address findNearestAddress(Location loc, List<Address> addresses)
 {
     double minDistance = double.PositiveInfinity;
     Address closestAddress = null;
     double currentDistance = 0.0;
     double x1 = 0.0, y1 = 0.0;
     double x2 = loc.Easting, y2 = loc.Northing;
     foreach(Address a in addresses) {
         x1 = a.GpxLocation.Easting;
         y1 = a.GpxLocation.Northing;
         currentDistance = Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
         if(currentDistance < minDistance) {
             minDistance = currentDistance;
             closestAddress = a;
         }
     }
     return new Address(closestAddress);
 }
 public static string parse(XmlNode node, ref string address, ref string streetName, ref Location goeLoc)
 {
     //get the address
     foreach (XmlNode n in node.ChildNodes) {
         if (n.Name == "address") { node = n; break; } else if (n.Name == "status") {
             return SERVERS_OVERLOADED;
         }
     }
     //get the lat lon
     goeLoc = new Location();
     foreach (XmlNode n in node.ChildNodes) {
         if (n.Name == "street")
             streetName = n.InnerText;
         if (n.Name == "streetNumber")
             address = n.InnerText + " " + streetName;
         if (n.Name == "lat")
             goeLoc.Lat = double.Parse(n.InnerText);
         if (n.Name == "lng")
             goeLoc.Lon = double.Parse(n.InnerText);
     }
     return "Ok";
 }
        public KmlParser(string fileName, TrackPath path)
        {
            string s = "";
            string[] lines;
            string[] coords;
            string[] splitstrings = { "\r\n", "\n", "\r" };
            try {
                StreamReader sr = new StreamReader(fileName);
                s = sr.ReadToEnd();
                sr.Close();
                s = s.Substring(s.IndexOf("<coordinates>")
                    , s.IndexOf("</coordinates>") - s.IndexOf("<coordinates>"));
                s = s.Replace("<coordinates>", "");
                s = s.Replace("</coordinates>", "");
                s = s.Replace(" ", "");
                s = s.Trim();
                lines = s.Split(splitstrings, StringSplitOptions.None);

                // after string processing, have one long string like this:
                // -124.058970,43.979150,0.000000\n
                // -123.177780,44.048160,0.000000\n
                // ...

                // so split into lines, then split each line by ','

                foreach (string line in lines) {
                    coords = line.Split(',');
                    Location loc = new Location(double.Parse(coords[1]), double.Parse(coords[0]));
                    loc.Elevation = double.Parse(coords[2]);
                    path.Locations.Add(loc);
                }
                _status = "Read " + path.Locations.Count + " locations";
            } catch (Exception e) {
                //_status = e.Message;
                _status = "Parsing error, cannot read input file.";
                path.Locations.Clear();
            }
        }
 /// <summary>
 /// get a system.drawing point from a location
 /// </summary>
 public Point getPoint(Location wpt)
 {
     Point pt = new Point();
     pt.X = (int)((wpt.Easting - _horizontalOffset) / _horizontalScale);
     pt.Y = (int)((wpt.Northing - _verticalOffset) / _verticalScale);
     if (pt.X < 0 || pt.X >= _width || pt.Y < 0 || pt.Y >= _height) {
         pt.X = 0;
         pt.Y = 0;
     }
     return pt;
 }
 public PointOfInterest(Location loc, Address one, Address two, Address three)
     : base(one, two, three)
 {
     _locationFromMouse = loc;
 }
 public static string parse(XmlNode node, ref string address, ref string streetName, ref Location geoLoc)
 {
     foreach (XmlNode n in node) {
         if (n.Name == "result") { node = n; break; } else if (n.InnerText == OVER_QUERY_LIMIT) {
             return OVER_QUERY_LIMIT;
         }
     }
     //get the address
     foreach (XmlNode n in node.ChildNodes) {
         if (n.Name == "formatted_address") {
             address = n.FirstChild.InnerText;
             string s = address;
             //this may not work for foreign addresses
             if (Regex.IsMatch(s.Substring(0, s.IndexOf(" ")), "[0-9]")) {
                 int i = s.IndexOf(" ");
                 s = s.Substring(i + 1, s.IndexOf(",") - i - 1);
             } else
                 s = s.Substring(0, s.IndexOf(","));
             streetName = s;
             break;
         }
     }
     ////get the lat lon
     geoLoc = new Location();
     foreach (XmlNode n in node.ChildNodes) {
         if (n.Name == "geometry") { node = n; break; }
     }
     foreach (XmlNode n in node) {
         if (n.Name == "location") { node = n; break; }
     }
     foreach (XmlNode n in node.ChildNodes) {
         if (n.Name == "lat")
             geoLoc.Lat = double.Parse(n.InnerText);
         if (n.Name == "lng")
             geoLoc.Lon = double.Parse(n.InnerText);
     }
     return "Ok";
 }
 //retrieves the address from either
 //google geocoding API or geonames.org
 private Address getAddress(Location loc)
 {
     Address tempAddress = null;
     while (tempAddress == null) {
         if (!_exceeded_query_limit) {
             tempAddress = googleReverseGeocoder.getAddress(loc, _web);
             if (tempAddress.Status == GoogleXml.OVER_QUERY_LIMIT) {
                 _exceeded_query_limit = true;
                 tempAddress = null;
             }
         } else {
             //if google cut us off, then try: http://ws.geonames.org/findNearestAddress?
             tempAddress = geoNamesReverseGeocoder.getAddress(loc, _web);
             if (tempAddress.Status == GeonamesXml.SERVERS_OVERLOADED) {
                 _exceeded_query_limit = false; //now that we bounced off geonames, try google again
                 tempAddress = null;
                 Thread.Sleep(20); //wait a bit before asking google agian
             }
         }
     }
     return tempAddress;
 }
 /// <summary>
 /// if the map has been located i.e. registered, then 
 /// we can return a UTM point given a mouse location on the image
 /// </summary>
 public void getLocationFromMousePosition(Point pt)
 {
     if (_rideMapFid.MapLocated && _path.Locations.Count > 0)
         _locationFromMouse = _rideMapFid.getLocation(pt);
     else _locationFromMouse = null;
 }
 int findSecondPrevious(Location loc)
 {
     int i = 2;
     while (i < _spacedOutPoints.Count && loc.Index > _spacedOutPoints[i].Index) i++;
     return _spacedOutPoints[i - 2].Index;
 }
 int findSecondNext(Location loc)
 {
     int i = _spacedOutPoints.Count - 3;
     while (i >= 0 && loc.Index < _spacedOutPoints[i].Index) i--;
     return _spacedOutPoints[i + 2].Index;
 }
 int findFirstPrevious(Location loc)
 {
     int i = 1;
     while (i < _spacedOutPoints.Count && loc.Index > _spacedOutPoints[i].Index) i++;
     return _spacedOutPoints[i-1].Index;
 }
 int findFirstNext(Location loc)
 {
     int i = _spacedOutPoints.Count-2;
     while (i >= 0 && loc.Index < _spacedOutPoints[i].Index) i--;
     return _spacedOutPoints[i+1].Index;
 }
 /// <summary>
 /// The distance of a point from a line made from point1 and point2.
 /// </summary>
 /// <param name="pt1">The PT1.</param>
 /// <param name="pt2">The PT2.</param>
 /// <param name="p">The p.</param>
 /// <returns></returns>
 public static Double PerpendicularDistance(Location Point1, Location Point2, Location Point)
 {
     Double area = Math.Abs(.5 * (Point1.Easting * Point2.Northing + Point2.Easting *
     Point.Northing + Point.Easting * Point1.Northing - Point2.Easting * Point1.Northing - Point.Easting *
     Point2.Northing - Point1.Easting * Point.Northing));
     Double bottom = Math.Sqrt(Math.Pow(Point1.Easting - Point2.Easting, 2) +
     Math.Pow(Point1.Northing - Point2.Northing, 2));
     Double height = area / bottom * 2;
     return height;
 }
 public static Address getAddress(Location loc, WebInterface web)
 {
     string fullGeoUrl = BASE_URL + loc.Lat + "," + loc.Lon + "&sensor=false";
     return new Address(web.downloadWebPage(fullGeoUrl), loc);
 }
 /// <summary>
 /// sets a correspondence between the image pixels and UTM coordinates
 /// </summary>
 public void setCorrespondence(Location wpt1, Location wpt2)
 {
     double dx1 = wpt2.Easting - wpt1.Easting;
     double dy1 = wpt2.Northing - wpt1.Northing;
     double dx2 = _lowerRight.X - _upperLeft.X;
     double dy2 = _lowerRight.Y - _upperLeft.Y;
     _horizontalScale = dx1 / dx2;
     _verticalScale = dy1 / dy2;
     _horizontalOffset = wpt1.Easting - _upperLeft.X * _horizontalScale;
     _verticalOffset = wpt1.Northing - _upperLeft.Y * _verticalScale;
 }
 /// <summary>
 /// looks up a location in the cache given an input location
 /// </summary>
 public Address lookup(Location wpt)
 {
     _cacheHit = false;
     //lookup the location in a cache
     //if it is not present, return null
     if (_currentCache == null) return null;
     if (wpt.Zone != _currentCache.Name) {
         foreach (Cache c in _caches) {
             if (wpt.Zone == c.Name)
                 _currentCache = c;
         }
     }
     _tempLocation = (Address)_currentCache.read(wpt.Key);
     if (_tempLocation != null) {
         _cacheHit = true;
         _tempLocation.GpxLocation = wpt;
     }
     return _tempLocation;
 }