網頁

2011年6月27日 星期一

Android學習_接ESRI ArcGIS Server服務並實現簡易Identify

對於ESRI的ArcGIS Server一值沒什麼機會可以實際操作,往往只是做一些簡單的介接測試,漸歇性的接觸對整個軟體架構可說是非常的陌生。這次,依然帶著完全不認識他的狀況測試了ESRI給Android的Libraries。

目標:展示圖層,並且進行屬性查詢動作。

步驟:
一、準備工作
1. 下載ESRI為大家準備的相關外掛(Eclipse→Help→Install New Software)

2. 於Work with輸入http://downloads.esri.com/software/arcgis/android,可以看到是0.9.XXX版,意思就是現在要測試測試版。ㄎㄎ


二、專案準備
1. 新建一個自己的專案(依照官方文件似乎一定要開Android2.1版以上的專案)
2. 引入相關的Library(安裝完後會有五個jar檔案,因為目前搞不懂各個檔案的功用是什麼,所以全部引入)

3. 給予適當的權限(因為要接服務,所以至少要給上網的權限)

<uses-permission name="android.permission.INTERNET"></uses-permission>


三、程式開發-接服務
1. 接服務與其他API相同,也分為定義檔的方式與動態程式碼的方式(服務由部門總管提供)

這邊接了兩個服務,一個是ArcGISTiledMapServiceLayer,一個是ArcGISTiledMapServiceLayer,最外層用com.esri.android.map.mapview包起來,並且給初始邊界的屬性(initextent)

<com.esri.android.map.mapview android="http://schemas.android.com/apk/res/android" id="@+id/map" layout_width="fill_parent" layout_height="fill_parent" initextent="289550 2758000 321800 2788900">
<com.esri.android.map.ags.arcgistiledmapservicelayer url="服務URL">
<com.esri.android.map.ags.arcgisdynamicmapservicelayer url="服務URL">

</com.esri.android.map.ags.arcgisdynamicmapservicelayer></com.esri.android.map.ags.arcgistiledmapservicelayer></com.esri.android.map.mapview>

2. JavaCode
如果是用定義檔的方式,只要將layout.xml設給顯示的Activity就可以了

setContentView(R.layout.main);


四、程式開發-屬性查詢
1. 取得手指的XY坐標
監聽ESRI MapView的點擊事件,取得手機上的XY坐標,再利用toMapPoint(x, y)方法轉為正確坐標值。

this.map.setOnLongPressListener(new OnLongPressListener() {
public void onLongPress(float x, float y) {
Point pt = map.toMapPoint(x, y);
}
});

2. 依照取得的坐標利用IdentifyTask進行查詢。

IdentifyParameters inputParameters = new IdentifyParameters();
inputParameters.setGeometry(pt); inputParameters.setUrl("服務URL");
inputParameters.setLayers(new int[] {1});
inputParameters.setMapExtent(map.getExtent());
inputParameters.setDPI(96);
inputParameters.setMapHeight(map.getHeight());
inputParameters.setMapWidth(map.getWidth());
inputParameters.setTolerance(30);
final IdentifyTask identifyAction = new IdentifyTask(inputParameters);

3. 取得查詢結果

try{
IdentifyResult[] results = identifyAction.execute();
}
catch{}

4. 秀出查詢結果。因為只是測試就先取三個欄位用Toast秀出。

五、執行畫面

11 則留言:

  1. 你好,我刚学ArcGIS for Android.看了你这篇文章很受用。我想请教一下,我已经取得手機上的XY坐標,再利用toMapPoint(x, y)方法轉為实际坐標值,那我想从ESRI ArcGIS Server取得这个坐標值有关的信息,如街道名称,街道所属的城市等,该如何实现?期待的你的答案,谢谢!
    联系方式:p.s.j_jj@163.com

    回覆刪除
  2. 我不太清楚你想要取得屬性的資料是哪一種型態,假設你要查詢的資料都已經發布成map server,那麼你可以利用IdentifyTask的方式進行屬性查詢(也就是GIS Server提供的方法);那如果你的資料其實有儲存在某種Spatial DataBase裡面(SQL or Oracle),那就可以直接以該空間資料庫的空間查詢對於你的坐標值做"包含"的空間查詢。

    如果是使用IdentifyTask了話,你就必須在MapServer後面增加identify的字樣(例:http://ola.com.tw/ArcGIS/rest/services/MapServer/identify),也就是照著ESRI的規定走。

    希望這回答有幫助到你。 :)

    回覆刪除
  3. 谢谢你的回答,我现在是起步刚学。如果你不介意的话,可以把你这篇文章的源代码发给我参考一下吗?谢谢。
    E-mail:p.s.j_jj@163.com

    回覆刪除
  4. 你好,我想请问一下,
    inputParameters.setUrl("服務URL");
    inputParameters.setLayers(new int[] {1});

    里面的”服務URL“ 链接是什么,能告诉我吗?
    1 代表的什么意思呢?
    谢谢

    回覆刪除
  5. 這篇的原始碼已經加了很多其他的東西了,可能看起來會更混亂;如果要找程式碼參考,建議你可以看ESRI提供的"HighlightFeatures" 範例,應該會很符合你的需要。

    1. 服務URL:這個就是我上一個留言提到的,直接在你發布的服務後面增加"/identify"的字樣(例:http://ola.com.tw/ArcGIS/rest/services/MapServer/identify)

    2. inputParameters.setLayers(new int[] {1});的1是代表我要查詢該服務的第幾個圖層(1代表作用在第一個圖層),你可以用瀏覽器開啟服務來看它的結構,或是直接問架服務的那個人。

    回覆刪除
  6. 你好,你的回答让我对ArcGIS有了更多的了解,对我的帮助很大。
    我现在有个问题,就是我在手机上使用ArcGIS map点击某一点(例如X点)然后取的经纬度,跟我在google map上点击同一个点X点所得的经纬度,两个值却不一样。这是为什么呢。这个问题困惑我很久。希望能在这得到答案。

    回覆刪除
  7. 再举一个例子吧,比如我定义了一个ArcGIS MAP的初始范围(这里是圣地亚哥)
    initExtent="
    -1.304443708158695E7 3858805.863529274
    -1.30395451117767E7 3854729.2095798096"

    但是在google map上面查圣地亚哥,也是差不多的范围。
    但是经纬度却是 在
    -117.1612286567688,32.71893842737362 ~
    -117.1610845667688,32.67745812456256


    请问这是什么问题,谢谢~

    回覆刪除
  8. 对上一次个问题的补充,例如我在 ArcGIS map上得圣地亚哥位置上点了一个点(我的方法是获取屏幕的x,y 再用toMapPoint转换成真实坐标值)获得的坐标值是-130.41260416603088 38.580177083969116 而在google map上同一点的坐标值却是-117.1525490283966,32.71744452664886
    这是什么问题呢,就是这个问题导致我无法从ESRI ArcGIS Server中获得正确的信息反馈。请帮忙解答,如果打扰,请原。万分感谢~

    回覆刪除
  9. google傳回來的是WGS84坐標系統,ArcGIS Server所傳回來的坐標系統則要看你的服務定義。在不同坐標系統下就必須要先做轉換了。

    回覆刪除
  10. 怎么看自己的服务定义呢。我在XML文件里面是这样定义MAP的。








    ArcGIS Server有跟WGS84坐標系統一样的坐标系统吗?

    回覆刪除
  11. 如果你沒有做特別的轉換,理論上你發布的服務應該會跟你來源圖層相同,你可以先看一下你服務內圖層的坐標系統,應該就可以知道了。

    另外,ArcGIS Server是一定有WGS84坐標系統的,其實也就是經緯度坐標。

    回覆刪除