public async Task ElevationService_SinglePointMapZenTest()
        {
            var client = new HttpClient();

            var testData = GrandCanyonPointsWithMapZenElevations();

            foreach (var loopTests in testData)
            {
                var result = await ElevationService.OpenTopoMapZenElevation(client, loopTests.Latitude,
                                                                            loopTests.Longitude, DebugTrackers.DebugProgressTracker());

                Assert.NotNull(result, $"Null result from {loopTests.Name}");
                Assert.AreEqual(loopTests.RoundedElevationInMeters, Math.Round(result.Value, 2), $"{loopTests.Name}");
            }
        }
        public async Task Line_SanPedroTwoTrackFile()
        {
            var testFile = new FileInfo(Path.Combine(Directory.GetCurrentDirectory(), "TestMedia",
                                                     "TwoTrackGpxNearTheSanPedro.gpx"));

            Assert.True(testFile.Exists, "Test File Found");

            var tracks = await SpatialHelpers.TracksFromGpxFile(testFile, DebugTrackers.DebugProgressTracker());

            Assert.AreEqual(2, tracks.Count, "Should find 2 tracks");
            Assert.True(tracks.All(x => !string.IsNullOrWhiteSpace(x.description)),
                        "Found Tracks with Blank Description?");

            var shortTrack = tracks.OrderBy(x => x.track.Count).First().track;

            Assert.AreEqual(214, shortTrack.Count, "Unexpected Point Count");

            var preElevationReplacementStats = SpatialHelpers.LineStatsInImperialFromCoordinateList(shortTrack);

            Assert.IsTrue(preElevationReplacementStats.Length.IsApproximatelyEqualTo(2.8, .05),
                          $"ExpertGPS Length 2.79, Measured {preElevationReplacementStats.Length}");
            Assert.IsTrue(preElevationReplacementStats.ElevationClimb.IsApproximatelyEqualTo(158, 1),
                          $"ExpertGPS Climb 158.4, Measured {preElevationReplacementStats.ElevationClimb}");
            Assert.IsTrue(preElevationReplacementStats.ElevationDescent.IsApproximatelyEqualTo(285, 1),
                          $"ExpertGPS Descent 285.6, Measured {preElevationReplacementStats.ElevationDescent}");
            Assert.IsTrue(preElevationReplacementStats.MinimumElevation.IsApproximatelyEqualTo(3795, 1),
                          $"ExpertGPS Min Elevation 3795.25, Measured {preElevationReplacementStats.MinimumElevation}");
            Assert.IsTrue(preElevationReplacementStats.MaximumElevation.IsApproximatelyEqualTo(3944, 1),
                          $"ExpertGPS Max Elevation 3944.76, Measured {preElevationReplacementStats.MaximumElevation}");

            await ElevationService.OpenTopoMapZenElevation(new HttpClient(), shortTrack,
                                                           DebugTrackers.DebugProgressTracker());

            Assert.True(shortTrack.All(x => x.Z > 0), "After Elevation replacement some 0 values found");

            var postElevationReplacementStats = SpatialHelpers.LineStatsInImperialFromCoordinateList(shortTrack);

            Assert.IsTrue(postElevationReplacementStats.Length.IsApproximatelyEqualTo(2.8, .05),
                          $"ExpertGPS Length 2.79, Measured {preElevationReplacementStats.Length}");
            Assert.IsTrue(postElevationReplacementStats.ElevationClimb.IsApproximatelyEqualTo(36.08, 1),
                          $"Expected 36.08, Measured {preElevationReplacementStats.ElevationClimb}");
            Assert.IsTrue(postElevationReplacementStats.ElevationDescent.IsApproximatelyEqualTo(187, 1),
                          $"Expected 187, Measured {preElevationReplacementStats.ElevationDescent}");
            Assert.IsTrue(postElevationReplacementStats.MinimumElevation.IsApproximatelyEqualTo(3891.07, 1),
                          $"Expected 3891, Measured {preElevationReplacementStats.MinimumElevation}");
            Assert.IsTrue(postElevationReplacementStats.MaximumElevation.IsApproximatelyEqualTo(4041.99, 1),
                          $"Expected 4041, Measured {preElevationReplacementStats.MaximumElevation}");
        }
        public async Task ElevationService_MultiPointMapZenTest()
        {
            var client = new HttpClient();

            var testData = GrandCanyonPointsWithMapZenElevations()
                           .Select(x => new CoordinateZ(x.Longitude, x.Latitude, 0)).ToList();

            await ElevationService.OpenTopoMapZenElevation(client, testData, DebugTrackers.DebugProgressTracker());

            Assert.IsTrue(testData.All(x => x.Z > 0), "Not all point have an elevation greater than zero.");

            var referenceData = GrandCanyonPointsWithMapZenElevations();

            foreach (var loopTestData in testData)
            {
                var referenceItem =
                    referenceData.Single(x => x.Latitude == loopTestData.Y && x.Longitude == loopTestData.X);
                Assert.AreEqual(Math.Round(referenceItem.RoundedElevationInMeters, 2), Math.Round(loopTestData.Z, 2),
                                $"{referenceItem.Name} didn't match expected");
            }
        }
        public static async Task <string> GeoJsonWithLineStringFromCoordinateList(List <CoordinateZ> pointList,
                                                                                  bool replaceElevations, IProgress <string> progress)
        {
            if (replaceElevations)
            {
                await ElevationService.OpenTopoMapZenElevation(new HttpClient(), pointList, progress);
            }

            // ReSharper disable once CoVariantArrayConversion It appears from testing that a linestring will reflect CoordinateZ
            var newLineString     = new LineString(pointList.ToArray());
            var newFeature        = new Feature(newLineString, new AttributesTable());
            var featureCollection = new FeatureCollection {
                newFeature
            };

            var serializer = GeoJsonSerializer.Create(Wgs84GeometryFactory(), 3);

            await using var stringWriter = new StringWriter();
            using var jsonWriter         = new JsonTextWriter(stringWriter);
            serializer.Serialize(jsonWriter, featureCollection);
            return(stringWriter.ToString());
        }