ArcGIS Server 入门学习

ArcGIS Server 入门学习()

来源:浩淼的天空


【摘要】
ArcGIS Server是用于开发基于网络的企业级服务器端程序的一套组件集,服务器端程序包括Web Service、Web 应用程序和EJB等。使用AS开发的程序,其功能可以从普通的显示地图跨越到复杂的网络分析等,即它提供的功能比ArcIMS强大得多。ESRI提供的 AS包括两个部分,一是ArcGIS Server,它是AS的服务器,AS能够运行全靠它;另一个是用于客户端开发的程序ADF(Application Developer Framework)开发集,它提供了一套可视化的WEB组件和模板,用于运行在WEB页面上(在9.2中,IMS的开发手段比以前有了很大的进步,和 AS差不多)。同AE一样,AS的核心组件也是AO,简单讲,它是运行在服务器端的AO组件集。

【全文】

ArcGIS Server是用于开发基于网络的企业级服务器端程序的一套组件集,服务器端程序包括Web Service、Web 应用程序和EJB等。使用AS开发的程序,其功能可以从普通的显示地图跨越到复杂的网络分析等,即它提供的功能比ArcIMS强大得多。ESRI提供的 AS包括两个部分,一是ArcGIS Server,它是AS的服务器,AS能够运行全靠它;另一个是用于客户端开发的程序ADF(Application Developer Framework)开发集,它提供了一套可视化的WEB组件和模板,用于运行在WEB页面上(在9.2中,IMS的开发手段比以前有了很大的进步,和 AS差不多)。同AE一样,AS的核心组件也是AO,简单讲,它是运行在服务器端的AO组件集。

开发AS的手段有两种,一是使用,NET开发,另一种是使用JAVA开发。

AS的关键特征有:
1. 标准的GIS框架,即它和ESRI其它的软件框架都是一样的,这样降低了开发难度。
2. 降低了分布费用,由于AS是基于WEB的GIS程序,因此ADF的运行时是不需要license的,这也使得服务器端的功能可以免费被多用户使用。
3. Web Control,一系列可视化控件的提供,降低开发难度
4. Web程序模板
5. 跨平台分布使用
6. 多种开发语言
7. 可以使用ArcGIS的多种高级功能,如3D分析,空间分析等
8. 提供了大量的开发资源

ESRI提供了一份PDF文件《ArcGIS Server Administrator and Developer Guide》供AS管理员和开发者使用。

 

====================================================

ArcGIS Server学习

ArcGIS Server产品包括两个部分,一是GIS Server,它是一个提供GIS服务的服务器软件产品,包括一系列核心AO库和一个管理这些AO组件的可缩放的运行环境;另一个是ADF,即应用程序开 发框架,它有JAVA和.NET两种开发组件集,它是用来开发和部署基于GIS Server的web应用程序的产品,包括组件对象、web控件、web模板和开发帮助,它还有一个web程序的runtime,专门用于发布和部署使用 ADF开发的web程序,如ASP.NET等。

GIS Server是一套GIS服务器组件,专门用于管理和发布地图服务和定位服务,安装在GIS服务器上;ADF是供开发人员使用的开发组件集,安装在开发人 员的机器上,这些程序包括WEB应用程序、WEB服务和桌面端程序,都可以使用ADF;ADF Runtime是专门用于部署开发人员开发的GIS web程序和GIS WEB Service的工具,安装在WEB服务器上。GIS服务器、WEB服务器和开发人员的电脑可以是同一台机器,也可以分开安装。

AS的安装和配置

不 明白为什么那么多人都说AS的安装和配置复杂,甚至还要重装系统。其实,如果你多次安装过IMS这类的产品,对于AS,那是小菜一碟,首先是按照安装步骤 一步步NEXT下去即可,在安装完毕后,程序将会要求Post Installation的设置,这是关键。当程序弹出一个对话框要用户填入SOM和SOC用户名和密码时,直接键入,如SOM为arcgissom, SOC为arcgissoc,这两个用户将来将用于管理AS,键入即可,先不用管它们。在填完用户名和密码后,再设置许可文件,这样,程序就配置完成了一 大步。

打开“控制面板--管理工具--计算机管理--本地用户和组--组”,我们将看到agsadmin和agsuser两个组,这两个组 的用户是用于管理AS的,分别将administrator用户填入这两个组中(一般是登录用户,比如我通常用administrator登录到操作系 统)。这样,administrator用户就可以用来管理和使用AS了。

在IIS中新建一个虚拟目录,其实很简单,也可以通过下面的方法设置:新建一个文件夹xxx,在右键web共享属性中选择共享即可,然后在浏览器中使用http://localhost/xxx来测试一下目录是否可以访问,如果可以,则设置成功。

重启电脑,为了保证我们设置的用户及其权限能够成功。

在 新启动的电脑中打开ArcCatalog,这是AS管理服务的软件,注意,我们必须是使用agsadmin组中的账户登录,这样才能管理AS。点击GIS Server---Add GIS Server,会弹出个对话框,我们需要设置各种属性。Host中设置AS安装的机器名,Directory中设置我们在前面建立虚拟目录时候新建的文件 夹。点击确定,这样AS服务管理器的配置设置好了。

点击Add Server Object,开始新建服务对象,这些属性都很容易设置,除了一点,即“参数”中的“选择输出目录”,这个目录还必须选我们之前设置的文件夹,并且正确填写通过HTTP访问该文件夹的方式,即前面的http://localhost/xxx。点击确定,这样一个AS的服务对象就新建好了。

如果不出意外,当我们点击ArcCatalog中的Preview时,就会出现图像了。

如果没有图像,我们先打开XXX文件夹,看看其中是否有图片存在,如果有,那就是服务成功,但是访问不成功,这个时候我们需要重启IIS,保证能够通过http://localhost/xxx的方式访问到XXX文件夹。这是因为我们访问AS是通过WEB服务器进行的,而不是直接连接到服务。

 ==================================================================

ArcGIS Server是一个服务器端的AO组件集,我们对AS的编程操作,都意味着对远端服务器上对象的操作,这是一个很大的不同。以使用AE开发成为为例,我们 新建一个对象,使用的是new关键字,这是在本地机器上新建一个对象的操作,这个操作一直封装在一个进程中。而AS的开发,意味着本地的一个对象,必须调 用远端的一个对象来实现某种功能,本地的操作进程与远程的操作进程实际上是两个不同的进程,如何在两个进程之间进行通讯呢?

AS使用了分布 式对象技术DOT来处理这个问题,ADF提供了一系列所谓的ArcObjects proxy对象,一个proxy对象就是一个远端对象在本地的引用,它的接口和方法与proxy对象的远端对象完全一致,这样,我们对proxy对象的操 作,就会直接影响到它代理的远端对象。

我们说过,AS是一个三层模型,其中通过浏览器访问的WEB程序和WEB服务都是放在第二层,即 WEB服务器上的,为了让WEB服务器上的程序能够通过操作AO组件来与GIS服务器上的AO组件进行交互,我们需要在WEB服务器上安装ADF,如果是 发布的话,安装ADF Runtime就行了。因此,AO的proxy对象都是安装在web服务器上的。

WEB程序或WEB Service使用的组件是Server API,这些API分为三种:Server API,.NET WebControl和Java WebControl。

当一个WEB应用程序连接到GIS服务器的时候,WEB程序使用的Server API将调用一个代理对象去访问远程服务器上的SOM对象,并通过SOM对象寻找到SOM管理的Server Object对象。它使用了分布式对象技术DOT。这个过程是这样的:

IGISServerConnection pGISServerConn=new GISServerConnectionClass();
pGISServerConn.Connect("nbjbt");//连接到GIS服务器
IServerObjectManager SOM=pGISServerConn.ServerObjectManager;//找到GIS Server上的SOM
IServerContext pServerContext=SOM.CreateServerContext("nbserver","MapServer");//通过SOM创建一个服务器对象的上下文
IServerObject pSO=pServerContext.ServerObject; //从上下文对象找到服务器对象
IMapServer pMapServer=(IMapServer)(pSO);//使用IMapServer接口来访问服务器对象
。。。。。。
pServerContext.ReleaseContext();//释放服务器对象的上下文,即关闭该进程

ServerContext 本质上是一个GIS服务器上的进程,它也是我们服务器端编程的起点。因此,我们是通过CreateServerContext命令在服务器端上创建的,而 不是使用NEW关键字在本机上创建。我们是通过这个进程在访问服务器对象nbserver。我们的工作也是在这个进程中完成的。

 既然是在一个进程中编程,那么,在这个进程中新建一个对象使用的关键字就不是NEW了,而是下面的方式:
新建对象 pSC.CreateObject("esriGeometry.IPoint")
将一个对象放入一个进程 pSC.LoadObject(pPt)
将一个对象放在进程的字典中pSC.SetObject("a",pPt)
将对象从进程字典取出pNewPt=pSC.GetObject("a")

ServerObject的池化和非池化模式

  当我们访问一个服务器对象Server Object的时候,这个对象是已经存在的呢?还是在访问时新建的?都有可能,这取决于我们如何选择。如果我们选择共享池化模式,则在SOM启动的时候, SOM就建立了几个SO供外界访问,一个SO被A请求访问后,被释放回共享池中,还可以下次被B访问使用,因此,SO将可以被多个用户访问。如果是非共享 池模式,当一个请求访问时,SOM专门为它新建一个SO。

这样,在池化模式下,访问与SO的比例不是1:1,它支持更多的用户;而非池化模式就是1:1的,它支持的用户比池化模式少。

SO 放在什么地方,对,它就放在一个Server Context中,即一个进程中。一个访问连接到SO,是一个例程,这个例程是放置在一个进程中的。而对于这个进程的特征,我们还需要进一步设置,即进程 的孤立性。如果Server Context是高孤立的(high isolation),那么一个进程中只能放置一个例程,这样保障了安全性;如果是低孤立的,四个访问连接的例程都可以放置在一个进程中,它的特点是节约 资源。至于如何设置,就有必要考虑我们的硬件设备了。

池化和非池化的设置对状态或非状态的应用程序也有影响,这些我们将在后面的blog中提到。

====================================================================

 

在前文中我们说道,Server Object实际上就是我们建立的地图服务和定位服务,这个服务都是必须通过一个进程来被请求访问到的,那么,这个过程是怎么样的呢?下面我们介绍在共享池模式下的连接过程:

  1. 客户端程序连接到SOM,要求访问一个SO;
  2. SOM分配一个SOC给客户端程序的AO Proxy对象,这个SOC是AS启动时建立的,默认最少为2个,最多为4个;
  3. 客户端程序通过调用远程AO对象的Proxy对象操作AO对象;
  4. 执行完操作后。执行pSC.ReleaseContext,SOC返回共享池中,等待下一次请求访问。

如果是非共享池模式,这个过程不同在于:

  1. SOM新建一个SOC给代理对象
  2. 执行执行pSC.ReleaseContext后,SOC被销毁而不是返回到共享池中。

有状态和无状态的GIS应用程序

我 们知道,一个web程序在每个用户访问的时候,都会产生一个session来记录访客的信息,如果所有用户的访问与session的状态无关,则我们认为 这个程序是无状态的,否则就是有状态。例如my google这些站点,每个人登录后的信息都是不同的,我们则认为这是一个有状态的程序。

对 于AS的Server Object而言,状态state也是非常重要的。一个SO如果是有状态的,那么它的属性就能改变,否则,非状态的SO的属性是不能被修改的。一个SO的 状态如何暗示了它是否能够被跨session共享使用。如果一个SO是无状态的,那么它就是共享的,否则就是独占式的。

SO是否使用状态与 SO是否是共享池模式有密切个关系。这是因为,一个池式的SO是不能被改变的,不能被用于有状态的程序中;一个非池式的SO的属性是能够改变的,它能够用 于有状态的程序中。一个池式的Server Object是默认为无状态使用的,这是因为这个SO可能会给多个用户访问,而且它用完后是会放回共享池中的,如果改变了它的状态,则意味着不同的访问者 访问它时获得的信息不一致,这本身是一种非状态的行为。而我们要求的是保证不同的人都是一样的结果的一种无状态模式,因此,保证本身具有“共享”特征的池 式SO的无状态使用才是到达目的的方法。因此,共享池模式的SO的无状态使用,是有效率满足访问的方式。如果要做无模式的程序,共享池式的SO是首选。

如果是建立有模式的程序,那么使用非共享池式的SO是首选,由于这种情况下访问请求与SO数量是1:1,这就使得一个人对SO的改变不会影响另一个人的使用。

下面是一个无状态的代码:

ServerConnection pServerConn=new ESRI.ArcGIS.Server.WebControls.ServerConnection("nbjbt");
   pServerConn.Connect();
   IServerObjectManager pSOM=pServerConn.ServerObjectManager;
   IServerContext pSC=pSOM.CreateServerContext("nbserver","MapServer");
   IServerObject pSO=pSC.ServerObject;
   IMapServer pMapServer=(IMapServer)pSO;
   IMapServerInfo pMapServerInfo=pMapServer.GetServerInfo(pMapServer.DefaultMapName);
   IMapDescription pMapDesc=pMapServerInfo.DefaultMapDescription;

   IImageType it=(IImageType)pSC.CreateObject("esriCarto.ImageType");
   it.Format =esriImageFormat.esriImageJPG;
   it.ReturnType =esriImageReturnType.esriImageReturnURL;

   IImageDisplay idisp=(IImageDisplay)pSC.CreateObject("esriCarto.ImageDisplay");
   idisp.Height =400;
   idisp.Width =400;
   idisp.DeviceResolution=150;

   IImageDescription pID=(IImageDescription)pSC.CreateObject("esriCarto.ImageDescription");
   pID.Display =idisp;
   pID.Type =it;

   IImageResult pImgResult=pMapServer.ExportMapImage(pMapDesc,pID);
   
   this.Label1.Text =pImgResult.URL;
   pSC.ReleaseContext();

 

=================================================================

有状态和无状态的应用程序2

我们继续讨论web程序的状态问题。其实写过诸如asp jsp的人都知道,类似session、cookie等东西在web页面程序中应用的非常广泛,因为这是我们让程序记住一个用户标志的方法,唯有使用这些对象,我们才能区分不同的用户。

事 实上,有状态的web程序是极其常见的,许多我们根本没有意识到的“无状态”操作都依赖有状态的方法来实现,这种方法我们称为“浅状态程序”,例如下面这 个例子,我们启动一个页面,然后点击一个“固定放大”按钮去放大地图,看起来似乎与状态无关,但是仔细想想,这种固定放大是依赖地图放大前一次的范围的, 这意味着我们必须记录前一次的地图状态,这其实就是一种状态程序。

我们下面写这个代码:

页面启动:
  private void Page_Load(object sender, System.EventArgs e)
  {
   // 在此处放置用户代码以初始化页面
   if(!Page.IsPostBack)
   {
    if(Session.IsNewSession)
    {
     ESRI.ArcGIS.Server.WebControls.ServerConnection pServerConn=new ESRI.ArcGIS.Server.WebControls.ServerConnection("nbjbt");
     pServerConn.Connect();
     IServerObjectManager pSOM=pServerConn.ServerObjectManager;
     //将SOM保存到全局变量区
     Application.Set("som",pSOM);

     IServerContext pSC=pSOM.CreateServerContext("nbserver","MapServer");
     IServerObject pSO=pSC.ServerObject;
     IMapServer pMapServer=(IMapServer)pSO;
     IMapServerInfo pMapServerInfo=pMapServer.GetServerInfo(pMapServer.DefaultMapName);
     IMapDescription pMapDesc=pMapServerInfo.DefaultMapDescription;
     //将pMapDesc序列化为一个字符串,保存到一个session中
     string ss=pSC.SaveObject(pMapDesc);
     Session["md"]=ss;
     //显示启动时默认地图
     this.Image1.ImageUrl=this.CreateImage(pMapDesc,pSC);
     //释放进程
     pSC.ReleaseContext();
    }
   }
  }

下面是按下固定放大时候的代码:
  private void Button1_Click(object sender, System.EventArgs e)
  {
   IServerObjectManager pSom=(IServerObjectManager)Application.Get("som");
   IServerContext pSC=pSom.CreateServerContext("nbserver","MapServer");
   IMapServer pMapServer=(IMapServer)pSC.ServerObject;
   //从session中取出上一次地图的描述对象
   string smd=(string)Session["md"];
   IMapDescription pMapDesc=(IMapDescription)pSC.LoadObject(smd);

   IMapArea ma=pMapDesc.MapArea;
   IEnvelope pEnv=ma.Extent;
   pEnv.Expand(0.9,0.9,true);

   IMapExtent mx=(IMapExtent)ma;
   mx.Extent =pEnv;
   pMapDesc.MapArea =ma;
   //改变地图
   this.Image1.ImageUrl=this.CreateImage(pMapDesc,pSC);
   //将改变后的地图描述对象存入同名的session中
   string ss=pSC.SaveObject(pMapDesc);
   Session["md"]=ss;
   pSC.ReleaseContext();
  }

有“浅状态程序”,也就有相应的“深状态程序”了,后者必须是一种独占式的SO才行,因为深状态程序做的内容可能包括删除地图中的一个图层等操作,如果是非独占式的SO,显然不行,这就是说我们在深状态程序中,必须使用非池化SO才行。

最 后还需要记住的一点是,如果访问非共享池模式的SO时产生了session,需要在Session_End事件中手工将这些session清除,这是因为 服务器的空间和性能是有限的,产生太多的session会对服务器的性能有影响,而且对于非共享池模式的session而言,反正是独占式享用SO,在退 出时保留session是浪费资源而已。

代码执行完毕后,在Label1中将出现一张图片的地址,我们在AS服务器的输出目录看看,会发现已经生成了一张JPG的图片

===================================================================================

WEB服务

使 用Server API和web控件既可以开发供用户直接交互的Web应用程序,也可以开发供程序使用的Web Service。AS支持的WEB Service分为两种,即Application Web Service和ArcGIS Server Web Service。

Application Web Service

Application Web Service是我们见过的最普通的WEB SERVICE编写形式,它的编写方法同ASP.NET WEB SERVICE并无二致,同样,由于web service也是放在web服务器上的,我们的程序写法同样是前面介绍的方法,这里就不多讲我个人的学习体会了。

ArcGIS Server Web Service

这 是使用ADF提供的模板将我们在GIS服务器上建立的Server Object通过WEB Service的方式发布的方式,由于MapServer和GeoCoder同样支持SOAP协议,因此我们也可以通过SOAP API来展示服务器上的SO。这样即是通过web service的方式来访问GIS服务器上的SO对象。

其过程如下:

在ArcGIS Server Project中选择Web Service Catalog,建立项目为nbservice,然后键入主机名,获得所要发布为web service的SO对象,点击确定即可。这样就自动建立了web service了。如我有个SO为nbserver被添加了服务。

新建一个asp.net项目,添加web引用,键入http://<主机名>/nbservice/nbserver.aspx?wsdl,将WEB引用名改为NBS,然后在WEB页面中写下如下代码:

private void Page_Load(object sender, System.EventArgs e)
  {
   // 在此处放置用户代码以初始化页面
   NBS.nbserver map=new NBS.nbserver();
   NBS.MapServerInfo mapi=map.GetServerInfo(map.GetDefaultMapName());
   NBS.MapDescription mapdesc=mapi.DefaultMapDescription;

   NBS.ImageType it=new NBS.ImageType();
   it.ImageFormat=NBS.esriImageFormat.esriImageJPG;
   it.ImageReturnType =NBS.esriImageReturnType.esriImageReturnURL;

   NBS.ImageDisplay idisp=new NBS.ImageDisplay();
   idisp.ImageWidth =400;
   idisp.ImageHeight =400;
   idisp.ImageDPI =200;

   NBS.ImageDescription pID=new NBS.ImageDescription();
   pID.ImageDisplay =idisp;
   pID.ImageType =it;

   NBS.MapImage pMI=map.ExportMapImage(mapdesc,pID);
   this.Image1.ImageUrl=pMI.ImageURL;
  }

编译执行,同样会出现一幅地图。

我们可以看到,使用这种方式编码真的是非常简单,使用SOAP API和Server API达到了同样的效果。

 

你可能感兴趣的:(ArcEngine,日积月累)