// ----------------------------------------------------------------------- // // TODO: Update copyright text. // // ----------------------------------------------------------------------- namespace OsmReader.OsmData.Elements { using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Globalization; using System.Xml.Serialization; /// /// TODO: Update summary. /// public class OsmNode : AbstractTaggedOsmElement { private const double EARTH_RADIUS = 6371000.0; private const double HALFCIRCLE = 180.0; [XmlAttribute(AttributeName = "id")] public long id { get; set; } [XmlAttribute(AttributeName = "lat")] public double lat { get; set; } [XmlAttribute(AttributeName = "lon")] public double lon { get; set; } [XmlAttribute(AttributeName = "user")] public string user { get; set; } [XmlAttribute(AttributeName = "uid")] public int uid { get; set; } [XmlAttribute(AttributeName = "visible")] public bool visible { get; set; } [XmlAttribute(AttributeName = "version")] public int version { get; set; } [XmlAttribute(AttributeName = "changeset")] public long changeset { get; set; } [XmlAttribute(AttributeName = "timestamp")] public string timestamp { get; set; } [XmlIgnore] public int links { get; set; } [XmlIgnore] public int inLinks { get; set; } [XmlIgnore] public int outLinks { get; set; } [XmlIgnore] public string NodeType { get { return getTagValue("highway"); } } [XmlIgnore] public string Ref { get { return getTagValue("ref"); } } /// /// Get the distance in meters between two nodes. /// /// Node 1 /// Node 2 /// Distance in meters. public static double calcDistance(OsmNode node1, OsmNode node2) { double d = 0; if (node1 != null && node2 != null) { double dLat = (node2.lat - node1.lat) / HALFCIRCLE * Math.PI; double dLon = (node2.lon - node1.lon) / HALFCIRCLE * Math.PI; double lat1 = node1.lat / HALFCIRCLE * Math.PI; double lat2 = node2.lat / HALFCIRCLE * Math.PI; double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Sin(dLon / 2) * Math.Sin(dLon / 2) * Math.Cos(lat1) * Math.Cos(lat2); double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); d = EARTH_RADIUS * c; } return d; } public override string ToString() { return id.ToString() + " [" + this.lat.ToString(CultureInfo.InvariantCulture) + "," + this.lon.ToString(CultureInfo.InvariantCulture) + "]"; } public override int GetHashCode() { uint hash = (uint)this.lat.GetHashCode() ^ (((uint)this.lon.GetHashCode() & 0xffff) << 16 | ((uint)this.lon.GetHashCode() & 0xffff0000) >> 16); return (int)hash; } public override bool Equals(object obj) { bool match = false; if (obj is OsmNode) { OsmNode node1 = (OsmNode)obj; match = (this.lat == node1.lat) && (this.lon == node1.lon); } return match; } /// /// Check if the position is close to the given position. /// /// Object to compare with. /// Distance to cover from position. /// public bool CloseTo(OsmNode obj, double radius) { bool match = calcDistance(this, obj) <= radius; return match; } } }