本文的应用场景,是要通过某市的行政区划,去查询覆盖指定县市的影像数据。其中行政区划采用Xian80地理坐标系,而影像数据则采用了该市的地方平面坐标系,因此需要进行坐标转换。
下文将为您介绍如何在ArcGIS Server开发中进行坐标系转换。
本文所谓的自定义坐标系,是指没有包含在ArcGIS自带的坐标系中的坐标系。比如你通过ArcGIS的坐标系定义工具自定义的,或者从其他部门得到的.prj文件等。
自定义坐标系在国内应用比较普通,通常每个城市都会有自己的地方坐标系,以获得最高的测量精度。这些地方坐标系与其他标准坐标系(WGS84、Xian80、Beijing54或CGCS2000)之间的转换参数(如七参数、三参数)一般都是保密的。我们知道,在进行ArcGIS Server客户端应用(如Flex、Silverlight、JavaScript、Android、iOS、Windows Phone等)开发的时候,都是通过REST接口,使用的坐标系的时候通常是通过WKID,但这个WKID只包含了ArcGIS自带的那些标准的坐标系,对于自定义的坐标系则无法使用WKID。
在ArcGIS Server 10.0中,推出了新的WKT(Well-KnownText),即可以通过标准的文本来定义坐标系。
另外在ArcGIS 10.1中,对投影函数进行了增强,使之支持自定义的大地基准转换,这样我们就可以完全在ArcGIS Server开发中使用自定义坐标系了。本文示例为作者根据已有的坐标系,进行微调生成的自定义坐标系,我们姑且叫他“XX市独立坐标系(xx_duli)”吧。坐标系定义(即WKT)如下:
PROJCS["xx_duli",GEOGCS["GCS_Krasovsky_1940",DATUM["D_Krasovsky_1940",SPHEROID["Krasovsky_1940",6378245.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",50000.0],PARAMETER["False_Northing",-3202855.272],PARAMETER["Central_Meridian",106.419263889],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]另外定义了一个大地基准转换,用于在该坐标系的大地基准(D_Krasovsky_1940)和Xian80的大地基准(GCS_Xian_1980)之间进行转换,转换定义如下:
GEOGTRAN["GCS_Xian_1980_To_Krasovsky_1940",GEOGCS["GCS_Xian_1980",DATUM["D_Xian_1980",SPHEROID["Xian_1980",6378140.0,298.257]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433],METADATA["China- onshore",73.66,18.04,134.85,53.59,0.0,0.0174532925199433,0.0,3228]],GEOGCS["GCS_Krasovsky_1940",DATUM["D_Krasovsky_1940",SPHEROID["Krasovsky_1940",6378245.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433],METADATA["Notspecified",-180.0,-90.0,180.0,90.0,0.0,0.0174532925199433,0.0,1263]],METHOD["Geocentric_Translation"],PARAMETER["X_Axis_Translation",0.0],PARAMETER["Y_Axis_Translation",0.0],PARAMETER["Z_Axis_Translation",0.0]]接下来就可以进行程序开发了,首先看一下进行坐标转换的代码(本文示例代码使用Silverlight):
SpatialReference outSR = new SpatialReference("PROJCS[\"xx_duli\",GEOGCS[\"GCS_Krasovsky_1940\",DATUM[\"D_Krasovsky_1940\",SPHEROID[\"Krasovsky_1940\",6378245.0,298.3]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Gauss_Kruger\"],PARAMETER[\"False_Easting\",50000.0],PARAMETER[\"False_Northing\",-3202855.272],PARAMETER[\"Central_Meridian\",106.419263889],PARAMETER[\"Scale_Factor\",1.0],PARAMETER[\"Latitude_Of_Origin\",0.0],UNIT[\"Meter\",1.0]]"); DatumTransform trans = new DatumTransform("GEOGTRAN[\"GCS_Xian_1980_To_Krasovsky_1940\",GEOGCS[\"GCS_Xian_1980\",DATUM[\"D_Xian_1980\",SPHEROID[\"Xian_1980\",6378140.0,298.257]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433],METADATA[\"China - onshore\",73.66,18.04,134.85,53.59,0.0,0.0174532925199433,0.0,3228]],GEOGCS[\"GCS_Krasovsky_1940\",DATUM[\"D_Krasovsky_1940\",SPHEROID[\"Krasovsky_1940\",6378245.0,298.3]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433],METADATA[\"Not specified\",-180.0,-90.0,180.0,90.0,0.0,0.0174532925199433,0.0,1263]],METHOD[\"Geocentric_Translation\"],PARAMETER[\"X_Axis_Translation\",0.0],PARAMETER[\"Y_Axis_Translation\",0.0],PARAMETER[\"Z_Axis_Translation\",0.0]]"); GeometryService projectTask = new GeometryService(geometryUrl); projectTask.ProjectCompleted += new EventHandler<GraphicsEventArgs>(projectTask_ProjectCompleted); projectTask.Failed += new EventHandler<TaskFailedEventArgs>(projectTask_Failed); projectTask.ProjectAsync(e.FeatureSet, outSR, trans, true, null);
QueryTask spatialQuery = new QueryTask(cqduliUrl); spatialQuery.Failed += new EventHandler<TaskFailedEventArgs>(spatialQuery_Failed); spatialQuery.ExecuteCompleted += new EventHandler<QueryEventArgs>(spatialQuery_ExecuteCompleted); Query query = new Query(); query.ReturnGeometry = true; query.OutFields.Add("OBJECTID"); query.Geometry = e.Results[0].Geometry; query.OutSpatialReference = new SpatialReference(4610); spatialQuery.ExecuteAsync(query);
通过中间这个县的区划要素,查询到三景影像覆盖。
以上就是如何在客户端开发中使用自定义坐标系和自定义大地基准转换,关键就是要用好WKT,而且该功能是由REST SDK提供的,因此对于Flex、Silverlight、JavaScript、Android、Windows Phone或者iOS都同等支持。