Tag Archives: ArcObjects

ArcGIS中的线性参考/动态分段技术(三)几个Linear Referencing应用场景在AGS中的实现

        现在来实现上面提到的3个功能。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; … Continue reading ArcGIS中的线性参考/动态分段技术(三)几个Linear Referencing应用场景在AGS中的实现 »

ArcGIS中的线性参考/动态分段技术(二):Linear Referencing在ArcGIS Server中的实现原理

        首先来思考几个Linear Referencing的应用场景(后面会对这些场景一一实现):        1、对于某条公路上的一点进行Identify操作,要求返回该点处在公路上的里程值;        2、输入起始和终止桩号,要求将其间的路段显示在地图上;        3、类似GoogleMap的交通流量地图。        要将这些功能在ArcGIS Server中“落地”,首先决定采用哪种开发方式:客户端API还是Web ADF?两者皆可。但是稍加思考,两种方式的API中都没有提供有关Linear Referencing的解决办法。所以,Linear Referencing在ArcGIS Server中的实现原理还是得依靠ArcObjects了。        ArcObjects中,Linear Referencing的功能在ESRI.ArcGIS.Location库中,请见:http://resources.esri.com/help/9.3/ArcGISEngine/dotnet/10745641-b5e3-4600-979f-cdf9d2bbc7ce.htm#About%20linear%20referencing。        为了实现上述功能,其中比较关键的有两个类:RouteLocator和RouteEventSource。RouteLocator的IRouteLocator2接口有Identify和Locate两个方法,前者可根据地理坐标识别出Route上的位置(M值);后者可根据M值来定位出Route上相应的Geometry。如果已有EventTable,需要对上面的每个Event进行定位,除了重复使用IRouteLocator2.Locate方法(或者LocateRow方法)外,也可通过构建RouteEventSource来实现。它是一种特殊的FeatureClass(继承自FeatureClass),其中的每个Feature代表了EventTable中的一个Event,而这个Feature的Shape字段内容则是根据EventTable和Route FeatureClass,利用Dynamic Segmentation技术实时计算出来的。        关于如何获得可用的IRouteLocator2接口和RouteEventSource,文档中已经讲的很清楚;另外ESRI.ArcGIS.Location中还提供了实现ArcMap中Linear Referencing里所有功能的接口,有兴趣的朋友可以仔细阅读。

AO查询过程中对结果进行排序

        在AO中查询,通常用Search方法,传入一个IQueryFilter类型的变量,但其只有一个Whereclause可选,要对查询结果按照某列排序的话还需要用IQueryDefinition接口。一个例子: IQueryFilter pQF = new QueryFilterClass(); IQueryFilterDefinition queryFilterDef = (IQueryFilterDefinition)pQF; queryFilterDef.PostfixClause = “ORDER BY ” + (axMapControl1.get_Layer(0) as IFeatureLayer).DisplayField; IFeatureCursor pFeatureCursor = pFC.Search(pQF, true);//pFC,featureclass        还需要注意一点,此属性不适用与FileGDB:Please note, file geodatabases do not support the PostFixClause property, and any specifications within the PostFixClause will be ignored。        结果curcor里面的feature就已经按照displayfield排好序了。另外,如果要对已有表进行排序的话可以使用ITableSort接口。

在ArcGIS Server程序中连接GIS Server的注意事项

        为什么要在ArcGIS Server的程序中来连接GIS Server呢?通常有两个理由:1、连接后,创建ServerContext,之后创建更多的AO对象,从而在程序中调用AO来工作;2、连接后,可以用来管理GIS Server,比如重新启动某个服务。        先解释两个概念。这里所说的ArcGIS Server程序是指利用了GIS Server上资源的程序,包括了Desktop Application,Engine Application,但最常见的还是Web Application;要调用AO来服务自己的AGS程序,就必须通过局域网直接连接到SOM机器,因为ArcObjects实际上寄存在SOC机器上,而我们是不能与SOC直接打交道的,只能通过SOM来完成这项工作(通过Internet连接的方式只能连接到Web Server)。        好了,要通过程序来连接到GIS Server,主要有两个对象可以使用:ESRI.ArcGIS.Server.GISServerConnection(实现了IGISServerConnection2接口)和ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection。前者是com对象,后者是原生的.net对象。        先来看ESRI.ArcGIS.Server.GISServerConnection。使用方法如下:ESRI.ArcGIS.Server.IGISServerConnection2 pGISSC = new ESRI.ArcGIS.Server.GISServerConnectionClass();pGISSC.Connect(“yourservername”);ESRI.ArcGIS.Server.IServerObjectAdmin pAdm = pGISSC.ServerObjectAdmin;注意,要成功获得pGISSC.ServerObjectAdmin属性得有一个前提条件,就是运行当前AGS程序(注意看前面对AGS程序的解释)的用户必须是agsadmin组里的成员。那么接下来就可以通过IServerObjectAdmin来对GIS Server进行管理了;如果运行当前AGS程序的用户只是agsuser组里的成员,那么你只能获得ServerObjectManager,从而通过IServerObjectManager来创建AO对象,但是不能对GIS Server进行管理;如果运行当前AGS程序的用户既不是agsuser成员也不是agsadmin成员,那么在connect的时候就会报错了。可以看出ESRI.ArcGIS.Server.GISServerConnection对象不能显式指定连接GIS Server的用户。那么连接GIS Server的用户身份很重要吗?下面通过Web Application来说明一下。        新建一个website,在其中使用如上的代码,调试,通过;将网站发布,浏览,将会出现“拒绝访问”的错误。这正是因为连接GIS Server的用户身份发生了变化。在VS中调试的时候,调用的是VS自带的ASP.NET程序,而不是IIS中的ASP.NET。如下图:可以看出,调试的进程是以系统管理员身份运行的,而通常在安装完AGS后会将系统管理员添加到agsadmin组中;网站发布后,web app运行在IIS进程中,而IIS进程通常以ASPNET账户身份运行,正常情况下,这个账户当然既不属于agsadmin也不属于agsuser了。        同理,如果是Desktop或者Engine的程序,在调试阶段和上面的情况是一致的,如果程序部署到了其他机器上,那么就得考虑一些添加用户的工作了。        下面再来看ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection。这是ADF中的.net对象,通常推荐使用这个对象来进行连接工作,因为它可以指定使用特定的账户身份来连接GIS Server,就是下面的Identity:ESRI.ArcGIS.ADF.Identity identity = new ESRI.ArcGIS.ADF.Identity(“yourusername”, “yourpassword”, “yourdomain”); ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsconnection = new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection(“yourgisservername”, identity); agsconnection.Connect(); ESRI.ArcGIS.Server.IServerObjectAdmin pAdm = agsconnection.ServerObjectAdmin;同样的,要成功获得pAdm,Identity中指定的用户必须是agsadmin成员。如果你的网站,在调试时可以运行,而发布后“拒绝访问”,那么首先检查web.config的identity,如果使用了以上代码,请确保使用的user在正确的用户组中。        再来看看这个Identity与web.config中的identity属性的区别。1、此处的Identity优先级比web.config中的identity属性要高。举例说明,如果在VS中已经做过Add ArcGIS Identity,添加了一个agsuser成员,那么可以在此处用agsadmin成员来连接GIS Server,依然可以获得对SOM机器的管理权限。2、web.config中的identity是在process级别上的impersonation,而此处的Identity是thread级别上的impersonation。如果服务是pooled,low isolation,那么并发请求发生时,会有多个instance运行在同一进程中,而这些instance(thread)就可以通过上面的Identity来以不同用户身份对GIS Server进行连接了。例如:public partial class _Default : System.Web.UI.Page{ private UserThread m_thread; protected void Button1_Click(object sender, EventArgs e) { m_thread = … Continue reading 在ArcGIS Server程序中连接GIS Server的注意事项 »

在ArcGIS Server中调用ESRI自带符号库的一个问题

        在ArcGIS Engine中,如果要调用ESRI自带符号库中的一个符号,比如图中的ColorRamp:         可以利用以下代码来得到: IStyleGallery pSG=new ServerStyleGalleryClass(); pSG.ImportStyle(“ESRI.ServerStyle”); IEnumStyleGalleryItem pESGI = pSG.get_Items(“Color Ramps”, null, null); IStyleGalleryItem pSGI=pESGI.Next();while(pSGI!=null){if(“Pastels”==pSGI.Name)//pastels是该colorramp的名字break;pSGI=pESGI.Next();}IColorRamp pColorRamp=pSGI.Item as IColorRamp;…        但在AGS中发现,执行完IStyleGalleryItem pSGI=PESGI.Next();后,pSGI始终为null,但pSG.ClassCount却为22,表明已经导入了符号库文件,原因后面。但pSG.get_Items()方法执行时也不报错,且在engine下都没有问题……最后发现,在pSG.get_Items()之后,pESGI.Next();之前,插入一句pESGI.Reset()问题就解决了,比较无厘头。