/// <summary> /// Serializes content from the writer /// </summary> public override void InternalFromBinary(IBinaryRawReader reader) { base.InternalFromBinary(reader); var version = VersionSerializationHelper.CheckVersionByte(reader, VERSION_NUMBER); if (version == 1) { CellSize = reader.ReadDouble(); StartPoint = new WGS84Point(); if (reader.ReadBoolean()) { StartPoint.FromBinary(reader); } EndPoint = new WGS84Point(); if (reader.ReadBoolean()) { EndPoint.FromBinary(reader); } PositionsAreGrid = reader.ReadBoolean(); } }
public static HashSet <GeoObj> SearchGeoHashIndex(SessionBase session, double lat, double lon, double radius) { HashSet <GeoObj> resultSet = new HashSet <GeoObj>(); WGS84Point center = new WGS84Point(lat, lon); GeoHashCircleQuery query = new GeoHashCircleQuery(center, radius); // radius in meters BoundingBox bbox = query.BoundingBox; var btreeSet = session.AllObjects <BTreeSet <GeoObj> >().FirstOrDefault(); foreach (GeoHash hash in query.SearchHashes) { var itr = btreeSet.Iterator(); itr.GoTo(new GeoObj(hash.LongValue)); var current = itr.Current(); while (current != null) { GeoHash geoHash = GeoHash.FromLongValue(current.GeoHashAsLong); if ((geoHash.SignificantBits >= hash.SignificantBits && geoHash.Within(hash)) || (geoHash.SignificantBits < hash.SignificantBits && hash.Within(geoHash))) { if (!(current.Latitude < bbox.MinLat || current.Latitude > bbox.MaxLat || current.Longitude < bbox.MinLon || current.Longitude > bbox.MaxLon)) { resultSet.Add(current); } current = itr.Next(); } else { break; } } } return(resultSet); }
/// <summary> /// Serializes content from the writer /// </summary> public override void InternalFromBinary(IBinaryRawReader reader) { base.InternalFromBinary(reader); var version = VersionSerializationHelper.CheckVersionByte(reader, VERSION_NUMBER); if (version == 1) { ProfileTypeRequired = (GridDataType)reader.ReadInt(); ProfileStyle = (ProfileStyle)reader.ReadInt(); StartPoint = new WGS84Point(); if (reader.ReadBoolean()) { StartPoint.FromBinary(reader); } EndPoint = new WGS84Point(); if (reader.ReadBoolean()) { EndPoint.FromBinary(reader); } PositionsAreGrid = reader.ReadBoolean(); ReturnAllPassesAndLayers = reader.ReadBoolean(); VolumeType = (VolumeComputationType)reader.ReadInt(); } }
/// <summary> /// create a <seealso cref="GeoHashCircleQuery"/> with the given center point and a /// radius in meters. /// </summary> public GeoHashCircleQuery(WGS84Point center, double radius) { m_radius = radius; m_center = center; WGS84Point northEast = VincentyGeodesy.MoveInDirection(VincentyGeodesy.MoveInDirection(center, 0, radius), 90, radius); WGS84Point southWest = VincentyGeodesy.MoveInDirection(VincentyGeodesy.MoveInDirection(center, 180, radius), 270, radius); BoundingBox bbox = new BoundingBox(northEast, southWest); m_query = new GeoHashBoundingBoxQuery(bbox); }
public void WGS84Point_with_ZERO_height_should_return_valid_result(double lat, double lon, double height, double toY, double toX, double toZ, string csib) { var points = new WGS84Point(lon, lat, height); var xyzCoords = _convertCoordinates.WGS84ToCalibration(csib, points, InputAs.Radians); xyzCoords.Should().NotBeNull(); xyzCoords.Y.Should().BeApproximately(toY, GRID_CM_TOLERANCE); xyzCoords.X.Should().BeApproximately(toX, GRID_CM_TOLERANCE); xyzCoords.Z.Should().BeApproximately(toZ, GRID_CM_TOLERANCE); }
public void WGS84Point_with_NULL_height_should_return_invalid_result() { var points = new WGS84Point(lon: 0.14729266728569143, lat: 0.8596927023775642, height: TestConsts.NULL_DOUBLE); var xyzCoords = _convertCoordinates.WGS84ToCalibration(CSIB.PHILIPSBURG, points, InputAs.Radians); xyzCoords.Should().NotBeNull(); xyzCoords.Y.Should().Be(0); xyzCoords.X.Should().Be(0); xyzCoords.Z.Should().Be(0); }
public GeoHashBoundingBoxQuery(BoundingBox bbox) { int fittingBits = GeoHashSizeTable.NumberOfBitsForOverlappingGeoHash(bbox); WGS84Point center = bbox.CenterPoint; GeoHash centerHash = GeoHash.WithBitPrecision(center.Latitude, center.Longitude, fittingBits); if (HashFits(centerHash, bbox)) { AddSearchHash(centerHash); } else { ExpandSearch(centerHash, bbox); } }
public static double DistanceInMeters(WGS84Point foo, WGS84Point bar) { double a = 6378137, b = 6356752.3142, f = 1 / 298.257223563; // WGS-84 // ellipsiod double L = (bar.Longitude - foo.Longitude) * DegToRad; double U1 = Math.Atan((1 - f) * Math.Tan(foo.Latitude * DegToRad)); double U2 = Math.Atan((1 - f) * Math.Tan(bar.Latitude * DegToRad)); double sinU1 = Math.Sin(U1), cosU1 = Math.Cos(U1); double sinU2 = Math.Sin(U2), cosU2 = Math.Cos(U2); double cosSqAlpha, sinSigma, cos2SigmaM, cosSigma, sigma; double lambda = L, lambdaP, iterLimit = 20; do { double sinLambda = Math.Sin(lambda), cosLambda = Math.Cos(lambda); sinSigma = Math.Sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda)); if (sinSigma == 0) { return(0); // co-incident points } cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda; sigma = Math.Atan2(sinSigma, cosSigma); double sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma; cosSqAlpha = 1 - sinAlpha * sinAlpha; cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha; if (double.IsNaN(cos2SigmaM)) { cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 } double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)); lambdaP = lambda; lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))); } while (Math.Abs(lambda - lambdaP) > EPSILON && --iterLimit > 0); if (iterLimit == 0) { return(double.NaN); } double uSquared = cosSqAlpha * (a * a - b * b) / (b * b); double A = 1 + uSquared / 16384 * (4096 + uSquared * (-768 + uSquared * (320 - 175 * uSquared))); double B = uSquared / 1024 * (256 + uSquared * (-128 + uSquared * (74 - 47 * uSquared))); double deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))); double s = b * A * (sigma - deltaSigma); return(s); }
/// <summary> /// returns the <seealso cref="WGS84Point"/> that is in the given direction at the /// following distance of the given point.<br> /// Uses Vincenty's formula and the WGS84 ellipsoid. /// </summary> /// <param name="bearingInDegrees"> /// : must be within 0 and 360 </param> /// <param name="point"> : where to start </param> /// <param name="distanceInMeters">: How far to move in the given direction </param> public static WGS84Point MoveInDirection(WGS84Point point, double bearingInDegrees, double distanceInMeters) { if (bearingInDegrees < 0 || bearingInDegrees > 360) { throw new System.ArgumentException("direction must be in (0,360)"); } double a = 6378137, b = 6356752.3142, f = 1 / 298.257223563; // WGS-84 // ellipsiod double alpha1 = bearingInDegrees * DegToRad; double sinAlpha1 = Math.Sin(alpha1), cosAlpha1 = Math.Cos(alpha1); double tanU1 = (1 - f) * Math.Tan(point.Latitude * DegToRad); double cosU1 = 1 / Math.Sqrt((1 + tanU1 * tanU1)), sinU1 = tanU1 * cosU1; double sigma1 = Math.Atan2(tanU1, cosAlpha1); double sinAlpha = cosU1 * sinAlpha1; double cosSqAlpha = 1 - sinAlpha * sinAlpha; double uSq = cosSqAlpha * (a * a - b * b) / (b * b); double A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))); double B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))); double sinSigma = 0, cosSigma = 0, cos2SigmaM = 0; double sigma = distanceInMeters / (b * A), sigmaP = 2 * Math.PI; while (Math.Abs(sigma - sigmaP) > 1e-12) { cos2SigmaM = Math.Cos(2 * sigma1 + sigma); sinSigma = Math.Sin(sigma); cosSigma = Math.Cos(sigma); double deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))); sigmaP = sigma; sigma = distanceInMeters / (b * A) + deltaSigma; } double tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1; double lat2 = Math.Atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1, (1 - f) * Math.Sqrt(sinAlpha * sinAlpha + tmp * tmp)); double lambda = Math.Atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1); double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)); double L = lambda - (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))); double newLat = lat2 / DegToRad; double newLon = point.Longitude + L / DegToRad; newLon = (newLon > 180.0 ? 360.0 - newLon : newLon); newLon = (newLon < -180.0 ? 360.0 + newLon : newLon); return(new WGS84Point(newLat, newLon)); }
/// <summary> /// Constructor taking the full state of the elevation patch computation operation /// </summary> public CalculateDesignProfileArgument(Guid projectUid, double cellSize, Guid designUid, double offset, WGS84Point startPoint, WGS84Point endPoint, bool positionsAreGrid = false) : this() { ProjectID = projectUid; CellSize = cellSize; ReferenceDesign.DesignID = designUid; ReferenceDesign.Offset = offset; StartPoint = startPoint; EndPoint = endPoint; PositionsAreGrid = positionsAreGrid; }
public static double DistanceInMeters(WGS84Point foo, WGS84Point bar) { double a = 6378137, b = 6356752.3142, f = 1 / 298.257223563; // WGS-84 // ellipsiod double L = (bar.Longitude - foo.Longitude) * DegToRad; double U1 = Math.Atan((1 - f) * Math.Tan(foo.Latitude * DegToRad)); double U2 = Math.Atan((1 - f) * Math.Tan(bar.Latitude * DegToRad)); double sinU1 = Math.Sin(U1), cosU1 = Math.Cos(U1); double sinU2 = Math.Sin(U2), cosU2 = Math.Cos(U2); double cosSqAlpha, sinSigma, cos2SigmaM, cosSigma, sigma; double lambda = L, lambdaP , iterLimit = 20; do { double sinLambda = Math.Sin(lambda), cosLambda = Math.Cos(lambda); sinSigma = Math.Sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda)); if (sinSigma == 0) { return 0; // co-incident points } cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda; sigma = Math.Atan2(sinSigma, cosSigma); double sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma; cosSqAlpha = 1 - sinAlpha * sinAlpha; cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha; if (double.IsNaN(cos2SigmaM)) { cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 } double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)); lambdaP = lambda; lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))); } while (Math.Abs(lambda - lambdaP) > EPSILON && --iterLimit > 0); if (iterLimit == 0) { return double.NaN; } double uSquared = cosSqAlpha * (a * a - b * b) / (b * b); double A = 1 + uSquared / 16384 * (4096 + uSquared * (-768 + uSquared * (320 - 175 * uSquared))); double B = uSquared / 1024 * (256 + uSquared * (-128 + uSquared * (74 - 47 * uSquared))); double deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))); double s = b * A * (sigma - deltaSigma); return s; }
public static HashSet <GeoObj> SearchGeoHashIndex(SessionBase session, double minLat, double minLon, double maxLat, double maxLon) { HashSet <GeoObj> resultSet = new HashSet <GeoObj>(); if (minLat > maxLat) { double t = minLat; minLat = maxLat; maxLat = t; } if (minLon > maxLon) { double t = minLon; minLon = maxLon; maxLon = t; } WGS84Point min = new WGS84Point(minLat, minLon); WGS84Point max = new WGS84Point(maxLat, maxLon); BoundingBox bbox = new BoundingBox(min, max); GeoHashBoundingBoxQuery query = new GeoHashBoundingBoxQuery(bbox); var btreeSet = session.AllObjects <BTreeSet <GeoObj> >().FirstOrDefault(); foreach (GeoHash hash in query.SearchHashes) { var itr = btreeSet.Iterator(); itr.GoTo(new GeoObj(hash.LongValue)); var current = itr.Current(); while (current != null) { GeoHash geoHash = GeoHash.FromLongValue(current.GeoHashAsLong); if ((geoHash.SignificantBits >= hash.SignificantBits && geoHash.Within(hash)) || (geoHash.SignificantBits < hash.SignificantBits && hash.Within(geoHash))) { if (!(current.Latitude < bbox.MinLat || current.Latitude > bbox.MaxLat || current.Longitude < bbox.MinLon || current.Longitude > bbox.MaxLon)) { resultSet.Add(current); } current = itr.Next(); } else { break; } } } return(resultSet); }
/// <inheritdoc/> public XYZ WGS84ToCalibration(string csib, WGS84Point wgs84Point, InputAs inputAs) { var requestId = Guid.NewGuid(); if (_log.IsTraceEnabled()) { _log.LogTrace($"{nameof(WGS84ToCalibration)}: CoreXRequestID: {requestId}, wgs84Point: {wgs84Point}, InputAs: {inputAs}, CSIB: {csib}"); } if (inputAs == InputAs.Degrees) { wgs84Point.Lat = wgs84Point.Lat.DegreesToRadians(); wgs84Point.Lon = wgs84Point.Lon.DegreesToRadians(); } var nee = _coreX .TransformLLHToNEE(csib, new LLH { Latitude = wgs84Point.Lat, Longitude = wgs84Point.Lon, Height = wgs84Point.Height }, fromType: CoordinateTypes.ReferenceGlobalLLH, toType: CoordinateTypes.OrientatedNEE); var result = new XYZ { X = nee.East, Y = nee.North, Z = nee.Elevation }; if (_log.IsTraceEnabled()) { _log.LogTrace($"{nameof(WGS84ToCalibration)}: CoreXRequestID: {requestId}, Returning XYZ: {result}"); } return(result); }
/// <inheritdoc /> public XYZ NullWGSLLToXY(WGS84Point wgsPoint) => new XYZ(wgsPoint.Lon, wgsPoint.Lat);
public bool Contains(WGS84Point point) { return(Contains(GeoHash.WithBitPrecision(point.Latitude, point.Longitude, 64))); }
public bool Contains(WGS84Point point) { return(m_query.Contains(point)); }
/// <summary> /// Computes a geometric profile across the design given a series of vertices describing the path to be profiled. /// </summary> public async Task <(List <XYZS> profile, DesignProfilerRequestResult errorCode)> ComputeProfile(Guid projectUid, WGS84Point startPoint, WGS84Point endPoint, double cellSize, double offset, bool arePositionsGrid) { // Query the DesignProfiler service to get the patch of elevations calculated try { var profileRequest = new DesignProfileRequest(); var arg = new CalculateDesignProfileArgument { ProjectID = projectUid, CellSize = cellSize, StartPoint = startPoint, EndPoint = endPoint, PositionsAreGrid = arePositionsGrid, ReferenceDesign = { DesignID = DesignDescriptor.DesignID, Offset = offset } }; var profileResult = await profileRequest.ExecuteAsync(arg); return(profileResult.Profile, profileResult.RequestResult); } catch { return(null, DesignProfilerRequestResult.UnknownError); } }
public bool Contains(WGS84Point point) { return Contains(GeoHash.WithBitPrecision(point.Latitude, point.Longitude, 64)); }
public bool Contains(WGS84Point point) { return m_query.Contains(point); }
public static HashSet <Person> SearchGeoHashIndex(string bootDirectory, double minLat, double minLon, double maxLat, double maxLon) { HashSet <Person> resultSet = new HashSet <Person>(); if (minLat > maxLat) { double t = minLat; minLat = maxLat; maxLat = t; } if (minLon > maxLon) { double t = minLon; minLon = maxLon; maxLon = t; } WGS84Point min = new WGS84Point(minLat, minLon); WGS84Point max = new WGS84Point(maxLat, maxLon); BoundingBox bbox = new BoundingBox(min, max); GeoHashBoundingBoxQuery query = new GeoHashBoundingBoxQuery(bbox); using (SessionNoServer session = new SessionNoServer(bootDirectory)) { session.BeginRead(); BTreeMap <Int64, VelocityDbList <Person> > btreeMap = session.AllObjects <BTreeMap <Int64, VelocityDbList <Person> > >().FirstOrDefault(); foreach (GeoHash hash in query.SearchHashes) { BTreeMapIterator <Int64, VelocityDbList <Person> > itr = btreeMap.Iterator(); itr.GoTo(hash.LongValue); var current = itr.Current(); while (current.Value != null) { GeoHash geoHash = GeoHash.FromLongValue(current.Key); if (geoHash.Within(hash) || (geoHash.SignificantBits > hash.SignificantBits && hash.Within(geoHash))) { foreach (Person person in current.Value) { resultSet.Add(person); } current = itr.Next(); } else { break; } } } // actual geohash bounding box may be including some that are not within requested bounding box so remove such items if any HashSet <Person> notWithin = new HashSet <Person>(); foreach (Person person in resultSet) { if (person.Lattitude < min.Latitude || person.Lattitude > max.Latitude || person.Longitude < min.Longitude || person.Lattitude > max.Latitude) { notWithin.Add(person); } } foreach (Person person in notWithin) { resultSet.Remove(person); } foreach (Person person in resultSet) { Console.WriteLine(person.ToString() + " Lattitude: " + person.Lattitude + " Longitude: " + person.Longitude); } session.Commit(); } return(resultSet); }
/// <summary> /// returns the <seealso cref="WGS84Point"/> that is in the given direction at the /// following distance of the given point.<br> /// Uses Vincenty's formula and the WGS84 ellipsoid. /// </summary> /// <param name="bearingInDegrees"> /// : must be within 0 and 360 </param> /// <param name="point"> : where to start </param> /// <param name="distanceInMeters">: How far to move in the given direction </param> public static WGS84Point MoveInDirection(WGS84Point point, double bearingInDegrees, double distanceInMeters) { if (bearingInDegrees < 0 || bearingInDegrees > 360) { throw new System.ArgumentException("direction must be in (0,360)"); } double a = 6378137, b = 6356752.3142, f = 1 / 298.257223563; // WGS-84 // ellipsiod double alpha1 = bearingInDegrees * DegToRad; double sinAlpha1 = Math.Sin(alpha1), cosAlpha1 = Math.Cos(alpha1); double tanU1 = (1 - f) * Math.Tan(point.Latitude * DegToRad); double cosU1 = 1 / Math.Sqrt((1 + tanU1 * tanU1)), sinU1 = tanU1 * cosU1; double sigma1 = Math.Atan2(tanU1, cosAlpha1); double sinAlpha = cosU1 * sinAlpha1; double cosSqAlpha = 1 - sinAlpha * sinAlpha; double uSq = cosSqAlpha * (a * a - b * b) / (b * b); double A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))); double B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))); double sinSigma = 0, cosSigma = 0, cos2SigmaM = 0; double sigma = distanceInMeters / (b * A), sigmaP = 2 * Math.PI; while (Math.Abs(sigma - sigmaP) > 1e-12) { cos2SigmaM = Math.Cos(2 * sigma1 + sigma); sinSigma = Math.Sin(sigma); cosSigma = Math.Cos(sigma); double deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))); sigmaP = sigma; sigma = distanceInMeters / (b * A) + deltaSigma; } double tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1; double lat2 = Math.Atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1, (1 - f) * Math.Sqrt(sinAlpha * sinAlpha + tmp * tmp)); double lambda = Math.Atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1); double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)); double L = lambda - (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))); double newLat = lat2 / DegToRad; double newLon = point.Longitude + L / DegToRad; newLon = (newLon > 180.0 ? 360.0 - newLon : newLon); newLon = (newLon < -180.0 ? 360.0 + newLon : newLon); return new WGS84Point(newLat, newLon); }