private void AssertResultStatisticsForLeafImplementation( CrsTransformationResult transformResult ) { CrsTransformationResultStatistic crsTransformationResultStatistic = transformResult.CrsTransformationResultStatistic; Assert.IsNotNull(crsTransformationResultStatistic); Assert.IsTrue(crsTransformationResultStatistic.IsStatisticsAvailable); Assert.AreEqual(1, crsTransformationResultStatistic.NumberOfPotentiallySuccesfulResults); Assert.AreEqual(0, crsTransformationResultStatistic.MaxDifferenceForYNorthingLatitude); Assert.AreEqual(0, crsTransformationResultStatistic.MaxDifferenceForXEastingLongitude); Assert.AreEqual(transformResult.OutputCoordinate, crsTransformationResultStatistic.CoordinateAverage); Assert.AreEqual(transformResult.OutputCoordinate, crsTransformationResultStatistic.CoordinateMedian); }
private CrsTransformationResult CreateCrsTransformationResult( CrsCoordinate outputCoordinate, ICrsTransformationAdapter adapter, CrsCoordinate inputCoordinateNotUsedInThisTest ) { Exception exceptionNull = null; bool isSuccessTrue = true; return CrsTransformationResult._CreateCrsTransformationResult( inputCoordinateNotUsedInThisTest, outputCoordinate, exceptionNull, isSuccessTrue, adapter, CrsTransformationResultStatistic._CreateCrsTransformationResultStatistic(new List<CrsTransformationResult>()) ); }
public void TransformResult_ShouldReturnStatisticsObjectWithCorrectAverageAndMeanAndMaxDiffValues_WhenCreatingResultWithListOfSubresults() { // Both the setup code and the verify/assertion code for this test method // is placed in a base class because it is reused from another test class. // The keyword "super" is used below to make that more obvious. CrsTransformationResult transformResult = CrsTransformationResult._CreateCrsTransformationResult( base.inputCoordinateNotUsedInStatisticsTest, base.outputCoordinateNotUsedInStatisticsTest, null, true, base.compositeAdapterForResultTest, CrsTransformationResultStatistic._CreateCrsTransformationResultStatistic(base.listOfSubresultsForStatisticsTest) ); CrsTransformationResultStatistic crsTransformationResultStatistic = transformResult.CrsTransformationResultStatistic; base.AssertCrsTransformationResultStatistic(crsTransformationResultStatistic); }
// Lots of method in this test class creates a // CrsTransformationResult with three of the six // parameters being exactly the same. // For that reason this helper method is used, // i.e. to not duplicate the three // parameters almost always being the same. private CrsTransformationResult CreateCrsTransformationResult( //CrsCoordinate inputCoordinate: , CrsCoordinate outputCoordinate, Exception exceptionOrNull, bool isSuccess //crsTransformationAdapterResultSource: ICrsTransformationAdapter, //nullableCrsTransformationResultStatistic: CrsTransformationResultStatistic// = null ) { var transformResult = CrsTransformationResult._CreateCrsTransformationResult( inputCoordinate, outputCoordinate, exceptionOrNull, isSuccess, base.compositeAdapterForResultTest, CrsTransformationResultStatistic._CreateCrsTransformationResultStatistic(base.listOfSubresultsForStatisticsTest) ); return transformResult; }
public void CalculateAggregatedResult_ShouldThrowException_WhenResultIsBasedOnLeafsNotBeingPartOfTheWeightedAverageAdapter() { CrsCoordinate coordinate = CrsCoordinateFactory.LatLon(59, 18); List <CrsTransformationResult> emptyListOfTransformationResults = new List <CrsTransformationResult>(); ICrsTransformationAdapter leafMightyLittleGeodesy = new CrsTransformationAdapterMightyLittleGeodesy(); List <CrsTransformationAdapterWeight> leafWeightsForOnlyMightyLittleGeodesy = new List <CrsTransformationAdapterWeight> { weightFactory.CreateFromInstance( leafMightyLittleGeodesy, 1 ) }; // The below type ICompositeStrategy is "internal" in the F# project but still available from here // because of "InternalsVisibleTo" configuration in the .fsproj file. ICompositeStrategy compositeStrategyWeightedAverageForOnlyMightyLittleGeodesy = CompositeStrategyWeightedAverage._CreateCompositeStrategyWeightedAverage(leafWeightsForOnlyMightyLittleGeodesy); // The above composite was created with only one leaf in the list ICrsTransformationAdapter leafDotSpatial = new CrsTransformationAdapterDotSpatial(); CrsTransformationResult crsTransformationResultProblem = new CrsTransformationResult( coordinate, // inputCoordinate irrelevant in this test so okay to use the same as the output coordinate, // outputCoordinate null, // exception true, // isSuccess leafDotSpatial, // crsTransformationAdapterResultSource, CrsTransformationResultStatistic._CreateCrsTransformationResultStatistic(emptyListOfTransformationResults) ); // The composite strategy used below was created with only MightyLittleGeodesy, // and therefore if the result (as below) would be based on "DotSpatial" // then there is a bug somewhere i.e. an exception is thrown // which is tested below InvalidOperationException exception = Assert.Throws <InvalidOperationException>(() => { compositeStrategyWeightedAverageForOnlyMightyLittleGeodesy._CalculateAggregatedResult( new List <CrsTransformationResult> { crsTransformationResultProblem }, // allResults coordinate, coordinate.CrsIdentifier, // crsIdentifier for OutputCoordinateSystem leafDotSpatial // SHOULD CAUSE EXCEPTION ! ); }, "The result adapter was not part of the weighted average composite adapter" ); }
public void TransformResultStatistic_ShouldCalculateCorrectAverageAndMeanAndMaxDiffValues() { // Both the setup code and the verify/assertion code for this test method // is placed in a base class because it is reused from another test class // The keyword "base" is not needed but used below to make that more obvious. CrsTransformationResultStatistic crsTransformationResultStatistic = CrsTransformationResultStatistic._CreateCrsTransformationResultStatistic( base.listOfSubresultsForStatisticsTest ); // the above factory method is "internal" in the F# project // but still can be used from this test project // because of the following configuration in the F# core project: //<ItemGroup> // <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo"> // <_Parameter1>Programmerare.CrsTransformations.Test</_Parameter1> // </AssemblyAttribute> //</ItemGroup> base.AssertCrsTransformationResultStatistic(crsTransformationResultStatistic); }
private void verifyThreeImplementations( CrsTransformationAdapterComposite crsTransformationAdapterComposite ) { CrsCoordinate input = CrsCoordinateFactory.LatLon(59.0, 18.0); CrsTransformationResult result = crsTransformationAdapterComposite.Transform(input, EpsgNumber.SWEDEN__SWEREF99_TM__3006); Assert.IsNotNull(result); Assert.IsTrue(result.IsSuccess); const int numberOfImplementations = CrsTransformationAdapterTest.EXPECTED_NUMBER_OF_ADAPTER_LEAF_IMPLEMENTATIONS; Assert.AreEqual(numberOfImplementations, result.TransformationResultChildren.Count); CrsTransformationResultStatistic crsTransformationResultStatistic = result.CrsTransformationResultStatistic; Assert.IsNotNull(crsTransformationResultStatistic); Assert.IsTrue(crsTransformationResultStatistic.IsStatisticsAvailable); Assert.AreEqual(numberOfImplementations, crsTransformationResultStatistic.NumberOfPotentiallySuccesfulResults); Assert.That(crsTransformationResultStatistic.MaxDifferenceForXEastingLongitude, Is.LessThan(0.001)); }
protected void AssertCrsTransformationResultStatistic(CrsTransformationResultStatistic crsTransformationResultStatistic) { Assert.IsNotNull(crsTransformationResultStatistic); Assert.IsTrue(crsTransformationResultStatistic.IsStatisticsAvailable); Assert.AreEqual( listOfSubresultsForStatisticsTest.Count, crsTransformationResultStatistic.NumberOfPotentiallySuccesfulResults ); Assert.AreEqual( this.expectedLatDiffMax, crsTransformationResultStatistic.MaxDifferenceForYNorthingLatitude ); Assert.AreEqual( this.expectedLonDiffMax, crsTransformationResultStatistic.MaxDifferenceForXEastingLongitude ); CrsCoordinate coordinateAverage = crsTransformationResultStatistic.CoordinateAverage; CrsCoordinate coordinateMean = crsTransformationResultStatistic.CoordinateMedian; Assert.IsNotNull(coordinateAverage); Assert.IsNotNull(coordinateMean); Assert.AreEqual(this.expectedCoordinateMean, coordinateMean); Assert.AreEqual(this.expectedCoordinateAverage, coordinateAverage); }
public void IsReliableTest() { var crsTransformationAdapterCompositeFactory = CrsTransformationAdapterCompositeFactory.Create(); CrsTransformationAdapterComposite crsTransformationComposite = crsTransformationAdapterCompositeFactory.CreateCrsTransformationAverage(); var children = crsTransformationComposite.TransformationAdapterChildren; Assert.AreEqual(3, children.Count); CrsCoordinate wgs84coordinateInSweden = CrsCoordinateFactory.LatLon(59.31, 18.04); CrsTransformationResult resultWhenTransformingToSwedishCRS = crsTransformationComposite.Transform(wgs84coordinateInSweden, EpsgNumber.SWEDEN__SWEREF99_TM__3006); Assert.IsNotNull(resultWhenTransformingToSwedishCRS); Assert.IsTrue(resultWhenTransformingToSwedishCRS.IsSuccess); CrsTransformationResultStatistic crsTransformationResultStatistic = resultWhenTransformingToSwedishCRS.CrsTransformationResultStatistic; Assert.IsNotNull(crsTransformationResultStatistic); Assert.IsTrue(crsTransformationResultStatistic.IsStatisticsAvailable); int actualNumberOfResults = crsTransformationResultStatistic.NumberOfPotentiallySuccesfulResults; Assert.AreEqual( EXPECTED_NUMBER_OF_ADAPTER_LEAF_IMPLEMENTATIONS, actualNumberOfResults ); double actualMaxDiffXLongitude = crsTransformationResultStatistic.MaxDifferenceForXEastingLongitude; double actualMaxDiffYLatitude = crsTransformationResultStatistic.MaxDifferenceForYNorthingLatitude; double actualMaxDiffXorY = Math.Max(actualMaxDiffXLongitude, actualMaxDiffYLatitude); Assert.That(actualMaxDiffXorY, Is.LessThan(0.01)); Assert.IsTrue(resultWhenTransformingToSwedishCRS.IsReliable(actualNumberOfResults, actualMaxDiffXorY)); // assertFalse below since trying to require one more result than available Assert.IsFalse(resultWhenTransformingToSwedishCRS.IsReliable(actualNumberOfResults + 1, actualMaxDiffXorY)); // assertFalse below since trying to require too small maxdiff Assert.IsFalse(resultWhenTransformingToSwedishCRS.IsReliable(actualNumberOfResults, actualMaxDiffXorY - 0.00000000001)); }
public void CSharpeExampleCode() { int epsgWgs84 = EpsgNumber.WORLD__WGS_84__4326; int epsgSweRef = EpsgNumber.SWEDEN__SWEREF99_TM__3006; Assert.AreEqual(4326, epsgWgs84); Assert.AreEqual(3006, epsgSweRef); CrsCoordinate centralStockholmWgs84 = CrsCoordinateFactory.LatLon(59.330231, 18.059196, epsgWgs84); ICrsTransformationAdapter crsTransformationAdapter = CrsTransformationAdapterCompositeFactory.Create().CreateCrsTransformationMedian(); CrsTransformationResult centralStockholmResultSweRef = crsTransformationAdapter.Transform(centralStockholmWgs84, epsgSweRef); Assert.IsNotNull(centralStockholmResultSweRef); Assert.IsTrue(centralStockholmResultSweRef.IsSuccess); IList <CrsTransformationResult> transformationResultChildren = centralStockholmResultSweRef.TransformationResultChildren; // Reason for the below assertion with value 3 : // If the NuGet configuration includes all (currently three) adapter implementations, then the // above created 'Composite' implementation will below use all three 'leaf' implementations // and return a coordinate with a median longitude and a median latitude Assert.AreEqual(3, transformationResultChildren.Count); // Console.WriteLine(centralStockholmResultSweRef.OutputCoordinate); // Console output from the above code row: // CrsCoordinate(xEastingLongitude=674032.357177155, yNorthingLatitude=6580821.99121561, crsIdentifier=CrsIdentifier(crsCode='EPSG:3006', isEpsgCode=True, epsgNumber=3006)) var outputCoordinate = centralStockholmResultSweRef.OutputCoordinate; Assert.IsNotNull(outputCoordinate); Assert.AreEqual(674032.357177155, outputCoordinate.XEastingLongitude, SmallDeltaValue); Assert.AreEqual(6580821.99121561, outputCoordinate.YNorthingLatitude, SmallDeltaValue); CrsTransformationResultStatistic crsTransformationResultStatistic = centralStockholmResultSweRef.CrsTransformationResultStatistic; var medianCoordinate = crsTransformationResultStatistic.CoordinateMedian; // the median values have already been tested above since we used 'CreateCrsTransformationMedian' // for creating the main result. var averageCoordinate = crsTransformationResultStatistic.CoordinateAverage; Assert.AreEqual(674032.35716645606, averageCoordinate.XEastingLongitude, SmallDeltaValue); Assert.AreEqual(6580821.9921956062, averageCoordinate.YNorthingLatitude, SmallDeltaValue); Assert.IsTrue(crsTransformationResultStatistic.IsStatisticsAvailable); Assert.AreEqual(3, crsTransformationResultStatistic.NumberOfPotentiallySuccesfulResults); Assert.That(crsTransformationResultStatistic.MaxDifferenceForXEastingLongitude, Is.LessThan(0.01)); Assert.That(crsTransformationResultStatistic.MaxDifferenceForYNorthingLatitude, Is.LessThan(0.01)); // "Reliable True" below since there should be three sucesful results // and the absolute value for the difference between longitudes and longitudes // should be less than 0.01 Assert.IsTrue( centralStockholmResultSweRef.IsReliable( 3, // minimumNumberOfSuccesfulResults 0.01 // maxDeltaValueForXLongitudeAndYLatitude ) ); // "Reliable False" below because too extreme requirements of equal values for all the results // i.e. very small tolerance for differences Assert.IsFalse( centralStockholmResultSweRef.IsReliable( 3, // minimumNumberOfSuccesfulResults 0.000000000000000000001 // maxDeltaValueForXLongitudeAndYLatitude ) ); // "Reliable False" below because can not require 4 succesful values // when there are only 3 implementations Assert.IsFalse( centralStockholmResultSweRef.IsReliable( 4, // minimumNumberOfSuccesfulResults 0.01 // maxDeltaValueForXLongitudeAndYLatitude ) ); ICrsTransformationAdapter crsTransformationAdapterResultSource = centralStockholmResultSweRef.CrsTransformationAdapterResultSource; CrsTransformationAdapteeType adapteeType = crsTransformationAdapterResultSource.AdapteeType; Assert.AreEqual(CrsTransformationAdapteeType.COMPOSITE_MEDIAN, adapteeType); var dict = new Dictionary <CrsTransformationAdapteeType, bool>(); foreach (CrsTransformationResult crsTransformationResultLeaf in transformationResultChildren) { Assert.IsTrue(crsTransformationResultLeaf.IsSuccess); dict.Add(crsTransformationResultLeaf.CrsTransformationAdapterResultSource.AdapteeType, true); // Leafs always only have one result and thus there are zero difference between max and min result. // Therefore the below assertion should succeed Assert.IsTrue( crsTransformationResultLeaf.IsReliable( 1, // minimumNumberOfSuccesfulResults 0.0000000000000000000000000000001 // maxDeltaValueForXLongitudeAndYLatitude ) ); // Leafs always only have one result and thus the below tested method should return False Assert.IsFalse( crsTransformationResultLeaf.IsReliable( 2, // minimumNumberOfSuccesfulResults 0.1 // maxDeltaValueForXLongitudeAndYLatitude ) ); CrsTransformationResultStatistic leafResultStatistic = crsTransformationResultLeaf.CrsTransformationResultStatistic; Assert.IsTrue(leafResultStatistic.IsStatisticsAvailable); Assert.AreEqual(1, leafResultStatistic.NumberOfPotentiallySuccesfulResults); Assert.That(leafResultStatistic.MaxDifferenceForXEastingLongitude, Is.LessThan(0.01)); Assert.That(leafResultStatistic.MaxDifferenceForYNorthingLatitude, Is.LessThan(0.01)); } Assert.AreEqual(3, dict.Count); Assert.IsTrue(dict.ContainsKey(CrsTransformationAdapteeType.LEAF_MIGHTY_LITTLE_GEODESY_1_0_1)); Assert.IsTrue(dict.ContainsKey(CrsTransformationAdapteeType.LEAF_DOT_SPATIAL_2_0_0_RC1)); Assert.IsTrue(dict.ContainsKey(CrsTransformationAdapteeType.LEAF_PROJ_NET_4_GEO_API_1_4_1)); }
public void SetUp() { weightFactory = CrsTransformationAdapterWeightFactory.Create(); crsTransformationAdapterCompositeFactory = CrsTransformationAdapterCompositeFactory.Create(); double[] outputLatitudes = { 59.1, 59.2, 59.3, 59.4, 59.6, }; expectedMedianLatitude = 59.3; expectedAverageLatitude = 59.32; double[] outputLongitudes = { 18.2, 18.3, 18.4, 18.8, 18.9 }; expectedMedianLongitude = 18.4; expectedAverageLongitude = 18.52; outputCoordinateWgs84ForImplementation_1 = CrsCoordinateFactory.CreateFromLatitudeLongitude(outputLatitudes[0], outputLongitudes[3]); outputCoordinateWgs84ForImplementation_2 = CrsCoordinateFactory.CreateFromLatitudeLongitude(outputLatitudes[2], outputLongitudes[1]); outputCoordinateWgs84ForImplementation_3 = CrsCoordinateFactory.CreateFromLatitudeLongitude(outputLatitudes[4], outputLongitudes[4]); outputCoordinateWgs84ForImplementation_4 = CrsCoordinateFactory.CreateFromLatitudeLongitude(outputLatitudes[1], outputLongitudes[0]); outputCoordinateWgs84ForImplementation_5 = CrsCoordinateFactory.CreateFromLatitudeLongitude(outputLatitudes[3], outputLongitudes[2]); outputCoordinates = new List <CrsCoordinate> { outputCoordinateWgs84ForImplementation_1, outputCoordinateWgs84ForImplementation_2, outputCoordinateWgs84ForImplementation_3, outputCoordinateWgs84ForImplementation_4, outputCoordinateWgs84ForImplementation_5 }; mock1 = new Mock <ICrsTransformationAdapter>(); mock2 = new Mock <ICrsTransformationAdapter>(); mock3 = new Mock <ICrsTransformationAdapter>(); mock4 = new Mock <ICrsTransformationAdapter>(); mock5 = new Mock <ICrsTransformationAdapter>(); leafAdapterImplementation_1 = mock1.Object; leafAdapterImplementation_2 = mock2.Object; leafAdapterImplementation_3 = mock3.Object; leafAdapterImplementation_4 = mock4.Object; leafAdapterImplementation_5 = mock5.Object; inputCoordinateSweref99 = CrsCoordinateFactory.CreateFromYNorthingLatitudeAndXEastingLongitude(6580822.0, 674032.0, EpsgNumber.SWEDEN__SWEREF99_TM__3006); CrsTransformationResult leafResult1 = CrsTransformationResult._CreateCrsTransformationResult( inputCoordinateSweref99, outputCoordinateWgs84ForImplementation_1, null, true, leafAdapterImplementation_1, CrsTransformationResultStatistic._CreateCrsTransformationResultStatistic(new List <CrsTransformationResult>()) ); CrsTransformationResult leafResult2 = CrsTransformationResult._CreateCrsTransformationResult( inputCoordinateSweref99, outputCoordinateWgs84ForImplementation_2, null, true, leafAdapterImplementation_2, CrsTransformationResultStatistic._CreateCrsTransformationResultStatistic(new List <CrsTransformationResult>()) ); CrsTransformationResult leafResult3 = CrsTransformationResult._CreateCrsTransformationResult( inputCoordinateSweref99, outputCoordinateWgs84ForImplementation_3, null, true, leafAdapterImplementation_3, CrsTransformationResultStatistic._CreateCrsTransformationResultStatistic(new List <CrsTransformationResult>()) ); CrsTransformationResult leafResult4 = CrsTransformationResult._CreateCrsTransformationResult( inputCoordinateSweref99, outputCoordinateWgs84ForImplementation_4, null, true, leafAdapterImplementation_4, CrsTransformationResultStatistic._CreateCrsTransformationResultStatistic(new List <CrsTransformationResult>()) ); CrsTransformationResult leafResult5 = CrsTransformationResult._CreateCrsTransformationResult( inputCoordinateSweref99, outputCoordinateWgs84ForImplementation_5, null, true, leafAdapterImplementation_5, CrsTransformationResultStatistic._CreateCrsTransformationResultStatistic(new List <CrsTransformationResult>()) ); crsIdentifierWGS84 = CrsIdentifierFactory.CreateFromEpsgNumber(EpsgNumber.WORLD__WGS_84__4326); mock1.Setup(leaf => leaf.Transform(inputCoordinateSweref99, crsIdentifierWGS84)).Returns(leafResult1); mock2.Setup(leaf => leaf.Transform(inputCoordinateSweref99, crsIdentifierWGS84)).Returns(leafResult2); mock3.Setup(leaf => leaf.Transform(inputCoordinateSweref99, crsIdentifierWGS84)).Returns(leafResult3); mock4.Setup(leaf => leaf.Transform(inputCoordinateSweref99, crsIdentifierWGS84)).Returns(leafResult4); mock5.Setup(leaf => leaf.Transform(inputCoordinateSweref99, crsIdentifierWGS84)).Returns(leafResult5); //mock1.Setup(leaf => leaf.LongNameOfImplementation).Returns("1"); //mock2.Setup(leaf => leaf.LongNameOfImplementation).Returns("2"); //mock3.Setup(leaf => leaf.LongNameOfImplementation).Returns("3"); //mock4.Setup(leaf => leaf.LongNameOfImplementation).Returns("4"); //mock5.Setup(leaf => leaf.LongNameOfImplementation).Returns("5"); mock1.Setup(leaf => leaf.AdapteeType).Returns(CrsTransformationAdapteeType.LEAF_DOT_SPATIAL_2_0_0_RC1); mock2.Setup(leaf => leaf.AdapteeType).Returns(CrsTransformationAdapteeType.LEAF_PROJ_NET_2_0_0); mock3.Setup(leaf => leaf.AdapteeType).Returns(CrsTransformationAdapteeType.LEAF_MIGHTY_LITTLE_GEODESY_1_0_2); // The type must be different but there are only three concrete types as above to use // but then instead can use the ones below (and the purpose of this enum is to use it as key in a dictionary/hashtable) mock4.Setup(leaf => leaf.AdapteeType).Returns(CrsTransformationAdapteeType.UNSPECIFIED_LEAF); mock5.Setup(leaf => leaf.AdapteeType).Returns(CrsTransformationAdapteeType.UNSPECIFIED); allLeafAdapters = new List <ICrsTransformationAdapter> { leafAdapterImplementation_1, leafAdapterImplementation_2, leafAdapterImplementation_3, leafAdapterImplementation_4, leafAdapterImplementation_5 }; }
public void IsReliable_ShouldReturnTrueOrFalseForComposites_DependingOnCriteriasUsedAsMethodParameter() { // the below value is the max difference when comparing the three leaf implementations double actualMaxDiffXorY = 0.0032574664801359177; // the above value is obviously fragile and might change if/when some adaptee library is upgraded int criteriaNumberOfResultsSuccess = EXPECTED_NUMBER_OF_ADAPTER_LEAF_IMPLEMENTATIONS; // all 3 should succeed int criteriaNumberOfResultsFailure = EXPECTED_NUMBER_OF_ADAPTER_LEAF_IMPLEMENTATIONS + 1; // 4 implementations can not currently succeed since there are currently not so many implementations double criteriaMaxDiffFailure = actualMaxDiffXorY - 0.0001; // a little too small requirement for max difference double criteriaMaxDiffSuccess = actualMaxDiffXorY + 0.0001; // should result in success since the actual number is smaller List<ICrsTransformationAdapter> crsTransformationAdapterImplementationsExpectingManyResults = new List<ICrsTransformationAdapter>(); foreach (ICrsTransformationAdapter crsTransformationAdapterComposite in base.crsTransformationAdapterCompositeImplementations) { if(crsTransformationAdapterComposite.AdapteeType != CrsTransformationAdapteeType.COMPOSITE_FIRST_SUCCESS) { crsTransformationAdapterImplementationsExpectingManyResults.Add(crsTransformationAdapterComposite); } } Assert.AreEqual( 3, // 3 composites i.e. all composite except COMPOSITE_FIRST_SUCCESS crsTransformationAdapterImplementationsExpectingManyResults.Count ); foreach (ICrsTransformationAdapter crsTransformationAdapterComposite in crsTransformationAdapterImplementationsExpectingManyResults) { CrsCoordinate wgs84coordinateInSweden = CrsCoordinateFactory.LatLon(59.29,18.03); CrsTransformationResult resultWhenTransformingToSwedishCRS = crsTransformationAdapterComposite.Transform(wgs84coordinateInSweden, EpsgNumber.SWEDEN__SWEREF99_TM__3006); Assert.IsNotNull(resultWhenTransformingToSwedishCRS); Assert.IsTrue(resultWhenTransformingToSwedishCRS.IsSuccess); CrsTransformationResultStatistic crsTransformationResultStatistic = resultWhenTransformingToSwedishCRS.CrsTransformationResultStatistic; Assert.IsNotNull(crsTransformationResultStatistic); Assert.IsTrue(crsTransformationResultStatistic.IsStatisticsAvailable); // so far the same code as the previous test method for the test method with leafs int actualNumberOfResults = crsTransformationResultStatistic.NumberOfPotentiallySuccesfulResults; Assert.AreEqual( criteriaNumberOfResultsSuccess, actualNumberOfResults ); double actualMaxDiffXLongitude = crsTransformationResultStatistic.MaxDifferenceForXEastingLongitude; double actualMaxDiffYLatitude = crsTransformationResultStatistic.MaxDifferenceForYNorthingLatitude; // double actualMaxDiffXorY = Math.max(actualMaxDiffXLongitude, actualMaxDiffYLatitude); // System.out.println("actualMaxDiffXorY " + actualMaxDiffXorY + " " + crsTransformationAdapterComposite.getAdapteeType()); // method "isReliable" used below is the method under test Assert.IsTrue( resultWhenTransformingToSwedishCRS.IsReliable( criteriaNumberOfResultsSuccess, criteriaMaxDiffSuccess ) ); Assert.IsFalse( resultWhenTransformingToSwedishCRS.IsReliable( criteriaNumberOfResultsSuccess, criteriaMaxDiffFailure ) ); Assert.IsFalse( resultWhenTransformingToSwedishCRS.IsReliable( criteriaNumberOfResultsFailure, criteriaMaxDiffSuccess ) ); Assert.IsFalse( resultWhenTransformingToSwedishCRS.IsReliable( criteriaNumberOfResultsFailure, criteriaMaxDiffFailure ) ); } }
public void IsReliable_ShouldReturnTrueForLeafs_WhenUsingCriteriaNumberOfResultsOneAndMaxDiffZero() { int criteriaNumberOfResults = 1; // always one for a Leaf double criteriaMaxDiff = 0.0; // always zero for a Leaf // The tested method 'IsReliable' is actually relevant only for aggregated // transformations, but nevertheless there is a reaonable behavouor also // for the "Leaf" implementations regarding the number of results (always 1) // and the "differences" in lat/long for the "different" implementations // i.e. the "difference" should always be zero since there is only one implementation List<ICrsTransformationAdapter> crsTransformationAdapterImplementationsExpectingOneResult = new List<ICrsTransformationAdapter>(); crsTransformationAdapterImplementationsExpectingOneResult.AddRange(base.crsTransformationAdapterLeafImplementations); crsTransformationAdapterImplementationsExpectingOneResult.Add(crsTransformationAdapterCompositeFactory.CreateCrsTransformationFirstSuccess()); Assert.AreEqual( EXPECTED_NUMBER_OF_ADAPTER_LEAF_IMPLEMENTATIONS + 1, // 3 leafs plus 1 crsTransformationAdapterImplementationsExpectingOneResult.Count ); foreach (ICrsTransformationAdapter crsTransformationAdapterLeaf in crsTransformationAdapterImplementationsExpectingOneResult) { // suffix "Leaf" is not quite true, but in one of the iterations // it will be the Composite FirstSuccess which also will only have one result // and thus can be tested in the same way as the leafs in this method CrsCoordinate wgs84coordinateInSweden = CrsCoordinateFactory.LatLon(59.29,18.03); CrsTransformationResult resultWhenTransformingToSwedishCRS = crsTransformationAdapterLeaf.Transform(wgs84coordinateInSweden, EpsgNumber.SWEDEN__SWEREF99_TM__3006); Assert.IsNotNull(resultWhenTransformingToSwedishCRS); Assert.IsTrue(resultWhenTransformingToSwedishCRS.IsSuccess); CrsTransformationResultStatistic crsTransformationResultStatistic = resultWhenTransformingToSwedishCRS.CrsTransformationResultStatistic; Assert.IsNotNull(crsTransformationResultStatistic); Assert.IsTrue(crsTransformationResultStatistic.IsStatisticsAvailable); int actualNumberOfResults = crsTransformationResultStatistic.NumberOfPotentiallySuccesfulResults; Assert.AreEqual(criteriaNumberOfResults, actualNumberOfResults); double actualMaxDiffXLongitude = crsTransformationResultStatistic.MaxDifferenceForXEastingLongitude; double actualMaxDiffYLatitude = crsTransformationResultStatistic.MaxDifferenceForYNorthingLatitude; double actualMaxDiffXorY = Math.Max(actualMaxDiffXLongitude, actualMaxDiffYLatitude); Assert.AreEqual(criteriaMaxDiff, actualMaxDiffXorY); // zero differences since there should be only one result ! // method "IsReliable" used below is the method under test Assert.IsTrue( resultWhenTransformingToSwedishCRS.IsReliable( criteriaNumberOfResults, criteriaMaxDiff ) ); // Assert.IsFalse below since trying to require one more result than available Assert.IsFalse( resultWhenTransformingToSwedishCRS.IsReliable( criteriaNumberOfResults + 1, criteriaMaxDiff ) ); // Assert.IsFalse below since trying to require too small maxdiff Assert.IsFalse( resultWhenTransformingToSwedishCRS.IsReliable( criteriaNumberOfResults, criteriaMaxDiff - 0.00000000001 ) ); } }
public void method() { Console.WriteLine("LargerCSharpeExample starts"); // Some terminology regarding the names used in the below code example: // "CRS" = Coordinate Reference System // "WGS84" is the most frequently used coordinate system (e.g. the coordinates usually used in a GPS) // "SWEREF99TM" is the official coordinate system used by authorities in Sweden // "EPSG" = "European Petroleum Survey Group" was (but the EPSG name is still often used) // an organization defining CRS with integer numbers e.g. 4326 for WGS84 or 3006 for SWEREF99TM int epsgWgs84 = EpsgNumber.WORLD__WGS_84__4326; int epsgSweRef = EpsgNumber.SWEDEN__SWEREF99_TM__3006; // The above "EpsgNumber" class with LOTS OF constants (and more constants classes) have been generated, // using "FreeMarker" and database downloaded from EPSG ( http://www.epsg.org or http://www.epsg-registry.org ) // from "crs-transformation-code-generation" in the project https://github.com/TomasJohansson/crsTransformations CrsCoordinate centralStockholmWgs84 = CrsCoordinateFactory.LatLon(59.330231, 18.059196, epsgWgs84); // https://kartor.eniro.se/m/03Yxp // SWEREF99TM coordinates (for WGS84 59.330231, 18.059196) // according to Eniro (above URL): 6580822, 674032 (northing, easting) ICrsTransformationAdapter crsTransformationAdapter; // interface with concrete "leaf" implementation or "composite" implementations // This code example is using a "composite" which will use multiple libraries to do the same transformation and then // return a coordinate with the median values (median of the northing values and median of the easting values) crsTransformationAdapter = CrsTransformationAdapterCompositeFactory.Create().CreateCrsTransformationMedian(); // The above factory will try to use those known objects which implements the interface i.e. the number // of "leaf" objects will depend on how many you included as for example NuGet dependencies (three in the above NuGet example) Console.WriteLine("Number of 'leafs' : " + crsTransformationAdapter.TransformationAdapterChildren.Count); // Console output from the above row: // Number of 'leafs' : 3 // Transform the WGS84 coordinate to a SWEREF99TM coordinate: CrsCoordinate centralStockholmSweRef = crsTransformationAdapter.TransformToCoordinate(centralStockholmWgs84, epsgSweRef); Console.WriteLine("Median Composite Northing: " + centralStockholmSweRef.Northing); Console.WriteLine("Median Composite Easting: " + centralStockholmSweRef.Easting); // Console output from the above two rows: // Median Composite Northing: 6580821.99121561 // Median Composite Easting: 674032.357177155 // (and these can be compared with the 'Eniro' values above i.e. '6580822, 674032 (northing, easting)' ) // The coordinate class provides four properties with different names for the same east-west value and // four properties for the same name each north-south value, as below: // Four EQUIVALENT properties: Easting , X , Longitude , XEastingLongitude // Four EQUIVALENT properties: Northing , Y , Latitude , YNorthingLatitude // Regarding the above alternative methods, depending on the desired semantic in your context, you may want to use: // X/Y for a geocentric or cartesian system // Longitude/Latitude for a geodetic or geographic system // Easting/Northing for a cartographic or projected system // xEastingLongitude/yNorthingLatitude for general code handling different types of system // If you want more details for the result you can use the following 'Transform' method: // (instead of the method 'TransformToCoordinate' used above) CrsTransformationResult centralStockholmResultSweRef = crsTransformationAdapter.Transform(centralStockholmWgs84, epsgSweRef); if(!centralStockholmResultSweRef.IsSuccess) { Console.WriteLine("No coordinate result"); } else { if(centralStockholmResultSweRef.IsReliable( 2, // minimumNumberOfSuccesfulResults 0.01 // maxDeltaValueForXLongitudeAndYLatitude )) { // at least 2 succesful results and the maximal difference in northing or easting is less than 0.01 // (and if you want to know the exact difference you can find it in this code example further down the page) Console.WriteLine("Reliable result"); // according to your chosen parameters to the method 'isReliable' } else { Console.WriteLine("Not reliable result"); } Console.WriteLine(centralStockholmResultSweRef.OutputCoordinate); // Console output from the above code row: // CrsCoordinate(xEastingLongitude=674032.357177155, yNorthingLatitude=6580821.99121561, crsIdentifier=CrsIdentifier(crsCode='EPSG:3006', isEpsgCode=True, epsgNumber=3006)) // When your code is in a context where you only have the result (but not the adapter object) // (e.g. in a method receiving the result as a parameter) // you can get back the object which created the result as below: ICrsTransformationAdapter crsTransformationAdapterResultSource = centralStockholmResultSweRef.CrsTransformationAdapterResultSource; CrsTransformationAdapteeType adapteeType = crsTransformationAdapterResultSource.AdapteeType; Console.WriteLine("adapteeType: " + adapteeType); // console output: COMPOSITE_MEDIAN // The above code row returned an enum which is not really a true adaptee just like the 'composite' is not a true adapter. // However, when iterating (as below) the "leaf" results, // it might be more interesting to keep track of from where the different values originated IList<CrsTransformationResult> transformationResultChildren = centralStockholmResultSweRef.TransformationResultChildren; foreach (CrsTransformationResult crsTransformationResultLeaf in transformationResultChildren) { if(!crsTransformationResultLeaf.IsSuccess) continue; // continue with the next 'leaf' ICrsTransformationAdapter resultAdapter = crsTransformationResultLeaf.CrsTransformationAdapterResultSource; Console.WriteLine(resultAdapter.AdapteeType); // The above code row will output rows like this: // "LEAF_PROJ_NET_4_GEO_API_1_4_1" or "LEAF_MIGHTY_LITTLE_GEODESY_1_0_1" and so on if(!crsTransformationResultLeaf.IsReliable( 2, // minimumNumberOfSuccesfulResults 1000 // maxDeltaValueForXLongitudeAndYLatitude )) { // The above constraint "at least 2 implementations" will always fail because now we are dealing with "leafs" // The above delta value constraint has very high tolerance but it does not matter since // the constraint about the number of implementations will fail Console.WriteLine("Only 'composites' can have more than one result and this is a 'leaf' and thus does not have at least two results"); } Console.WriteLine("Adapter long name: " + resultAdapter.LongNameOfImplementation); // full class name including package Console.WriteLine("Adapter short name: " + resultAdapter.ShortNameOfImplementation); // class name suffix i.e. the unique part // The above "long" names will be for example: // Programmerare.CrsTransformations.Adapter.DotSpatial.CrsTransformationAdapterDotSpatial // Programmerare.CrsTransformations.Adapter.MightyLittleGeodesy.CrsTransformationAdapterMightyLittleGeodesy // The above "short" names will be for example: // DotSpatial // MightyLittleGeodesy Console.WriteLine("adaptee: " + resultAdapter.AdapteeType); // The above row will output for example: // LEAF_DOT_SPATIAL_2_0_0_RC1 // LEAF_MIGHTY_LITTLE_GEODESY_1_0_1 // (note that the version number is included for the adaptees) Console.WriteLine("isComposite: " + resultAdapter.IsComposite); // "False" since we are iterating "leaf" results Console.WriteLine("Coordinate result for " + resultAdapter.AdapteeType + " : " + crsTransformationResultLeaf.OutputCoordinate); // The above row will output these rows when doing the iteration: // Coordinate result for LEAF_DOT_SPATIAL_2_0_0_RC1 : CrsCoordinate(xEastingLongitude=674032.357322213, yNorthingLatitude=6580821.99121561, crsIdentifier=CrsIdentifier(crsCode='EPSG:3006', isEpsgCode=True, epsgNumber=3006)) // Coordinate result for LEAF_PROJ_NET_4_GEO_API_1_4_1 : CrsCoordinate(xEastingLongitude=674032.357177155, yNorthingLatitude=6580821.99437121, crsIdentifier=CrsIdentifier(crsCode='EPSG:3006', isEpsgCode=True, epsgNumber=3006)) // Coordinate result for LEAF_MIGHTY_LITTLE_GEODESY_1_0_1 : CrsCoordinate(xEastingLongitude=674032.357, yNorthingLatitude=6580821.991, crsIdentifier=CrsIdentifier(crsCode='EPSG:3006', isEpsgCode=True, epsgNumber=3006)) // Note that the median value for "x" is 674032.357177155 for the above // three values 674032.357 , 674032.357177155 , 674032.357322213 . // That is the same value as was displayed before the iteration of the children/leafs for the median composite. // The same applies for the above "y" i.e. the median is 6580821.99121561 // for the three y values 6580821.991 , 6580821.99121561 , 6580821.99437121 } // The result object also provides convenience methods for the results (which you of course otherwise might calculate by iterating the above results) CrsTransformationResultStatistic crsTransformationResultStatistic = centralStockholmResultSweRef.CrsTransformationResultStatistic; // Note that the initially created composite was a "median composite" returning the median as the main value, // but you can also create an average composite and regardless you can access both the median and the average with the aggregated statistics object: Console.WriteLine("average coordinate: " + crsTransformationResultStatistic.CoordinateAverage); Console.WriteLine("median coordinate: " + crsTransformationResultStatistic.CoordinateMedian); // Console output from the above two rows: // average coordinate: CrsCoordinate(xEastingLongitude=674032.357166456, yNorthingLatitude=6580821.99219561, crsIdentifier=CrsIdentifier(crsCode='EPSG:3006', isEpsgCode=True, epsgNumber=3006)) // median coordinate: CrsCoordinate(xEastingLongitude=674032.357177155, yNorthingLatitude=6580821.99121561, crsIdentifier=CrsIdentifier(crsCode='EPSG:3006', isEpsgCode=True, epsgNumber=3006)) Console.WriteLine("MaxDifferenceForXEastingLongitude: " + crsTransformationResultStatistic.MaxDifferenceForXEastingLongitude); Console.WriteLine("MaxDifferenceForYNorthingLatitude: " + crsTransformationResultStatistic.MaxDifferenceForYNorthingLatitude); // Output from the above two rows: // MaxDifferenceForXEastingLongitude: 0.000322213280014694 // MaxDifferenceForYNorthingLatitude: 0.00337121076881886 // As you can see in the above iteration, the min and max x values are 674032.357 and 674032.357322213 (and the difference is 0.000322213). // Similarly the min and max y values are 6580821.991 and 6580821.99437121 (and the difference is 0.00337121). // The above two "MaxDifference" methods are used within the implementation of the convenience method 'isReliable' // (also illustrated in this example further above) } // else statement ends Console.WriteLine("LargerCSharpeExample ends"); Console.ReadLine(); } // method ends
public void FindPotentialBuggyImplementationsHelper( int minEpsgCrsCode, int maxEpsgCrsCode, double?optionalDelta = null ) { int numberIfEpsgCodesToConsiderInIteration = maxEpsgCrsCode - minEpsgCrsCode; bool manyWillBeIterated = numberIfEpsgCodesToConsiderInIteration > 100; double deltaDiffToUse = manyWillBeIterated ? deltaDiff : double.MinValue; if (optionalDelta.HasValue) { deltaDiffToUse = optionalDelta.Value; } var crsTransformationAdapterCompositeFactory = CrsTransformationAdapterCompositeFactory.Create(); CrsTransformationAdapterComposite crsTransformationComposite = crsTransformationAdapterCompositeFactory.CreateCrsTransformationMedian(); verifyThreeImplementations(crsTransformationComposite); // to make sure that the above factory really creates an object which will use three implementations IList <CrsTransformationResult> transformResultsWithLargeDifferences = new List <CrsTransformationResult>(); CrsIdentifier wgs84 = CrsIdentifierFactory.CreateFromEpsgNumber(EpsgNumber.WORLD__WGS_84__4326); var stopWatch = new Stopwatch(); stopWatch.Start(); IList <EpsgCrsAndAreaCodeWithCoordinates> coordinatesFromGeneratedCsvFile = CoordinateTestDataGeneratedFromEpsgDatabaseTest.GetCoordinatesFromGeneratedCsvFile(); int seconds = (int)stopWatch.Elapsed.TotalSeconds; WriteLine("Time for reading the content of the input file: " + seconds); stopWatch.Restart(); int totalNumberOfSeconds; WriteLine("number of rows to iterate: " + coordinatesFromGeneratedCsvFile.Count); for (int i = 0; i < coordinatesFromGeneratedCsvFile.Count; i++) { if (manyWillBeIterated && (i % 100 == 0)) { //WriteLine("number of rows iterated so far: " + i); totalNumberOfSeconds = (int)stopWatch.Elapsed.TotalSeconds; //WriteLine("Number of seconds so far: " + totalNumberOfSeconds); // if (i > 50) break; } EpsgCrsAndAreaCodeWithCoordinates epsgCrsAndAreaCodeWithCoordinates = coordinatesFromGeneratedCsvFile[i]; if ( epsgCrsAndAreaCodeWithCoordinates.epsgCrsCode < minEpsgCrsCode || epsgCrsAndAreaCodeWithCoordinates.epsgCrsCode > maxEpsgCrsCode ) { continue; } if (!manyWillBeIterated) { //Console.WriteLine("iterated epsgCrsCode: " + epsgCrsAndAreaCodeWithCoordinates.epsgCrsCode); } CrsCoordinate coordinateInputWgs84 = CrsCoordinateFactory.CreateFromYNorthingLatitudeAndXEastingLongitude(epsgCrsAndAreaCodeWithCoordinates.centroidY, epsgCrsAndAreaCodeWithCoordinates.centroidX, wgs84); CrsTransformationResult resultOutputFromWgs4 = crsTransformationComposite.Transform(coordinateInputWgs84, epsgCrsAndAreaCodeWithCoordinates.epsgCrsCode); if (!resultOutputFromWgs4.IsSuccess) { continue; } CrsTransformationResult resultWhenTransformedBackToWgs84 = crsTransformationComposite.Transform(resultOutputFromWgs4.OutputCoordinate, wgs84); if (!resultWhenTransformedBackToWgs84.IsSuccess) { continue; } CrsTransformationResultStatistic crsTransformationResultStatistic = resultWhenTransformedBackToWgs84.CrsTransformationResultStatistic; Assert.IsNotNull(crsTransformationResultStatistic); Assert.IsTrue(crsTransformationResultStatistic.IsStatisticsAvailable); if ( crsTransformationResultStatistic.MaxDifferenceForXEastingLongitude > deltaDiffToUse || crsTransformationResultStatistic.MaxDifferenceForYNorthingLatitude > deltaDiffToUse ) { transformResultsWithLargeDifferences.Add(resultWhenTransformedBackToWgs84); } else { if (!manyWillBeIterated) { //Console.WriteLine("NOT 'big' difference for EPSG " + epsgCrsAndAreaCodeWithCoordinates.epsgCrsCode); int count = crsTransformationComposite.TransformationAdapterChildren.Count; //Console.WriteLine("Number of implementations not having big difference: " + count); } } } WriteLine("Number of iterated rows/coordinates: " + coordinatesFromGeneratedCsvFile.Count); WriteLine("Number of results with 'large' differences: " + transformResultsWithLargeDifferences.Count); for (int i = 0; i < transformResultsWithLargeDifferences.Count; i++) { CrsTransformationResult transformResult = transformResultsWithLargeDifferences[i]; WriteLine("----------------------------------------"); WriteLine("epsg " + transformResult.InputCoordinate.CrsIdentifier.CrsCode); WriteLine("MaxDiffYLatitude : " + transformResult.CrsTransformationResultStatistic.MaxDifferenceForYNorthingLatitude); WriteLine("MaxDiffYLongitude: " + transformResult.CrsTransformationResultStatistic.MaxDifferenceForXEastingLongitude); IList <CrsTransformationResult> subResults = transformResult.TransformationResultChildren; for (int j = 0; j < subResults.Count; j++) { CrsTransformationResult subTransformResult = subResults[j]; if (subTransformResult.IsSuccess) { WriteLine(subTransformResult.OutputCoordinate + " , " + subTransformResult.CrsTransformationAdapterResultSource.AdapteeType); } } } }