/// <summary> /// Calculate the destination if we start at: /// Lincoln Memorial in Washington, D.C --> 38.8892N, 77.04978W /// and travel at /// 51.7679 degrees for 6179.016136 kilometers /// /// WGS84 reference ellipsoid /// </summary> static void TwoDimensionalDirectCalculation() { // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // set Lincoln Memorial coordinates GlobalCoordinates lincolnMemorial; lincolnMemorial = new GlobalCoordinates( new Angle(38.88922), new Angle(-77.04978) ); // set the direction and distance Angle startBearing = new Angle(51.7679); double distance = 6179016.13586; // find the destination Angle endBearing; GlobalCoordinates dest = geoCalc.CalculateEndingGlobalCoordinates(reference, lincolnMemorial, startBearing, distance, out endBearing); Console.WriteLine("Travel from Lincoln Memorial at 51.767921 deg for 6179.016 km"); Console.Write(" Destination: {0:0.0000}{1}", dest.Latitude.Degrees, (dest.Latitude > 0) ? "N" : "S" ); Console.WriteLine(", {0:0.0000}{1}", dest.Longitude.Degrees, (dest.Longitude > 0) ? "E" : "W"); Console.WriteLine(" End Bearing: {0:0.00} degrees", endBearing.Degrees); }
/// <summary> /// Calculate the two-dimensional path from /// Lincoln Memorial in Washington, D.C --> 38.8892N, 77.04978W /// to /// Eiffel Tower in Paris --> 48.85889N, 2.29583E /// using /// WGS84 reference ellipsoid /// </summary> static void TwoDimensionalInverseCalculation() { // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // set Lincoln Memorial coordinates GlobalCoordinates lincolnMemorial; lincolnMemorial = new GlobalCoordinates( new Angle(38.88922), new Angle(-77.04978) ); // set Eiffel Tower coordinates GlobalCoordinates eiffelTower; eiffelTower = new GlobalCoordinates( new Angle(48.85889), new Angle(2.29583) ); // calculate the geodetic curve GeodeticCurve geoCurve = geoCalc.CalculateGeodeticCurve(reference, lincolnMemorial, eiffelTower); double ellipseKilometers = geoCurve.EllipsoidalDistance / 1000.0; double ellipseMiles = ellipseKilometers * 0.621371192; Console.WriteLine("2-D path from Lincoln Memorial to Eiffel Tower using WGS84"); Console.WriteLine(" Ellipsoidal Distance: {0:0.00} kilometers ({1:0.00} miles)", ellipseKilometers, ellipseMiles); Console.WriteLine(" Azimuth: {0:0.00} degrees", geoCurve.Azimuth.Degrees); Console.WriteLine(" Reverse Azimuth: {0:0.00} degrees", geoCurve.ReverseAzimuth.Degrees); }
public void TestCalculateGeodeticMeasurement() { // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // set Pike's Peak position GlobalPosition pikesPeak; pikesPeak = new GlobalPosition(new GlobalCoordinates(new Angle(38.840511), new Angle(-105.0445896)), 4301.0); // set Alcatraz Island coordinates GlobalPosition alcatrazIsland; alcatrazIsland = new GlobalPosition(new GlobalCoordinates(new Angle(37.826389), new Angle(-122.4225)), 0.0); // calculate the geodetic measurement GeodeticMeasurement geoMeasurement; geoMeasurement = geoCalc.CalculateGeodeticMeasurement(reference, pikesPeak, alcatrazIsland); Assert.AreEqual(-4301.0, geoMeasurement.ElevationChange, 0.001); Assert.AreEqual(1521788.826, geoMeasurement.PointToPointDistance, 0.001); Assert.AreEqual(1521782.748, geoMeasurement.EllipsoidalDistance, 0.001); Assert.AreEqual(271.21039153, geoMeasurement.Azimuth.Degrees, 0.0000001); Assert.AreEqual(80.38029386, geoMeasurement.ReverseAzimuth.Degrees, 0.0000001); }
public void TestAntiPodal1() { // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // set position 1 GlobalCoordinates p1; p1 = new GlobalCoordinates(10, 80.6); // set position 2 GlobalCoordinates p2; p2 = new GlobalCoordinates(-10, -100); // calculate the geodetic measurement GeodeticCurve geoCurve; geoCurve = geoCalc.CalculateGeodeticCurve(reference, p1, p2); Assert.AreEqual(19970718.422432076, geoCurve.EllipsoidalDistance, 0.001); Assert.AreEqual(90.0004877491174, geoCurve.Azimuth.Degrees, 0.0000001); Assert.AreEqual(270.0004877491174, geoCurve.ReverseAzimuth.Degrees, 0.0000001); }
public static GeodeticMeasurement CalculateDistance(double lat1, double lon1, double lat2, double lon2) { GlobalCoordinates p1 = new GlobalCoordinates(new Angle(lat1), new Angle(lon1)); GlobalCoordinates p2 = new GlobalCoordinates(new Angle(lat2), new Angle(lon2)); GeodeticCalculator gc = new GeodeticCalculator(); GlobalPosition gp1 = new GlobalPosition(p1); GlobalPosition gp2 = new GlobalPosition(p2); GeodeticMeasurement gm = gc.CalculateGeodeticMeasurement(Ellipsoid.WGS84, gp1, gp2); return gm; }
public static void GetEnvelope(double lat, double lon, double dist, out double minLat, out double minLon, out double maxLat, out double maxLon) { var gc = new GeodeticCalculator(); var endpoints = new List<GlobalCoordinates>(); endpoints.Add(gc.CalculateEndingGlobalCoordinates(Ellipsoid.WGS84, new GlobalCoordinates(new Angle(lat), new Angle(lon)), new Angle(0), dist * 1000.0)); endpoints.Add(gc.CalculateEndingGlobalCoordinates(Ellipsoid.WGS84, new GlobalCoordinates(new Angle(lat), new Angle(lon)), new Angle(90), dist * 1000.0)); endpoints.Add(gc.CalculateEndingGlobalCoordinates(Ellipsoid.WGS84, new GlobalCoordinates(new Angle(lat), new Angle(lon)), new Angle(180), dist * 1000.0)); endpoints.Add(gc.CalculateEndingGlobalCoordinates(Ellipsoid.WGS84, new GlobalCoordinates(new Angle(lat), new Angle(lon)), new Angle(270), dist * 1000.0)); minLat = endpoints.Min(x => x.Latitude.Degrees); maxLat = endpoints.Max(x => x.Latitude.Degrees); minLon = endpoints.Min(x => x.Longitude.Degrees); maxLon = endpoints.Max(x => x.Longitude.Degrees); }
private void DoGeodaeticCalculations () { DataRow RootRow = MapDataWrapper.Instance.GetMapKachelRootImageRow (TypenName, RootKachelName); GeodeticCalculator GeoCalc = new GeodeticCalculator(); Ellipsoid ReferenceModell = Ellipsoid.WGS84; GlobalCoordinates TopLeftStart = new GlobalCoordinates (new Angle(Convert.ToDouble(RootRow["TopY"])), new Angle(Convert.ToDouble(RootRow["LeftX"]))); GlobalCoordinates TopRightEnd = new GlobalCoordinates (new Angle(Convert.ToDouble(RootRow["TopY"])), new Angle(Convert.ToDouble(RootRow["RightX"]))); GlobalCoordinates BottomLeftStart = new GlobalCoordinates (new Angle(Convert.ToDouble(RootRow["BottomY"])), new Angle(Convert.ToDouble(RootRow["LeftX"]))); GlobalCoordinates BottomRightEnd = new GlobalCoordinates (new Angle(Convert.ToDouble(RootRow["BottomY"])), new Angle(Convert.ToDouble(RootRow["RightX"]))); GeodeticCurve TopCurve = GeoCalc.CalculateGeodeticCurve(ReferenceModell, TopLeftStart, TopRightEnd); double TopMeters = TopCurve.EllipsoidalDistance; GeodeticCurve BottomCurve = GeoCalc.CalculateGeodeticCurve(ReferenceModell, BottomLeftStart, BottomRightEnd); double BottomMeters = BottomCurve.EllipsoidalDistance; GeodeticCurve LeftCurve = GeoCalc.CalculateGeodeticCurve(ReferenceModell, BottomLeftStart, TopLeftStart); double LeftMeters = LeftCurve.EllipsoidalDistance; GeodeticCurve RightCurve = GeoCalc.CalculateGeodeticCurve(ReferenceModell, BottomRightEnd, TopRightEnd); double RightMeters = RightCurve.EllipsoidalDistance; LeftToRightDistance = (TopMeters + BottomMeters) / 2.0; BottomToTopDistance = (LeftMeters + RightMeters) / 2.0; LeftMeasure = new Point (Convert.ToDouble(RootRow["LeftX"]), Convert.ToDouble(RootRow["TopY"])); TopMeasure = new Point (Convert.ToDouble(RootRow["LeftX"]), Convert.ToDouble(RootRow["TopY"])); RightMeasure = new Point (Convert.ToDouble(RootRow["RightX"]), Convert.ToDouble(RootRow["BottomY"])); BottomMeasure = new Point (Convert.ToDouble(RootRow["RightX"]), Convert.ToDouble(RootRow["BottomY"])); double MaxDrawingAreaAspectRatio = MaxDrawingWidth / MaxDrawingHeight; double RootKachelAspectRatio = LeftToRightDistance / BottomToTopDistance; if (RootKachelAspectRatio >= MaxDrawingAreaAspectRatio) { FullDrawingWidth = MaxDrawingWidth; FullDrawingHeight = FullDrawingWidth / RootKachelAspectRatio; } else { FullDrawingHeight = MaxDrawingHeight; FullDrawingWidth = FullDrawingHeight * RootKachelAspectRatio; } }
public override object Execute(object[] args, ExecutionContext ctx) { string ret = ""; ArgumentChecker checker = new ArgumentChecker(this.GetType().Name); checker.CheckForNumberOfArguments(ref args, 3, null); Framework.Data.Location ll = Utils.Conversion.StringToLocation(args[0].ToString()); double distance = Utils.Conversion.StringToDouble(args[1].ToString()); double angle = Utils.Conversion.StringToDouble(args[2].ToString()); if (ll != null) { GeodeticCalculator gc = new GeodeticCalculator(); GlobalCoordinates p = gc.CalculateEndingGlobalCoordinates(Ellipsoid.WGS84, new GlobalCoordinates(new Angle(ll.Lat), new Angle(ll.Lon)), new Angle(angle), distance); ret = Utils.Conversion.GetCoordinatesPresentation(p.Latitude.Degrees, p.Longitude.Degrees); } return ret; }
public void TestCalculateGeodeticCurve() { // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // set Lincoln Memorial coordinates GlobalCoordinates lincolnMemorial; lincolnMemorial = new GlobalCoordinates(38.88922, -77.04978); // set Eiffel Tower coordinates GlobalCoordinates eiffelTower; eiffelTower = new GlobalCoordinates(48.85889, 2.29583); // calculate the geodetic curve GeodeticCurve geoCurve = geoCalc.CalculateGeodeticCurve(reference, lincolnMemorial, eiffelTower); Assert.AreEqual(6179016.136, geoCurve.EllipsoidalDistance, 0.001); Assert.AreEqual(51.76792142, geoCurve.Azimuth.Degrees, 0.0000001); Assert.AreEqual(291.75529334, geoCurve.ReverseAzimuth.Degrees, 0.0000001); }
/// <summary> /// Calculate the three-dimensional path from /// Pike's Peak in Colorado --> 38.840511N, 105.0445896W, 4301 meters /// to /// Alcatraz Island --> 37.826389N, 122.4225W, sea level /// using /// WGS84 reference ellipsoid /// </summary> static void ThreeDimensionalInverseCalculation() { // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // set Pike's Peak position GlobalPosition pikesPeak; pikesPeak = new GlobalPosition( new GlobalCoordinates(new Angle(38.840511), new Angle(-105.0445896)), 4301.0 ); // set Alcatraz Island coordinates GlobalPosition alcatrazIsland; alcatrazIsland = new GlobalPosition( new GlobalCoordinates(new Angle(37.826389), new Angle(-122.4225)), 0.0 ); // calculate the geodetic measurement GeodeticMeasurement geoMeasurement; double p2pKilometers; double p2pMiles; double elevChangeMeters; double elevChangeFeet; geoMeasurement = geoCalc.CalculateGeodeticMeasurement(reference, pikesPeak, alcatrazIsland); p2pKilometers = geoMeasurement.PointToPointDistance / 1000.0; p2pMiles = p2pKilometers * 0.621371192; elevChangeMeters = geoMeasurement.ElevationChange; elevChangeFeet = elevChangeMeters * 3.2808399; Console.WriteLine("3-D path from Pike's Peak to Alcatraz Island using WGS84"); Console.WriteLine(" Point-to-Point Distance: {0:0.00} kilometers ({1:0.00} miles)", p2pKilometers, p2pMiles); Console.WriteLine(" Elevation change: {0:0.0} meters ({1:0.0} feet)", elevChangeMeters, elevChangeFeet); Console.WriteLine(" Azimuth: {0:0.00} degrees", geoMeasurement.Azimuth.Degrees); Console.WriteLine(" Reverse Azimuth: {0:0.00} degrees", geoMeasurement.ReverseAzimuth.Degrees); }
public void TestAntiPodal2() { // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // set position 1 GlobalCoordinates p1; p1 = new GlobalCoordinates(11, 80); // set position 2 GlobalCoordinates p2; p2 = new GlobalCoordinates(-10, -100); // calculate the geodetic measurement GeodeticCurve geoCurve; geoCurve = geoCalc.CalculateGeodeticCurve(reference, p1, p2); Assert.AreEqual(19893320.272061437, geoCurve.EllipsoidalDistance, 0.001); Assert.AreEqual(360.0, geoCurve.Azimuth.Degrees, 0.0000001); Assert.AreEqual(0.0, geoCurve.ReverseAzimuth.Degrees, 0.0000001); }
public void TestPoleCrossing() { // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // set Lincoln Memorial coordinates GlobalCoordinates lincolnMemorial; lincolnMemorial = new GlobalCoordinates(new Angle(38.88922), new Angle(-77.04978)); // set a bearing of 1.0deg (almost straight up) and a distance Angle startBearing = new Angle(1.0); double distance = 6179016.13586; // set the expected destination GlobalCoordinates expected; expected = new GlobalCoordinates(new Angle(85.60006433), new Angle(92.17243943)); // calculate the ending global coordinates Angle endBearing; GlobalCoordinates dest = geoCalc.CalculateEndingGlobalCoordinates(reference, lincolnMemorial, startBearing, distance, out endBearing); Assert.AreEqual(expected.Latitude.Degrees, dest.Latitude.Degrees, 0.0000001); Assert.AreEqual(expected.Longitude.Degrees, dest.Longitude.Degrees, 0.0000001); }
public void TestInverseWithDirect() { // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // set Lincoln Memorial coordinates GlobalCoordinates lincolnMemorial; lincolnMemorial = new GlobalCoordinates( new Angle(38.88922), new Angle(-77.04978)); // set Eiffel Tower coordinates GlobalCoordinates eiffelTower; eiffelTower = new GlobalCoordinates(48.85889, 2.29583); // calculate the geodetic curve GeodeticCurve geoCurve = geoCalc.CalculateGeodeticCurve(reference, lincolnMemorial, eiffelTower); // now, plug the result into to direct solution GlobalCoordinates dest; Angle endBearing = new Angle(); dest = geoCalc.CalculateEndingGlobalCoordinates(reference, lincolnMemorial, geoCurve.Azimuth, geoCurve.EllipsoidalDistance, out endBearing); Assert.AreEqual(eiffelTower.Latitude.Degrees, dest.Latitude.Degrees, 0.0000001); Assert.AreEqual(eiffelTower.Longitude.Degrees, dest.Longitude.Degrees, 0.0000001); }
private void calculateProjection() { Framework.Data.Location ll = Utils.Conversion.StringToLocation(textBox3.Text); if (ll != null) { GeodeticCalculator gc = new GeodeticCalculator(); GlobalCoordinates p = gc.CalculateEndingGlobalCoordinates(Ellipsoid.WGS84, new GlobalCoordinates(new Angle(ll.Lat), new Angle(ll.Lon)), new Angle((double)numericUpDown2.Value), radioButton1.Checked ? (double)numericUpDown1.Value : 1609.26939 * (double)numericUpDown2.Value); textBox4.Text = Utils.Conversion.GetCoordinatesPresentation(p.Latitude.Degrees, p.Longitude.Degrees); } else { textBox4.Text = ""; } }
public override async Task<bool> Load() { var client1 = new HttpClient(); var request1 = new HttpRequestMessage(HttpMethod.Get, "http://mesonet-nexrad.agron.iastate.edu/level2/raw/" + this.siteName + "/dir.list"); string scanList = await (await client1.SendAsync(request1)).Content.ReadAsStringAsync(); var scans = scanList.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); var chosen = scans[scans.Length - 2].Split(' ')[1]; var filelink = "http://mesonet-nexrad.agron.iastate.edu/level2/raw/" + this.siteName +"/" + chosen; var scaleColorsText = FileLoader.LoadTextFile("config/scale_BR.json"); var scaleColors = JsonConvert.DeserializeObject<List<ColorScaleItem>>(scaleColorsText); cells = new List<RadarCell>(); var uncompressedData = new MemoryStream(); var start = DateTime.UtcNow; Debug.WriteLine("start"); var client = new HttpClient(); var request = new HttpRequestMessage(HttpMethod.Get, filelink); Stream contentStream = await (await client.SendAsync(request)).Content.ReadAsStreamAsync(); var memoryReader = new MemoryStream((int)contentStream.Length); await contentStream.CopyToAsync(memoryReader); // Copy file into memory //var fileReader = File.OpenRead(this.filename); //var memoryReader = new MemoryStream((int)fileReader.Length); //fileReader.CopyTo(memoryReader); //fileReader.Close(); memoryReader.Seek(0, SeekOrigin.Begin); var chunks = new List<Chunk>(); var binaryReader = new BinaryReader(memoryReader); var bigEndianReader = new BigEndianReader(binaryReader); bigEndianReader.Skip(24); bool last = false; // Read each chunk, Get offset and size for each while (!last) { var chunkSize = bigEndianReader.ReadInt32(); if (chunkSize < 0) { chunkSize *= -1; last = true; } if (chunkSize == 0) { continue; } var compressedSignifier = bigEndianReader.ReadChars(2); long pointer = bigEndianReader.BaseStream.Seek(-2, SeekOrigin.Current); bigEndianReader.Skip(chunkSize); chunks.Add(new Chunk { offset = (int)pointer, length = chunkSize, isCompressed = compressedSignifier == "BZ" }); } bigEndianReader.Close(); binaryReader.Close(); var byteBuffer = memoryReader.GetBuffer(); memoryReader.Close(); var opts = new ParallelOptions { MaxDegreeOfParallelism = 6 }; // Decompress each chunk from file. Parallel.ForEach(chunks, opts, chunk => { if (chunk.isCompressed) { chunk.uncompressed = new MemoryStream(); var chunkStream = new MemoryStream(byteBuffer, chunk.offset, chunk.length); var chunkStart = DateTime.UtcNow; ICSharpCode.SharpZipLib.BZip2.BZip2.Decompress(chunkStream, chunk.uncompressed, false); chunk.uncompressed.Seek(0, SeekOrigin.Begin); } }); // Sum the sizes for each chunk var size = (int)chunks.Sum(x => { if (x.isCompressed) { return x.uncompressed.Length; } else { return x.length; } }); // var uncompressedStream = new MemoryStream(size); foreach(var chunk in chunks){ if (chunk.isCompressed) { chunk.uncompressed.CopyTo(uncompressedStream); } else { uncompressedStream.Write(byteBuffer, chunk.offset, chunk.length); } } Debug.WriteLine("took " + (DateTime.UtcNow - start).TotalMilliseconds + " ms file is reassembled"); uncompressedStream.Seek(0, SeekOrigin.Begin); var uncompressedBinaryReader = new BinaryReader(uncompressedStream); var uncompressedReader = new BigEndianReader(uncompressedBinaryReader); var uncompressedLength = uncompressedStream.Length; var counts = new Dictionary<int, int>(); var elevations = new Dictionary<int, int>(); var azimuths = new Dictionary<int, float>(); int record = 0; int message_offset31 = 0; int countRefs = 0; while (true) { long offset = record * 2432 + message_offset31; record++; if (offset >= uncompressedLength) { break; } uncompressedReader.BaseStream.Seek(offset, SeekOrigin.Begin); uncompressedReader.Skip(12); var messageSize = uncompressedReader.ReadUInt16(); var idChannel = uncompressedReader.ReadBytes(1); var messageType = uncompressedReader.ReadBytes(1); uncompressedReader.Skip(8); var numSegments = uncompressedReader.ReadUInt16(); var curSegment = uncompressedReader.ReadUInt16(); if (!counts.ContainsKey(messageType[0])) { counts.Add(messageType[0], 1); } else { counts[messageType[0]]++; } if (messageType[0] == 31) { message_offset31 = message_offset31 + (messageSize * 2 + 12 - 2432); var identier = uncompressedReader.ReadChars(4); uncompressedReader.Skip(6); var azimuthNumber = uncompressedReader.ReadUInt16(); var azimuthAngle = uncompressedReader.ReadFloat(); var compressedFlag = uncompressedReader.ReadBytes(1)[0]; var sp = uncompressedReader.ReadBytes(1)[0]; var rlength = uncompressedReader.ReadInt16(); var ars = uncompressedReader.ReadBytes(1)[0]; if (!azimuths.ContainsKey(azimuthNumber)) { azimuths.Add(azimuthNumber, azimuthAngle); } if (ars != 1) { //not HI res. continue; } var rs = uncompressedReader.ReadBytes(1)[0]; var elevation_num = uncompressedReader.ReadBytes(1)[0]; // RDA elevation number var cut = uncompressedReader.ReadBytes(1); // sector number within cut var elevation = uncompressedReader.ReadFloat(); if (elevation_num != 1) { continue; } if (!elevations.ContainsKey(elevation_num)) { elevations.Add(elevation_num, 1); } else { elevations[elevation_num]++; } var rsbs = uncompressedReader.ReadBytes(1)[0]; var aim = uncompressedReader.ReadBytes(1)[0]; var dcount = uncompressedReader.ReadInt16(); uint[] data_pointers = new uint[9]; for (int i = 0; i < 9; i++) { data_pointers[i] = uncompressedReader.ReadUInt32(); } for (int i = 0; i < 9; i++) { uncompressedReader.BaseStream.Seek(offset + 28+ data_pointers[i], SeekOrigin.Begin); uncompressedReader.Skip(1); var dataBlockName = uncompressedReader.ReadChars(3); if (dataBlockName == "REF") { uncompressedReader.Skip(4); var numGates = uncompressedReader.ReadUInt16(); var firstGateDistance = uncompressedReader.ReadUInt16(); var gateDistanceInterval = uncompressedReader.ReadUInt16(); uncompressedReader.Skip(6); var dataMomentScale = uncompressedReader.ReadFloat(); var dataMomentOffset = uncompressedReader.ReadFloat(); for (int j = 0; j < numGates; j++) { var gateBytes = uncompressedReader.ReadBytes(1)[0]; var dist = firstGateDistance + gateDistanceInterval * j; var reflectivity = gateBytes * 0.5f - 33; if (reflectivity < 1) { continue; } var cell = new RadarCell { reflectivity = reflectivity, azimuth = azimuthAngle, dist = dist, azimuthNumber = azimuthNumber }; this.cells.Add(cell); } countRefs++; } else if (this.latitude == 0 && dataBlockName == "VOL") { Debug.WriteLine("Found VOL"); uncompressedReader.Skip(4); this.latitude = uncompressedReader.ReadFloat(); this.longitude = uncompressedReader.ReadFloat(); } } } } Debug.WriteLine("took " + (DateTime.UtcNow - start).TotalMilliseconds + " ms radar ready to render"); this.vertexArray = new float[this.cells.Count * 3 * 6]; this.colorArray = new float[this.cells.Count * 4 * 6]; var earth = Ellipsoid.WGS84; var stationGeo = new GlobalCoordinates(new Angle(this.latitude), new Angle(this.longitude)); var calc = new GeodeticCalculator(); Parallel.For(0, this.cells.Count, opts, i => { var cell = this.cells[i]; if (cell.azimuthNumber == azimuths.Count()) { cell.azimuth_after = azimuths[1]; } else { cell.azimuth_after = azimuths[cell.azimuthNumber+1]; } int bucket = -1; for(int j = 0; j < scaleColors.Count; j++){ if( cell.reflectivity > scaleColors[j].dbZ ) { bucket = j; break; } } switch (bucket) { case 0: case -1: //off scale. break; case 1: default: int[] lowColor = null; int[] highColor = null; if (bucket == 1) { lowColor = new int[] { scaleColors[0].range[0], scaleColors[0].range[1], scaleColors[0].range[2] }; highColor = new int[] { scaleColors[1].range[0], scaleColors[1].range[1], scaleColors[1].range[2] }; } else { lowColor = new int[] { scaleColors[bucket].range[3], scaleColors[bucket].range[4], scaleColors[bucket].range[5] }; highColor = new int[] { scaleColors[bucket].range[0], scaleColors[bucket].range[1], scaleColors[bucket].range[2] }; } var range = scaleColors[bucket - 1].dbZ - scaleColors[bucket].dbZ; var percentForLowColor = (cell.reflectivity - scaleColors[bucket].dbZ) / range; var percentForHighColor = 1 - percentForLowColor; cell.r = (percentForHighColor * highColor[0] + percentForLowColor * lowColor[0]) / 255.0f; cell.g = (percentForHighColor * highColor[1] + percentForLowColor * lowColor[1]) / 255.0f; cell.b = (percentForHighColor * highColor[2] + percentForLowColor * lowColor[2]) / 255.0f; break; } var r = cell.dist; int baseVertex = 3 * 6 * i; var top_left = calc.CalculateEndingGlobalCoordinates(earth, stationGeo, new Angle(cell.azimuth_after), r+250.0f); var top_right = calc.CalculateEndingGlobalCoordinates(earth, stationGeo, new Angle(cell.azimuth), r+250.0f); var bottom_right = calc.CalculateEndingGlobalCoordinates(earth, stationGeo, new Angle(cell.azimuth), r); var bottom_left = calc.CalculateEndingGlobalCoordinates(earth, stationGeo, new Angle(cell.azimuth_after), r); this.vertexArray[baseVertex + 0] = ConvertLongitude(top_left.Longitude.Degrees);//top left x this.vertexArray[baseVertex + 1] = ConvertLatitude(top_left.Latitude.Degrees);///top left y this.vertexArray[baseVertex + 3] = ConvertLongitude(top_right.Longitude.Degrees); //top right x this.vertexArray[baseVertex + 4] = ConvertLatitude(top_right.Latitude.Degrees); //top right y this.vertexArray[baseVertex + 6] = ConvertLongitude(bottom_right.Longitude.Degrees); //bottom right x this.vertexArray[baseVertex + 7] = ConvertLatitude(bottom_right.Latitude.Degrees); //bottom right y this.vertexArray[baseVertex + 9] = ConvertLongitude(bottom_right.Longitude.Degrees);//bottom right x this.vertexArray[baseVertex + 10] =ConvertLatitude(bottom_right.Latitude.Degrees); //bottom right y this.vertexArray[baseVertex + 12] = ConvertLongitude(bottom_left.Longitude.Degrees); //bottom left x this.vertexArray[baseVertex + 13] = ConvertLatitude(bottom_left.Latitude.Degrees);//bottom left y this.vertexArray[baseVertex + 15] = ConvertLongitude(top_left.Longitude.Degrees); //top left x this.vertexArray[baseVertex + 16] = ConvertLatitude(top_left.Latitude.Degrees); //top left y int baseColor = 4 * 6 * i; const float alpha = 0.6f; this.colorArray[baseColor + 0] = cell.r; this.colorArray[baseColor + 1] = cell.g; this.colorArray[baseColor + 2] = cell.b; this.colorArray[baseColor + 3] = alpha; this.colorArray[baseColor + 4] = cell.r; this.colorArray[baseColor + 5] = cell.g; this.colorArray[baseColor + 6] = cell.b; this.colorArray[baseColor + 7] = alpha; this.colorArray[baseColor + 8] = cell.r; this.colorArray[baseColor + 9] = cell.g; this.colorArray[baseColor + 10] = cell.b; this.colorArray[baseColor + 11] = alpha; this.colorArray[baseColor + 12] = cell.r; this.colorArray[baseColor + 13] = cell.g; this.colorArray[baseColor + 14] = cell.b; this.colorArray[baseColor + 15] = alpha; this.colorArray[baseColor + 16] = cell.r; this.colorArray[baseColor + 17] = cell.g; this.colorArray[baseColor + 18] = cell.b; this.colorArray[baseColor + 19] = alpha; this.colorArray[baseColor + 20] = cell.r; this.colorArray[baseColor + 21] = cell.g; this.colorArray[baseColor + 22] = cell.b; this.colorArray[baseColor + 23] = alpha; }); //this.isLoaded = true; return true; }