程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> ArcGIS Server開發Web GIS新手體驗

ArcGIS Server開發Web GIS新手體驗

編輯:.NET實例教程

原創作者:<不詳>

一、前述

(原創作品網址:http://www.vscodes.com/article/3/2379.Html

(以下針對於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究竟是怎樣實現的呢?

二、開發講解(一)

(原創作品網址:http://www.vscodes.com/article/3/2380.Html

  我們知道,.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" Default 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'');"
 
  ><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接口。呵呵,其實很簡單嘛,我們也完全可以自己寫一個類,來執行自定義的請求。

三、開發講解(二)

(原創作品網址:http://www.vscodes.com/article/3/2381.Html

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

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

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

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這個網頁。

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的封裝方式,您已經可以開始償試修改已有的功能,或者進行一些簡單的擴展了。下一節我就再介紹一下怎樣進行簡單的功能擴展。

四、開發講解(三)

(原創作品網址:http://www.vscodes.com/article/3/2382.Html

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

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();
&nbsp;   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();
 &nbsp; 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.LayerDesc

riptions.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;
  &nbsp;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();
  }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved