现在来实现上面提到的3个功能。
1、对于某条公路上的一点进行Identify操作,要求返回该点在公路上的桩号值:
以Silverlight API为例。为了在服务器端使用ArcObjects,在Asp.net工程中添加一个名为LinearRef的Silverlight-Enabled WCF Service,在LinearRef.svc.cs文件中添加以下代码:
复制代码
其中,IdentifyResult是自定义的一个类,用来存储查询的结果:
复制代码
Identify方法需要传入3个参数,一个点的地理坐标以及当前地图的Resolution,后者用来生成一个10像素的缓冲区,方便用户的点击操作;其中利用IRouteLocator2.Identify方法获得M值,据此利用 IRouteLocator2.Locate方法获得精确落在公路上的点的Geometry,用以显示在客户端;如果用户点击的点距离公路较远,则IRouteLocator2.Identify结果为空,返回的IdentifyResult中M值为-1。
在Silverlight工程中,Add Service Reference,找到刚才的LinearRef服务,取名为LRService。
客户端中,新建一个COperation类,实现业务操作。
复制代码
在需要使用Identify功能时,将Map控件的Click事件绑定到Map1_Identify即可。结果如图:
2、输入起始和终止桩号,要求将其间的路段显示在地图上:
要解决这个问题,关键是根据两个M值,求的其间一段公路的Geometry。利用的仍然是IRouteLocator2.Locate方法,其中的第一个参数routeLocation,传入的是用IRouteMeasureLineLocation接口定义的“线性位置”,具体可参考帮助文档。
仍然是在LinearRef.svc.cs文件的LinearRef类中,添加以下方法:
复制代码
由于在服务器端的AO操作,产生的结果是ESRI.ArcGIS.Geometry.IGeometry类型,而客户端需要的则是ESRI.ArcGIS.Client.Geometry.Geometry类型,所以需要对结果序列化/反序列化,这里采用JSON字符串处理。客户端处理结果的函数仍然放在COperation.cs文件中,如下:
复制代码
Silverlight中提供了System.Json库,可以非常方便的对JSON字符串进行解析。结果如图:
3、类似GoogleMap的交通流量地图:
首先看一下Google的交通流量地图:
可以看出,之所以能产生不同颜色段,需要的数据有3个:该段的起始和终止M值,该段的车流量。假设我们获取的业务数据表(EventTable)如下:
联想到上面第二个应用场景,我们便想可以获取所有交通数据后,用循环的办法展示出交通流量地图。但这里有两个问题需要思考:1、即使使用IRouteLocator2.LocateRow方法,服务器端根据起止M值解析出所有的分段图形需要一次循环,客户端将这些图形显示出来还需要一次循环,这样是否合理?2、由于结果显示在客户端,不同用户发出请求时,都将重复上面两个循环,如何改进?
解决问题一:在第二节的Linear Referencing实现原理中,提到了RouteEventSource类,可以将它看作是把Route FeatureClass和EventTable组合在一起的结果,而该类继承自FeatureClass,可当作一个FeatureClass来用。在ArcMap中观察生成后(利用Make Route Event Layer工具)的RouteEventSource层:
不仅包含了EventTable中的事件,还有了我们想要的Shape字段(可取出Geometry)。其实Shape字段中的内容,是利用Dynamic Segmentation技术动态计算出来的。看其图层属性便知,它是在内存中动态生成的:
有了FeatureClass,我们便可以对整个图层进行一次渲染,避免服务器端和客户端的两次循环了。这里要注意,FeatureClass是动态生成的,图层便是动态添加,在地图服务的REST接口中无法暴露出来,也就不能利用客户端API的渲染技术了。
解决问题二:利用SOA的思想,将交通流量图做成一个Traffic服务,不同用户请求时动态添加该服务即可。想想这个服务应该具有的特性:不同时段的交通图,需要动态生成;如果交通图已经生成,则无需重新生成,显示即可。所以我们采取池化方式服务(pooled-service)的特性,刚好解决这一问题。
这个场景我们用Web ADF来实现(客户端API与前两个场景相同)。
首先准备两个Map Service:底图服务:shaanxi,交通流量图服务:ShaanxiTraffic。
后者在ArcMap中打开是这样的:
ShaanxiTraffic服务除了动态生成的交通流量图外,不需要在显示任何信息,所以发布时是空白的;因为动态生成的RouteEventSource将作为图层插入到这个地图服务中,所以Route FeatureClass必须也在这个mxd中才行。
Default.aspx页面中放置一个MapResourceManager控件、一个Map控件、一个CallbackButton按钮和一个GridView控件。先看一下结果:
点击按钮后:
看一下Default.aspx.cs中按钮的点击事件:
复制代码
思路都在代码中。依次来看几个函数:
复制代码
对于ShaanxiTraffic服务,在获得的Server Object中,查看当前Map的图层数(默认有一个隐藏的Road图层),若为1则还未产生结果。
下面是动态添加服务的函数,注意要设置背景透明,以便能够看到底图服务:
复制代码
MakeResult函数利用ESRI.ArcGIS.Location库来生成交通流量图。由于Traffic服务是池化服务,当第一个用户请求,生成交通流量图后,该实例(servercontext)会返回服务器上而不被销毁,所以下一个用户再次请求时可以直接显示。如果要实现实时的交通流量图,定时在服务器端重生servercontext,并读取当前时段的EventTable即可。
复制代码
一点注意,在使用IServerContext接口时要及时进行释放。
思考一下:如何通过Geoprocessing Service来实现“交通流量图”?
1、对于某条公路上的一点进行Identify操作,要求返回该点在公路上的桩号值:
以Silverlight API为例。为了在服务器端使用ArcObjects,在Asp.net工程中添加一个名为LinearRef的Silverlight-Enabled WCF Service,在LinearRef.svc.cs文件中添加以下代码:
- namespace RoadDycSeg.Web.WCF
- {
- [ServiceContract(Namespace = "")]
- [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
- public class LinearRef
- {
- public IRouteLocator2 pRtLocator = null;
- ESRI.ArcGIS.Server.IServerObjectManager pSOM = null;
- public ESRI.ArcGIS.Server.IServerContext pServerContext = null;
- public LinearRef()
- {
- ESRI.ArcGIS.ADF.Identity identity = new ESRI.ArcGIS.ADF.Identity("ArcGISWebServices", "yourpassword", "");
- ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsconn = new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection("localhost", identity);
- agsconn.Connect();
- pSOM = agsconn.ServerObjectManager;
- pServerContext = pSOM.CreateServerContext("shaanxi", "MapServer");
- ESRI.ArcGIS.Carto.IMapServer2 pMapServer = pServerContext.ServerObject as ESRI.ArcGIS.Carto.IMapServer2;
- ESRI.ArcGIS.Carto.IMapServerObjects2 pMapServerObjects = pMapServer as ESRI.ArcGIS.Carto.IMapServerObjects2;
- ESRI.ArcGIS.Carto.IMap pMap = pMapServerObjects.get_Map(pMapServer.DefaultMapName);
- IFeatureClass pFC = (pMap.get_Layer(2) as ESRI.ArcGIS.Carto.IFeatureLayer).FeatureClass;
- //create the RouteLocator
- IDataset dS = (IDataset)pFC; // A polylineM feature class.
- IName name = dS.FullName;
- IRouteLocatorName rtLocatorName = pServerContext.CreateObject("esriLocation.RouteMeasureLocatorName") as IRouteLocatorName;
- rtLocatorName.RouteFeatureClassName = name;
- rtLocatorName.RouteIDFieldName = "道路编码";
- rtLocatorName.RouteMeasureUnit = esriUnits.esriUnknownUnits;
- name = (IName)rtLocatorName;
- pRtLocator = (IRouteLocator2)name.Open();
- pServerContext.ReleaseContext();
- }
- // Add more operations here and mark them with [OperationContract]
- [OperationContract]
- /// <summary>
- /// used by the client Identify operation and return the result
- /// </summary>
- /// <param name="mapX">the x coords of the mouseclick in map units</param>
- /// <param name="mapY">the y coords of the mouseclick in map units</param>
- /// <param name="resolution">the map distance of 1 pixel</param>
- /// <returns>a identifyresult class defined in Classes.cs. If no result, mvalue=x=y=-1</returns>
- public IdentifyResult Identify(double mapX, double mapY, double resolution)
- {
- pServerContext = pSOM.CreateServerContext("shaanxi", "MapServer");
- IdentifyResult ir = new IdentifyResult("", -1, -1, -1);
- IPoint pPoint = pServerContext.CreateObject("esriGeometry.Point") as IPoint;
- pPoint.PutCoords(mapX, mapY);
- IEnvelope pEnvelope = pPoint.Envelope;
- pEnvelope.Expand(10 * resolution, 10 * resolution, false);
- IEnumRouteIdentifyResult pEnumResult = pRtLocator.Identify(pEnvelope, "");
- pEnumResult.Reset();
- //only get the first result
- if (pEnumResult.Count > 0)
- {
- IRouteLocation pRL = null;
- IFeature pF = null;
- pEnumResult.Next(out pRL, out pF);
- IRouteMeasurePointLocation pRMPL = pRL as IRouteMeasurePointLocation;
- //retrieve the location geometry by calling LOCATE method
- IRouteLocation routeLocation = pServerContext.CreateObject("esriLocation.RouteMeasurePointLocation") as IRouteLocation;
- routeLocation.MeasureUnit = esriUnits.esriUnknownUnits;
- routeLocation.RouteID = pRL.RouteID;
- routeLocation.LateralOffset = 0;
- IRouteMeasurePointLocation rMPointLoc = (IRouteMeasurePointLocation)routeLocation;
- rMPointLoc.Measure = pRMPL.Measure;
- IGeometry geom;
- esriLocatingError locError;
- pRtLocator.Locate((IRouteLocation)rMPointLoc, out geom, out locError);
- ir.RouteID = pRL.RouteID.ToString();
- ir.MValue = pRMPL.Measure;
- ir.X = (geom as IPointCollection5).get_Point(0).X;
- ir.Y = (geom as IPointCollection5).get_Point(0).Y;
- }
- pServerContext.ReleaseContext();
- return ir;
- }
- namespace RoadDycSeg.Web.WCF
- {
- /// <summary>
- /// the result of Identify operation
- /// </summary>
- [DataContract]
- public class IdentifyResult
- {
- [DataMember]
- public string RouteID {get;set;}
- [DataMember]
- public double MValue {get;set;}
- [DataMember]
- public double X {get;set;}
- [DataMember]
- public double Y {get;set;}
- public IdentifyResult(string routeid, double mvalue, double x, double y)
- {
- RouteID = routeid;
- MValue = mvalue;
- X = x;
- Y = y;
- }
- }
- }
在Silverlight工程中,Add Service Reference,找到刚才的LinearRef服务,取名为LRService。
客户端中,新建一个COperation类,实现业务操作。
- public class COperation
- {
- private LRService.LinearRefClient LR = null;
- private GraphicsLayer glayer = null;
- private bool isBusy = false;//indicate whether there is an operation is performing
- private Map Map1 = null;
- public COperation(Map map)
- {
- Map1=map;
- glayer = Map1.Layers["glayer"] as GraphicsLayer;
- //initialize the LR object
- LR = new RoadDycSeg.LRService.LinearRefClient();
- LR.IdentifyCompleted += new EventHandler<RoadDycSeg.LRService.IdentifyCompletedEventArgs>(LR_IdentifyCompleted);
- }
- private void LR_IdentifyCompleted(object sender, LRService.IdentifyCompletedEventArgs e)
- {
- LRService.IdentifyResult ir = e.Result;
- //add a point graphic to the map with attributes displaying by the maptip, maptip defined in mainpage.xaml
- if (ir.X > 0)//the result exists
- {
- Graphic g = new Graphic()
- {
- Geometry = new MapPoint(ir.X, ir.Y),
- Symbol = Application.Current.Resources["strobeSymbol"] as Symbol,
- };
- g.Attributes.Add("RouteID", ir.RouteID);
- g.Attributes.Add("桩号", ir.MValue);
- g.Attributes.Add("X坐标", ir.X);
- g.Attributes.Add("Y坐标", ir.Y);
- glayer.Graphics.Clear();
- glayer.Graphics.Add(g);
- }
- isBusy = false;
- }
-
- private void Map1_Identify(object sender, ESRI.ArcGIS.Client.Map.MouseEventArgs e)
- {
- if (!isBusy)
- {
- LR.IdentifyAsync(e.MapPoint.X, e.MapPoint.Y, Map1.Resolution);
- isBusy = true;
- }
- }
2、输入起始和终止桩号,要求将其间的路段显示在地图上:
要解决这个问题,关键是根据两个M值,求的其间一段公路的Geometry。利用的仍然是IRouteLocator2.Locate方法,其中的第一个参数routeLocation,传入的是用IRouteMeasureLineLocation接口定义的“线性位置”,具体可参考帮助文档。
仍然是在LinearRef.svc.cs文件的LinearRef类中,添加以下方法:
- [OperationContract(Name = "RetrieveRoutePortionGeometry")]
- /// <summary>
- /// used by the client,such as QueryPortion operation, to retrieve the geometry of the route portion
- /// </summary>
- /// <param name="routeid">the route id which the portion is part of</param>
- /// <param name="fromMValue">fromMvalue</param>
- /// <param name="toMValue">toMvalue</param>
- /// <returns>a json string with specific format,such as [{"x":1111,"y":1111},{"x":2222,"y":2222},{"x":3333,"y":3333}.....]</returns>
- public string RetrieveRoutePortionGeometry(string routeid, double fromMValue, double toMValue)
- {
- pServerContext = pSOM.CreateServerContext("shaanxi", "MapServer");
- IRouteLocation routeLoc = pServerContext.CreateObject("esriLocation.RouteMeasureLineLocation") as IRouteLocation;
- routeLoc.MeasureUnit = esriUnits.esriUnknownUnits;
- routeLoc.RouteID = routeid;
- routeLoc.LateralOffset = 0;
- IRouteMeasureLineLocation rMLineLoc = (IRouteMeasureLineLocation)routeLoc;
- rMLineLoc.FromMeasure = fromMValue;
- rMLineLoc.ToMeasure = toMValue;
- IGeometry geom;
- esriLocatingError locError;
- pRtLocator.Locate((IRouteLocation)rMLineLoc, out geom, out locError);
- pServerContext.ReleaseContext();
- //return the routeportion's vertices
- StringBuilder sb = new StringBuilder("[");
- IPolyline pLine = geom as IPolyline;
- IPointCollection pPC = pLine as IPointCollection;
- //json format such as:
- //[{"x":1111,"y":1111},{"x":2222,"y":2222},{"x":3333,"y":3333}.....]
- for (int i = 0; i < pPC.PointCount; i++)
- {
- sb.Append("{\"x\":");
- sb.Append(pPC.get_Point(i).X.ToString());
- sb.Append(",\"y\":");
- sb.Append(pPC.get_Point(i).Y.ToString());
- sb.Append("},");
- }
- //remove the last ","
- sb.Remove(sb.Length - 1, 1);
- sb.Append("]");
- return sb.ToString();
- }
- private void LR_RetrieveRoutePortionGeometryCompleted(object sender,LRService.RetrieveRoutePortionGeometryCompletedEventArgs e)
- {
- //create a esri.arcgis.client.geometry.polyline from the coords of points contained in the json string
- string jsonpoints = e.Result;
- JsonArray jsonarrays = (JsonArray)JsonArray.Load(new System.IO.StringReader(jsonpoints));
- ESRI.ArcGIS.Client.Geometry.Polyline line = new ESRI.ArcGIS.Client.Geometry.Polyline()
- {
- SpatialReference = Map1.SpatialReference,
- };
- ESRI.ArcGIS.Client.Geometry.PointCollection pc = new ESRI.ArcGIS.Client.Geometry.PointCollection();
- foreach (JsonObject jo in jsonarrays)
- {
- pc.Add(new ESRI.ArcGIS.Client.Geometry.MapPoint(jo["x"], jo["y"]));
- }
- line.Paths.Add(pc);
- //add a graphic
- Graphic g = new Graphic()
- {
- Geometry = line,
- Symbol = Application.Current.Resources["LineSymbol"] as SimpleLineSymbol,
- };
- glayer.Graphics.Add(g);
- }
3、类似GoogleMap的交通流量地图:
首先看一下Google的交通流量地图:
可以看出,之所以能产生不同颜色段,需要的数据有3个:该段的起始和终止M值,该段的车流量。假设我们获取的业务数据表(EventTable)如下:
联想到上面第二个应用场景,我们便想可以获取所有交通数据后,用循环的办法展示出交通流量地图。但这里有两个问题需要思考:1、即使使用IRouteLocator2.LocateRow方法,服务器端根据起止M值解析出所有的分段图形需要一次循环,客户端将这些图形显示出来还需要一次循环,这样是否合理?2、由于结果显示在客户端,不同用户发出请求时,都将重复上面两个循环,如何改进?
解决问题一:在第二节的Linear Referencing实现原理中,提到了RouteEventSource类,可以将它看作是把Route FeatureClass和EventTable组合在一起的结果,而该类继承自FeatureClass,可当作一个FeatureClass来用。在ArcMap中观察生成后(利用Make Route Event Layer工具)的RouteEventSource层:
不仅包含了EventTable中的事件,还有了我们想要的Shape字段(可取出Geometry)。其实Shape字段中的内容,是利用Dynamic Segmentation技术动态计算出来的。看其图层属性便知,它是在内存中动态生成的:
有了FeatureClass,我们便可以对整个图层进行一次渲染,避免服务器端和客户端的两次循环了。这里要注意,FeatureClass是动态生成的,图层便是动态添加,在地图服务的REST接口中无法暴露出来,也就不能利用客户端API的渲染技术了。
解决问题二:利用SOA的思想,将交通流量图做成一个Traffic服务,不同用户请求时动态添加该服务即可。想想这个服务应该具有的特性:不同时段的交通图,需要动态生成;如果交通图已经生成,则无需重新生成,显示即可。所以我们采取池化方式服务(pooled-service)的特性,刚好解决这一问题。
这个场景我们用Web ADF来实现(客户端API与前两个场景相同)。
首先准备两个Map Service:底图服务:shaanxi,交通流量图服务:ShaanxiTraffic。
后者在ArcMap中打开是这样的:
ShaanxiTraffic服务除了动态生成的交通流量图外,不需要在显示任何信息,所以发布时是空白的;因为动态生成的RouteEventSource将作为图层插入到这个地图服务中,所以Route FeatureClass必须也在这个mxd中才行。
Default.aspx页面中放置一个MapResourceManager控件、一个Map控件、一个CallbackButton按钮和一个GridView控件。先看一下结果:
点击按钮后:
看一下Default.aspx.cs中按钮的点击事件:
- protected void CallbackButton1_Clicked(object sender, EventArgs args)
- {
- //先判断Traffic服务中是否已经产生结果
- if (hasTrafficResult())//Traffic服务中已经有结果
- {
- //将结果插入地图
- InsertTrafficService();
- }
- else//服务中还没有结果
- {
- //先生成交通流量结果
- MakeResult();
- //将结果插入地图
- InsertTrafficService();
- }
- //显示RouteEventSource的属性表
- DisplayAttributeTable();
- }
- /// <summary>
- /// 判断池化的Traffic服务中,获取的ServerContext是否已经产生结果
- /// </summary>
- /// <returns>true or false</returns>
- private bool hasTrafficResult()
- {
- ESRI.ArcGIS.ADF.Identity identity = new ESRI.ArcGIS.ADF.Identity("ArcGISWebServices", "yourpassword", "");
- ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsconn = new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection("machinename", identity);
- agsconn.Connect();
- pSOM = agsconn.ServerObjectManager;
- ESRI.ArcGIS.Server.IServerContext pServerContext = pSOM.CreateServerContext("ShaanxiTraffic", "MapServer");
- ESRI.ArcGIS.Carto.IMapServer2 pMapServer = pServerContext.ServerObject as ESRI.ArcGIS.Carto.IMapServer2;
- ESRI.ArcGIS.Carto.IMapServerObjects2 pMapServerObjects = pMapServer as ESRI.ArcGIS.Carto.IMapServerObjects2;
- ESRI.ArcGIS.Carto.IMap pMap = pMapServerObjects.get_Map(pMapServer.DefaultMapName);
- pServerContext.ReleaseContext();
- return pMap.LayerCount == 1 ? false : true;
- }
下面是动态添加服务的函数,注意要设置背景透明,以便能够看到底图服务:
- /// <summary>
- /// 动态添加服务
- /// </summary>
- private void InsertTrafficService()
- {
- if (MapResourceManager1.ResourceItems.Count==1)//若已插入交通流量服务,则不做动作
- {
- MapResourceItem mapResourceItem = new MapResourceItem();
- GISResourceItemDefinition definition = new GISResourceItemDefinition();
- mapResourceItem.Name = "Traffic";
- definition.ResourceDefinition = "Layers@ShaanxiTraffic";
- definition.DataSourceDefinition = "machinename";
- definition.DataSourceType = "ArcGIS Server Local";
- mapResourceItem.Parent = MapResourceManager1;
- mapResourceItem.Definition = definition;
- ESRI.ArcGIS.ADF.Web.DisplaySettings displaysettings = new ESRI.ArcGIS.ADF.Web.DisplaySettings();
- displaysettings.Transparency = 0.0F;
- displaysettings.Visible = true;
- ESRI.ArcGIS.ADF.Web.ImageDescriptor imagedescriptor = new ESRI.ArcGIS.ADF.Web.ImageDescriptor();
- imagedescriptor.TransparentBackground = true;
- imagedescriptor.TransparentColor = System.Drawing.Color.White;
- displaysettings.ImageDescriptor = imagedescriptor;
- mapResourceItem.DisplaySettings = displaysettings;
- MapResourceManager1.ResourceItems.Insert(0, mapResourceItem);
- MapResourceManager1.CreateResource(mapResourceItem);
- if (Map1.ImageBlendingMode == ImageBlendingMode.WebTier)
- {
- Map1.Refresh();
- }
- else
- {
- Map1.RefreshResource("Traffic");
- }
- CallbackButton1.CallbackResults.CopyFrom(Map1.CallbackResults);
- }
- }
- /// <summary>
- /// 生成交通流量的结果
- /// </summary>
- private void MakeResult()
- {
- ESRI.ArcGIS.Server.IServerContext pServerContextTraffic = pSOM.CreateServerContext("ShaanxiTraffic", "MapServer");
- ESRI.ArcGIS.Carto.IMapServer2 pMapServer = pServerContextTraffic.ServerObject as ESRI.ArcGIS.Carto.IMapServer2;
- ESRI.ArcGIS.Carto.IMapServerObjects2 pMapServerObjects = pMapServer as ESRI.ArcGIS.Carto.IMapServerObjects2;
- ESRI.ArcGIS.Carto.IMap pMap = pMapServerObjects.get_Map(pMapServer.DefaultMapName);
- //创建RouteLocator
- IFeatureClass pFC = (GetLayerByName("Road",pMap) as IFeatureLayer).FeatureClass;
- IDataset dS = (IDataset)pFC; // A polylineM feature class.
- IName name = dS.FullName;
- IRouteLocatorName rtLocatorName = pServerContextTraffic.CreateObject("esriLocation.RouteMeasureLocatorName") as IRouteLocatorName;
- rtLocatorName.RouteFeatureClassName = name;
- rtLocatorName.RouteIDFieldName = "道路编码";
- rtLocatorName.RouteMeasureUnit = esriUnits.esriUnknownUnits;
- name = (IName)rtLocatorName;
- IRouteLocator2 pRtLocator = (IRouteLocator2)name.Open();
- //创建RouteEventProperties,为RouteEventSource做准备
- IRouteEventProperties2 rtProp = pServerContextTraffic.CreateObject("esriLocation.RouteMeasureLineProperties") as IRouteEventProperties2;
- rtProp.AddErrorField = true;
- rtProp.ErrorFieldName = "LOC_ERROR";
- rtProp.EventMeasureUnit = esriUnits.esriUnknownUnits;
- rtProp.EventRouteIDFieldName = "RouteID";
- IRouteMeasureLineProperties rMLineProp = (IRouteMeasureLineProperties)rtProp;
- rMLineProp.FromMeasureFieldName = "FromM";
- rMLineProp.ToMeasureFieldName = "ToM";
- //创建RouteEventSource
- ITable eventTable = (pFC.FeatureDataset.Workspace as IFeatureWorkspace).OpenTable("lineEventsTable");
- IDataset ds = (IDataset)eventTable;
- IName name2 = ds.FullName;
- IRouteEventSourceName rtEvtSrcName = pServerContextTraffic.CreateObject("esriLocation.RouteEventSourceName") as IRouteEventSourceName;
- rtEvtSrcName.EventTableName = name2;
- rtEvtSrcName.EventProperties = (IRouteEventProperties)rMLineProp;
- rtEvtSrcName.RouteLocatorName = rtLocatorName;
- name2 = (IName)rtEvtSrcName;
- IRouteEventSource rtEvtSrc = (IRouteEventSource)name2.Open();
- //转换到FeatureClass
- pFC = rtEvtSrc as IFeatureClass;
- //将RouteEventSource添加到地图中,并进行唯一值渲染
- IUniqueValueRenderer pUVR = pServerContextTraffic.CreateObject("esriCarto.UniqueValueRenderer") as IUniqueValueRenderer;
- pUVR.FieldCount = 1;
- pUVR.set_Field(0, "Vehicles");
- pUVR.UseDefaultSymbol = false;
- IFeatureCursor pFeatureCursor = pFC.Search(null, false);
- IFeature pFeature = pFeatureCursor.NextFeature();
- int ifiledindex = pFC.Fields.FindField("Vehicles");//EventTable中的车流量字段
- while (pFeature != null)
- {
- ISimpleLineSymbol pSymbol = pServerContextTraffic.CreateObject("esriDisplay.SimpleLineSymbol") as ISimpleLineSymbol;
- double value = double.Parse(pFeature.get_Value(ifiledindex).ToString());
- if (value <= 20)
- pSymbol.Color = ESRI.ArcGIS.ADF.Converter.ToRGBColor(pServerContextTraffic, System.Drawing.Color.FromArgb(71, 196, 69)) as IColor;
- else if (value > 20 && value <= 50)
- pSymbol.Color = ESRI.ArcGIS.ADF.Converter.ToRGBColor(pServerContextTraffic, System.Drawing.Color.FromArgb(255, 255, 0)) as IColor;
- else if (value > 50 && value <= 100)
- pSymbol.Color = ESRI.ArcGIS.ADF.Converter.ToRGBColor(pServerContextTraffic, System.Drawing.Color.FromArgb(201, 59, 46)) as IColor;
- else
- pSymbol.Color = ESRI.ArcGIS.ADF.Converter.ToRGBColor(pServerContextTraffic, System.Drawing.Color.FromArgb(250, 52, 17)) as IColor;
- pSymbol.Width = 5;
- pUVR.AddValue(pFeature.get_Value(ifiledindex).ToString(), "Vehicles", pSymbol as ISymbol);
- pFeature = pFeatureCursor.NextFeature();
- }
- IFeatureLayer pFL = pServerContextTraffic.CreateObject("esriCarto.FeatureLayer") as IFeatureLayer;
- pFL.Name = "RouteEventSource";
- pFL.FeatureClass = pFC;
- (pFL as IGeoFeatureLayer).Renderer = pUVR as IFeatureRenderer;
-
- pMap.AddLayer(pFL as ILayer);//to the 0 index
- pMapServerObjects.RefreshServerObjects();
- pServerContextTraffic.ReleaseContext();
- }
思考一下:如何通过Geoprocessing Service来实现“交通流量图”?