天天看點

ArcGis Server開發Web GIS新手體驗

(以下針對于windows作業系統.net開發環境)

        ArcGIS Server是ESRI公司最新推出的伺服器端品,主要可以實作兩大功能:

        1、強大的Web GIS系統的開發;

     2、分布式GIS系統的開發;

  ArcGIS Server其核心與ArcGIS Desktop和ArcGIS Engine一樣,都是ArcObjects庫。其所謂的Web GIS,其實無非就是用Web技術來封裝ArcObjects而已;而分布式的開發則是通過DCOM來實作的。

  小弟前幾個月搞了一下ArcIMS,發覺開發起來确實痛苦啊,整天就是折騰javascript+arcxml,郁悶死了,聽聞有ArcGIS Server這種好東西,稍稍了解一下,便向老闆建議轉向ArcGIS Server,老闆居然同意了。于是便開發學習了。網上四下裡找了一下,發現可用的資源非常少,隻好自己琢磨。從零開始真不容易啊,這不,剛上手就碰到了兩個問題,好在都已經解決,現在寫下來,希望對和我一樣的新手有所幫助。

  ArcGIS Server的安裝非常簡單,先安裝ArcGIS Server,然後安裝DotNet ADF,最後用ArcCatelog添加一個Server,然後再添加一個ServerObject,這樣就可以進行開發了。這裡的ServerObject與ArcIMS中的Service很像,其實應該是一個概念上的東西吧。添加一個ServerObject需要一個mxd或pmf檔案,用來儲存和管理需要釋出的資料。

  好了,現在可以開始開發了。

  打開Visual Studio 2003,打開建立項目對話框,發現ESRI公司已經為我們準備好了一些ArcGIS Server Projects的模闆,包括Map Viewer Web Application,Page Layout Web Applicaiton等等,我們就建一個Map Viewer Web Application吧,選中它,輸入項目名稱,然後點選“确定”按鈕,我們發現一個已經包含了基本資料浏覽和查詢功能的Web GIS程式已經建好了。

  好,打開Default.aspx檔案,發現網頁包含一個Map元件,一個Toolbar元件,一個TOC元件,一個OverviewMap元件等等。看來與C/S開發模式下很像嘛,爽啊。其中Map元件和OverviewMap元件有兩個必填屬性:Host和ServerObject,就分别對應着我們在ArcCatelog中添加的的Server和ServerObject,輸入它。然後設定TOC元件和Toolbar元件的Buddy屬性,OK,大功告成!

  運作!咦,發生錯誤,定睛一看,原來是通路拒絕,這是怎麼回事呢?記得以前看到一篇文章,說在Asp.net中使用COM元件,經常由于權限原因,産生通路拒絕,而ArcGIS Server本身就是對ArcObjects這些COM元件的再封裝,看來就是這麼回事了。找出這篇文章來,原來要在Web.config中加入一行就可以了:

        <identity impersonate="true" userName="Administrator" password="123456"/>

  再運作,哇塞,酷斃了,一個漂亮的WebGIS展現在眼前。可以浏覽,查詢,圖層管理,鷹眼導航,還有指北針...

   (後來發現頁面上還一個元件叫impersonation沒用上,看了一下它的屬性,隻有一個identity,點選它,你會發現...呵呵,原來這個元件就是用來幹這個事的,暈,又浪費了我兩個小時的寶貴時間...)

  一行代碼都不用寫,爽。可是又很失落,心裡沒有底,這個Web GIS究竟是怎樣實作的呢?

  待續

  我們知道,.net adf提供的map元件、toc元件等都是标準的asp.net元件。這些元件在運作時,會生成相應的html代碼,将自己展現出來。一般還會通過ViewState來儲存狀态,并生成_doPostBack(javascript)函數,在必要的時候,通過javascript來調用該函數,将用戶端資料傳回來伺服器端,進而激發伺服器的響應。總之,我們通過分析生成的html頁面,應該可以大緻窺見asp.net元件是怎麼運作的。

  好,我們現在按F5運作首頁,然後在浏覽器中檢視網頁的源代碼,趕快看下一吧:

  

  1、首先會看到ID,MapIdClick,start等javascript函數,這些函數是模闆為我們生成的,在default.aspx檔案中定義的。ID函數中有兩行:

 var iddiv = document.getElementById("MapDiv_Map1");

 if (iddiv!=null) iddiv.onmousedown = MapIdClick;

  可以看到,這幾個函數的作用是對地圖的Identify(點選查詢)作出處理。

  為什麼要放在這裡呢,為什麼單單隻有點選查詢的javascript要在這裡定義呢,其它如放大、縮小、平移為什麼不在這裡處理?這是因為Toolbar元件對放大、縮小、平移等提供了預設的處理方式,而identify沒有,這樣可以更友善進行擴充。在後面的代碼中有一行<esri:Tool ToolTip="Identify" DefaultImage="Images/identify.gif" ClientToolAction="ID()" Name="Identify"...>,可以看到,這個調用是模闆為我們生成的(并且這個調用是可以修改的)。待會我們在進一步分析中可以看到這一點。

  2、再向下,是幾個隐藏域,其中包含__VIEWSTATE隐藏域,還有__doPostBack函數,這些是asp.net元件生成的,作用是向伺服器送出資料,進而與伺服器進行互動。

 

  3、往下我們看到了一些引入js腳本檔案的代碼:

  <script language="Javascript" src="/aspnet_client/esri_arcgis_server_webcontrols/9_1/JavaScript/common.js"></script>

  <script language="Javascript" src="/aspnet_client/esri_arcgis_server_webcontrols/9_1/JavaScript/map_functions.js"></script>

  <script language="Javascript" src="/aspnet_client/esri_arcgis_server_webcontrols/9_1/JavaScript/overview_functions.js"></script>

  <script language="Javascript" src="/aspnet_client/esri_arcgis_server_webcontrols/9_1/JavaScript/toolbar_functions.js"></script>

  可以看到,共引入了四個js腳本檔案,這些檔案的位址也比較奇怪,不是與目前網站在同一個虛拟目錄下,而是在http://localhost//aspnet_client/esri_arcgis_server_webcontrols/9_1/JavaScript目錄下。在c:/inetpub/webroot/aspnet_client/esri_arcgis_server_webcontrols/9_1/JavaScript/檔案夾下可以找到這些檔案。原來,為了重用的友善,在安裝Arcgis Server時,安裝程式就已經建立了一個虛拟目錄,用于提供這些共享的資源。在這個檔案夾上一級目錄中,還可以看到images和treeimages兩個子目錄,以及treeview.htc檔案。

  知道了這些javascript檔案的藏身之所,各位可以把這些javascript檔案逐個看一遍,可以發現其作用主要是與浏覽器進行互動。

 4、再往下,是TOC元件的Html代碼,代碼片斷如下:

  <tvns:treenode Expanded="False" DefaultStyle="color:silver;" ImageUrl="/aspnet_client/esri_arcgis_server_webcontrols/9_1/images/outscale.gif" CheckBox="False">

   道路注記<tvns:treenode Expanded="True" ImageUrl="ESRI.Web.Controls.MIMEImage.aspx?ImgID=Default.aspx_Toc1_0_1_0_0&amp;NoCache=true"></tvns:treenode>

  這一段代碼有一個特别之處就是ImageUrl="ESRI.Web.Controls.MIMEImage.aspx...",這個ESRI.Web.Controls.MIMEImage.aspx是什麼東東,是一個網頁嗎?在機器裡找一下,發現根本就不存在這個網頁,那它又是何方神聖,竟然可以作為一個圖檔的位址?我們先往下看看。

 5、<div id='OverviewMap1backdrop' style = 'position: absolute; left: 16px; top: 400px; width:204px; height:124px; 

Z-INDEX:104; border-color:LightSteelBlue; border-width:3px; border-style:Solid; overflow:hidden;'>

<table cellspacing=0 cellpadding=0 style = 'width:198px; height:118px; overflow:hidden;'><tr><td id=OVCell_OverviewMap1></td></tr></table>

</div>

  是鷹眼導航圖的代碼。怎麼隻有一個空的Div層和一個空的表格呢?唉,比較簡單,我懶得分析了,同志們自己去找吧~

 6、再往下是Toolbar元件的代碼,沒什麼特别的:

<td nowrap width="29" height ="32" align='Center'

  id="Toolbar1ZoomIn"

  onMouseDown="ToolbarMouseDown( 'Toolbar1', 'ZoomIn', 'Tool', event);"

  onMouseOver="ToolbarMouseOver('Toolbar1', 'ZoomIn');"

  onMouseOut="ToolbarMouseOut( 'Toolbar1', 'ZoomIn');"

  style="background-color:LightSteelBlue;font-family:Arial;font-size:Smaller;font-weight:bold;"

  ><img id="Toolbar1ZoomInImage" alt="Zoom In" src="Images/zoominD.gif"  align="absMiddle"></td>

 7、再下面是生成地圖元件的代碼:

<script language="JavaScript" id="cs_dynamic_Map1">

Maps[mapCounter] = new MapCreation('Map1',0,mapCounter,0,0,502,378,'MapDiv_Map1','Black',2);

mapURL[mapCounter] = "ESRI.Web.Controls.MIMEImage.aspx?ImgID=Default.aspx-Map1&ct=5";

MakeMapDiv(mapCounter, 'Map1','ESRI.Web.Controls.MIMEImage.aspx?ImgID=Default.aspx-Map1&ct=5', 'MapCell_Map1','');

mapCounter++;

MapDragRectangle('Map1','ZoomIn', true);

</script>

  又看到了MIMEImage這個東東!它究竟是什麼東東呢?

  如果對asp.net不是很熟悉的話,要破解這個秘密可能确實比較困難。

  在asp.net中,所有的請求,都是通過httpHandler來進行處理的。那httphandler又是什麼東東呢?其實隻要實作在IHttpHandler接口的類,都可以作為一個HttpHandler。在web.config或machine.config檔案中,可以定義哪些請求可以由哪個httphandler來處理。檢視一下web.config檔案,沒有這些聲明。那就看一下mapchine.config檔案吧,這個檔案在WINDOWS/Microsoft.NET/Framework/v1.1.4322目錄下,用記事本打開它,查找ESRI.Web.Controls.MIMEImage.aspx,好家夥,果然在這裡啊!

  <httpHandlers>

  <add verb="*" path="ESRI.Web.Controls.MIMEImage.aspx" type="ESRI.ArcGIS.Server.WebControls.ImageHandler, ESRI.ArcGIS.Server.WebControls, Version= 9.1.0 .722, Culture=neutral, PublicKeyToken=8fc3cc631e44ad86"/>

  原來ESRI.Web.Controls.MIMEImage.aspx請求是能過ESRI.ArcGIS.Server.WebControls.ImageHandler來處理的。在Visual Studio中,使用對像浏覽器檢視一下esri.arcgis.server.webcontrols.dll檔案,可以看到ImageHandler類,果然實作了IHttpHandler接口。呵呵,其實很簡單嘛,我們也完全可以自己寫一個類,來執行自定義的請求。

  

  又寫累了,就到這裡吧。

  待續

ArcGis Server開發Web GIS新手體驗(三)

接(二)

  在(二)中我們分析了HTML代碼,也就基本弄清了.net adf怎樣封裝用戶端的互動,以及用戶端怎樣與伺服器端進行互動。下面我們再看一看伺服器端的開發方式是怎樣的,實際是就是進入了比較簡單的實戰。用其它工作開發Web GIS的朋友如果能夠了解一下AGS的實作,一定會有很的大啟發,你會在其中學到一些封裝用戶端、伺服器端以及兩者互動的技巧,怎樣做到既封裝一些常用的功能,又不妨礙我們進行功能的擴充。

        好了,廢話少說,開始我們新的體驗吧。

  在(一)中我們已經說了,.net adf提供了一系列的模闆,這些模闆又根據不同的需要,封裝了一些常用的功能。我們的開發一般是從這些模闆開始的。如果我們對這些模闆生成的程式已經很熟了,當然也可以不需要這些模闆,但如果你是新手,請從模闆開始,這樣可以避免走很多彎路。

        首先,我們啟動Visual Studio 2003,建立一個項目,在建立對話框中,在“項目類型”中可以看到ArcGIS Server Projects這一項,選擇語言Visual C#,在右邊的模闆清單中可以看到有七種模闆可供選擇,每種模闆可用于建立不同用途的應用,如下圖所示:

  我們先建立一個Map Viewer Web Application,也就是地圖浏覽程式。我們待會通過分析可以看到這個地圖浏覽程式是怎樣實作的,以及怎樣擴充自己的功能。

     建立了一個Map Viewer Web Application之後,界面如下圖所示。可以看到,.net為我們建立了一個asp.net web工程。工程包括三個頁面,default.aspx,errorpage.aspx和identify.aspx。其中,default.aspx是主界面,errorpage.aspx用于出錯資訊的顯示,identify用于點選查詢操作的結果的顯示。下面我們主要分析default.aspx這個網頁。

     這個網頁的的上部分是一個banner,不用管。下部分由七個asp.net元件構成。這七個元件分别是:

  1、Map元件:地圖元件。有兩個關鍵屬性:Host和ServerObject,不用我說,也知道這是什麼意思。

  2、Toc元件:圖層控件元件(table of contents)。有一個關鍵屬性BuddyControl,即與哪個Map元件相關聯。

        3、Toolbar元件:工具條元件。有一個關鍵屬性BuddyControls,表示可以綁定多個Map元件或PageLayout元件。

        4、OverviewMap元件:導航圖元件。有三個關鍵屬性Host,ServerObject和BuddyControl。

  5、Impersonation元件:身份驗證元件。有一個關鍵屬性identity,用于設計怎麼登入到伺服器,擁有操作的權限。

  6、NorthArrow元件:指北針

  7、ScaleBar元件:比例尺元件,有一個關鍵屬性BuddyControl。BarFont屬性好像有Bug,怎麼設定也不起效,字型總是很小,不知為什麼,哪位朋友也幫俺一個忙,看看怎麼回事?

  這七個元件中,顯然Map元件最為重要,因為它負責地圖顯示并與使用者互動。我們看一下Map元件有的事件,隻有MapChanged的事件包含代碼,仔細看一下,是與視圖(地圖範圍)儲存相關的代碼。那Map元件與使用者互動以及伺服器端的處理代碼,如縮放地圖,在哪裡呢?

        再看一看Toolbar元件,共包含七個按鈕,分别是放大,縮小,平移,全圖,上一視圖,下一視圖和點選。點開它的ToolbarItems屬性看一下,原來工具條按鈕的定義都在這裡面。

        工具條按鈕有兩種類型:Tool和Command

        Tool:工具按鈕。表示點選後并不立即執行某項功能,而是需要使用者與地圖進行互動再執行。是以需要儲存它的狀态。并且同時需要有相應的用戶端代碼(javascript)和伺服器端代碼。放大、縮小、平移和點選屬于這種類型。

  Command:指令按鈕。立即執行某項操作,不需要有戶互動,是以不需要何存狀态。全圖、上一視圖、下一視圖屬于這種類型。

        我們在ToolbarItems的定制界面中,選中identify,看一下它的屬性,包括五部份:

        1、Appearance Images組:定義按鈕顯示的圖檔。這些設定會轉化成HTML代碼。

        2、Appearance Text組:有兩個子項。Text表示在按鈕中顯示的文字,也就是說按鈕可以由圖檔和文字兩部份組成。ToolTip,即滑鼠放在按鈕上面時顯示的提示資訊。

  3、Client-side Action組:這組隻有一個屬性,就是ClientToolAction,這裡就是與用戶端互動的javascript代碼了。内容是ID()。我們打開defaut.aspx,檢視HTML,可以看到ID函數的内容。這裡互動比較簡單的情況,互動比較複雜,如放大時需要拉框,怎麼封裝?原來,Cient-side Action實際上隻是javascript中onmousedown的執行函數,拉框所需的onmousemove和omnouseup去哪裡找?其實隻是一個小技巧而已,在onmousedown中動态地給onmousemove和onmouseup指派不就可以了嗎?事實上,.net adf封裝zoomin等操作就是這要樣做的。 

        Client-side Action屬性有一個下拉選項,包含的是DragImage,DragRectangle,Point,Line,PolyLine,Polygon,Circle,Oval,none,Custom。不用解釋,相信大家也明白了,是Toolbar元件封裝了各種不同類型的用戶端操作。這些與用戶端互動的javascript在哪裡呢?(二)中已經介紹了,這裡就省略啦。

        4、General組。包括Disabled,Name,ShowLoading三個屬性。

        5、Server-side Action組:有兩個屬性,ServerToolActionAssembly和ServerToolActionClass,用于定義伺服器端要執行的功能。在.net adf中,每個被封閉的服務端操作,都是由一個類來實作的,ServerToolActionAssembly表示這個類在哪個程式集中,ServerToolActionClass就是這個類的名稱。我們在ServerToolActionAssembly中選擇ESRI.ArcGIS.Server.WebControls,可以清楚的看到該程式集中定義了四個這種類:MapCenterAt,MapPan,MapZoomin,MapZoomout。事件上,我們也可以定義自己的處理類,隻要實作ESRI.ArcGIS.Server.WebControls.Tools.IMapServerToolAction接口就可以了。

        關于擴充:

        1、用戶端互動:即Client-side Action組,adf封裝了DragImage,DragRectangle,Point,Line,PolyLine,Polygon,Circle,Oval這幾種操作,相信已經能夠應付我們絕大部份的應用了。如果還不行,别忘了最後還有一項custom,選中它,自己寫javascript就可以了。記得是onmousedown的javascript哦。在互動完畢後的代碼中,如果需要傳回到伺服器端的話,記得執行_doPostback函數。

        2、伺服器端功能實作:即Server-side Action組。Map元件針對用戶端封裝的每種行為,都提供了一個事件,表示用戶端互動完畢後,立即執行該事件中的代碼。這些事件有Oval,Line,Point,Polygon等。如果用戶端操作是自己寫的javascript,并最後送出了操作到伺服器的話,可以在Page_Load中處理你自己的操作。

        上面介始的是Tool類型的工具條按鈕。至于Command類型的就簡單多了,我們可以選中FullExtent看一下,它的屬性少了Client-side Action組和Server-side Action組。它的實作代碼就直接到Toolbar元件的CommandClick事件中。自己去看吧。

       其它元件就不介紹了。

  

  說了這麼多,相信您對用.net adf開發Web GIS已經有一個大緻的了解,也基本明白了.net adf的封裝方式,您已經可以開始償試修改已有的功能,或者進行一些簡單的擴充了。下一節我就再介紹一下怎樣進行簡單的功能擴充。

  待續

 ArcGis Server開發Web GIS新手體驗(四)

接(三)

這一節主要貼代碼算了,通過代碼看一下一些簡單功能的實作。偶快要放假了,靜不下心來寫了,寫得也不好。說不定貼代碼效果更好。

1、擷取所有圖層

    ESRI.ArcGIS.Server.WebControls.WebMap webmap= Map1.CreateWebMap();

    try

    {

     ESRI.ArcGIS.Carto.IMapDescription descr = webmap.MapDescription;  

     ddlLayers.Items.Clear();

     int id;

     for (int i=0;i<= descr.LayerDescriptions.Count-1;i++)

     {

      id = descr.LayerDescriptions.get_Element(i).ID;

      ddlLayers.Items.Add(id.ToString() + "," + webmap.LayerNameFromID(id));    //ddlLayers是一個DropDownList控件

     }

     if (ddlLayers.Items.Count>0)

     {

      ddlLayers.SelectedIndex=0;

     }

    }

    finally

    {

     webmap.Dispose();

    }

2、通過圖層的ID擷取圖層對象

    private IFeatureLayer GetFeatureLayer(int lyid)

  {

   WebMap webmap = Map1.CreateWebMap();

   try

   {

    ILayer layer = (webmap.MapServer as IMapServerObjects).get_Layer(webmap.DataFrame,lyid);

    if (layer==null)

     return null;

    else

    {

     return (layer as IFeatureLayer);

    }

   }

   finally

   {

    webmap.Dispose();

   }

  }

3、建立一個多邊形

  private void Map1_Polygon(object sender, ESRI.ArcGIS.Server.WebControls.PolygonEventArgs args)

  {

   if (args.ToolName == "newpolygon")

   {

    IFeatureLayer flayer = GetCurFeatureLayer();        //擷取目前活動圖層了函數,這裡就不貼了,就是調用GetFeatureLayer(int lyid)函數

    if (flayer == null) return;

    if (flayer.FeatureClass.ShapeType != ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon)

    {

     string sc;

     sc = "<script language=javascript>alert('目前圖層何類型不對!')</script>";

     Page.RegisterClientScriptBlock("ShapeTypeError",sc);

     return;

    }

    //生成多邊形

    ESRI.ArcGIS.Server.IServerContext context;

    ESRI.ArcGIS.Server.WebControls.WebMap webmap = Map1.CreateWebMap();

    webmap.ManageLifetime(flayer);

    context = webmap.ServerContext;

    ESRI.ArcGIS.Geometry.IPolygon poly = context.CreateObject("esriGeometry.Polygon") as ESRI.ArcGIS.Geometry.IPolygon; //'new ag.PolygonClass();

    webmap.ManageLifetime(poly);

    ESRI.ArcGIS.Geometry.IPoint pt;

    ESRI.ArcGIS.Geometry.IGeometryCollection ringcol = context.CreateObject("esriGeometry.Polygon") as ESRI.ArcGIS.Geometry.IGeometryCollection;// new  PolygonClass();

    webmap.ManageLifetime(ringcol);

    ESRI.ArcGIS.Geometry.IPointCollection ptcol =context.CreateObject("esriGeometry.Ring") as ESRI.ArcGIS.Geometry.IPointCollection;// new RingClass();

    webmap.ManageLifetime(ptcol);

    object obj=Type.Missing;

    for (int i=0;i<=args.Vectors.Length-1;i++)

    {

     pt = webmap.ToMapPoint(args.Vectors[i].X,args.Vectors[i].Y);

     ptcol.AddPoint(pt,ref obj,ref obj);

    }

    ringcol.AddGeometry(ptcol as IGeometry,ref obj,ref obj);   

    poly = ringcol as IPolygon;   

    //将多邊形寫入到圖層中

    ESRI.ArcGIS.Geodatabase.IFeature feature =  flayer.FeatureClass.CreateFeature();

    feature.Shape = poly as IGeometry;

    feature.Store();

    webmap.Refresh();

    webmap.Dispose();

   }

  }

4、矩形選擇,獲得選擇集,并在地圖上顯示選中的對象。(這個功能花費了偶一天多的時間。)

  private void Map1_DragRectangle(object sender, ESRI.ArcGIS.Server.WebControls.ToolEventArgs args)

  {

   string strTool = args.ToolName.ToLower();

   if (strTool=="rectsel")

   {

    //取得目前層

    if (ddlLayers.SelectedValue=="")

     return;

    IFeatureLayer flayer = GetCurFeatureLayer();

    if (flayer == null) return;

    //獲得選擇集

    int t1=Environment.TickCount;

    ESRI.ArcGIS.Server.WebControls.WebMap webmap = Map1.CreateWebMap();

    ESRI.ArcGIS.Server.IServerContext ctx = webmap.ServerContext;

    webmap.ManageLifetime(ctx);

    ESRI.ArcGIS.Geodatabase.IWorkspace ws = (flayer.FeatureClass as ESRI.ArcGIS.Geodatabase.IDataset).Workspace;

    ESRI.ArcGIS.Geometry.IEnvelope env = ctx.CreateObject("esriGeometry.Envelope") as ESRI.ArcGIS.Geometry.IEnvelope;

    webmap.ManageLifetime(ws);

    webmap.ManageLifetime(env);

    IPoint pt = webmap.ToMapPoint(Convert.ToInt32(Request.Params.Get("maxx")),Convert.ToInt32(Request.Params.Get("maxy")));

    env.XMax = pt.X;

    env.YMin = pt.Y;

    pt = webmap.ToMapPoint(Convert.ToInt32(Request.Params.Get("minx")),Convert.ToInt32(Request.Params.Get("miny")));

    env.XMin= pt.X;

    env.YMax = pt.Y;   

    ESRI.ArcGIS.Geodatabase.ISpatialFilter filter = ctx.CreateObject("esriGeodatabase.SpatialFilter") as ESRI.ArcGIS.Geodatabase.ISpatialFilter;

    webmap.ManageLifetime(filter);

    filter.SpatialRel = ESRI.ArcGIS.Geodatabase.esriSpatialRelEnum.esriSpatialRelIntersects;

    filter.Geometry = env as ESRI.ArcGIS.Geometry.IGeometry;

    filter.GeometryField = flayer.FeatureClass.ShapeFieldName;

    ESRI.ArcGIS.Geodatabase.ISelectionSet sset = flayer.FeatureClass.Select(filter,ESRI.ArcGIS.Geodatabase.esriSelectionType.esriSelectionTypeSnapshot,ESRI.ArcGIS.Geodatabase.esriSelectionOption.esriSelectionOptionNormal,ws);

   

    int t2=Environment.TickCount;

    int t3=t2-t1;    //t3是查詢響應的時間,可以用來測試一下性能,呵呵   

    //顯示選擇集    

    int id;

    ESRI.ArcGIS.Geodatabase.IEnumIDs ids;

    ids = sset.IDs;

    webmap.ManageLifetime(ids);

    ids.Reset();

    ESRI.ArcGIS.Geodatabase.IFIDSet fidset = ctx.CreateObject("esriGeodatabase.FIDSet") as ESRI.ArcGIS.Geodatabase.IFIDSet;   

    id = ids.Next();

    while (id>=0)

    {

     fidset.Add(id);

     id =ids.Next();

    }

    IMapDescription desc = webmap.MapDescription as IMapDescription;

    webmap.ManageLifetime(desc);

    ILayerDescription ldesc = desc.LayerDescriptions.get_Element(flyid);

    webmap.ManageLifetime(ldesc);

    ldesc.SelectionFeatures = fidset;

    //将選擇資訊儲存在session中

    Session["selection"] = sset;

    Session["layerid"] = flyid;

    webmap.Refresh();

    webmap.Dispose();

   }

  }

5、删除選中的對象

  private void DeleteSel()

  {

   if (Session["layerid"]==null) return;

   if (Session["selection"] == null) return;

   int layerid = (int)Session["layerid"];

   if (layerid == -1) return;

   ESRI.ArcGIS.Geodatabase.ISelectionSet sset = Session["selection"] as ESRI.ArcGIS.Geodatabase.ISelectionSet;

   if (sset == null) return;

   WebMap webmap = Map1.CreateWebMap();

   IFeatureLayer layer = GetFeatureLayer(layerid);

   if (layer==null) return;

   webmap.ManageLifetime(layer);

   webmap.ManageLifetime(sset);

   ESRI.ArcGIS.Geodatabase.IEnumIDs ids = sset.IDs;

   webmap.ManageLifetime(ids);

   ids.Reset();

   int id;

   id = ids.Next();

   ESRI.ArcGIS.Geodatabase.IFeature feature;

   ESRI.ArcGIS.Server.IServerContext ctx = webmap.ServerContext;

   webmap.ManageLifetime(ctx);

   //将selectionset轉化為featurecursor對象

   ESRI.ArcGIS.Geodatabase.IFeatureCursor fcursor;

   ESRI.ArcGIS.Geodatabase.ICursor cursor;

   sset.Search(null,false,out cursor);

   fcursor =  cursor as ESRI.ArcGIS.Geodatabase.IFeatureCursor;

   ESRI.ArcGIS.esriSystem.ISet pDeleteSet = ctx.CreateObject("esriSystem.Set") as ESRI.ArcGIS.esriSystem.Set;

   webmap.ManageLifetime(pDeleteSet);

   //設定ISet對象

   feature = fcursor.NextFeature();

   while (feature != null)

   {

    pDeleteSet.Add(feature);

    feature = fcursor.NextFeature();

   }

   ESRI.ArcGIS.Geodatabase.IFeatureEdit fedit;

   pDeleteSet.Reset();

   fedit = pDeleteSet.Next() as ESRI.ArcGIS.Geodatabase.IFeatureEdit;

   while (fedit != null)

   {

    fedit.DeleteSet(pDeleteSet);

    fedit = pDeleteSet.Next() as ESRI.ArcGIS.Geodatabase.IFeatureEdit;

   }

   Session.Remove("layerid");

   Session.Remove("selection");

   webmap.Refresh();

   webmap.Dispose();

  }

繼續閱讀