/// <summary> /// Converts a grid column to Longitude /// </summary> /// <param name="x"></param> /// <param name="zoom"></param> /// <returns></returns> public static double XToLongitudeAtZoom(int x, int zoom) { double arc = EarthCircumference / ((1 << zoom) * 256); double metersX = (x * arc) - HalfEarthCircumference; double result = GISHelper.RadToDeg(metersX / 6378137); return(result); }
/// <summary> /// Converts a grid row to Latitude /// </summary> /// <param name="y"></param> /// <param name="zoom"></param> /// <returns></returns> public static double YToLatitudeAtZoom(int y, int zoom) { double arc = EarthCircumference / ((1 << zoom) * 256); double metersY = HalfEarthCircumference - (y * arc); double a = Math.Exp(metersY * 2 / 6378137); double result = GISHelper.RadToDeg(Math.Asin((a - 1) / (a + 1))); return(result); }
/// <summary> /// /// </summary> /// <param name="latlong"></param> /// <returns></returns> private static Point3D LatLongToPoint(LatLong latlong) { double latitude = latlong.Latitude; double degrees = latlong.Longitude - 90.0; Point3D pointd = new Point3D(); latitude = GISHelper.DegToRad(latitude); degrees = GISHelper.DegToRad(degrees); pointd.Y = Math.Sin(latitude); pointd.X = -Math.Cos(degrees) * Math.Cos(latitude); pointd.Z = Math.Sin(degrees) * Math.Cos(latitude); return(pointd); }
/// <summary> /// /// </summary> void RedrawSphere() { double extent = ZoomManager.ZoomLevelMetersPerPixel[CurrentZoomLevel]; double EarthRadius = 6378135.0; double num1 = (EarthRadius * 3.1415926535897931) / 2.0; Viewport3D viewport = ViewPort; double num3 = viewport.ActualWidth / ((2.0 * EarthRadius) / extent); double num4 = 1.15470054; double num5 = num4 * num3; double num6 = num5 / Math.Tan(GISHelper.DegToRad(5E-07)); _scale.ScaleX = num6; _scale.ScaleY = num6; _scale.ScaleZ = num6; }
/// <summary> /// Converts Globe Point to Lat Long. /// </summary> /// <param name="point"></param> /// <returns></returns> LatLong PointToLatLong(Point3D point) { Point3D pointd = ViewPointToSpherePoint(point); double d = Math.Asin(pointd.Y); double radians = Math.Acos(-pointd.X / Math.Cos(d)); d = GISHelper.RadToDeg(d); radians = GISHelper.RadToDeg(radians); if (pointd.Z < 0.0) { radians = 180.0 + (180.0 - radians); } radians = (radians + 270.0) % 360.0; return(new LatLong(d, radians - 180.0)); }
/// <summary> /// A tessellation or tiling of the plane is a collection of plane figures that fills the plane with /// no overlaps and no gaps. One may also speak of tessellations of the parts of the plane or of other surfaces. /// http://en.wikipedia.org/wiki/Tesselate /// </summary> /// <param name="tDiv"></param> /// <param name="pDiv"></param> /// <param name="radius"></param> /// <param name="ThetaStart"></param> /// <param name="PhiStart"></param> /// <param name="ThetaEnd"></param> /// <param name="PhiEnd"></param> /// <returns>MeshGeometry3D</returns> internal static MeshGeometry3D Tessellate(int tDiv, int pDiv, double radius, double ThetaStart, double PhiStart, double ThetaEnd, double PhiEnd) { double slopeX = GISHelper.DegToRad(ThetaEnd - ThetaStart) / ((double)tDiv); double slopeY = GISHelper.DegToRad(PhiEnd - PhiStart) / ((double)pDiv); // Fill the Position, Normals, and TextureCoordinates collections MeshGeometry3D geometryd = new MeshGeometry3D(); for (int stack = 0; stack <= pDiv; stack++) { double phi = stack * slopeY; phi += GISHelper.DegToRad(PhiStart); for (int slice = 0; slice <= tDiv; slice++) { double theta = slice * slopeX; theta += GISHelper.DegToRad(ThetaStart); geometryd.Positions.Add(GetPosition(theta, phi, radius)); geometryd.Normals.Add(GetNormal(theta, phi)); } } //Get Texture co-ordinates. geometryd.TextureCoordinates = GetTextureCoordinates(tDiv, pDiv, ThetaStart, PhiStart, ThetaEnd, PhiEnd); // Fill the TriangleIndices collection. for (int stack = 0; stack < pDiv; stack++) { for (int slice = 0; slice < tDiv; slice++) { int topL = slice; int topR = slice + 1; int bottomL = stack * (tDiv + 1); int bottomR = (stack + 1) * (tDiv + 1); geometryd.TriangleIndices.Add(topL + bottomL); geometryd.TriangleIndices.Add(topL + bottomR); geometryd.TriangleIndices.Add(topR + bottomL); geometryd.TriangleIndices.Add(topR + bottomL); geometryd.TriangleIndices.Add(topL + bottomR); geometryd.TriangleIndices.Add(topR + bottomR); } } geometryd.Freeze(); return(geometryd); }
/// <summary> /// /// </summary> /// <returns></returns> double GetPhiStart() { if (double.IsNaN(this.phiStart)) { double num = 7.1288559127654789; double num3 = (GISHelper.LatitudeToMercatorY(GISHelper.DegToRad(45.0)) * num) / 2.0; double num4 = -num3; double num5 = num3 - num4; double num6 = ((double)this.Row) / ((double)ZoomManager.ZoomLevelRows(this.ZoomLevel)); double num1 = (this.Row + 1.0) / ((double)ZoomManager.ZoomLevelRows(this.ZoomLevel)); GISHelper.RadToDeg(GISHelper.MercatorYToLatitude(1.0)); ZoomManager.ZoomLevelRows(this.ZoomLevel); double y = (num6 - 0.5) * num5; this.phiStart = GISHelper.RadToDeg(GISHelper.MercatorYToLatitude(y)) + 90.0; } return(this.phiStart); }
/// <summary> /// /// </summary> /// <param name="tDiv"></param> /// <param name="pDiv"></param> /// <param name="thetaStart"></param> /// <param name="phiStart"></param> /// <param name="thetaEnd"></param> /// <param name="phiEnd"></param> /// <returns></returns> static PointCollection GetTextureCoordinates(int tDiv, int pDiv, double thetaStart, double phiStart, double thetaEnd, double phiEnd) { double radi = (GISHelper.LatitudeToMercatorY(GISHelper.DegToRad(45.0)) * 7.1288559127654789) / 2.0; double invRadi = -radi; PointCollection points = new PointCollection(); double elipseX = GISHelper.DegToRad(thetaEnd - thetaStart) / ((double)tDiv); double elipseY = GISHelper.DegToRad(phiEnd - phiStart) / ((double)pDiv); for (int i = 0; i <= pDiv; i++) { double times = i * elipseY; times += GISHelper.DegToRad(phiStart); for (int k = 0; k <= tDiv; k++) { double num10 = k * elipseX; num10 += GISHelper.DegToRad(thetaStart); Point point = new Point(num10 / 6.2831853071795862, times / 3.1415926535897931); double phi = times - 1.5707963267948966; point.Y = GISHelper.LatitudeToMercatorY(phi);; points.Add(point); } } double minValue = double.MinValue; double maxValue = double.MaxValue; foreach (Point point2 in points) { if ((point2.Y > minValue) && !double.IsPositiveInfinity(point2.Y)) { minValue = point2.Y; } if ((point2.Y < maxValue) && !double.IsNegativeInfinity(point2.Y)) { maxValue = point2.Y; } } minValue = Math.Min(minValue, radi); maxValue = Math.Max(maxValue, invRadi); for (int j = 0; j < points.Count; j++) { Point point6; Point point9; Point point3 = points[j]; if (!double.IsPositiveInfinity(point3.Y)) { Point point4 = points[j]; if (point4.Y <= minValue) { point6 = points[j]; if (!double.IsNegativeInfinity(point6.Y)) { Point point7 = points[j]; if (point7.Y >= maxValue) { point9 = PopulatePoints(points, minValue, maxValue, j); continue; } } Point point8 = points[j]; points[j] = new Point(point8.X, maxValue); } } Point point5 = points[j]; points[j] = new Point(point5.X, minValue); point9 = PopulatePoints(points, minValue, maxValue, j); } return(points); }