百度、高德地图功能进一步探索之—电子围栏绘制(三)

开始最前提到对地图覆盖物的使用,到目前为止只剩  Polygon(多边形)  Circle(圆形)这两个还没有进一步说明,那么今天我们所要讲解的电子围栏功能会用到这两个覆盖物,当然也会用到Marker覆盖物 Polyline(折线)一起来实现:

实现思路(多边形实现):

  • 用户触发添加按钮,打开添加电子围栏模式(当然通过布尔变量来决定是否可以绘制)
  • 当用户打开电子围栏绘制是,点击第一个顶点是可以给一个参照使用Marker覆盖物做一个锚点
  • 点击第二个或锚点是移除第一个顶点的锚点,并且通过Polyline(折线)将一 二顶点连接,接下来的顶点自动连接即可
  • 当用需要保持电子围栏时,将之前的点位全部传入PolygonOptions,生成PolygonOptions对象,添加到地图
  • 需要实现是将 Polygon对象显示出来
  • 需要保存数据是,通过地图可以获取到Polygon对象,通过Polygon对象可以获取到经纬度的集合,保存即可
  • 使用时有经纬度的集合可,可以显示电子围栏也,可以根据经纬度集合判断指定的位置是否在围栏中

看到这里可能有点懵,怎么一会儿是Polygon对象一会儿又是PolygonOptions对象,其实给地图添加覆盖物时需要的参数都是xxOptions对象,但是添加到地图时,返回的可操作对象就是xx了。之前添加Marker覆盖物添加时必须使用MarkerOptions,而返回的对象就是Marker对象。

 

开始实现功能(代码部分使用的kotlin实现):

高德地图:

用户点击地图选择电子围栏范围:

//地图上点击监听 
aMap.setOnMapClickListener {
            /**
             * 根据用户在地图上的点击,绘制多边形的定点
             */
            if (iseDitMode) { //iseditMode是一个控制当用户点击添加电子围栏时该变量修改为true
                //将位置加入集合
                latLngs.add(it)
                //判断是否为第一个顶点
                if (latLngs.size > 1) {
                     /*
                      * 如果非首个顶点添加到轨迹中
                      */
                    //这里逻辑在运动轨迹文章中已经介绍
                  var  polyline =  aMap.addPolyline(PolylineOptions()
                         
                            //集合数据
                            .addAll(latLngs).width(4f).setDottedLine(false).geodesic(true)
                            //颜色
                            .color(Color.argb(255, 255, 68, 0)))
                    polylines.add(polyline)
                    //移除首个锚点
                    this.marker!!.remove()
                } else {
                    如果是首个顶点那么先标记成锚点
                    markerOptions.position(it)
                    marker = aMap.addMarker(markerOptions);
                    trajectory(it)
                }
            }
        }

选择好电子围栏顶点点击保存:

//使用本次添加的顶点生成多边形对象并存储起来 
mPolygonOptions.add(PolygonOptions().addAll(latLngs))
 /**
  * 移除绘制过程的定点覆盖物
*/
 for (polyline in polylines) {
      polyline.remove()
}

显示电子围栏

/**
     * 根据用户存储的多边形对象显示电子围栏
     * 通过aMap.addPolygon(polygonOptions)可以得到多边形对象
     * 通过polygon.contains(LatLng)可以判断出该Latlng对象是否在电子围栏中
     *
     */
    private fun showPolygonOptions() {

        //将存储的多边形对象取出添加到地图上
        for (polygonOptions in mPolygonOptions) {
            polygonOptions.fillColor(Color.argb(150, 239, 113, 113))
                    .strokeColor(Color.argb(150, 239, 113, 113)).strokeWidth(1f)
            var  polygon = aMap.addPolygon(polygonOptions);
            mPolygons.add(aMap.addPolygon(polygonOptions))
        }
    }

关闭电子围栏显示:

 /**
     * 关闭显示的电子围覆盖层
     */
    private fun closAllPolygonOptions() {

        //循化将多个电子围栏覆盖物移除
        for (polygon in mPolygons) {
            polygon.remove()
        }
        aMap.invalidate()
    }

到目前高德地图的设置不规则电子围栏设置步骤完成,但是代码还有待优化尤其显示和关闭,其实可以用显示和隐藏,不用每次添加和移除。百度地图的实现将使用不同的方式,这里就不给贴代码了 。

百度地图:

用户点击地图选择电子围栏范围:

//用户点击地图回调
        mBaiduMap.setOnMapClickListener(object : BaiduMap.OnMapClickListener {
            override fun onMapClick(latLng: LatLng) {

                /**
                 * 根据用户的点击绘制多边形的定点
                 */
                if (iseDitMode) {
                    latLngs.add(latLng)
                    if (latLngs.size > 1) {

                        if (bdPolyline != null) {
                            bdPolyline!!.remove()
                        }
                        mPolylineOptions.points(latLngs).dottedLine(false).color(Color.argb(255, 255, 20, 147)).width(5)
                        bdPolyline = mBaiduMap.addOverlay(mPolylineOptions);
                        bdStartMarker1!!.remove()
                    } else if (latLngs.size > 0) {

                        var markerOption = MarkerOptions()
                        markerOption.position(latLng).icon(BitmapDescriptorFactory.fromResource(R.drawable.express_icon_location_centre_point))
                        bdStartMarker1 = mBaiduMap.addOverlay(markerOption)
                    }
                }

            }

            override fun onMapPoiClick(mapPoi: MapPoi): Boolean {
                return false
            }
        })

用户点击保存电子围栏:

/**
     * 根据定点生产多边形对象,及可以作为围栏对象
     * 通过com.baidu.mapapi.utils
     *                SpatialRelationUtil
     *              可以判断经纬度是否在电子围栏中
     *              isPolygonContainsPoint()可以判断对象点位是否在电子围栏中
     */
    private fun savPolygonOptions() {
        if (latLngs.size > 2) {
            //latLngs.add(latLngs.get(0))
            var latLng = arrayListOf()
            latLng = latLngs.clone() as ArrayList;
            //生成多边形对象
            var polygonOptions = PolygonOptions().points(latLngs).fillColor(Color.argb(150, 239, 113, 113))
            //设置为不可见
            polygonOptions.visible(false)
            //将多边形对象存储
            bdPolygonOptions.add(polygonOptions)
            //添加多边形到地图,并将返回的可操作对象(电子围栏)存储
            bdDrawPolylineOptionsOverlayList.add(mBaiduMap.addOverlay(polygonOptions))
            //移除添加电子围栏时的选点过程
            if (bdPolyline != null) {
                bdPolyline!!.remove()
            }
            trajectory.setText("显示围栏")

        } else {
            Toast.makeText(this, "至少添加三个点才能建立围栏", Toast.LENGTH_LONG).show()
        }
    }

显示电子围栏

/**
     * 显示围栏对象(高德地图也可以使用该方式显示,)
     */
    private fun showPolygonOptions() {
        //将电子存储的电子围栏对象取出通过setVisible(true)方法显示出来
        for (overlay in bdDrawPolylineOptionsOverlayList) {
            overlay.setVisible(true)
        }

    }

关闭电子围栏:

/**
     * 隐藏围栏对象
     */
    private fun closAllPolygonOptions() {
        for (overlay in bdDrawPolylineOptionsOverlayList) {
            overlay.setVisible(false)
        }
    }

 

百度地图添加电子围栏过程到这里完成了

 

拓展:

通过以上分别介绍了高德地图和百度地图的电子围栏实现方法,但是怎么确定某一个位置是否位于电子围栏中呢:

高德地图通过:Polygon的contains(LatLng latLng) 方法可以知道指定的位置是否在电子围栏中不

百度地图需要通过一个工具类:com.baidu.mapapi.utils.SpatialRelationUtil

百度、高德地图功能进一步探索之—电子围栏绘制(三)_第1张图片 后两个方法可以判断指定位置是否在区域中

 

 

总结:

这里是通过百度地图提供的一些覆盖为去划定,区域做电子围栏添加和管理,其实还可以自定义一个画图控件覆盖在地图上,通过手动绘制区域,通过地图的Api获取屏幕位置对应的Api可以添加电子围栏,电子围栏其实就是划定的一个区域,通过两个的对不您应该发现了,百度地图和高德地图有一些Api的使用和甚至名称都相同。如果您有更好的实现过程请您分享一下。地图的使用文章更新到这里,如果有问题欢迎提问 

项目已经上传Github项目地址点击这里

你可能感兴趣的:(地图,电子围栏)