ArcGIS for Android Runtime 100 升級實踐(一)地圖載入,圖形和符號初始化
阿新 • • 發佈:2019-02-02
去年的Esri大會,隨著最新的ArcGIS 10.5產品的釋出,全新的ArcGIS Runtime 100.0也隨之釋出。ArcGIS Runtime 100.0 可謂是有了個天翻地覆的改進,比如跨平臺、3D地圖的載入以及多樣的地圖離線選擇等。其實這裡面我最感興趣的是可以載入MMPK資料,MMPK是一種全新的移動地圖包,有很多創新和優勢,總結起來是一下幾點:
- 資料儲存於壓縮的Mobile GDB中,相比起切片資料,體積小了很多;
- 儲存了所有的fearture要素,底圖上展示的都是要素,可供查詢和分析;
- 可以將所有地圖和資料資源打包,
allprojects { repositories { jcenter() maven { url 'http://esri.bintray.com/arcgis'} } }
然後在module的build.gradle裡新增compile:
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:25.3.1' // compile 'com.esri.arcgis.android:arcgis-android:10.2.8' compile 'com.esri.arcgisruntime:arcgis-android:100.0.0'}
注意下面個是Runtime100,被我註釋掉的是之前用的10.2.8 二、匯入包 等gradle更新完畢了以後,進入我們的主activity頁面會看到這樣的情況:
祖國江山一片紅,可謂悽慘。 不過沒關係,這主要是原來10.2版本的包名和現在的包名不一樣導致的。我們需要將以前匯入的類刪掉,重新匯入一下:
重新匯入包以後,我們會發現,呃,好像好了一點,但依然是祖國江山半壁紅。
其實是Runtime100裡很多類和方法都進行了更改,比如上圖裡我們可以看到之前常用的Line和GraphicsLayer類都已經不存在了,只能用其他類替代;另外改變了很多方法,也新增了很多方法,所以我們就一步一步來看看吧。 三、地圖和圖層的載入(MapView和Layer) 首先我們先回顧下10.2裡的MapView和Layer的關係。 在10.2裡MapView直接繼承於ViewGroup類,本身就是地圖內容的展示容器,使用時候直接在MapView可以載入各種基礎底圖、業務圖層和繪製圖層。
但是在Runtime100裡,增加了3D地圖顯示的功能。為了滿足大多數人的使用習慣,Esri依然採用MapView類作為2D地圖的展示容器,新增了SceneView類作為3D地圖的展示容器,然後這兩個類共同繼承於一個叫GeoView的基類。
然後整個MapView的結構也進行了更改。不再是作為一個容器直接新增圖層,而是分成了地圖內容和繪製圖層兩部分進行新增:
所以,Runtime100裡要新增基礎底圖和業務圖層,需要新建一個ArcGISMap類,在這個類裡新增圖層,然後用MapView.setMap()的方法新增地圖。 第二點,對於圖層來說,Runtime100裡更改了不少圖層類。 比如將基礎圖層中的ArcGISLocalTiledLayer類和ArcGISTiledMapServiceLayer類合併成了一個ArcGISTiledLayer類,也就是將離線和線上載入瓦片資料的類合成了一個,其實也是為了簡化程式設計師的負擔,弱化了離線和線上的概念; 比如將之前的臨時圖形圖層GraphicsLayer換成了GraphicsOverlay,同樣是一個臨時圖層,比起之前的優化來就是它基於GeoView基類並且始終置於頂層,(很棒吧,媽媽再也不用擔心臨時圖層被業務圖層覆蓋的問題了!)呼叫的方法也有所改變,比如官網給的例子:
第三點,關於圖層的載入。 上面說了Runtime100裡,如果要新增基礎底圖和業務圖層需要通過ArcGISMap類來實現,那麼我們來實踐下如何載入圖層。 對於載入切片資料,需要當做基礎底圖進行載入,比起以前的方法,相當於是在MapView裡有且僅有一個底圖, 這個底圖無法進行編輯,僅能提供背景和座標參考系。
mMapView=(MapView)findViewById(R.id.mapview); String url=StorageUtil.getSDCardRootPath(getApplicationContext())+"/ArcGIS/localtilelayer/CY_YGYX_BG.tpk";
TileCache mainTileCache = new TileCache(url);ArcGISTiledLayer layer =new ArcGISTiledLayer(mainTileCache);Basemap basemap=new Basemap(layer);arcGISMap=new ArcGISMap(basemap);mMapView.setMap(arcGISMap);
對於離線業務資料,方法和原來基本一樣,唯一有所不同的就是獲取GeodatabaseFeatureTable的方法名由getGeodatabaseTables()變成了getGeodatabaseFeatureTables()。
String url= StorageUtil.getROMRootPath(getApplicationContext())+"/ArcGIS/localtilelayer/ncdc.geodatabase"; Geodatabase localGdb=null; try { localGdb = new Geodatabase(url); }catch (Exception e){ e.printStackTrace(); } if (localGdb != null) { for (GeodatabaseFeatureTable gdbFeatureTable : localGdb.getGeodatabaseFeatureTables()) { if (gdbFeatureTable.hasGeometry()){ dataFeatureLayer = new FeatureLayer(gdbFeatureTable); } } }對於臨時繪製圖層,我們則需要先獲取MapView裡的GraphicOverlays的列表,向裡面增加我們需要新增的臨時繪製圖層即可。
mMapView=(MapView)findViewById(R.id.mapview);
mMapView.getGraphicsOverlays().add(messureLayer); mMapView.getGraphicsOverlays().add(pointAnalysistAllGraphicsLayer); mMapView.getGraphicsOverlays().add(pointAnalysistOneGraphicsLayer);
四、圖形和符號(Geometry和Symbol) 在地圖載入完畢後,我們再來看看程式碼:
可以看出紅色報錯的地方少多了。在我們初始化地圖並載入好圖層後,接下來我們考慮的初始化我們的圖形和符號了。然後我們看看初始化地方的程式碼:
果然錯誤很多,我們先來看看圖形吧。在Runtime 100裡不能通過例項化空模型來完成圖形的例項化,我們可以看看Polygon API裡的構造方法(Polyline與之完全類似):
也就是說得通過PointCollection或者Part進行構造。 這兩個類都是Runtime 100裡新出現的類,但是對於PointCollection看名稱我們就知道這是個Point的集合,而我們之前在畫面的時候,就是採用點的集合完成的。於是我想就把之前的List<Point>改成PointCollection類,將圖形的構造往後放不就可以了。於是嘗試一下: 首先是構造一個PointCollection類,而構造PointCollection需要座標參考資訊SpatialReference(),這個資訊我們可以從地圖內容裡獲取,於是:
pointCollection=new PointCollection(arcGISMap.getSpatialReference());
然後我們可以考慮在獲取點的時候構造線和麵就可以:
pointCollection.add(mPoint);// 選擇點加入點的集合 if (pointCollection.size() > 1) { messurePolyline = new Polyline(pointCollection); if (pointCollection.size() > 1) { messurePolygon = new Polygon(pointCollection); } }
接下來是符號,可以看出所有的符號建構函式都在報錯,我們先看看SimpleLineSymbol類,它在Runtime 100裡的建構函式是:
比起10.2裡也多了一項,是SimpleLineSymbol.Style。這是個列舉類,裡面包含了幾種樣式可以修飾符號。(具體的我測試後再發出效果圖)
public static enum Style { DASH, DASH_DOT, DASH_DOT_DOT, DOT, SOLID, NULL; private Style() { } }接下來是SimpleFillSymbol類,看看它在Runtime 100裡符號的建構函式是:
可以看出比起10.2的SimpleFillSymbol類,建構函式裡還多了個LineSymbol類,我們知道SimpleFillSymbol主要是用來定義面的樣式,最後這個LineSymbol類是給這個面加個輪廓,如果不需要加,寫null即可。 以前如果需要在面符號里加上輪廓樣式的話,還需要用SimpleFillSymbol.setOutline(SimpleLineSymbol)的方法,也就是說新的構造類是將兩個方法合二為一,更加方便。 最後是SimpleMarkerSymbol類,它在在Runtime 100裡符號的建構函式和10.2裡幾乎沒變,只是將引數的順序變了下。 於是修改後,原函式裡的符號初始化定義變化為:
pointCollection=new PointCollection(arcGISMap.getSpatialReference()); mMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE,Color.RED, 10); messureLineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.NULL,Color.BLUE, 3);// 初始化線的樣式 messureMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE,Color.RED, 10);// 初始化測量時點的樣式 messureLayer =new GraphicsOverlay();// 初始化測量圖層 pAnalysistSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.NULL,Color.RED, 3); messureFillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.BACKWARD_DIAGONAL,Color.argb(100, 225, 225, 0),new SimpleLineSymbol(SimpleLineSymbol.Style.NULL,Color.BLACK, 2));// 初始化測量時面的樣式 messureFillSymbol_red = new SimpleFillSymbol(SimpleFillSymbol.Style.BACKWARD_DIAGONAL,Color.argb(100, 225, 0, 0),new SimpleLineSymbol(SimpleLineSymbol.Style.NULL,Color.BLACK, 2)); messureFillSymbol_blue = new SimpleFillSymbol(SimpleFillSymbol.Style.BACKWARD_DIAGONAL,Color.argb(100, 0, 0, 225),new SimpleLineSymbol(SimpleLineSymbol.Style.NULL,Color.BLACK, 2)); messureFillSymbol_green = new SimpleFillSymbol(SimpleFillSymbol.Style.BACKWARD_DIAGONAL,Color.argb(100, 0, 225, 0),new SimpleLineSymbol(SimpleLineSymbol.Style.NULL,Color.BLACK, 2)); pointAnalysistAllGraphicsLayer = new GraphicsOverlay(); pointAnalysistOneGraphicsLayer = new GraphicsOverlay();
大功告成!