这段时间我一直在研究如何用PIE加载在线地图服务,遇到了许多问题,多亏了技术员小姐姐的帮助,才让我能正确加载ArcGIS Online在线服务、天地图在线地图和谷歌在线地图。我是根据博客园PIE官方博文(https://www.cnblogs.com/PIESat/p/10184862.html)进行研究的,主要参照打开网络地图数据、加载自定义切片服务数据两篇博文,最后实现是用的加载自定义瓦片地图。
加载在线地图服务关键在于服务接口URL的写法和瓦片参数的设置,自定义服务接口需要路径含有级别,行列信息,以调用ArcGIS Online在线瓦片地图服务为例,服务路径应写为
http://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/[$Level]/[$Row]/[$Column];其中Level表示级别,Row表示为行,Column表示为列。服务路径不能在浏览器中直接复制打开,这是因为加载一个URL将链接在请求服务信息中的返回瓦片比例尺级别和行列号用了模糊查找,如果为了测试可以将链接中的[$Level]、[$Row] 和[$Column] 换成你要浏览的参数即可。
瓦片参数可直接访问调用的ArcGIS Online在线地图服务(http://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer),结果如下图所示:
其中坐标系WKID为3857,代表的是WGS84墨卡托投影,瓦片图像格式可以为PNG32,PNG24,PNG,JPG,DIB,TIFF,EMF,PS,PDF,GIF,SVG,SVGZ,BMP 13种,每英寸点数96,压缩的质量为75。0级瓦片分辨率为156543.03392800014m,比例尺为2019-05-305.91657527591555E8;瓦片开始位置为(-2.0037508342787E7, 2.0037508342787E7);瓦片显示范围为(-2.003750722959434E7, -1.997186888040859E7, 2.003750722959434E7, 1.9971868880408563E7);瓦片的高度和宽度都为256。
在实现过程中还遇到了一些其他的小问题,比如PIE.Carto.TileImageFormat枚举类型里面什么也没有,还有就是一些接口运行时不能正常工作。对于第一个问题,我自己写了一个枚举类,如下图所示,并将它强制转换为PIE.Carto.TileImageFormat类型(tileInfo.Format = (TileImageFormat)TileImageFormat2.PNG;),但是最好还是不要这样做哦,我觉得这是流氓做法。对于第二个问题,则需要将运行路径设置为SDK安装路径下的bin目录下,这样就能正常运行了。
源代码如下
1 private void toolStripButton1_Click(object sender, EventArgs e) 2 { 3 string strUrl = "http://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/[$Level]/[$Row]/[$Column]"; 4 ISpatialReference spatialReference = SpatialReferenceFactory.CreateSpatialReference(3857); 5 PIE.Carto.TileInfo tileInfo = new TileInfo(); 6 tileInfo.Format = (TileImageFormat)TileImageFormat2.TIFF; 7 tileInfo.DPI = 96; 8 tileInfo.CompressionQuality = 75; 9 10 tileInfo.LODInfos = new List<LODInfo>(); 11 double dResolution = 156543.03392800014;//1.40625; 12 double dScale = 5.91657527591555E8;//5.90995197141668E8; 13 for (int i = 0; i < 24; ++i)//显示23级数据 14 { 15 PIE.Carto.LODInfo lodInfo = new LODInfo(); 16 lodInfo.Level = i; 17 lodInfo.Resolution = dResolution / Math.Pow(2.0, i); 18 lodInfo.Scale = dScale / Math.Pow(2.0, i); ; 19 tileInfo.LODInfos.Add(lodInfo); 20 } 21 PIE.Carto.CustomerOnlineTiledLayer tiledLayer = new CustomerOnlineTiledLayer(strUrl); 22 tiledLayer.Name = "ArcgisServer"; 23 24 //设置瓦片开始位置 25 tileInfo.SpatialReference = spatialReference; 26 IPoint point = new PIE.Geometry.Point(); 27 point.PutCoords(-2.0037508342787E7, 2.0037508342787E7);//开始点切片 28 (point as IGeometry).SpatialReference = spatialReference; 29 tileInfo.Origin = point; 30 31 //设置瓦片显示范围 32 IEnvelope envelope = new Envelope(); 33 envelope.PutCoords(-2.003750722959434E7, -1.997186888040859E7, 2.003750722959434E7, 1.9971868880408563E7); 34 tileInfo.InitialExtent = envelope; 35 tileInfo.FullExtent = envelope; 36 tileInfo.TileWidth = 256; 37 tileInfo.TileHeight = 256; 38 tiledLayer.SetTileInfo(tileInfo); 39 40 //加载影像并设置显示范围 41 mapControlMain.FocusMap.AddLayer(tiledLayer); 42 IEnvelope envelop = new Envelope(); 43 envelop.PutCoords(12551838, 3260183, 12605687, 3295447);//长沙市主校区 44 mapControlMain.ActiveView.Extent = envelop; 45 mapControlMain.ActiveView.PartialRefresh(ViewDrawPhaseType.ViewAll); 46 }