ArcGIS Android API 应用开发之图形绘制与长度面积量算

本文通过一个简单的小Demo,向大家介绍如何使用ArcGIS Android API绘制点、线、面图形,并且测量线的长度和多边形的面积。

首先来看一下程序运行的效果图:

ArcGIS Android API 应用开发之图形绘制与长度面积量算_第1张图片

ArcGIS Android API 应用开发之图形绘制与长度面积量算_第2张图片

ArcGIS Android API 应用开发之图形绘制与长度面积量算_第3张图片

ArcGIS Android API 应用开发之图形绘制与长度面积量算_第4张图片

实现上述功能,首先需要向地图中添加一个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;
		}
    }
如需要完整代码,请在评论中留下邮箱。

你可能感兴趣的:(android,api,String,layout,null,图形)