Silverlight API 动态图层查询扩展

ArcGIS Server 10.1 最大的功能改进之一:动态图层,可以实现地图服务动态添加数据、动态改变图层顺序、动态改变渲染等很强大的功能。

Silverlight API 3.0 之后的版本,实现了对动态图层操作的支持,API中主要新增了两个类:

DynamicLayerInfo

以及

LayerDrawingOptions


简单的说, DynamicLayerInfo主要用来添加动态图层数据,LayerDrawingOptions主要用来更改图层渲染,改变图层顺序。

关于动态图层的具体使用方法,可以参考http://resources.arcgis.com/en/help/silverlight-api/samples/start.htm#DynamicLayer

然而以上都是针对动态地图服务的(Dynamic Map Service),即客户端收到的都是一张export出来的图片,那么我能不能把动态图层作为feature Layer来查询,取回属性和要素呢?答案是肯定的,参考 Rest API 10.1帮助,http://resources.arcgis.com/en/help/rest/apiref/dynamicLayer.html  dynamiclayer 有query 方法,而且给出了查询的语法,对于这种很自然的需求,让人蛋疼的是,Silverlight API中,竟然没有对应的查询方法。

我们先来看REST 目录中动态图层的查询方法,

要构造一个动态图层,必须给动态地图服务传一个正确的参数layer:参考下图




这个参数指定了动态图层的类型,以及动态图层的数据源。在网页底部,我们能够找到Query方法:


进去以后,我们就能进行动态图层的查询了:


注意其中的url,对动态图层的查询就是对 dynamicLayer 资源做 query方法,其中参数 layer必须填对。

下 面来到客户端,让人蛋疼的是,客户端的 QueryTask 以及 Query 查询参数这两个都不支持动态图层,肿么办,自己写吧。首先,我们需要拼出正确的layer参数,实际上就是把DynamicLayerInfo给序列化了 (可惜DynamicLayerInfo内部序列化的方法SL API也没有暴露出来),以下是把DynamicLayerInfo 对象序列化为 layer 参数的扩展方法:


(更新,DataSource 基类有ToJson 的public方法,它的4种子类JoinDataSource, RasterDataSource, TableDataSouce , QueryDataSource都重载了这个方法,所以下面代码中source 的json部分就不用自己拼了,只需要加上id就行)

public static class Extension
	{
		public static string ToLayerString(this DynamicLayerInfo info)
		{
			StringBuilder sb = new StringBuilder();
			//sb.Append("?layer={\"id\":");
			sb.Append("&layer={\"id\":");

			sb.Append(info.ID.ToString());
			sb.Append(",\"source\":{\"type\":");
			sb.Append(GetDLISourceType(info));
			switch (GetDLISourceType(info))
			{
				case "\"mapLayer\"":
					sb.Append(",\"mapLayerId\":");
					sb.Append((info.Source as LayerMapSource).MapLayerID.ToString());
					sb.Append("}}");
					break;
				default:
					sb.Append(",\"dataSource\":{\"type\":\"table\",\"workspaceId\":\"");
					sb.Append(((info.Source as LayerDataSource).DataSource as TableDataSource).WorkspaceID);
					sb.Append("\",\"dataSourceName\":\"");
					sb.Append(((info.Source as LayerDataSource).DataSource as TableDataSource).DataSourceName);
					sb.Append("\"}}}");
					break;
			}

			return sb.ToString();
		}

		public static string GetDLISourceType(DynamicLayerInfo info)
		{
			if (info.Source is LayerDataSource)
			{
				return "\"dataLayer\"";
			}
			else
				return "\"mapLayer\"";
		}
	}

然后又来到了QueryTask, Silverlight的QueryTask 写的非常的死,它就直接把传给它的URL 加上/query 然后加上查询Query参数的各种字符串,见反编译截图


所以不论我怎么传QueryTask 的URL ,例如:http://xxx.MapServer/dynamicLayer?layer= info.ToLayerString()这样的URL QueryTask 会直接再后面加上/query 以及查询参数,导致查询失败,因为QueryTask没有自动把layer 参数给移到query之后的逻辑,顺带说一句,JavaScript可以这么传URL, 它的QueryTask 有处理dynamicLayer的逻辑,本来想直接扩展ExecuteAsync方法的,无奈其中调用的都是各种 privateinternal方法,只好抛弃这条途径,直接调用WebClient,构造QueryTask的一个扩展方法;


	public static void ExecuteAsyncExtension(this QueryTask qt, Query para, DynamicLayerInfo info, DownloadStringCompletedEventHandler queryCompleteCallBack)
		{
			var url = qt.GetRequestUri(para).ToString() + info.ToLayerString();
			WebClient wc = new WebClient();
			wc.DownloadStringAsync(new Uri(url));
			wc.DownloadStringCompleted += queryCompleteCallBack;
		}

这个方法接受3个参数,Query 查询参数, DynamicLayerInfo 动态图层信息, 以及查询完成回调函数的delegate,这样在实际使用中,我们可以象普通的查询一样,设定查询的参数,然后查询:


另外要注意的是,webclient download的回来是纯json,我们还需要使用FeatureSet 的FromJson静态方法来反序列化获得要素的对象:


测试结果图,注意蓝色是动态图层 (image) 红色的是graphicLayer






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值