Android高德地图多边形的绘制与编辑

最近项目中用到了一个高德地图画地块的功能,差了一下api,发现只有js有相关的方法,所以仿照js的交互方式做了一个android版的多边形绘制与编辑。

先不说,上一张效果图

完成效果图

1.通过观察,我们大致能知道主要的绘制与编辑方式,点完第二个点之后,和第一个点连成线段,这个线段的中间位置会有一个小点,下面是添加marker点的代码

/**

* 添加marker

*/

private void addMarker(LatLng latLng) {

    if (allLatLngs.size() == 0) {

        MarkerOptions options= new MarkerOptions();

        options.position(latLng).draggable(false).visible(true);

        Marker marker= aMap.addMarker(options);

        marker.setObject((allLatLngs.size() + 1));

        marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_dian_s));

        marker.setAnchor(0.5f, 0.5f);

        allLatLngs.add(new MyLatLng(latLng, MyLatLng.ABLE));

        allLatLngsWithLine.add(latLng);

        markers.add(marker);

        //画线

        drawLine(latLng, null);

    } else {

        if (isEnd) {

            MarkerOptions options= new MarkerOptions();

            latLng= new LatLng(((latLng.latitude + allLatLngs.get(allLatLngs.size() - 1).getLatLng().latitude) / 2), ((latLng.longitude + allLatLngs.get(allLatLngs.size() - 1).getLatLng().longitude) / 2));

            options.position(latLng).draggable(false).visible(true);

            Marker marker= aMap.addMarker(options);

            marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_dian_y));

            marker.setAnchor(0.5f, 0.5f);

            allLatLngs.add(new MyLatLng(latLng, MyLatLng.UNABLE));

            allLatLngsWithLine.add(latLng);

            markers.add(marker);

            drawLine(allLatLngsWithLine.get(allLatLngsWithLine.size() - 1), allLatLngsWithLine.get(0));

        } else {

            for (int i= 0; i< 2; i++) { // 在地图上添一组图片标记(marker)对象,并设置是否改变地图状态以至于所有的marker对象都在当前地图可视区域范围内显示

                MarkerOptions options= new MarkerOptions();

                if (i== 0) {

                    LatLng latLng2= new LatLng(((latLng.latitude + allLatLngs.get(allLatLngs.size() - 1).getLatLng().latitude) / 2), ((latLng.longitude + allLatLngs.get(allLatLngs.size() - 1).getLatLng().longitude) / 2));

                    options.position(latLng2).draggable(false).visible(true);

                    allLatLngs.add(new MyLatLng(latLng2, MyLatLng.UNABLE));

                    allLatLngsWithLine.add(latLng2);

                } else {

                    options.position(latLng).draggable(false).visible(true);

                    allLatLngs.add(new MyLatLng(latLng, MyLatLng.ABLE));

                    allLatLngsWithLine.add(latLng);

}

                Marker marker= aMap.addMarker(options);

                marker.setAnchor(0.5f, 0.5f);

                if (i== 1) {

                    marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_dian_s));

                } else {

                    marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_dian_y));

}

                markers.add(marker);

}

            drawLine(allLatLngsWithLine.get(allLatLngsWithLine.size() - 2), allLatLngsWithLine.get(allLatLngsWithLine.size() - 1));

}

}

}

2.画上marker点之后还要画点之间的线,还有多边形的填充色这里贴一下相关的代码

/**

* 画线

*/

private void drawLine(LatLng latLng, LatLng latLng2) {

    if (polyline == null) {

        polyline = aMap.addPolyline(new PolylineOptions().

                add(latLng).width(10).color(Color.argb(255, 1, 1, 1)));

    } else {

        List<LatLng> points= polyline.getPoints();

        if (isEnd) {

            points.add(latLng);

            points.add(latLng2);

        } else {

            if (!points.contains(latLng)) {

                points.add(latLng);

}

            if (!points.contains(latLng2)) {

                points.add(latLng2);

}

}

        polyline.setPoints(points);

        //计算周长

        setPerimeter();

}

}

/**

* 画多边形

*/

private void drawRect() {

    if (polygon == null) {

        polygonOptions.addAll(allLatLngsWithLine);

        //创建多边形

        polygon = aMap.addPolygon(polygonOptions);

    } else {

        polygon.setPoints(allLatLngsWithLine);

}

    //计算面积

    setArea();

}

3.是时候该拖动marker点改变多边形的形状了.一开始我是准备用marker点的监听做它的移动监听的,发现marker的拖动必须要长按才能拖动,用户体验并不好,所以就改成了地图的触摸监听.大致说一下思路:如果拖拽的是大点,则改变其左右两个小点的坐标和与其相邻的两个大点间的线段,而拖拽小点则先将其变成一个大点,然后在与其相邻的两个大点之间添加两个小点就行.下面上关键代码

//添加拖拽事件

aMap.setOnMapTouchListener(new AMap.OnMapTouchListener() {

    @Override

    public void onTouch(MotionEvent motionEvent) {

        switch (motionEvent.getAction()) {

            //按下

            case MotionEvent.ACTION_DOWN:

                float down_x= motionEvent.getX();

                float down_y= motionEvent.getY();

                Point downPoint= new Point();

                downPoint.set((int) down_x, (int) down_y);

                //获取触摸到的位置

                LatLng downLatLng= aMap.getProjection().fromScreenLocation(downPoint);

                //获取触摸的点下标

                checkPos = getNearestLatLng(downLatLng);

                //触摸的点是矩形的点

                if (checkPos > -1) {

                    //如果是小点

                    if (allLatLngs.get(checkPos).getState() == MyLatLng.UNABLE) {

                        //更改为大点

                        chageMarker();

                        //如果是封闭图形并且点击的是最后的一个点

                        if (isEnd && checkPos == allLatLngs.size() - 1) {

                            //添加两个mark

                            addTwoMarker(getCenterLatlng(allLatLngs.get(checkPos).getLatLng(), allLatLngs.get(checkPos - 1).getLatLng()), getCenterLatlng(allLatLngs.get(checkPos).getLatLng(), allLatLngs.get(0).getLatLng()));

                        } else {

                            //不是封闭图形

//添加两个marker

                            addTwoMarker(getCenterLatlng(allLatLngs.get(checkPos).getLatLng(), allLatLngs.get(checkPos - 1).getLatLng()), getCenterLatlng(allLatLngs.get(checkPos).getLatLng(), allLatLngs.get(checkPos + 1).getLatLng()));

}

                        //将选中点的下标更改

                        checkPos += 1;

}

                    //获取选中的marker点

                    touchMark = markers.get(checkPos);

                    //禁止地图放大旋转等操作

                    uiSettings.setScrollGesturesEnabled(false);

}

                break;

                //移动中

            case MotionEvent.ACTION_MOVE:

                //有选中的marker点

                if (touchMark != null) {

                    float move_x= motionEvent.getX();

                    float move_y= motionEvent.getY();

                    Point movePoint= new Point();

                    movePoint.set((int) move_x, (int) move_y);

                    //获取到触摸点经纬度

                    LatLng moveLatLng= aMap.getProjection().fromScreenLocation(movePoint);

                    //更新的坐标点位置

                    touchMark.setPosition(moveLatLng);

                    //如果已经画出线(两个大点)

                    if (polyline != null) {

                        //会比markers多一个点

                        List<LatLng> points= polyline.getPoints();

                        //修改线数据中当前触摸点的坐标信息

                        points.set(checkPos, moveLatLng);

                        //修改当前选中marker点坐标集合的信息

                        allLatLngs.get(checkPos).setLatLng(moveLatLng);

                        //修改当前选中线的点的坐标集合的信息

                        allLatLngsWithLine.set(checkPos, moveLatLng);

                        //不需要添加两个点

                        if (checkPos == 0) {

                            //获取选中大点旁边的小点

                            Marker marker= markers.get(checkPos + 1);

                            //获取第一个大点和第二个大点的中间坐标

                            LatLng center= getCenterLatlng(moveLatLng, allLatLngs.get(checkPos + 2).getLatLng());

                            //修改marker的坐标

                            marker.setPosition(center);

                            //修改线的坐标

                            points.set(checkPos + 1, center);

                            //修改总marker坐标集合信息

                            allLatLngs.get(checkPos + 1).setLatLng(center);

                            //修改总线集合信息

                            allLatLngsWithLine.set(checkPos + 1, center);

                            //如果是已经封闭的则需要修改最后一个大点与第一个大点中间点的坐标

                            if (isEnd) {

                                //操作同上

                                Marker marker2= markers.get(markers.size() - 1);

                                LatLng cen= getCenterLatlng(moveLatLng, allLatLngs.get(markers.size() - 2).getLatLng());

                                marker2.setPosition(cen);

                                points.set(points.size() - 1, moveLatLng);

                                points.set(points.size() - 2, cen);

                                allLatLngs.get(markers.size() - 1).setLatLng(cen);

                                allLatLngsWithLine.set(markers.size() - 1, cen);

}

                            //当触摸的点是最后一个大点或者最后一个小点的时候

                        } else if (checkPos == markers.size() - 2 || checkPos == markers.size() - 1) {

                            //原理同上

//最后一个点

                            Marker marker2= markers.get(checkPos - 1);

                            LatLng center= getCenterLatlng(moveLatLng, allLatLngs.get(checkPos - 2).getLatLng());

                            marker2.setPosition(center);

                            points.set(checkPos - 1, center);

                            allLatLngs.get(checkPos - 1).setLatLng(center);

                            allLatLngsWithLine.set(checkPos - 1, center);

                            if (isEnd) {

                                Marker marker= markers.get(checkPos + 1);

                                LatLng cen= getCenterLatlng(moveLatLng, allLatLngs.get(0).getLatLng());

                                marker.setPosition(cen);

                                points.set(checkPos + 1, cen);

                                allLatLngs.get(checkPos + 1).setLatLng(cen);

                                allLatLngsWithLine.set(checkPos + 1, cen);

}

                        } else {

                            //原理同上

//中间的点

                            Marker marker= markers.get(checkPos + 1);

                            LatLng center= getCenterLatlng(moveLatLng, allLatLngs.get(checkPos + 2).getLatLng());

                            marker.setPosition(center);

                            allLatLngs.get(checkPos + 1).setLatLng(center);

                            allLatLngsWithLine.set(checkPos + 1, center);

                            Marker marker2= markers.get(checkPos - 1);

                            LatLng center2= getCenterLatlng(moveLatLng, allLatLngs.get(checkPos - 2).getLatLng());

                            marker2.setPosition(center2);

                            allLatLngs.get(checkPos - 1).setLatLng(center2);

                            allLatLngsWithLine.set(checkPos - 1, center2);

                            //移动线

                            points.set(checkPos + 1, center);

                            points.set(checkPos - 1, center2);

}

                        //更改线数据

                        polyline.setPoints(points);

                        //计算周长

                        setPerimeter();

                        //如果封闭的话

                        if (isEnd) {

                            //计算面积

                            drawRect();

}

}

}

                break;

                //抬起

            case MotionEvent.ACTION_UP:

                if (touchMark != null) {

                    //清除选中点信息

                    touchMark = null;

                    //恢复地图操作

                    uiSettings.setScrollGesturesEnabled(true);

}

                break;

}

}

});

4.下面贴出完整代码

package com.amap.map3d.demo.basic;

import android.app.Activity;

import android.graphics.Color;

import android.graphics.Point;

import android.os.Bundle;

import android.support.annotation.NonNull;

import android.view.MotionEvent;

import android.widget.TextView;

import com.amap.api.maps.AMap;

import com.amap.api.maps.AMapUtils;

import com.amap.api.maps.TextureMapView;

import com.amap.api.maps.UiSettings;

import com.amap.api.maps.model.BitmapDescriptorFactory;

import com.amap.api.maps.model.LatLng;

import com.amap.api.maps.model.Marker;

import com.amap.api.maps.model.MarkerOptions;

import com.amap.api.maps.model.Polygon;

import com.amap.api.maps.model.PolygonOptions;

import com.amap.api.maps.model.Polyline;

import com.amap.api.maps.model.PolylineOptions;

import com.amap.map3d.demo.MyLatLng;

import com.amap.map3d.demo.R;

import java.math.BigDecimal;

import java.util.ArrayList;

import java.util.List;

/**

* AMapV2地图中介绍如何TextureMapView显示一个基本地图

*/

public class TextureMapViewActivity extends Activity {

    private TextureMapView mapView;

    private AMap aMap;

    //存放所有marker点标记

    private List<MyLatLng> allLatLngs = new ArrayList<>();

    //所有线段的点

    private List<LatLng> allLatLngsWithLine = new ArrayList<>();

    //所有marker点

    private List<Marker> markers = new ArrayList<>();

    //线的对象

    private Polyline polyline;

    //多边形的对象

    private Polygon polygon;

    //是否为封闭图形

    private boolean isEnd = false;

    //矩形对象的配置

    private PolygonOptions polygonOptions = new PolygonOptions();

    //当前触摸的marker

    private Marker touchMark;

    //当前选中的点下标,相对于allLatLngs的

    private int checkPos;

    //地图设置

    UiSettings uiSettings;

    ///周长

    private TextView mPerimeterTv;

    //面积

    private TextView mAreaTv;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.basic_texturemap_activity);

        mPerimeterTv = findViewById(R.id.perimeter);

        mAreaTv = findViewById(R.id.area);

        /*

* 设置离线地图存储目录,在下载离线地图或初始化地图设置;

* 使用过程中可自行设置, 若自行设置了离线地图存储的路径,

* 则需要在离线地图下载和使用地图页面都进行路径设置

* */

        //Demo中为了其他界面可以使用下载的离线地图,使用默认位置存储,屏蔽了自定义设置

//  MapsInitializer.sdcardDir =OffLineMapUtils.getSdCacheDir(this);

        mapView = (TextureMapView) findViewById(R.id.map);

        mapView.onCreate(savedInstanceState);// 此方法必须重写

        init();

}

    /**

* 初始化AMap对象

*/

    private void init() {

        if (aMap == null) {

            aMap = mapView.getMap();

}

        //获取地图ui设置对象

        uiSettings = aMap.getUiSettings();

        //地图点击监听

        aMap.setOnMapClickListener(new AMap.OnMapClickListener() {

            @Override

            public void onMapClick(LatLng latLng) {

                if (!isEnd) {

                    addMarker(latLng);

}

}

        });

        //marker点击监听

        aMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {

            @Override

            public boolean onMarkerClick(Marker marker) {

                if (isEnd) {

                } else {

                    if (markers.get(0).equals(marker)) {

                        //封闭图形

                        isEnd = true;

                        //初始化多边形参数

                        createAreaStyle();

                        //添加marker

                        addMarker(marker.getPosition());

                        //画多边形

                        drawRect();

                        return true;

                    } else {

                        //未封闭,点击其它marke

                    }

}

                return false;

}

        });

        //添加拖拽事件

        aMap.setOnMapTouchListener(new AMap.OnMapTouchListener() {

            @Override

            public void onTouch(MotionEvent motionEvent) {

                switch (motionEvent.getAction()) {

                    //按下

                    case MotionEvent.ACTION_DOWN:

                        float down_x= motionEvent.getX();

                        float down_y= motionEvent.getY();

                        Point downPoint= new Point();

                        downPoint.set((int) down_x, (int) down_y);

                        //获取触摸到的位置

                        LatLng downLatLng= aMap.getProjection().fromScreenLocation(downPoint);

                        //获取触摸的点下标

                        checkPos = getNearestLatLng(downLatLng);

                        //触摸的点是矩形的点

                        if (checkPos > -1) {

                            //如果是小点

                            if (allLatLngs.get(checkPos).getState() == MyLatLng.UNABLE) {

                                //更改为大点

                                chageMarker();

                                //如果是封闭图形并且点击的是最后的一个点

                                if (isEnd && checkPos == allLatLngs.size() - 1) {

                                    //添加两个mark

                                    addTwoMarker(getCenterLatlng(allLatLngs.get(checkPos).getLatLng(), allLatLngs.get(checkPos - 1).getLatLng()), getCenterLatlng(allLatLngs.get(checkPos).getLatLng(), allLatLngs.get(0).getLatLng()));

                                } else {

                                    //不是封闭图形

//添加两个marker

                                    addTwoMarker(getCenterLatlng(allLatLngs.get(checkPos).getLatLng(), allLatLngs.get(checkPos - 1).getLatLng()), getCenterLatlng(allLatLngs.get(checkPos).getLatLng(), allLatLngs.get(checkPos + 1).getLatLng()));

}

                                //将选中点的下标更改

                                checkPos += 1;

}

                            //获取选中的marker点

                            touchMark = markers.get(checkPos);

                            //禁止地图放大旋转等操作

                            uiSettings.setScrollGesturesEnabled(false);

}

                        break;

                        //移动中

                    case MotionEvent.ACTION_MOVE:

                        //有选中的marker点

                        if (touchMark != null) {

                            float move_x= motionEvent.getX();

                            float move_y= motionEvent.getY();

                            Point movePoint= new Point();

                            movePoint.set((int) move_x, (int) move_y);

                            //获取到触摸点经纬度

                            LatLng moveLatLng= aMap.getProjection().fromScreenLocation(movePoint);

                            //更新的坐标点位置

                            touchMark.setPosition(moveLatLng);

                            //如果已经画出线(两个大点)

                            if (polyline != null) {

                                //会比markers多一个点

                                List<LatLng> points= polyline.getPoints();

                                //修改线数据中当前触摸点的坐标信息

                                points.set(checkPos, moveLatLng);

                                //修改当前选中marker点坐标集合的信息

                                allLatLngs.get(checkPos).setLatLng(moveLatLng);

                                //修改当前选中线的点的坐标集合的信息

                                allLatLngsWithLine.set(checkPos, moveLatLng);

                                //不需要添加两个点

                                if (checkPos == 0) {

                                    //获取选中大点旁边的小点

                                    Marker marker= markers.get(checkPos + 1);

                                    //获取第一个大点和第二个大点的中间坐标

                                    LatLng center= getCenterLatlng(moveLatLng, allLatLngs.get(checkPos + 2).getLatLng());

                                    //修改marker的坐标

                                    marker.setPosition(center);

                                    //修改线的坐标

                                    points.set(checkPos + 1, center);

                                    //修改总marker坐标集合信息

                                    allLatLngs.get(checkPos + 1).setLatLng(center);

                                    //修改总线集合信息

                                    allLatLngsWithLine.set(checkPos + 1, center);

                                    //如果是已经封闭的则需要修改最后一个大点与第一个大点中间点的坐标

                                    if (isEnd) {

                                        //操作同上

                                        Marker marker2= markers.get(markers.size() - 1);

                                        LatLng cen= getCenterLatlng(moveLatLng, allLatLngs.get(markers.size() - 2).getLatLng());

                                        marker2.setPosition(cen);

                                        points.set(points.size() - 1, moveLatLng);

                                        points.set(points.size() - 2, cen);

                                        allLatLngs.get(markers.size() - 1).setLatLng(cen);

                                        allLatLngsWithLine.set(markers.size() - 1, cen);

}

                                    //当触摸的点是最后一个大点或者最后一个小点的时候

                                } else if (checkPos == markers.size() - 2 || checkPos == markers.size() - 1) {

                                    //原理同上

//最后一个点

                                    Marker marker2= markers.get(checkPos - 1);

                                    LatLng center= getCenterLatlng(moveLatLng, allLatLngs.get(checkPos - 2).getLatLng());

                                    marker2.setPosition(center);

                                    points.set(checkPos - 1, center);

                                    allLatLngs.get(checkPos - 1).setLatLng(center);

                                    allLatLngsWithLine.set(checkPos - 1, center);

                                    if (isEnd) {

                                        Marker marker= markers.get(checkPos + 1);

                                        LatLng cen= getCenterLatlng(moveLatLng, allLatLngs.get(0).getLatLng());

                                        marker.setPosition(cen);

                                        points.set(checkPos + 1, cen);

                                        allLatLngs.get(checkPos + 1).setLatLng(cen);

                                        allLatLngsWithLine.set(checkPos + 1, cen);

}

                                } else {

                                    //原理同上

//中间的点

                                    Marker marker= markers.get(checkPos + 1);

                                    LatLng center= getCenterLatlng(moveLatLng, allLatLngs.get(checkPos + 2).getLatLng());

                                    marker.setPosition(center);

                                    allLatLngs.get(checkPos + 1).setLatLng(center);

                                    allLatLngsWithLine.set(checkPos + 1, center);

                                    Marker marker2= markers.get(checkPos - 1);

                                    LatLng center2= getCenterLatlng(moveLatLng, allLatLngs.get(checkPos - 2).getLatLng());

                                    marker2.setPosition(center2);

                                    allLatLngs.get(checkPos - 1).setLatLng(center2);

                                    allLatLngsWithLine.set(checkPos - 1, center2);

                                    //移动线

                                    points.set(checkPos + 1, center);

                                    points.set(checkPos - 1, center2);

}

                                //更改线数据

                                polyline.setPoints(points);

                                //计算周长

                                setPerimeter();

                                //如果封闭的话

                                if (isEnd) {

                                    //计算面积

                                    drawRect();

}

}

}

                        break;

                        //抬起

                    case MotionEvent.ACTION_UP:

                        if (touchMark != null) {

                            //清除选中点信息

                            touchMark = null;

                            //恢复地图操作

                            uiSettings.setScrollGesturesEnabled(true);

}

                        break;

}

}

        });

}

    /**

* 获取两个点的中点坐标

*

    * @parammyLatLng

    * @parammyLatLng2

    * @return

*/

    private LatLng getCenterLatlng(LatLng myLatLng, LatLng myLatLng2) {

        return new LatLng((myLatLng.latitude + myLatLng2.latitude) / 2, (myLatLng.longitude + myLatLng2.longitude) / 2);

}

    /**

* 修改makeer类型和icon

*/

    private void chageMarker() {

        Marker marker= markers.get(checkPos);

        //修改点类型为大点

        allLatLngs.get(checkPos).setState(MyLatLng.ABLE);

        marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_dian_s));

}

    /**

* 在拖拽点两侧添加maker

*/

    private void addTwoMarker(LatLng latLng, LatLng latLng2) {

        List<LatLng> points= polyline.getPoints();

        //先添加2再添加1

        MarkerOptions options= new MarkerOptions();

        options.position(latLng2).draggable(false).visible(true);

        Marker marker= aMap.addMarker(options);

        marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_dian_y));

        //设置偏移

        marker.setAnchor(0.5f, 0.5f);

        //如果是最后一个点

        if (isEnd && checkPos == allLatLngs.size() - 1) {

            //直接把点信息添加进去

            allLatLngs.add(new MyLatLng(latLng2, MyLatLng.UNABLE));

            allLatLngsWithLine.add(latLng2);

            markers.add(marker);

        } else {

            //按位置插入点信息

            allLatLngs.add(checkPos + 1, new MyLatLng(latLng2, MyLatLng.UNABLE));

            allLatLngsWithLine.add(checkPos + 1, latLng2);

            markers.add(checkPos + 1, marker);

}

        points.add(checkPos + 1, latLng2);

        MarkerOptions options2= new MarkerOptions();

        options2.position(latLng).draggable(false).visible(true);

        Marker marker2= aMap.addMarker(options2);

        marker2.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_dian_y));

        marker2.setAnchor(0.5f, 0.5f);

        allLatLngs.add(checkPos, new MyLatLng(latLng, MyLatLng.UNABLE));

        allLatLngsWithLine.add(checkPos, latLng);

        markers.add(checkPos, marker2);

        points.add(checkPos, latLng);

        polyline.setPoints(points);

}

    /**

* 方法必须重写

*/

    @Override

    protected void onResume() {

        super.onResume();

        mapView.onResume();

}

    /**

* 方法必须重写

*/

    @Override

    protected void onPause() {

        super.onPause();

        mapView.onPause();

}

    /**

* 方法必须重写

*/

    @Override

    protected void onSaveInstanceState(Bundle outState) {

        super.onSaveInstanceState(outState);

        mapView.onSaveInstanceState(outState);

}

    /**

* 方法必须重写

*/

    @Override

    protected void onDestroy() {

        super.onDestroy();

        mapView.onDestroy();

}

    /**

* 添加marker

*/

    private void addMarker(LatLng latLng) {

        if (allLatLngs.size() == 0) {

            MarkerOptions options= new MarkerOptions();

            options.position(latLng).draggable(false).visible(true);

            Marker marker= aMap.addMarker(options);

            marker.setObject((allLatLngs.size() + 1));

            marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_dian_s));

            marker.setAnchor(0.5f, 0.5f);

            allLatLngs.add(new MyLatLng(latLng, MyLatLng.ABLE));

            allLatLngsWithLine.add(latLng);

            markers.add(marker);

            //画线

            drawLine(latLng, null);

        } else {

            if (isEnd) {

                MarkerOptions options= new MarkerOptions();

                latLng= new LatLng(((latLng.latitude + allLatLngs.get(allLatLngs.size() - 1).getLatLng().latitude) / 2), ((latLng.longitude + allLatLngs.get(allLatLngs.size() - 1).getLatLng().longitude) / 2));

                options.position(latLng).draggable(false).visible(true);

                Marker marker= aMap.addMarker(options);

                marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_dian_y));

                marker.setAnchor(0.5f, 0.5f);

                allLatLngs.add(new MyLatLng(latLng, MyLatLng.UNABLE));

                allLatLngsWithLine.add(latLng);

                markers.add(marker);

                drawLine(allLatLngsWithLine.get(allLatLngsWithLine.size() - 1), allLatLngsWithLine.get(0));

            } else {

                for (int i= 0; i< 2; i++) { // 在地图上添一组图片标记(marker)对象,并设置是否改变地图状态以至于所有的marker对象都在当前地图可视区域范围内显示

                    MarkerOptions options= new MarkerOptions();

                    if (i== 0) {

                        LatLng latLng2= new LatLng(((latLng.latitude + allLatLngs.get(allLatLngs.size() - 1).getLatLng().latitude) / 2), ((latLng.longitude + allLatLngs.get(allLatLngs.size() - 1).getLatLng().longitude) / 2));

                        options.position(latLng2).draggable(false).visible(true);

                        allLatLngs.add(new MyLatLng(latLng2, MyLatLng.UNABLE));

                        allLatLngsWithLine.add(latLng2);

                    } else {

                        options.position(latLng).draggable(false).visible(true);

                        allLatLngs.add(new MyLatLng(latLng, MyLatLng.ABLE));

                        allLatLngsWithLine.add(latLng);

}

                    Marker marker= aMap.addMarker(options);

                    marker.setAnchor(0.5f, 0.5f);

                    if (i== 1) {

                        marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_dian_s));

                    } else {

                        marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_dian_y));

}

                    markers.add(marker);

}

                drawLine(allLatLngsWithLine.get(allLatLngsWithLine.size() - 2), allLatLngsWithLine.get(allLatLngsWithLine.size() - 1));

}

}

}

    /**

* 计算周长

*/

    private void  setPerimeter(){

        List<LatLng> points= polyline.getPoints();

        float f= 0;

        for (int i= 0; i< points.size() - 1; i++) {

            f= f+ AMapUtils.calculateLineDistance(points.get(i), points.get(i+ 1));

}

        mPerimeterTv.setText("周长:" + f+"米");

}

    /**

* 计算面积

*/

    private void setArea(){

        List<LatLng> points2= new ArrayList<>();

        List<LatLng> points= polygon.getPoints();

        points2.addAll(points);

        BigDecimal bigDecimal= polygon_area(points2);

        mAreaTv.setText("面积:"+bigDecimal+"km²");

}

    /**

* 画线

*/

    private void drawLine(LatLng latLng, LatLng latLng2) {

        if (polyline == null) {

            polyline = aMap.addPolyline(new PolylineOptions().

                    add(latLng).width(10).color(Color.argb(255, 1, 1, 1)));

        } else {

            List<LatLng> points= polyline.getPoints();

            if (isEnd) {

                points.add(latLng);

                points.add(latLng2);

            } else {

                if (!points.contains(latLng)) {

                    points.add(latLng);

}

                if (!points.contains(latLng2)) {

                    points.add(latLng2);

}

}

            polyline.setPoints(points);

            //计算周长

            setPerimeter();

}

}

    /**

* 画多边形

*/

    private void drawRect() {

        if (polygon == null) {

            polygonOptions.addAll(allLatLngsWithLine);

            //创建多边形

            polygon = aMap.addPolygon(polygonOptions);

        } else {

            polygon.setPoints(allLatLngsWithLine);

}

        //计算面积

        setArea();

}

    /**

* 获取面积

    * @paramring

    * @return

*/

  private  BigDecimal  polygon_area(List<LatLng>  ring){

        double sJ= 6378137;

        double Hq= 0.017453292519943295;

        double c= sJ*Hq;

        double d= 0;

        if (3 > ring.size()) {

            return new BigDecimal( 0);

}

        for (int i= 0; i< ring.size() - 1; i++){

            LatLng h= ring.get(i);

            LatLng k= ring.get(i+ 1);

            double u= h.longitude * c* Math.cos(h.latitude * Hq);

            double hhh= h.latitude * c;

            double v= k.longitude * c* Math.cos(k.latitude *Hq);

            d= d+ (u* k.latitude * c- v* hhh);

}

        LatLng g1= ring.get(ring.size()-1);

        LatLng point= ring.get(0);

        double eee= g1.longitude * c* Math.cos(g1.latitude * Hq);

        double g2= g1.latitude * c;

        double k= point.longitude * c* Math.cos(point.latitude * Hq);

        d+= eee* point.latitude * c- k* g2;

        return new BigDecimal( 0.5*Math.abs(d)).divide(new BigDecimal(1000000));

}

    /**

* 绘制图形的颜色样式

*/

    private void createAreaStyle() {

        int fillColor= Color.parseColor("#11000000");

        // 设置多边形的边框颜色,32位 ARGB格式,默认为黑色

        polygonOptions.strokeWidth(10);

        polygonOptions.strokeWidth(10); // 设置多边形的填充颜色,32位ARGB格式

        polygonOptions.fillColor(fillColor); // 注意要加前两位的透明度 // 在地图上添加一个多边形(polygon)对象

    }

    /**

* 获取所有点里离该点最近的点的索引值,阈值为1000,如果所有值都比2大,则表示没有最近的点(返回-1)

*这个阈值可以继续做优化,根据地图缩放等级动态更改能获得更好体验

    * @paramlatLng

*/

    @NonNull

    private int getNearestLatLng(LatLng latLng) {

        for (int i= 0; i< allLatLngs.size(); i++) {

            //判断两点间的直线距离

            float distance= AMapUtils.calculateLineDistance(latLng, allLatLngs.get(i).getLatLng());

            if (((int) distance) < 1000) {

                return i;

}

}

        return -1;

}

}

5.还有一个涉及到的bean类也一并贴出

public class MyLatLng {

    public static final int ABLE = 1;

    public static final int UNABLE = 0;

    private LatLng latLng;

    private int state;

    public MyLatLng(LatLng latLng, int state) {

        this.latLng = latLng;

        this.state = state;

}

    public LatLng getLatLng() {

        return latLng;

}

    public void setLatLng(LatLng latLng) {

        this.latLng = latLng;

}

    public int getState() {

        return state;

}

    public void setState(int state) {

        this.state = state;

}

}

最后,这篇文章也基本结束,时间紧急,没有完善其中的一些判定方法,如果各位有更好的方案,欢迎留言!!!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容