1. 程式人生 > >arcgis for android 實現繪圖功能

arcgis for android 實現繪圖功能

一:實現繪圖功能的思路

1:首先需要一個點選地圖的一個監聽函式,可以實現點選地圖畫點、線、面。arcgis 提供一個MapOnTouchListener類。

2:建立點、線、面對象,arcgis提供的類有Point,Polygon,Line

3:設定樣式,不管是點、線、面都有自己的樣式。arcgis提供了 SimpleLineSymbol (線樣式類)SimpleMarkerSymbol(點樣式類)  SimpleFillSymbol(面樣式類)

4:建立一個繪畫的圖層,GraphicsLayer

5:將繪畫圖層新增到地圖上。

二:實現程式碼

1:建立一個類繼承MapOnTouchListener用來監聽地圖的點選 

public class MapTouchListener extends MapOnTouchListener {
        /**
	 * 單擊地圖
	 */
	public boolean onSingleTap(MotionEvent point) {
        }
}

2:建立點、線、面對象

//螢幕座標轉化成空間座標
Point mapPoint = map.toMapPoint(point.getX(),point.getY());
3:建立樣式
	//設定點、線、面的樣式
    private void initSymbols(){
    	markerSymbol = new SimpleMarkerSymbol(Color.BLUE,10,STYLE.CIRCLE);
    	lineSymbol =  new SimpleLineSymbol(Color.BLACK, 1, SimpleLineSymbol.STYLE.SOLID);
    	fillSymbol = new SimpleFillSymbol(Color.BLACK, SimpleFillSymbol.STYLE.SOLID);
    	fillSymbol.setAlpha(33);//設定的透明度
    } 
4:建立一個繪畫圖層
	   //建立繪圖圖層 物件
	   drawLayer = new GraphicsLayer();
	   mMapView.addLayer(drawLayer);

5:新增到地圖上(這一定要加上,否則地圖的監聽事件無法實現)

  //繫結觸控事件監聽器
	  mapTouchListener=new MapTouchListener(EarthquakeActivity.this,mMapView);
	  mapTouchListener.setLayer(drawLayer);
      mMapView.setOnTouchListener(mapTouchListener);
6:完成程式碼
package cn.zzu.Graphic;

import java.text.DecimalFormat;
import java.util.ArrayList;

import android.content.Context;
import android.graphics.Color;
import android.view.MotionEvent;
import android.widget.Toast;

import cn.zzu.Global.Variable;
import cn.zzu.Query.MyIdentifyTask;

import com.esri.android.map.GraphicsLayer;
import com.esri.android.map.MapOnTouchListener;
import com.esri.android.map.MapView;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Geometry;
import com.esri.core.geometry.Geometry.Type;
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.Line;
import com.esri.core.geometry.MultiPath;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.Polyline;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.map.Graphic;
import com.esri.core.symbol.SimpleFillSymbol;
import com.esri.core.symbol.SimpleLineSymbol;
import com.esri.core.symbol.SimpleMarkerSymbol;
import com.esri.core.symbol.SimpleMarkerSymbol.STYLE;
import com.esri.core.tasks.identify.IdentifyParameters;

public class MapTouchListener extends MapOnTouchListener {
	private Context context;//上下文
	private MapView map;//地圖物件
	private GraphicsLayer graphicsLayer;//畫圖圖層
	private Geometry.Type geoType = null;//繪圖的物件
	private Point endPonit = null;
	private Polygon polygon;
	private Polygon webPolygon;
	private SimpleLineSymbol lineSymbol;  
	private SimpleMarkerSymbol markerSymbol;  
	private SimpleFillSymbol fillSymbol;
	private ArrayList<Point> points=null;//記錄全部點
	private IdentifyParameters params;
	public MapTouchListener(Context context, MapView map) {		
		super(context, map);
		this.context = context;
		this.map = map;
		//樣式初始化
		initSymbols();
	}
	
	// 根據使用者選擇設定當前繪製的幾何圖形型別
	public void setDrawType(Geometry.Type geotype)
	{
		this.geoType=geotype;
		//將上一次繪圖的圖形刪除
		graphicsLayer.removeAll();
		endPonit = null;
		if(geoType == Geometry.Type.POLYGON)
			points=new ArrayList<Point>();
	}
	/**
	 * 判斷是否量測
	 * @param measure
	 */
	public void setMeasure(boolean measure){
		if(geoType == Geometry.Type.POLYLINE)
			Variable.measureLength = measure;
		if(geoType == Geometry.Type.POLYGON)
			Variable.measureArea = measure;
	}
	/**
	 * 
	 * 建立畫圖圖層
	 * @param drawLayer
	 */
	public void setLayer(GraphicsLayer drawLayer){
		this.graphicsLayer=drawLayer;
	}
	//設定點、線、面的樣式
    private void initSymbols(){
    	markerSymbol = new SimpleMarkerSymbol(Color.BLUE,10,STYLE.CIRCLE);
    	lineSymbol =  new SimpleLineSymbol(Color.BLACK, 1, SimpleLineSymbol.STYLE.SOLID);
    	fillSymbol = new SimpleFillSymbol(Color.BLACK, SimpleFillSymbol.STYLE.SOLID);
    	fillSymbol.setAlpha(33);//設定的透明度
    } 
    
    public void setQueryParams(){
    	//例項化物件,並且給實現初始化相應的值
    	params = new IdentifyParameters();//建立查詢的物件
    	params.setTolerance(20);//設定識別的容差
    	params.setDPI(98);//設定自解析度
    	params.setLayers(new int[]{0,1,2,3,6});//設定識別的圖層
    	params.setLayerMode(IdentifyParameters.ALL_LAYERS);//設定模式為識別服務上所有的圖層
    }

	/**
	 * 單擊地圖
	 */
	public boolean onSingleTap(MotionEvent point) {
		//螢幕座標轉化成空間座標
		Point mapPoint = map.toMapPoint(point.getX(),point.getY());
		if(Variable.singleQuery&&geoType ==null){
			params.setGeometry(mapPoint);
		    params.setSpatialReference(map.getSpatialReference());    // 設定座標系                                         
		    params.setMapHeight(map.getHeight());
		    params.setMapWidth(map.getWidth());
		    Envelope env = new Envelope();
		    map.getExtent().queryEnvelope(env);
		    params.setMapExtent(env);
		      //我們自己擴充套件的非同步類
		    MyIdentifyTask mTask = new MyIdentifyTask(context,map,mapPoint);
		    mTask.execute(params);//執行非同步操作並傳遞所需的引數    
		}
		
		if(geoType == Geometry.Type.POLYGON)
			points.add(mapPoint);//將當前點加入點集合中
		if(geoType == null)
			return true;
		if(geoType == Geometry.Type.POINT){
			//畫點
			Graphic graphic = new Graphic(mapPoint,markerSymbol);
			graphicsLayer.addGraphic(graphic);
		}else{
			if(endPonit==null){
				//線或者面的第一個點
				Graphic graphic = new Graphic(mapPoint,markerSymbol);
				graphicsLayer.addGraphic(graphic);
			}else{
				//畫點
				Graphic graphic = new Graphic(mapPoint,markerSymbol);
				graphicsLayer.addGraphic(graphic);
				//兩點連線
				Line line = new Line() ;
				line.setStart(endPonit);//起始點 
				line.setEnd(mapPoint);//終止點
				
				//畫折線
				if(geoType == Geometry.Type.POLYLINE){
					Polyline polyline = new Polyline(); 
					polyline.addSegment(line, true);  
		            Graphic iGraphic=new Graphic(polyline,lineSymbol); 
		            graphicsLayer.addGraphic(iGraphic);
		            if(Variable.measureLength)
		            	measure(endPonit,mapPoint,geoType);
				}
				if(geoType == Geometry.Type.POLYGON){
					graphicsLayer.removeAll();
					  //畫面
				      if(polygon==null){  
		                  polygon=new Polygon(); 
		                  webPolygon=new Polygon();
		              }  
				      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 line1 = new Line();  
			                line1.setStart(startPoint);  
			                line1.setEnd(endPoint);  
			                polygon.addSegment(line1, false);  
			              
			            }  		
			          Graphic gGraphic=new Graphic(polygon,fillSymbol);  
			          graphicsLayer.addGraphic(gGraphic);
			          if(Variable.measureArea)
			        	  measure(endPonit,mapPoint,geoType);
				}
			}
			//每一次的上一個點作為下一個的起點
            endPonit = mapPoint;			
		}
		return true;
	}
	
	/**
	 * 雙擊地圖
	 */
	public boolean onDoubleTap(MotionEvent point) {
		if(geoType!=null){
			geoType = null;
			endPonit = null;
			//結束量測
			Variable.measureLength = false;
			Variable.measureArea =false;
			Toast.makeText(context, "結束繪製", Toast.LENGTH_SHORT).show();
		}
		return true;
	}
	
	/**
	 * 長按地圖
	 */
	public void onLongPress(MotionEvent point) {
	}
    /**
     * 距離量測和麵積量測
     * @param startPonit
     * @param endPonit
     * @param geoType
     */
	public void measure(Point startPonit,Point endPonit,Geometry.Type geoType){
		Point msPoint = (Point) GeometryEngine.project(startPonit ,map.getSpatialReference(),SpatialReference.create(102100));
		Point mePoint = (Point) GeometryEngine.project(endPonit ,map.getSpatialReference(),SpatialReference.create(102100));
		//兩點連線
		Line line = new Line() ;
		line.setStart(mePoint);//起始點 
		line.setEnd(msPoint);//終止點
		
		if(geoType == Geometry.Type.POLYLINE ){
			//距離量測
			double mathLength = line.calculateLength2D();
			String  length = null;
			if(mathLength>1000){
				mathLength=mathLength/1000;
				String format = new DecimalFormat("0.00").format(mathLength);//保留小數點後兩位
				length = format+"公里";
			}else{
				String format = new DecimalFormat("0.00").format(mathLength);//保留小數點後兩位
				length = format+"米";
			}
			Toast.makeText(context, "距離:"+length, Toast.LENGTH_SHORT).show();
		}
		
		if(geoType == Geometry.Type.POLYGON ){ 
			Polygon polygon = new Polygon();  	  
            Point startPoint = null;  
            Point endPoint = null;  
            // 繪製完整的多邊形  
            for(int i=1;i<points.size();i++)
            {  
            	startPoint = (Point) GeometryEngine.project(points.get(i-1) ,map.getSpatialReference(),SpatialReference.create(102100));
        		endPoint = (Point) GeometryEngine.project(points.get(i) ,map.getSpatialReference(),SpatialReference.create(102100));
                Line line1 = new Line();  
                line1.setStart(startPoint);  
                line1.setEnd(endPoint);  
                polygon.addSegment(line1, false);  
            }  			        
			double  mathArea2D = Math.abs(polygon.calculateArea2D());
			System.out.println(mathArea2D);
			String  Area = null;
			if(mathArea2D>1000000){
				mathArea2D=mathArea2D/1000000;
				String format = new DecimalFormat("0.00").format(mathArea2D);//保留小數點後兩位
				Area = format+"平方公里";
			}else{
				String format = new DecimalFormat("0.00").format(mathArea2D);//保留小數點後兩位
				Area = format+"平方米";
			}
			Toast.makeText(context, "面積:"+Area, Toast.LENGTH_SHORT).show();
		}
		
	}

}