proj4经纬度bl转换xy_多种坐标系之间的转换之Proj.NET_转载
Proj.NET (http://www.codeplex.com/ProjNET)是一個(gè).NET下開(kāi)源的空間參照和投影引擎,遵循OGC相關(guān)標(biāo)準(zhǔn)。負(fù)責(zé)人(Coordinators
)是D_Guidi
和SharpGIS,開(kāi)發(fā)者(Developers)還有codekaizen、rstuven等,這些人也是.NET下其他的開(kāi)源系統(tǒng)如GeoAPI.NET、SharpMap等主要貢獻(xiàn)者。License:
GNU Library General Public License (LGPL).
Proj.NET支持基準(zhǔn)面轉(zhuǎn)換,地理坐標(biāo)系,投影坐標(biāo)系,地心坐標(biāo)系,可在多種.NET框架下使用,并支持SilverLight。它可進(jìn)行點(diǎn)對(duì)點(diǎn)之間的坐標(biāo)變換,同時(shí)也可以把坐標(biāo)系轉(zhuǎn)換為
Well-Known Text (WKT) 和 XML。目前支持投影類(lèi)型有:Mercator、橫軸墨卡托投影(Transverse
Mercator)、Albers、正軸等角割圓錐投影(Lambert Conformal Conic、蘭勃特投影)等。
目前最新版發(fā)布版本是1.0,2007年8月,binaries內(nèi)含Proj.NET.dll和Proj.NET.XML兩個(gè)文件,創(chuàng)建程序時(shí)引入dll文件,即可使用相關(guān)類(lèi)、函數(shù)、接口等。若想深入了解,建議把源碼和示例一并下載。下面以實(shí)例來(lái)注解Proj.NET進(jìn)行坐標(biāo)轉(zhuǎn)換的用法。
對(duì)地圖投影基本概念,如投影參數(shù),坐標(biāo)系,SRID,WKT等概念不清楚的話,LionGG前面幾篇文章都已介紹。理解則有助于閱讀下面的示例程序,像我先前一知半解,看著示例修改代碼也可以完成你自己的工作。
一個(gè)多月前,同學(xué)提供投影參數(shù)和四個(gè)投影坐標(biāo),讓幫忙轉(zhuǎn)換成經(jīng)緯度坐標(biāo)。ArcGIS我玩得不熟練,當(dāng)時(shí)便使用剛接觸不久的著名開(kāi)源投影庫(kù)proj4解決了問(wèn)題。這一個(gè)月閑散時(shí)間主要集中在.NET開(kāi)源GIS上,看了GeoAPI.NET和Proj.NET,于是順便用Proj.NET完成同樣的工作,兩相驗(yàn)證結(jié)果。
投影參數(shù):橢球體Krasovsky_1940;Datum:北京1954;投影:蘭勃特雙標(biāo)準(zhǔn)緯線,25N,47N。
坐標(biāo)數(shù)據(jù): 20634500,4660000; 20635500,466000; 20634500,
4659000;20635500,4659000 。
求經(jīng)緯度無(wú)非就是從自定義投影坐標(biāo)系轉(zhuǎn)換到WGS1984坐標(biāo)系,反之若求地理坐標(biāo)則是從WGS84geogCS轉(zhuǎn)換到要求的投影坐標(biāo)系。首先了解下在Proj.NET創(chuàng)建坐標(biāo)系的方法:
predefined、SRID、WKT、Code。
用預(yù)定義方法或SRID創(chuàng)建WGS84地理坐標(biāo)系:
GeographicCoordinateSystem toCS =
GeographicCoordinateSystem.WGS84;
預(yù)定義方法,十分簡(jiǎn)單,但系統(tǒng)預(yù)定義坐標(biāo)系為數(shù)不多。
ICoordinateSystem toCS = SridReader.GetCSbyID(4326);
使用SRID也比較容易,前提是引入EPSG的數(shù)據(jù)集,還有SridReader類(lèi)文件,在源碼中有。不知道什么EPSG什么SRID?參考《SRID、EPSG》。
用WKT或Code創(chuàng)建給定的投影坐標(biāo)系(寫(xiě)代碼時(shí)注意轉(zhuǎn)義字符"和刪除換行):
string bj1954Lcc = PROJCS["liongg",
GEOGCS["GCS_Beijing_1954",
DATUM["D_Beijing_1954",SPHEROID["Krasovsky_1940",6378245.0,298.3]],
PRIMEM["Greenwich",0.0],
UNIT["Degree",0.0174532925199433]],
PROJECTION["Lambert_Conformal_Conic"],
PARAMETER["False_Easting",20500000.0],
PARAMETER["False_Northing",0.0],
PARAMETER["Central_Meridian",0.0],
PARAMETER["Standard_Parallel_1",25.0],
PARAMETER["Standard_Parallel_2",47.0],
PARAMETER["Scale_Factor",1.0],
PARAMETER["Latitude_Of_Origin",0.0],
UNIT["Meter",1.0]] ;
不知道什么WKT?比瓢畫(huà)葫蘆,請(qǐng)參考《WKT
(Well Known Text)》。然后用下行語(yǔ)句解析為投影坐標(biāo)系。
IProjectedCoordinateSystem fromCS =
CoordinateSystemWktReader.Parse(bj1954Lcc) as
IProjectedCoordinateSystem;
對(duì)于用戶(hù)自定義坐標(biāo)系,即系統(tǒng)和EPSG沒(méi)有預(yù)設(shè)的坐標(biāo)系,只有通過(guò)WKT和Code方式來(lái)定義。所謂Code方式即把WKT中的“元素”如DATUM、SPHEROID、UNIT等分別定義,最后組合,何必那么麻煩?就像沒(méi)必要用WKT方式去創(chuàng)建WGS84地理坐標(biāo)系一樣。
看一下轉(zhuǎn)換多個(gè)坐標(biāo)對(duì)的函數(shù)原型:List
TransformList(List
points);
參數(shù)和返回值都是List型,List的每個(gè)元素是一個(gè)一維double型數(shù)組。每個(gè)一維數(shù)組即一個(gè)坐標(biāo)對(duì):兩個(gè)或三個(gè)元素,取決于有沒(méi)有高程等第三個(gè)坐標(biāo)Z,順序?yàn)?x,y,z)。因此我們需要把給的坐標(biāo)存儲(chǔ)到List中。(不懂泛型?不是吧……)
LionGG寫(xiě)了一個(gè)多點(diǎn)到多點(diǎn)的轉(zhuǎn)換函數(shù):參數(shù)分別是源坐標(biāo)系,目標(biāo)坐標(biāo)系,要轉(zhuǎn)換的坐標(biāo)值List,返回的坐標(biāo)值List。函數(shù)內(nèi)容就不再解釋,不精通設(shè)計(jì)模式?知道工廠模式不至于迷糊就行。
static void
PtsToPts(ICoordinateSystem fromCS, ICoordinateSystem
toCS,List pts, out
List results)
{
CoordinateTransformationFactory ctfac = new
CoordinateTransformationFactory();
ICoordinateTransformation trans =
ctfac.CreateFromCoordinateSystems(fromCS, toCS);
results = trans.MathTransform.TransformList(pts);
}
下面是主函數(shù),簡(jiǎn)略起見(jiàn),命名空間的引用,異常捕捉等省略,并不再注釋。
static void Main(string[] args)
{
string bj1954Lcc= "……"; //見(jiàn)上文
IProjectedCoordinateSystem fromCS =
CoordinateSystemWktReader.Parse(bj1954Lcc) as
IProjectedCoordinateSystem;
GeographicCoordinateSystem toCS =
GeographicCoordinateSystem.WGS84;
double[] xPts = new double[4] { 20634500, 20635500, 20634500,
20635500 };
double[] yPts = new double[4] { 4660000, 4660000, 4659000, 4659000
};
List pts = new
List();
for (int i = 0; i < 4; i++)
{
double[] xy = new double[] { xPts[i], yPts[i] };
pts.Add(xy);
List results = new
List();
PtsToPts(fromCS, toCS, pts, out results);
foreach (double[] result in results)
{
Console.WriteLine("{0},{1}", result[0], result[1]);
}
}
下面是計(jì)算結(jié)果,可以看出來(lái)和使用proj4的計(jì)算結(jié)果只有精度位數(shù)的差異。
118.611065451529,40.4621006468135
118.623041399559,40.4619479215536
118.610866262964,40.4529532936788
118.622840730867,40.4528005852267
proj4是用C寫(xiě)的,很好很強(qiáng)大,我暫且只會(huì)簡(jiǎn)單使用,沒(méi)看過(guò)源代碼。Proj4的計(jì)算結(jié)果:
Beijing 1954:?20634500.0?4660000.00
pj_inv result:
118.611065?40.462077
Beijing 1954:?20635500.0?4660000.00
pj_inv result:
118.623041?40.461924
Beijing 1954:?20634500.0?4659000.00
pj_inv result:
118.610866?40.452929
Beijing 1954:?20635500.0?4659000.00
pj_inv result:
118.622841?40.452777
本文介紹了Proj.NET的基本情況,如何創(chuàng)建坐標(biāo)系,如何在坐標(biāo)系間進(jìn)行多個(gè)坐標(biāo)點(diǎn)的轉(zhuǎn)換,滿(mǎn)足了最基本的需求。后續(xù)會(huì)逐步介紹更加深入一點(diǎn)功能。
總結(jié)
以上是生活随笔為你收集整理的proj4经纬度bl转换xy_多种坐标系之间的转换之Proj.NET_转载的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 货币基金赎回当天有没有收益
- 下一篇: asp.net ajax控件工具集 Au