/// <summary> /// Extract all information required from the specified dataset. /// </summary> /// <param name="dataset"> /// The <see cref="Dataset"/> from which the information must be extracted. /// </param> protected void ExtractGeoInformation(Dataset dataset, Rectangle area) { if (dataset == null) { throw new ArgumentNullException("dataset"); } // Geographic area // Geographic area double[] geoTransform = new double[6]; double[] lat = new double[2], lon = new double[2]; dataset.GetGeoTransform(geoTransform); Gdal.ApplyGeoTransform(geoTransform, area.Left, area.Bottom, out lon[0], out lat[0]); Gdal.ApplyGeoTransform(geoTransform, area.Right, area.Top, out lon[1], out lat[1]); Latitude = (lat[0] + lat[1]) / 2.0; Longitude = (lon[0] + lon[1]) / 2.0; Width = Math.Abs(lat[0] - lat[1]); Height = Math.Abs(lon[0] - lon[1]); // Textel precision double w1 = Vincenty.GetDistance(new Vertex2d(lon[0], lat[0]), new Vertex2d(lon[1], lat[0])); double w2 = Vincenty.GetDistance(new Vertex2d(lon[0], lat[1]), new Vertex2d(lon[1], lat[1])); double h1 = Vincenty.GetDistance(new Vertex2d(lon[0], lat[0]), new Vertex2d(lon[0], lat[1])); double h2 = Vincenty.GetDistance(new Vertex2d(lon[1], lat[0]), new Vertex2d(lon[1], lat[1])); double wp = ((w1 + w2) / 2.0) / (double)area.Width; double hp = ((h1 + h2) / 2.0) / (double)area.Height; _TextelPrecision = (wp + hp) / 2.0; }
static void Main(string[] args) { GeoPoint point = new GeoPoint(new Latitude(0), new Longitude(0), Ellipsoid.CGCS2000); Angle angle = new Angle(90, 0, 0.01); Bessel bessel = new Bessel(point, 1000.0, angle); Gauss gauss = new Gauss(point, 1000.0, angle); Vincenty vincenty = new Vincenty(point, 1000.0, angle); TransParameters trans = new TransParameters(null, null, -15.415, 157.025, 94.74, -1.465, 0.312, 0.08, 0.102); BursaWolf bursa = new BursaWolf(trans); GeodeticCoord pnt1 = new GeodeticCoord(new Latitude(35), new Longitude(100), 0); SpaceRectangularCoord xyz = Conversion.BLH_XYZ(Ellipsoid.Krassovsky, pnt1); xyz = bursa.Transform(xyz); GeodeticCoord p11 = Conversion.XYZ_BLH(Ellipsoid.WGS84, xyz); GeodeticCoord pnt2 = new GeodeticCoord(new Latitude(35), new Longitude(100), 3000); xyz = Conversion.BLH_XYZ(Ellipsoid.Krassovsky, pnt2); xyz = bursa.Transform(xyz); GeodeticCoord p22 = Conversion.XYZ_BLH(Ellipsoid.WGS84, xyz); double d = Math.Abs(pnt1.Height - pnt2.Height) - Math.Abs(p11.Height - p22.Height); //Origin origin = new Origin(lat, lng, 123); //object[] value = origin.GetPoint(); //Longitude lg = (Longitude)value[1]; //string json = JsonConvert.SerializeObject(Ellipsoid.CGCS2000); //Ellipsoid ellip = JsonConvert.DeserializeObject<Ellipsoid>(json); //GeoPoint point = new GeoPoint(lat, lng, ellip); //json = JsonConvert.SerializeObject(point); //GeoPoint pnt = JsonConvert.DeserializeObject<GeoPoint>(json); //Bessel bessel = new Bessel(new GeoPoint(lat, lng), 1000, new Angle(12, 23, 34), Ellipsoid.CGCS2000); //Angle a = bessel.Bearing; //Ellipsoid w84 = new Ellipsoid(6378137, 298.257222101, 7.292115e-5, 3.986004418e14); //Ellipsoid g84 = new Ellipsoid(6378137.0, 1.082629832258e-3, Angle.FromRadians(7.292115e-5), 3.986004418e14); //double ep = w84.ivf - g84.ivf; //Ellipsoid ellipsoid = Ellipsoid.WGS84; //GaussKrueger gauss = new GaussKrueger(new Ellipsoid(6378140, 298.257)); //gauss.Inverse(2280131, 465804, out Latitude lat, out Longitude lng); //lng += new Angle(111); //string aa = lat.Degrees.ToString() +"\\" +lng.Degrees.ToString(); //Dictionary<ProjectionParameter, double> parameters = new Dictionary<ProjectionParameter, double>(); //parameters.Add(ProjectionParameter.SemiMajor, Ellipsoid.WGS84.a); //parameters.Add(ProjectionParameter.InverseFlattening, -1); //parameters.Add(ProjectionParameter.FalseEasting, 5.0); //parameters.Add(ProjectionParameter.FalseNorthing, 6.0); //parameters.Add(ProjectionParameter.CenterMeridian, 120.0); //parameters.Add(ProjectionParameter.LatitudeOfOrigin, 30.0); //CassiniSoldner cassini = new CassiniSoldner(parameters); //cassini.Forward(new Latitude(34), new Longitude(123), out double northing, out double easting); //cassini.Inverse(northing, easting, out Latitude lat, out Longitude lng); }
private void UpdatePlot() { if (size.Width == 0 || size.Height == 0 || !IsVisible) { return; } if (locations.Count == 0) { Dispatcher.Invoke(() => { Status.Text = ""; plot.Source = null; }); return; } var measurements = locations.ToArray(); // Grab copy to avoid threading issues if (filterIndex > 0) { measurements = measurements.Where(m => filterIndex == 1 && (m.Quality == NmeaParser.Messages.Gga.FixQuality.DgpsFix || m.Quality == NmeaParser.Messages.Gga.FixQuality.FloatRtk || m.Quality == NmeaParser.Messages.Gga.FixQuality.Rtk) || filterIndex == 2 && (m.Quality == NmeaParser.Messages.Gga.FixQuality.FloatRtk || m.Quality == NmeaParser.Messages.Gga.FixQuality.Rtk) || filterIndex == 3 && m.Quality == NmeaParser.Messages.Gga.FixQuality.Rtk).ToArray(); } if (measurements.Length == 0) { Dispatcher.Invoke(() => { Status.Text = ""; plot.Source = null; }); return; } var latAvr = measurements.Select(l => l.Latitude).Average(); if (useWeightedAverage && !measurements.Any(m => double.IsNaN(m.LatError))) { latAvr = WeightedAverage(measurements, z => z.Latitude, z => 1 / z.LatError); } var lonAvr = measurements.Select(l => l.Longitude).Average(); if (useWeightedAverage && !measurements.Any(m => double.IsNaN(m.LonError))) { lonAvr = WeightedAverage(measurements, z => z.Longitude, z => 1 / z.LonError); } //List<double> lonDistances = new List<double>(locations.Count); //List<double> latDistances = new List<double>(locations.Count); List <double> distances = new List <double>(measurements.Length); var locations2 = new List <Point>(); foreach (var l in measurements) { var d = Vincenty.GetDistanceVincenty(latAvr, lonAvr, l.Latitude, l.Longitude); var dLat = Vincenty.GetDistanceVincenty(latAvr, lonAvr, l.Latitude, lonAvr); var dLon = Vincenty.GetDistanceVincenty(latAvr, lonAvr, latAvr, l.Longitude); distances.Add(d); if (latAvr > l.Latitude) { dLat = -dLat; } if (lonAvr > l.Longitude) { dLon = -dLon; } locations2.Add(new Point() { Latitude = dLat, Longitude = dLon, Quality = l.Quality, LatError = l.LatError, LonError = l.LonError, ZError = l.ZError }); } var latMin = locations2.Select(l => l.Latitude).Min(); var lonMin = locations2.Select(l => l.Longitude).Min(); var latMax = locations2.Select(l => l.Latitude).Max(); var lonMax = locations2.Select(l => l.Longitude).Max(); var latAvr2 = locations2.Select(l => l.Latitude).Average(); if (useWeightedAverage && !measurements.Any(m => double.IsNaN(m.LatError))) { latAvr2 = WeightedAverage(locations2, z => z.Latitude, z => 1 / z.LatError); } var lonAvr2 = locations2.Select(l => l.Longitude).Average(); if (useWeightedAverage && !measurements.Any(m => double.IsNaN(m.LonError))) { lonAvr2 = WeightedAverage(locations2, z => z.Longitude, z => 1 / z.LonError); } var maxDifLat = Math.Max(latAvr2 - latMin, latMax - latAvr2); var maxDifLon = Math.Max(lonAvr2 - lonMin, lonMax - lonAvr2); //var maxDif = Math.Max(maxDifLat, maxDifLon); double maxDif = 1; if (autoFit) { maxDif = distances.Max(); if (maxDif < 0.05) { maxDif = 0.05; } else if (maxDif < 1) { maxDif = Math.Ceiling(maxDif * 10) / 10d; } else { maxDif = Math.Ceiling(maxDif); } currentScale = maxDif / (Math.Min(size.Width, size.Height) * .5); } else { maxDif = currentScale * (Math.Min(size.Width, size.Height) * .5); } double scale = currentScale; if (scale == 0) { scale = 1; } int width = (int)size.Width; int height = (int)size.Height; int stride = width * 4; byte[] pixels = new byte[width * height * 4]; double[][] stamp = new double[][] { new double[] { .3, .5, .3 }, new double[] { .5, 1, .5 }, new double[] { .3, .5, .3 } }; Color col = Colors.Red; for (int i = 0; i < locations2.Count; i++) { var l = locations2[i]; var x = (int)(width * .5 + (l.Longitude - lonAvr2) / scale); var y = (int)(height * .5 - (l.Latitude - latAvr2) / scale); var index = ((int)y) * stride + ((int)x) * 4; for (int r = -1; r < stamp.Length - 1; r++) { for (int c = -1; c < stamp[r + 1].Length - 1; c++) { if (x + c >= width || x + c < 0 || y + r >= width || y + r < 0) { continue; } var p = index + r * stride + c * 4; var val = stamp[r + 1][c + 1]; switch (l.Quality) { case NmeaParser.Messages.Gga.FixQuality.Estimated: col = Colors.Red; break; case NmeaParser.Messages.Gga.FixQuality.GpsFix: col = Colors.Orange; break; case NmeaParser.Messages.Gga.FixQuality.DgpsFix: col = Colors.Yellow; break; case NmeaParser.Messages.Gga.FixQuality.FloatRtk: col = Color.FromRgb(0, 255, 0); break; case NmeaParser.Messages.Gga.FixQuality.Rtk: col = Colors.LightBlue; break; default: col = Colors.Gray; break; } pixels[p + 1] = col.B; pixels[p + 1] = col.G; pixels[p + 2] = col.R; pixels[p + 3] = (byte)Math.Min(255, pixels[p + 3] + val * 255); //Multiply alpha } } } var stdDevLat = Math.Sqrt(locations2.Sum(d => (d.Latitude - latAvr2) * (d.Latitude - latAvr2)) / locations2.Count); var stdDevLon = Math.Sqrt(locations2.Sum(d => (d.Longitude - lonAvr2) * (d.Longitude - lonAvr2)) / locations2.Count); var zs = measurements.Where(l => !double.IsNaN(l.Z)); var zAvr = measurements.Select(l => l.Z).Where(l => !double.IsNaN(l)).Average(); if (useWeightedAverage && !measurements.Any(m => double.IsNaN(m.ZError))) { zAvr = WeightedAverage(zs, z => z.Z, z => 1 / z.ZError); } var stdDevZ = Math.Sqrt(measurements.Select(l => l.Z).Where(l => !double.IsNaN(l)).Sum(d => (d - zAvr) * (d - zAvr)) / measurements.Select(l => l.Z).Where(l => !double.IsNaN(l)).Count()); var meanH = distances.Average(); var stdDevH = Math.Sqrt(distances.Sum(d => d * d) / distances.Count); var stdErrorH = stdDevH / Math.Sqrt(distances.Count); var marginOfErrorH = stdErrorH * 2; Dispatcher.Invoke(() => { SecondMeterLabel.Text = $"{maxDif.ToString("0.###")}m"; FirstMeterLabel.Text = $"{(maxDif / 2).ToString("0.###")}m"; // Specify the area of the bitmap that changed. var writeableBitmap = new WriteableBitmap((int)size.Width, (int)size.Height, 96, 96, PixelFormats.Bgra32, null); writeableBitmap.WritePixels(new Int32Rect(0, 0, width, height), pixels, stride, 0); plot.Source = writeableBitmap; Status.Text = $"Measurements: {measurements.Length}\nAverage:\n - Latitude: {latAvr.ToString("0.0000000")}\n - Longitude: {lonAvr.ToString("0.0000000")}\n - Elevation: {zAvr.ToString("0.000")}m\nStandard Deviation:\n - Latitude: {stdDevLat.ToString("0.###")}m\n - Longitude: {stdDevLon.ToString("0.###")}m\n - Horizontal: {stdDevH.ToString("0.###")}m\n95% confidence: {marginOfErrorH.ToString("0.###")}m\n - Elevation: {stdDevZ.ToString("0.###")}m"; }); }