/// <summary> /// Calculates the distance from the source to destination location (in meters). /// </summary> /// <param name="src">The source location.</param> /// <param name="dest">The destination location.</param> /// <param name="radiusofearth">The radius of the earth in meters (default: 6371000).</param> /// <returns>Returns the distance, in meters, from source to destination.</returns> /// <remarks> /// Note that we use the <a href="http://en.wikipedia.org/wiki/International_System_of_Units">International /// System of Units (SI)</a>; units of distance are specified in meters. If you want to use imperial system (e.g. /// miles, nautical miles, yards, foot and whathaveyou's) you need to convert from/to meters. You can use the /// helper methods <see cref="MilesToMeters"/> / <see cref="MetersToMiles"/> and /// <see cref="YardsToMeters"/> / <see cref="MetersToYards"/> for quick conversion. /// </remarks> internal static double DistanceTo(IGeoLocation src, IGeoLocation dest, double radiusofearth = RADIUSOFEARTH) { var dLat = GeoUtil.Deg2Rad(dest.Latitude - src.Latitude); var dLon = GeoUtil.Deg2Rad(dest.Longitude - src.Longitude); return(radiusofearth * (2 * Math.Asin(Math.Min(1, Math.Sqrt(Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(GeoUtil.Deg2Rad(src.Latitude)) * Math.Cos(GeoUtil.Deg2Rad(dest.Latitude)) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2)))))); }
/// <summary> /// Calculates a coordinate from a GeoName (latitude, longitude, altitude) /// </summary> /// <param name="n">The GeoName to determine the coordinate for.</param> /// <param name="radiusofearth">Radius of the earth, in meters.</param> /// <returns>Returns a coordinate (represented as an array of 3 doubles).</returns> /// <remarks>This method is for internal use (for the KdTree) only.</remarks> internal static double[] GetCoord(IGeoLocation n, double radiusofearth = RADIUSOFEARTH) { return(new[] { radiusofearth *Math.Cos(GeoUtil.Deg2Rad(n.Latitude)) * Math.Cos(GeoUtil.Deg2Rad(n.Longitude)), radiusofearth *Math.Cos(GeoUtil.Deg2Rad(n.Latitude)) * Math.Sin(GeoUtil.Deg2Rad(n.Longitude)), radiusofearth *Math.Sin(GeoUtil.Deg2Rad(n.Latitude)) }); }
/// <summary> /// Adds a node to the <see cref="ReverseGeoCode<T>"/> internal structure. /// </summary> /// <param name="node">The <see cref="IGeoLocation"/> to add.</param> public void Add(T node) { _tree.Add(GeoUtil.GetCoord(node), node); }
/// <summary> /// Performs a nearest neighbour search on the nodes from a specified center limiting the number of results. /// </summary> /// <param name="center">The center of the search.</param> /// <param name="maxcount">The maximum number of results to return.</param> /// <returns>Returns up to maxcount nodes in matching order of the nearest neighbour search.</returns> public IEnumerable <T> NearestNeighbourSearch(T center, int maxcount) { return(_tree.GetNearestNeighbours(GeoUtil.GetCoord(center), maxcount).Select(v => v.Value)); }
/// <summary> /// Performs a radial search on the nodes from a specified center within a given radius limiting the number of /// results. /// </summary> /// <param name="center">The center of the search.</param> /// <param name="radius">The radius to search in.</param> /// <param name="maxcount">The maximum number of results to return.</param> /// <returns>Returns up to maxcount nodes matching the radial search.</returns> public IEnumerable <T> RadialSearch(T center, double radius, int maxcount) { return(_tree.RadialSearch(GeoUtil.GetCoord(center), radius, maxcount).Select(v => v.Value)); }