关闭

ArcGis、高德计算选中地块的面积

标签: 高德地图面积ArGis面积android地图面积arggis for android详解
1392人阅读 评论(0) 收藏 举报
分类:



首先介绍下这张图,屏幕中间是一个图片(居中显示),我们可以拖动底层的地图 ,让这张图上的中心点指示在我们需要的地方,然后点击【打点】,就可以在图上标注一个点(我点的取图有点大,可以做小点),当我们在图上标注了3个点  他就会计算出标注地区的面积;

项目中使用了高德地图和ArcGis-android-10.2.7.aar;

高德地图只使用了定位和后面介绍高德地图获取面积的方法;

集成ArcGis:

1.将本地ArcGis-android-10.2.7.aar添加到lib目录(和jar同目录);

2.在app的build.gradle中添加

<span style="font-size:18px;">repositories{    flatDir            {                dirs 'libs'            }}</span>

compile (name: 'arcgis-android-10.2.7', ext: 'aar')
重新构建下项目  ok;
3.在xml中添加
<span style="font-size:18px;"><com.esri.android.map.MapView
        android:id="@+id/mapview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </com.esri.android.map.MapView></span>
原本想法是获取屏幕中心点,然后转换成地图坐标 来计算面积(当然这种方法没有使用,但是原理差不多):获取屏幕中心点方法:

int[] iv_locations = new int[2];
iv.getLocationInWindow(iv_locations); //获取在当前窗口内的绝对坐标
iv.getLocationOnScreen(iv_locations);//获取在整个屏幕内的绝对坐标
int x = iv_locations[0];//横坐标
int y = iv_locations[1];//纵坐标
//如果在Activity的OnCreate()事件输出那些参数,是全为0,要等UI控件都加载完了才能获取到这些。
//在onWindowFocusChanged(boolean hasFocus)中获取为好

-----------------------------------------华丽分割线----------------------------------------------------------------------------------

下面是代码:

<span style="font-size:18px;">public class Main2Activity extends AppCompatActivity {
    //图中间的标注物
    private ImageView iv;
    private MapView mMapView;
    //声明AMapLocationClient类对象
    public AMapLocationClient mLocationClient = null;
    //声明mLocationOption对象
    public AMapLocationClientOption mLocationOption = null;
    //记录定位j经纬度
    LatLng latlng;
    //选中的位置
    private LatLng mLatlng;
    //地图的图层
    private GoogleMapLayer YXLayer;// 影像图层
    private GoogleMapLayer XZQHLayer;// 行政区划图层
    private GraphicsLayer gpsLayers;// 卫星定位图层
    private final String FOLDER_NAME = app.folderName + "/MapCache";
    //范围
    public static Envelope townEnvelope;
    /**
     * 计算
     */
    private List<Point> pointList;
    private boolean clickComplete = true;
    private AreaBean areaBean;
    private FillSymbol fillSymbol;
    private List<AreaBean> areaList = new ArrayList<>();
    private PictureMarkerSymbol symbol;
    private Graphic MyLocation;

    private Point pointText;
    private TextSymbol textSymbol;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        mMapView= (MapView) findViewById(R.id.mapview);
        iv= (ImageView) findViewById(R.id.iv);
        location();
        //设置图层
        initMap();
        
    }
    /**
     * 图上按钮点击事件
     * @param v
     */
    public void click(View v){</span>
<span style="font-size:18px; white-space: pre;">	</span><span style="font-size:24px;">//获取地图中心点的x,y坐标点;</span><span style="font-size:18px;">
        Point point=mMapView.getCenter();
        Log.i("tag","屏幕位置:"+"X:"+point.getX()+">Y:"+point.getY());
        double [] mdouble=selectGoogleMapLonAndLat(point);
        Log.i("tag","Double:"+mdouble[0]+">>"+mdouble[1]);
        Point pointXY = mMapView.toMapPoint(point);
        /**
         * clickComplete:控制第一次进来时否点击的是已经选中的地块
         */
        if (clickComplete){
            pointList=new ArrayList<>();
            areaBean = new AreaBean();
            areaBean.setPointList(pointList);
            areaBean.setIsChanging(true);
            areaList.add(areaBean);
            clickComplete=false;
        }
        pointList.add(point);
        addAreaOnMap();
    }
    private void initMap() {
        fillSymbol = new SimpleFillSymbol(Color.BLUE);
        fillSymbol.setAlpha(90);
        pointList = new ArrayList<>();
        pointText = new Point();
        textSymbol = new TextSymbol(18, "", Color.RED);
        //        textSymbol.setFontFamily("DroidSansFallback.ttf");
        textSymbol.setOffsetX(0);
        textSymbol.setOffsetY(-15);
        Drawable image = getResources().getDrawable(R.mipmap.poi_marker_pressed);
        symbol = new PictureMarkerSymbol(image);
        try {
            YXLayer = new GoogleMapLayer(GoogleMapLayerTypes.IMAGE_GOOGLE_MAP,
                    FOLDER_NAME + "/yxCache");
            XZQHLayer = new GoogleMapLayer(
                    GoogleMapLayerTypes.ANNOTATION_GOOGLE_MAP,
                    FOLDER_NAME + "/qhCache");
            mMapView.addLayer(YXLayer);
            mMapView.addLayer(XZQHLayer);
        } catch (Exception e) {}
        gpsLayers = new GraphicsLayer();
        mMapView.addLayer(gpsLayers);
        townEnvelope = new Envelope(12957628.58241, 4864247.2803126, 12958114.4225065, 4864490.20036087);//范围
        mMapView.setExtent(townEnvelope);
    }

    /**
     * 高德地图的定位监听
     */
    public AMapLocationListener mLocationListener =new AMapLocationListener() {

        @Override
        public void onLocationChanged(AMapLocation aMapLocation) {
            if (aMapLocation.getErrorCode() == 0) {
                //定位成功回调信息,设置相关消息
                aMapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见定位类型表
                aMapLocation.getLatitude();//获取纬度
                aMapLocation.getLongitude();//获取经度
                aMapLocation.getAccuracy();//获取精度信息
                // 经纬度
                latlng = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                double latitude = aMapLocation.getLatitude();
                double longitude = aMapLocation.getLongitude();
                mMapView.centerAt(latitude, longitude, true);
               // mMapView.centerAndZoom(latitude,longitude,0.1f);
                Drawable image = getResources().getDrawable(R.mipmap.icon_point);
                PictureMarkerSymbol symbol = new PictureMarkerSymbol(image);
                MyLocation = new Graphic(new Point(longitude, latitude), symbol);
                addAreaOnMap();
            } else {
                //显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。
                Log.e("AmapError","location Error, ErrCode:"
                        + aMapLocation.getErrorCode() + ", errInfo:"
                        + aMapLocation.getErrorInfo());
            }
        }
    };
    /**
     * 定位
     */
    private void location() {
        mLocationClient = new AMapLocationClient(this);
        //初始化定位参数
        mLocationOption = new AMapLocationClientOption();
        //设置定位监听
        mLocationClient.setLocationListener(mLocationListener);
        //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //mLocationOption.setGpsFirst(true);//可选,设置是否gps优先,只在高精度模式下有效。默认关闭
        //设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.setInterval(2000);
        mLocationOption.setOnceLocation(true);
        //设置定位参数
        mLocationClient.setLocationOption(mLocationOption);
        // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
        // 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求
        // 在定位结束后,在合适的生命周期调用onDestroy()方法
        // 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除
        //启动定位
        mLocationClient.startLocation();
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMapView.destroyDrawingCache();
    }
    @Override
    protected void onResume() {
        super.onResume();
        mMapView.unpause();
    }
    @Override
    protected void onPause() {
        super.onPause();
        mMapView.pause();
    }
    //转换成地理坐标
    private double[] selectGoogleMapLonAndLat(Point point) {
        SpatialReference reference = SpatialReference.create(104199);
        Point pointB = (Point) GeometryEngine.project(point,
                mMapView.getSpatialReference(), reference);
        Gps gps = PositionUtil.gcj_To_Gps84(pointB.getY(), pointB.getX());
        return new double[]{gps.getWgLon(), gps.getWgLat()};
    }
    /**
     * 图上绘点
     *
     * @param geo
     */
    private void gpsTooMapView(Geometry geo) {
        Graphic graphic = new Graphic(geo, symbol);
        gpsLayers.addGraphic(graphic);
    }

    /**
     * 转换面积
     */
    private String getAreaString(double dValue) {
        long areaL = Math.abs(Math.round(dValue));
        String sArea = "";
        // 顺时针绘制多边形,面积为正,逆时针绘制,则面积为负
        if (areaL >= 1000000) {
            double dArea = areaL / 1000000.0;
            //            sArea = Double.toString(dArea) + " 平方公里";
            sArea = String.format("%.2f", dArea * 1500);//1平方千米(km²)=1500亩
        } else
            //    sArea = Double.toString(areaL) + " 平方米";
            sArea = String.format("%.2f", areaL * 0.0015);//1平方米(㎡)=0.0015亩
        return sArea;
    }
    double mResult=0;
    double total = 0;
    private void addAreaOnMap() {
        gpsLayers.removeAll();
        gpsLayers.addGraphic(MyLocation);
        for (int i=0;i<areaList.size();i++){
            AreaBean areaBean = areaList.get(i);
            List<Point> points = areaBean.getPointList();
            Polygon polygon = new Polygon();
            double x = 0, y = 0;
            for(int z=0;z<points.size();z++){
                Point point1 = points.get(z);
                if (z == 0) {
                    polygon.startPath(point1);
                } else {
                    polygon.lineTo(point1);
                }
                mResult = GeometryEngine.geodesicArea(polygon, this.mMapView.getSpatialReference(), null);
                gpsTooMapView(point1);
                x = x + point1.getX();
                y = y + point1.getY();
            }
            if (areaBean.isChanging()) {//正在修改只画透明多边形
                fillSymbol.setAlpha(0);
            } else {//画有填充色多边形+面积
                fillSymbol.setAlpha(50);
            }
            x = x / points.size();
            y = y / points.size();
            pointText.setX(x);
            pointText.setY(y);
            // 计算总面积
            String sArea = getAreaString(mResult);
            textSymbol.setText(sArea);
            gpsLayers.addGraphic(new Graphic(pointText, textSymbol));
            fillSymbol.setAlpha(50);
            areaBean.setArea(sArea);
            total += Double.parseDouble(sArea);
            Graphic graphics = new Graphic(polygon, fillSymbol);
            gpsLayers.addGraphic(graphics);
        }
        Toast.makeText(Main2Activity.this, "总面积:" + String.format("%.2f", total) + " 亩", Toast.LENGTH_SHORT).show();
    }
}
</span>

地图图层的代码如下:

<span style="font-size:18px;">public class GoogleMapLayer extends TiledServiceLayer {

	private int GoogleMapLayerType;
	private String cachepath;

	public GoogleMapLayer(int layerType, String cachepath) {
		super(true);
		this.cachepath = cachepath;
		this.GoogleMapLayerType = layerType;
		this.init();
	}

	private int minLevel = 0;
	private int maxLevel = 19;

	private double[] scales = new double[] { 591657527.591555,
			295828763.79577702, 147914381.89788899, 73957190.948944002,
			36978595.474472001, 18489297.737236001, 9244648.8686180003,
			4622324.4343090001, 2311162.217155, 1155581.108577, 577790.554289,
			288895.277144, 144447.638572, 72223.819286, 36111.909643,
			18055.954822, 9027.9774109999998, 4513.9887049999998, 2256.994353,
			1128.4971760000001 };
	private double[] resolutions = new double[] { 156543.03392800014,
			78271.516963999937, 39135.758482000092, 19567.879240999919,
			9783.9396204999593, 4891.9698102499797, 2445.9849051249898,
			1222.9924525624949, 611.49622628138, 305.748113140558,
			152.874056570411, 76.4370282850732, 38.2185141425366,
			19.1092570712683, 9.55462853563415, 4.7773142679493699,
			2.3886571339746849, 1.1943285668550503, 0.59716428355981721,
			0.29858214164761665 };

	private Point origin = new Point(-20037508.342787, 20037508.342787);

	private int dpi = 96;

	private int tileWidth = 256;
	private int tileHeight = 256;

	private void init() {
		try {
			getServiceExecutor().submit(new Runnable() {
				public void run() {
					GoogleMapLayer.this.initLayer();
				}
			});
		} catch (RejectedExecutionException rejectedexecutionexception) {
			Log.e("Google Map Layer", "initialization of the layer failed.",
					rejectedexecutionexception);
		}
	}

	protected byte[] getTile(int level, int col, int row) throws Exception {
		if (level > maxLevel || level < minLevel) {
			return new byte[0];
		}

		byte[] result = null;
		result = getOfflineCacheFile(level, col, row);

		if (result == null) {

			String s = "Galileo".substring(0, ((3 * col + row) % 8));
			String url = "";

			switch (GoogleMapLayerType) {

			case GoogleMapLayerTypes.IMAGE_GOOGLE_MAP:

				url = "http://mt" + (col % 4)
						+ ".google.cn/vt/lyrs=s&hl=zh-CN&gl=cn&" + "x=" + col
						+ "&" + "y=" + row + "&" + "z=" + level + "&" + "s="
						+ s;

				break;
			case GoogleMapLayerTypes.VECTOR_GOOGLE_MAP:

				url = "http://mt" + (col % 4)
						+ ".google.cn/vt/lyrs=m@158000000&hl=zh-CN&gl=cn&"
						+ "x=" + col + "&" + "y=" + row + "&" + "z=" + level
						+ "&" + "s=" + s;

				break;
			case GoogleMapLayerTypes.TERRAIN_GOOGLE_MAP:

				url = "http://mt"
						+ (col % 4)
						+ ".google.cn/vt/lyrs=t@131,r@227000000&hl=zh-CN&gl=cn&"
						+ "x=" + col + "&" + "y=" + row + "&" + "z=" + level
						+ "&" + "s=" + s;

				break;
			case GoogleMapLayerTypes.ANNOTATION_GOOGLE_MAP:

				url = "http://mt"
						+ (col % 4)
						+ ".google.cn/vt/imgtp=png32&lyrs=h@169000000&hl=zh-CN&gl=cn&"
						+ "x=" + col + "&" + "y=" + row + "&" + "z=" + level
						+ "&" + "s=" + s;

				break;

			}
			Map<String, String> map = null;
			result = com.esri.core.internal.io.handler.a.a(url, map);
			AddOfflineCacheFile(level, col, row, result);

		}

		return result;
	}

	protected void initLayer() {
		if (getID() == 0L) {
			nativeHandle = create();
			changeStatus(com.esri.android.map.event.OnStatusChangedListener.STATUS
					.fromInt(-1000));
		} else {
			this.setDefaultSpatialReference(SpatialReference.create(102113));
			this.setFullExtent(new Envelope(-22041257.773878,
					-32673939.6727517, 22041257.773878, 20851350.0432886));
			this.setTileInfo(new TileInfo(origin, scales, resolutions,
					scales.length, dpi, tileWidth, tileHeight));
			super.initLayer();
		}
	}

	private byte[] getOfflineCacheFile(int level, int col, int row) {
		byte[] bytes = null;
		File rowfile = new File(cachepath + "/" + level + "/" + col + "/" + row
				+ ".png");
		if (rowfile.exists()) {
			try {
				bytes = CopySdcardbytes(rowfile);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			bytes = null;
		}
		return bytes;
	}

	public byte[] CopySdcardbytes(File file) throws IOException {
		FileInputStream in = new FileInputStream(file);

		ByteArrayOutputStream out = new ByteArrayOutputStream(1024);

		byte[] temp = new byte[1024];

		int size = 0;

		while ((size = in.read(temp)) != -1) {
			out.write(temp, 0, size);
		}
		in.close();
		byte[] bytes = out.toByteArray();
		return bytes;
	}

	private byte[] AddOfflineCacheFile(int level, int col, int row, byte[] bytes) {
		File file = new File(cachepath);
		if (!file.exists()) {
			file.mkdirs();
		}
		File levelfile = new File(cachepath + "/" + level);
		if (!levelfile.exists()) {
			levelfile.mkdirs();
		}
		File colfile = new File(cachepath + "/" + level + "/" + col);
		if (!colfile.exists()) {
			colfile.mkdirs();
		}
		File rowfile = new File(cachepath + "/" + level + "/" + col + "/" + row
				+ ".png");
		if (!rowfile.exists()) {
			try {
				FileOutputStream out = new FileOutputStream(rowfile);
				out.write(bytes);
				out.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return bytes;

	}

}</span>

<span style="font-size:18px;">public class GoogleMapLayerTypes {

	/**
	 * 谷歌矢量地图服务
	 */
	public final static int VECTOR_GOOGLE_MAP = 1;
	/**
	 * 谷歌影像地图服务
	 */
	public final static int IMAGE_GOOGLE_MAP = 2;
	/**
	 * 谷歌地形地图服务
	 */
	public final static int TERRAIN_GOOGLE_MAP = 3;
	/**
	 * 谷歌道路等POI地图服务
	 */
	public final static int ANNOTATION_GOOGLE_MAP = 4;

}</span>
【我们中间图片和在图上标记点的位置会有一点偏差,在此并未做处理】

二:

高德地图获取地图中心点的方法是:实现implements AMap.OnCameraChangeListener接口;

实现他的2个方法:
@Override
public void onCameraChange(CameraPosition cameraPosition) {
//获取屏幕中心点的经纬度值
target = cameraPosition.target;
double latitude = target.latitude;
}@Overridepublic void onCameraChangeFinish(CameraPosition cameraPosition) { }
{代码中可能存在一些冗余,见谅,该实现方法可能有欠妥的地方,可以在评论指出 谢谢}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:14501次
    • 积分:322
    • 等级:
    • 排名:千里之外
    • 原创:17篇
    • 转载:4篇
    • 译文:0篇
    • 评论:9条
    文章分类
    最新评论