1. 程式人生 > >ArcGIS Android API 應用開發之圖形繪製與長度面積量算

ArcGIS Android API 應用開發之圖形繪製與長度面積量算

本文通過一個簡單的小Demo,向大家介紹如何使用ArcGIS Android API繪製點、線、面圖形,並且測量線的長度和多邊形的面積。

首先來看一下程式執行的效果圖:




實現上述功能,首先需要向地圖中新增一個GraphicsLayer,用來繪製Point、Polyline、Polygon等Graphic物件。其次需要監聽地圖的Touch事件,即繼承MapOnTouchListener類。最後呼叫Line或Polyline物件的calculateLength2D方法計算長度,呼叫Polygon物件的calculateArea2D的方法計算面積。

主要程式碼如下:

在main.xml佈局檔案中新增MapView控制元件:
	<com.esri.android.map.MapView
	    android:id="@+id/map"
	    android:layout_width="fill_parent"
	    android:layout_height="fill_parent"   
	    initExtent = "11575115, 3575676, 11596612, 3599415" 
	/>
在主Activity類中(本例是MeasureTestActivity.java)定義需要用到的全域性變數:
	private MapView map;
	private GraphicsLayer drawLayer;
	private String strMapUrl="http://www.arcgisonline.cn/ArcGIS/rest/services/ChinaCities_Community_BaseMap_CHN/ChengDu_Community_BaseMap_CHN/MapServer";
	private SimpleLineSymbol lineSymbol;
	private SimpleMarkerSymbol markerSymbol;
	private SimpleFillSymbol fillSymbol;
	private MapTouchListener mapTouchListener;
在MeasureTestActivity類的onCreate方法中獲取地圖,新增圖層:
		map = (MapView)findViewById(R.id.map);
		ArcGISTiledMapServiceLayer baseMapLayer = new ArcGISTiledMapServiceLayer(strMapUrl);
		map.addLayer(baseMapLayer);
		
		drawLayer = new GraphicsLayer();
		map.addLayer(drawLayer);
還是在MeasureTestActivity類的onCreate方法中,新增對地圖touch事件的監聽:
		mapTouchListener = new MapTouchListener(MeasureTestActivity.this, map);
		map.setOnTouchListener(mapTouchListener);
其中MapTouchListener類繼承自MapOnTouchListener類,主要用於監聽地圖上的touch事件,包括onSingleTap和onDoubleTap事件。onSingleTap用於繪製點、繪製當前線段(並計算長度)、繪製現有點構成的臨時多邊形(並計算當前面積);onDoubleTap用於結束繪製,並計算總長度和總面積。
    class MapTouchListener extends MapOnTouchListener {
    	private Geometry.Type geoType = null;//用於判定當前選擇的幾何圖形型別
    	private Point ptStart = null;//起點
    	private Point ptPrevious = null;//上一個點
    	private ArrayList<Point> points = null;//記錄全部點
    	private Polygon tempPolygon = null;//記錄繪製過程中的多邊形
    	
		public MapTouchListener(Context context, MapView view) {
			super(context, view);
			
			points = new ArrayList<Point>();
		}
		
		// 根據使用者選擇設定當前繪製的幾何圖形型別
		public void setType(String geometryType) {
			if(geometryType.equalsIgnoreCase("Point"))
				this.geoType = Geometry.Type.Point;
			else if(geometryType.equalsIgnoreCase("Polyline"))
				this.geoType = Geometry.Type.Polyline;
			else if(geometryType.equalsIgnoreCase("Polygon"))
				this.geoType = Geometry.Type.Polygon;
		}
		
		public Geometry.Type getType() {
			return this.geoType;
		}

		@Override
		public boolean onSingleTap(MotionEvent point) {
			Point ptCurrent = map.toMapPoint(new Point(point.getX(), point.getY()));
			if(ptStart == null) drawLayer.removeAll();//第一次開始前,清空全部graphic
			
			if (geoType == Geometry.Type.Point) {//直接畫點				
				drawLayer.removeAll();
				ptStart = ptCurrent;

				Graphic graphic = new Graphic(ptStart,markerSymbol);
				drawLayer.addGraphic(graphic);
				
				btnClear.setEnabled(true);
				return true;
			}
			else//繪製線或多邊形
			{
				points.add(ptCurrent);//將當前點加入點集合中
				
				if(ptStart == null){//畫線或多邊形的第一個點
					ptStart = ptCurrent;
										
					//繪製第一個點
					Graphic graphic = new Graphic(ptStart,markerSymbol);
					drawLayer.addGraphic(graphic);									
				}
				else{//畫線或多邊形的其他點
					//繪製其他點
					Graphic graphic = new Graphic(ptCurrent,markerSymbol);
					drawLayer.addGraphic(graphic);
					
					//生成當前線段(由當前點和上一個點構成)
					Line line = new Line();
					line.setStart(ptPrevious);
					line.setEnd(ptCurrent);
					
					if(geoType == Geometry.Type.Polyline){
						//繪製當前線段
						Polyline polyline = new Polyline();
						polyline.addSegment(line, true);
						
						Graphic g = new Graphic(polyline, lineSymbol);
						drawLayer.addGraphic(g);
						
						// 計算當前線段的長度
						String length = Double.toString(Math.round(line.calculateLength2D())) + " 米";
						
						Toast.makeText(map.getContext(), length, Toast.LENGTH_SHORT).show();
					}
					else{
						//繪製臨時多邊形
						if(tempPolygon == null) tempPolygon = new Polygon();
						tempPolygon.addSegment(line, false);
						
						drawLayer.removeAll();
						Graphic g = new Graphic(tempPolygon, fillSymbol);
						drawLayer.addGraphic(g);
						
						//計算當前面積
						String sArea = getAreaString(tempPolygon.calculateArea2D());
						
						Toast.makeText(map.getContext(), sArea, Toast.LENGTH_SHORT).show();
					}
				}
				
				ptPrevious = ptCurrent;
				return true;
			}
		}
		
		@Override
		public boolean onDoubleTap(MotionEvent point) {
			drawLayer.removeAll();
			if(bIsMeasureLength == true){
				Polyline polyline = new Polyline();
	
				Point startPoint = null;
				Point endPoint = null;
				
				// 繪製完整的線段
				for(int i=1;i<points.size();i++){
					startPoint = points.get(i-1);
					endPoint = points.get(i);
					
					Line line = new Line();
					line.setStart(startPoint);
					line.setEnd(endPoint);

					polyline.addSegment(line, false);
				}
				
				Graphic g = new Graphic(polyline, lineSymbol);
				drawLayer.addGraphic(g);
				
				// 計算總長度
				String length = Double.toString(Math.round(polyline.calculateLength2D())) + " 米";
				
				Toast.makeText(map.getContext(), length, Toast.LENGTH_SHORT).show();
			}
			else{
				Polygon polygon = new Polygon();

				Point startPoint = null;
				Point endPoint = null;
				// 繪製完整的多邊形
				for(int i=1;i<points.size();i++){
					startPoint = points.get(i-1);
					endPoint = points.get(i);
					
					Line line = new Line();
					line.setStart(startPoint);
					line.setEnd(endPoint);

					polygon.addSegment(line, false);
				}
				
				Graphic g = new Graphic(polygon, fillSymbol);
				drawLayer.addGraphic(g);
						
				// 計算總面積
				String sArea = getAreaString(polygon.calculateArea2D());
				
				Toast.makeText(map.getContext(), sArea, Toast.LENGTH_SHORT).show();
			}
			
			// 其他清理工作
			btnClear.setEnabled(true);
			ptStart = null;
			ptPrevious = null;
			points.clear();
			tempPolygon = null;
			
			return false;
		}	
		
		private String getAreaString(double dValue){
			long area = Math.abs(Math.round(dValue));
			String sArea = "";
			// 順時針繪製多邊形,面積為正,逆時針繪製,則面積為負
			if(area >= 1000000){					
				double dArea = area / 1000000.0;
				sArea = Double.toString(dArea) + " 平方公里";
			}
			else
				sArea = Double.toString(area) + " 平方米";
			
			return sArea;
		}
    }
如需要完整程式碼,請在評論中留下郵箱。

相關推薦

ArcGIS Android API 應用開發圖形繪製長度面積

本文通過一個簡單的小Demo,向大家介紹如何使用ArcGIS Android API繪製點、線、面圖形,並且測量線的長度和多邊形的面積。 首先來看一下程式執行的效果圖: 實現上述功能,首先需要向地圖中新增一個GraphicsLayer,用來繪製Point、Poly

Android應用開發所有動畫使用詳解

factory 技術分享 resource bsp phi 顯示 程序 恢復 分享 題外話:有段時間沒有更新博客了,這篇文章也是之前寫了一半一直放在草稿箱,今天抽空把剩余的補上的。消失的這段時間真的好忙,節奏一下子有些適應不過來,早晨七點四十就得醒來,晚上九點四十才準備下班

Android應用開發PNG、IconFont、SVG圖示資源優化詳解

1 背景 最近因為一些個人私事導致好久沒寫部落格了,多事之年總算要過去了,突然沒了動力,所以趕緊先拿個最近專案中重構的一個小知識點充下數,老題重談。 在我們App開發中大家可能都會有過如下痛疾(程式設計師和設計妹妹注意嘍): 好多小的圖示好煩人,又佔體積

Android應用開發PDF轉圖片功能實現

一、概述 轉眼畢業小兩年了,回想這兩年寫的程式碼,不由得想起了上學那會兒某位網際網路大牛說,搞IT這行如果你沒有寫夠十萬行程式碼,那你就還沒有入門,俺這個時候真的有點汗顏啊,此處省略十萬字。小編最近開始整理這兩年寫的程式碼,不由得首先想起了今天要寫的這個功能—

Android外掛化開發AMS應用程式(客戶端ActivityThread、Instrumentation、Activity)通訊模型分析

今天主要分析下ActivityManagerService(服務端) 與應用程式(客戶端)之間的通訊模型,在介紹這個通訊模型的基礎上,再    簡單介紹實現這個模型所需要資料型別。         本文所介紹內容基於android2.2版本。由於Android版本的不同

android程式設計圖形繪製

android課堂作業要求做個五子棋遊戲,想想如果直接用控制元件可能速度會比較慢,因此就想用比較常規的遊戲程式設計方法,螢幕繪製.今天查了些資料,並做個整理. 跟其他的螢幕繪製機制一樣,android

Android直播開發旅(9):OkCamera,Android 相機應用開發通用庫

OkCamera,Android 相機應用開發通用庫 轉載請宣告出處:http://blog.csdn.net/andrexpert/article/details/79302576     明天就可以回家過年了,有點小激動,於是乎趕緊寫篇文章壓壓驚!本文主要介紹最近

android應用開發View的大小計量單位(px、dpi、dp、dip、sp)

一、畫素(px)與螢幕解析度1)px(Pixels ,畫素):對應螢幕上的實際畫素點。例如,320*480的螢幕在橫向有320個象素,在縱向有480個象素。 2)螢幕解析度就是在螢幕上顯示的物理畫素總和

Android應用開發提升使用者體驗1–style和themes

Android的Style設計就是提升使用者體驗的關鍵之一。Android上的Style分為了兩個方面: 1.Theme是針對窗體級別的,改變窗體樣式; 2.Style是針對窗體元素級別的,改變指定控制元件或者Layout的樣式。 Android系統的th

Android 學習 圖形繪製篇 獲取要繪製的文字的寬度/長度

android自定義View繪製的時候,會有很多情況下要與字型打交道,涉及到字型寬度、高度的時候要特別注意一下幾個概念,見圖: baseLine:一行文字的底線。 Ascent: 字元頂部到baseLine的距離。 Descent: 字元底部到baseLine的距離。 Leading: 字元行間距。

Android應用開發PhoneStateListener 的使用

這兩天在做翻轉靜音的功能,需要用到PhoneStateListener,以前只是知道有這麼個東西,沒有具體用過 包含此類的包是:android.telephony.PhoneStateListener 由於StatusBar中用到了PhoneStateListener中較

android應用開發Activity的簡單佈局切換

Activity到底是什麼怎麼用,到現在感覺心裡還是沒底的,說不太清楚,看文件的時候發現一大堆方法,這裡我只寫了簡單佈局的切換,至於以後Activity的用法方法,我會慢慢學習的。 1、什麼是activity Activity是一種互動的介面,一個介面

OneNET麒麟座應用開發五:獲取加速度傳感器ADXL345數據

命令 多個 data lag 基本 采集 .cn 端口 成了 由於數據采集站基本都安裝在野外或者樓頂,安裝位置以及震動對檢測數據的準確性有一定影響。所以想要有一個位置狀態數據,正好發現麒麟作上有ADXL345,這樣一個數字輸出的加速度傳感器。如圖中紅框所示: 1、ADXL

Java進擊C#——應用開發Linq和EF

了吧 -1 擴展 有一點 增刪改 adk 對象 structure mis 本章簡言 上一章筆者對於WinForm開發過程用到的幾個知識點做了講解。筆者們可以以此為開端進行學習。而本章我們來講一個跟ORM思想有關的知識點。在講之前讓我們想一下關於JAVA的hib

Java進擊C#——應用開發WinForm開發

logs i++ mex 有時 數據 rst 流動 應用程序 dir 本章簡言 上一章筆者介紹了關於WinForm環境。這一章筆者將繼續講WinForm。只不過更加的面向開發了。事實就是在學習工具箱裏面的控件。對於WinForm開發來講,企業對他的要求並沒有那麽

Java進擊C#——應用開發WinForm環境

png 程序員 esp renderer 復制 表示 com ont mode 本章簡言 上一章筆者講到關於IO文件操作類,了解如何處理文件流。從這一章開始筆者將講解相對比較高級的知識點。而本章筆者就對WinForm開發的知識點進行講解和引導。現在很多業務都是面

OneNET麒麟座應用開發十:空氣質量數據監測站項目總結

device arr mpp mas 地址 實用 問題 volume 數據監測 大氣質量數據監測站用於測試空氣質量監測及數據采集,實現野外或者室內空氣質量的檢測。 1、項目概述 本項目是一個定制項目,要求采集大氣的壓力、溫度、濕度、PM25、位置等數據並上傳到指定的後臺服務

Android Api Demos登頂路(四十五)Loader--&gt;Cursor

adapt lists 清空 function icon 創建 nal pat lines 這個demo演示了類載入器的用法。關於類載入器的使用我們在前面的demo中已經介紹過了 在此再小小的復習一下。類載入器的使用步驟: * 1.獲取類載入

Java高級應用開發Jsp

java java高級 動作元素 blog 高級 應用 標簽 java註釋 class 1.Jsp簡介 2.腳本元素<% %>  java聲明全局變量<%! %>  java輸出變量值<%= %>  java註釋<%-- --%&g

Java高級應用開發Servlet

pos 持久化 session lte ces 請求轉發 狀態 p s 調用 學習路徑: 1.Servlet簡介 2.Servlet基礎 3.表單處理 4.請求頭信息 5.響應頭信息 6.cookie 7.session 8.scope: Servlet Context 全