어댑터 API 및 일반 코드가 장착 된 "핵심"라이브러리는 MIT 라이센스와 함께 릴리스됩니다.
그러나 어댑터 구현 라이브러리는 그러한 각 구현에 대해 별도의 "License_Notice"파일 (어댑터 기본 디렉토리)에 지정된 적응 된 라이브러리와 동일한 방식으로 라이센스가 부여됩니다.
이 F#/C#/. NET 프로젝트는 CRS (Coderinate Reference Systems) 간의 좌표를 변환하기위한 것입니다.
어댑터는 세 번째로 구성된 .NET 라이브러리를 Adaptee 's로 사용하고 있습니다.
이 코드는 F#으로 구현되었지만 테스트 (및 하위 프로젝트 "프로그래머 .crstransformations.constants"의 생성 상수는 C#으로 구현됩니다.
아래 버전은 NUGET 릴리스의 v3.0.0에 적용됩니다.
.NET 대상 버전은 .NET 표준 2.0 (예 : .NET 프레임 워크 4.6.1 이상)이지만 상수가있는 라이브러리의 버전 10.36 (프로그래머 .crstransformations.constants)은 .NET 프레임 워크 2.0 이상과 함께 사용할 수 있습니다.
F# 버전은 6.0.1입니다 (즉, "fsharp.core"에 대한 패키지 참조).
이 코드 프로젝트의 다음 5 개의 라이브러리가 Nuget에 출시/배포되었습니다.
이름에 " 어댑터 "를 포함하는 위의 세 가지 라이브러리는 위의 " Core "라이브러리의 어댑터 구현입니다.
이 3 개의 어댑터는 좌표 변환을 위해 3 개의 Adaptee 라이브러리를 사용하고 있습니다.
위의 ' MightylittleGeodesy '라이브러리는 WGS84 (매우 일반적인 글로벌 CRS)와 스웨덴 좌표 시스템 (CRS) SWEREF99 (예 : "SWEREF99 TM") 및 RT90 (예 : "RT90 2.5 gon V") 사이의 변환에만 유용합니다.
위의 라이브러리 "Programmerare.crstransformations. 상수 "는 실제로 다른 것과 완전히 독립적입니다.
그것은 아무것도 아니며 그것에 의존하지 않습니다.
C# 라이브러리 (즉, 다른 것과 같은 F#에 따라도)는 C# 상수가 많은 클래스 만있는 C# 라이브러리입니다.
(다른 4 개의 코어/어댑터 라이브러리는 F#로 구현됩니다)
C# Constant 클래스는 EPSG 데이터 세트 버전 10.036에서 생성되었으며, 이는 해당 버전 번호의 이유입니다.
"핵심"라이브러리에는 모든 "어댑터"라이브러리에서 "핵심"에 암시 적/전이 의존성이 있기 때문에 포함 할 필요가 없습니다.
"상수"라이브러리는 필요하지 않지만 정수 리터럴로 하드 코딩하거나 자신의 정수 상수를 정의하는 대신 EPSG 번호에 상수를 사용하려면 흥미로울 수 있습니다.
<!-- Use one, two or three of the below three Adapters -->
< PackageReference Include = " Programmerare.CrsTransformations.Adapter.DotSpatial " Version = " 3.0.0 " />
< PackageReference Include = " Programmerare.CrsTransformations.Adapter.ProjNet " Version = " 3.0.0 " />
< PackageReference Include = " Programmerare.CrsTransformations.Adapter.MightyLittleGeodesy " Version = " 3.0.0 " />
<!-- The Core should not be necessary to include explicitly as below (since it should be implicitly included when using one of the others above ) -->
< PackageReference Include = " Programmerare.CrsTransformations.Core " Version = " 3.0.0 " />
<!-- Optional (and totally independent) library with only one class with lots of integer constants -->
< PackageReference Include = " Programmerare.CrsTransformations.Constants " Version = " 10.36.0 " />위의 라이브러리는 내 Nuget 페이지에서 찾을 수 있습니다.
코드 (예 : 핵심 및 어댑터 라이브러리)는 F#로 구현되었지만 테스트 코드는 "프로그래머 .crstransformations.test"에서 C#으로 작성되었습니다.
3 개의 .NET 언어 C#, F# 및 vb.net에 대한 예제 코드 프로젝트도 있습니다.
이 세 가지 프로젝트는 동일한 종류의 코드를 사용하고 있지만 (예 : 같은 일을하는) 언어에 대해서는 다른 구문을 사용하고 있습니다.
위에서 언급 한 C# 코드 (예 : C# 테스트 프로젝트 및 C# Nuget 예제 프로젝트) 외에도 아래의 GitHub 페이지는 C# 코드와 함께 라이브러리를 사용하는 방법을 보여줍니다.
변환 좌표 방법은 인터페이스 ICRStransformationAdapter 에 정의되어 있습니다.
현재 인터페이스를 구현하는 7 개의 클래스가 있습니다. 3 개의 'Leafs'와 4 개의 '복합재'.
각 잎 어댑터는 구현에 일부 어댑티 라이브러리를 사용하고 있습니다.
4 개의 '복합재'는 다음과 같은 Leafs를 사용하고 있습니다.
다른 두 가지 핵심 유형은 crsidentifier와 crscoordinate입니다. 이 두 가지 모두 아래 섹션에 설명되어 있습니다.
using System . Collections . Generic ; // IList
using Programmerare . CrsTransformations ; // ICrsTransformationAdapter
using Programmerare . CrsTransformations . CompositeTransformations ; // CrsTransformationAdapterCompositeFactory
using Programmerare . CrsTransformations . Adapter . DotSpatial ;
using Programmerare . CrsTransformations . Adapter . ProjNet ;
using Programmerare . CrsTransformations . Adapter . MightyLittleGeodesy ;
// ...
// The interface with seven implementations as illustrated below
ICrsTransformationAdapter crsTransformationAdapter ;
// The interface is defined in the library "Programmerare.CrsTransformations.Core" with this full name:
// Programmerare.CrsTransformations.ICrsTransformationAdapter
// The three 'Leaf' implementations:
// Library "Programmerare.CrsTransformations.Adapter.DotSpatial", class:
// Programmerare.CrsTransformations.Adapter.DotSpatial.CrsTransformationAdapterDotSpatial
crsTransformationAdapter = new CrsTransformationAdapterDotSpatial ( ) ;
// Library "Programmerare.CrsTransformations.Adapter.ProjNet", class:
// Programmerare.CrsTransformations.Adapter.ProjNet.CrsTransformationAdapterProjNet
crsTransformationAdapter = new CrsTransformationAdapterProjNet ( ) ;
// Library "Programmerare.CrsTransformations.Adapter.MightyLittleGeodesy", class:
// Programmerare.CrsTransformations.Adapter.MightyLittleGeodesy.CrsTransformationAdapterMightyLittleGeodesy
crsTransformationAdapter = new CrsTransformationAdapterMightyLittleGeodesy ( ) ;
// - - - - - - - - - - - -
// The four 'Composite' implementations below are all located in the library
// "Programmerare.CrsTransformations.Core" and the factory class is:
// Programmerare.CrsTransformations.CompositeTransformations.CrsTransformationAdapterCompositeFactory
var crsTransformationAdapterCompositeFactory = CrsTransformationAdapterCompositeFactory . Create ( ) ;
crsTransformationAdapter = crsTransformationAdapterCompositeFactory . CreateCrsTransformationMedian ( ) ;
crsTransformationAdapter = crsTransformationAdapterCompositeFactory . CreateCrsTransformationAverage ( ) ;
crsTransformationAdapter = crsTransformationAdapterCompositeFactory . CreateCrsTransformationFirstSuccess ( ) ;
// All of the above three factory methods without any parameter will try to use as many of
// the three (currently) 'leaf' implementations as are available in runtime
// (e.g. are included as NuGet dependencies).
// If you want to specify explicitly which ones to be used, you can provide
// a parameter 'IList<ICrsTransformationAdapter>' to the Create method like this:
crsTransformationAdapterCompositeFactory = CrsTransformationAdapterCompositeFactory . Create (
new List < ICrsTransformationAdapter > {
new CrsTransformationAdapterDotSpatial ( ) ,
new CrsTransformationAdapterProjNet ( ) ,
new CrsTransformationAdapterMightyLittleGeodesy ( ) ,
}
) ;
// The fourth 'Composite' below does not use any implicit implementations
// but if you want to use a result created as a weighted average then the weights need
// to be specified explicitly per leaf implementation as in the example below.
var weightFactory = CrsTransformationAdapterWeightFactory . Create ( ) ;
crsTransformationAdapter = crsTransformationAdapterCompositeFactory . CreateCrsTransformationWeightedAverage (
new List < CrsTransformationAdapterWeight > {
weightFactory . CreateFromInstance ( new CrsTransformationAdapterDotSpatial ( ) , 1.0 ) ,
weightFactory . CreateFromInstance ( new CrsTransformationAdapterProjNet ( ) , 1.0 ) ,
weightFactory . CreateFromInstance ( new CrsTransformationAdapterMightyLittleGeodesy ( ) , 2.0 ) ,
}
) ;
// The weight values above illustrates a situation where you (for some reason) want to consider
// the transformation results from 'MightyLittleGeodesy' as being 'two times better' than the others.모든 변환 방법 (위의 인터페이스 ICRStrAnsformationAdapter 에 정의 됨)에는 두 개의 매개 변수가 필요합니다. 하나의 입력 좌표와 하나의 매개 변수는 입력 좌표가 변환 될 좌표 기준 시스템을 지정하는 대상 시스템을 지정합니다.
대상 시스템은 세 가지 데이터 유형 (예 : 오버로드 된 메소드), 정수 또는 문자열 또는 'crsidentifier'로 지정할 수 있습니다.
정수 또는 문자열을 사용하는 경우 내부적으로 'crsidentifier'가 생성되어 어댑터 구현에 매개 변수로 보내집니다.
따라서 코디네이션 기준 시스템에서 또는 많은 변환을하려는 경우, Crsidentifier의 Instace를 직접 만들도록 선택할 수 있지만, 더 편의를 위해 정수가있는 오버로드 된 메소드를 매개 변수로 사용할 수 있습니다 (또는 일부 "EPSG :"-문자열, 아래의 예를 참조하십시오).
좌표 (crscoordinate 유형)에는 좌표 기준 시스템에 대한 정보, 즉 'crsidentifier'에 대한 정보가 포함되어 있지만 정수 또는 문자열 매개 변수로 과부하되는 공장 메소드 (좌표 인스턴스 생성)도 있습니다.
아래 예제에서 명시된 두 (x/y) 위치 값에 대한 이름이 다른 많은 공장 방법이 있습니다.
당신의 상황에서 원하는 의미 론에 따라, 당신은 다음과 같은 다른 방법 (또는 유사하게 명명 된 액세서 )을 사용하고 싶을 수 있습니다.
using Programmerare . CrsTransformations . Identifier ; // CrsIdentifier
using Programmerare . CrsTransformations . Coordinate ; // CrsCoordinate
using static Programmerare . CrsTransformations . Coordinate . CrsCoordinateFactory ;
// The above row with "using static" enables many factory methods:
// LatLon , LonLat , YX , XY , ... and so on (see the example code below)
// ...
int epsgNumber = 4326 ;
string crsCode = "EPSG:" + epsgNumber ;
CrsIdentifier crsIdentifier ; // namespace Programmerare.CrsTransformations.Identifier
crsIdentifier = CrsIdentifierFactory . CreateFromEpsgNumber ( epsgNumber ) ;
// Alternative:
crsIdentifier = CrsIdentifierFactory . CreateFromCrsCode ( crsCode ) ;
double latitude = 59.330231 ;
double longitude = 18.059196 ;
CrsCoordinate crsCoordinate ; // namespace Programmerare.CrsTransformations.Coordinate
// All the below methods are alternatives for creating the same coordinate
// with the above latitude/longitude and coordinate reference system.
// No class or object is used for the methods below because of the following static import:
// using static Programmerare.CrsTransformations.Coordinate.CrsCoordinateFactory;
crsCoordinate = LatLon ( latitude , longitude , epsgNumber ) ;
crsCoordinate = LatLon ( latitude , longitude , crsCode ) ;
crsCoordinate = LatLon ( latitude , longitude , crsIdentifier ) ;
crsCoordinate = LonLat ( longitude , latitude , epsgNumber ) ;
crsCoordinate = LonLat ( longitude , latitude , crsCode ) ;
crsCoordinate = LonLat ( longitude , latitude , crsIdentifier ) ;
crsCoordinate = YX ( latitude , longitude , epsgNumber ) ;
crsCoordinate = YX ( latitude , longitude , crsCode ) ;
crsCoordinate = YX ( latitude , longitude , crsIdentifier ) ;
crsCoordinate = XY ( longitude , latitude , epsgNumber ) ;
crsCoordinate = XY ( longitude , latitude , crsCode ) ;
crsCoordinate = XY ( longitude , latitude , crsIdentifier ) ;
crsCoordinate = NorthingEasting ( latitude , longitude , epsgNumber ) ;
crsCoordinate = NorthingEasting ( latitude , longitude , crsCode ) ;
crsCoordinate = NorthingEasting ( latitude , longitude , crsIdentifier ) ;
crsCoordinate = EastingNorthing ( longitude , latitude , epsgNumber ) ;
crsCoordinate = EastingNorthing ( longitude , latitude , crsCode ) ;
crsCoordinate = EastingNorthing ( longitude , latitude , crsIdentifier ) ;
crsCoordinate = CreateFromYNorthingLatitudeAndXEastingLongitude ( latitude , longitude , epsgNumber ) ;
crsCoordinate = CreateFromYNorthingLatitudeAndXEastingLongitude ( latitude , longitude , crsCode ) ;
crsCoordinate = CreateFromYNorthingLatitudeAndXEastingLongitude ( latitude , longitude , crsIdentifier ) ;
crsCoordinate = CreateFromXEastingLongitudeAndYNorthingLatitude ( longitude , latitude , epsgNumber ) ;
crsCoordinate = CreateFromXEastingLongitudeAndYNorthingLatitude ( longitude , latitude , crsCode ) ;
crsCoordinate = CreateFromXEastingLongitudeAndYNorthingLatitude ( longitude , latitude , crsIdentifier ) ;
CrsIdentifier targetCrs = CrsIdentifierFactory . CreateFromEpsgNumber ( 3006 ) ;
ICrsTransformationAdapter crsTransformationAdapter = CrsTransformationAdapterCompositeFactory . Create ( ) . CreateCrsTransformationAverage ( ) ;
CrsTransformationResult crsTransformationResult = crsTransformationAdapter . Transform ( crsCoordinate , targetCrs ) ;
// see more example code further down in this webpage 아래는 현재 버전 1.0.0으로 작동하는 작은 C# 예제 코드입니다.
이 예제 코드는 글로벌 CRS WGS84 (EPSG 코드 4326) 위도/경도에서 스웨덴어 CRS SWEREF99TM (EPSG 코드 3006)으로 좌표를 변환합니다.
using Programmerare . CrsTransformations ;
using Programmerare . CrsTransformations . Coordinate ;
using Programmerare . CrsTransformations . CompositeTransformations ;
using System ; // Console
class SmallCSharpeExample {
static void Main ( string [ ] args ) {
int epsgWgs84 = 4326 ;
int epsgSweRef = 3006 ;
// alternative to the above two hardcodings: use the library "Programmerare.CrsTransformations.Constants"
// and constants EpsgNumber.WORLD__WGS_84__4326 and EpsgNumber.SWEDEN__SWEREF99_TM__3006
// from the class Programmerare.CrsConstants.ConstantsByAreaNameNumber.v9_5_4.EpsgNumber
CrsCoordinate centralStockholmWgs84 = CrsCoordinateFactory . LatLon ( 59.330231 , 18.059196 , epsgWgs84 ) ;
ICrsTransformationAdapter crsTransformationAdapter = CrsTransformationAdapterCompositeFactory . Create ( ) . CreateCrsTransformationMedian ( ) ;
// 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
CrsTransformationResult centralStockholmResultSweRef = crsTransformationAdapter . Transform ( centralStockholmWgs84 , epsgSweRef ) ;
if ( centralStockholmResultSweRef . IsSuccess ) {
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))
}
}
} using Programmerare . CrsConstants . ConstantsByAreaNameNumber . v10_036 ;
using Programmerare . CrsTransformations ;
using Programmerare . CrsTransformations . CompositeTransformations ;
using Programmerare . CrsTransformations . Coordinate ;
using System ;
using System . Collections . Generic ;
.. .
// 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)
}버전 3.0.0은 WKT-CRS에 대한 지원이 추가되었지만 WKT-CRS 문자열은 제공된 문자열이 "WKT OGC"또는 "WKT ESRI"인지 알아 내지 않고 구현에 전달됩니다.
코드 예제, 복합 어댑터 사용 (잎 구현 DOTSPATIAL 및 PROJNET 포함) :
crstransformationAdaptercompositewkttest.cs
정수 상수는 EPSG 데이터베이스를 사용하여 생성됩니다.
그리고 프로젝트 https://github.com/tomasjohansson/crstransformations의 "CRS-transformation-code-generation"의 Java Library Freemarker
각 상수는 좌표 기준 시스템 (CRS)을 정의하는 데 사용됩니다.
상수의 이름은 다음 세 부분을 연결하는 것입니다.
이 섹션의 아래 스크린 샷과 텍스트는 이전 버전 9.5.4에 대한 것이지만 이제는 이후 버전이 있습니다 . NUGET 저장소에서 최신 버전의 '프로그래머 are.crstransformations.constants'를 찾을 수 있습니다.
위의 세 열을 선택할 때 SQL 결과 예 :
위의 세 부분은 부품들 사이의 분리기로서 두 밑줄과 함께 (위의 순서, 즉 Areaname+crsname+epsgnumber) 연결됩니다.
공백 및 기타 특수 문자는 밑줄로 대체됩니다.
상수 이름은 아래 그림과 같이 대단합니다.
Class epsgnumber와 함께 Intellisense/Autocompletion을 사용할 때 Visual Studio 2017의 스크린 샷 : 

C# Class 프로그래머 are.crsconstants.constantsByAreanAmenumber.v9_5_4.epsgnumber에서 상수 이름의 몇 가지 예제 :
(아래 의이 상수 이름을 위의 SQL 스크린 샷의 세 가지 결과 열과 비교할 수 있습니다)
WORLD__WGS_84__4326
WORLD__85_S_TO_85_N__WGS_84__PSEUDO_MERCATOR__3857
NORTH_AMERICA__NAD83__NAD83__4269
USA__US_NATIONAL_ATLAS_EQUAL_AREA__2163
CANADA__NAD83__CANADA_ATLAS_LAMBERT__3978
UK__GREAT_BRITAIN_MAINLAND_ONSHORE__OSGB_1936__BRITISH_NATIONAL_GRID__ODN_HEIGHT__7405
IRELAND__ONSHORE__TM65__IRISH_GRID__29902
AUSTRALIA__GDA__GDA94__4283
NEW_ZEALAND__ONSHORE__NZGD49__NEW_ZEALAND_MAP_GRID__27200
SWEDEN__SWEREF99_TM__3006
FINLAND__19_5_E_TO_20_5_E_ONSHORE_NOMINAL__ETRS89__GK20FIN__3874
DENMARK__ONSHORE_BORNHOLM__ETRS89__KP2000_BORNHOLM__2198
NORWAY__ONSHORE__NGO_1948__OSLO__4817
ICELAND__ONSHORE__REYKJAVIK_1900__4657
NETHERLANDS__ONSHORE__AMERSFOORT__RD_NEW__28992
BELGIUM__ONSHORE__BELGE_1972__BELGIAN_LAMBERT_72__31370
GERMANY__WEST_GERMANY__10_5_E_TO_13_5_E__DHDN__3_DEGREE_GAUSS_KRUGER_ZONE_4__31468
AUSTRIA__ETRS89__AUSTRIA_LAMBERT__3416
EUROPE__LIECHTENSTEIN_AND_SWITZERLAND__CH1903__LV03__21781 상수가있는 위의 예는 그 중 거의 거의 표시되지 않습니다.
생성 된 클래스에는 수천 개의 상수가 있습니다.
실제 상수 수 (사용중인 상수 클래스의 버전의 경우)는 C# Code 'Typeof (epsgnumber) .getFields (). 길이'로 쉽게 검색 할 수 있습니다.
SQL 문 'Select Count (Select Coord_Ref_Sys_Code)에서 반환 된 값으로 동일한 숫자를 검증 할 수 있습니다. EPSG_COORDINATEREFERENCESYSTEM에서 SELFING EPSG_COORDINATEREFERENCESYSTEM'(또는 EPSG_COORDINATEREFERENCESYSTEM에서 'COORD_REF_SYS_CODE'가 기본 키이기 때문에).