arcgis for android實現量測
阿新 • • 發佈:2019-01-27
一:思路
注意:量測功能是在web墨卡託座標系下實現,如果使用天地圖(WGS-84座標)做底圖,不進行座標轉化會出現量測錯誤。
1:首先進行畫線,畫面。
2:量測
在距離量測的arcgis 提供了line.calculateLength2D();來實現
在面積量測arcgis提供了polygon.calculateArea2D()來實現。
二:實現的具體方法
/** * 距離量測和麵積量測 * @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));
WGS-84座標轉Web墨卡託座標 //兩點連線 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()); 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(); }
三:全部程式碼
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));//WGS-84座標轉web墨卡託座標
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());
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();
}
}
}
還需要在mapView中實現
//建立繪圖圖層 物件
drawLayer = new GraphicsLayer();
mMapView.addLayer(drawLayer);
//繫結觸控事件監聽器
mapTouchListener=new MapTouchListener(EarthquakeActivity.this,mMapView);
mapTouchListener.setLayer(drawLayer);
mMapView.setOnTouchListener(mapTouchListener);