{"version":"0.1.0","code":"0000","result":true,"message":"处理成功","errdetail":"","timestamp":1671508870819,"data":{"id":71713306,"title":"6.5.5自定义复杂业务图层","slug":"udrouo","format":"lake","bookId":26046811,"body":null,"body_draft":null,"body_html":"

基本介绍

前面自定义业务图层控制器介绍了如何实现显示基本点线面图层的需求,但是如果要实现比较复杂的业务逻辑的图层需求,自定义业务图层控制器就无法满足这样的需求。本文主要介绍如何使用基础图层和图元来实现复杂的业务图层。

实现一个自定义复杂业务图层需要关注的信息有:

场景图

关键参数

核心接口

//添加点击观察者回调\nvoid com.autonavi.gbl.map.layer.BaseLayer.addClickObserver(ILayerClickObserver pObserver)\n//图元批量添加items\nvoid com.autonavi.gbl.map.layer.BaseLayer.addItems(ArrayList<LayerItem> items)\n//开启或关闭碰撞,默认未开启\nvoid com.autonavi.gbl.map.layer.BaseLayer.enableCollision(boolean enable)\n//开启或关闭Poi Filter,默认未开启\nvoid com.autonavi.gbl.map.layer.BaseLayer.enablePoiFilter(boolean enable)\n//图元批量删除items\nvoid com.autonavi.gbl.map.layer.BaseLayer.removeItems(String[] itemIDs)\n//控制图层是否可点击\nvoid com.autonavi.gbl.map.layer.BaseLayer.setClickable(boolean bClickable)\n//设置图层样式回调接口\nvoid com.autonavi.gbl.map.layer.BaseLayer.setStyle(IPrepareLayerStyle pStyle)\n//将图层添加到图层管理器,绑定到主图\nvoid com.autonavi.gbl.map.layer.LayerMgr.addLayer(BaseLayer pLayer)\n//将图层从图层管理器中移除并释放图层\nvoid com.autonavi.gbl.map.layer.LayerMgr.removeLayer(BaseLayer pLayer)\n//图元样式JSON串回调接口\nString com.autonavi.gbl.map.layer.observer.IPrepareLayerStyle.getLayerStyle(BaseLayer pLayer, LayerItem pItem, boolean forJava)\n//图元样式中通过marker 图片文件名获取对应的marker id\nint com.autonavi.gbl.map.layer.observer.IPrepareLayerStyle.getMarkerId(BaseLayer pLayer, LayerItem pItem, String strMarkerId, String strMarkerInfo)

说明:函数详情,请复制函数名称到在线API搜索

调用示例

业务图元定义

import com.autonavi.gbl.map.layer.PointLayerItem;\n\npublic final class DemoConstant {\n    public static final int BusinessTypePoint = 0;\n    public static final int BusinessTypeLine = 1;\n    public static final int BusinessTypePolygon = 2;\n    public static final int BusinessTypeArrow = 3;\n    public static final int BusinessTypeCircle = 4;\n\n    public static final int BusinessTypeCollisionPoint = 5;\n}\n\nclass ItemDirection {\n    public static final int ItemDirectionLeft = 0;\n    public static final int ItemDirectionRight = 1;\n}\n\n/**< 自定义业务图元 */\nclass PointLayerItemDemo extends PointLayerItem {\n    public PointLayerItemDemo(String name, int direction) {\n        mName = name;\n        mDirection = direction;\n        mCollisionArea = 0.0f;\n    }\n\n    public String mName;//定义业务图层包含的新的业务属性\n    public int mDirection;\n}

点击观察者

import com.autonavi.auto.common.CommonUtil;\nimport com.autonavi.gbl.map.layer.BaseLayer;\nimport com.autonavi.gbl.map.layer.LayerItem;\nimport com.autonavi.gbl.map.layer.observer.ILayerClickObserver;\n\npublic class LayerClickObserverDemo implements ILayerClickObserver {\n    ...\n    @Override\n    public void onNotifyClick(BaseLayer baseLayer, LayerItem layerItem) {\n        //需要特别注意:baseLayer和layerItem只能在这个函数中使用,不能抛到其它线程中使用(因为对象可能已经被释放)\n        if (baseLayer == null || layerItem == null) {\n            return;\n        }\n\n        int businessType = layerItem.getBusinessType();\n        int itemType = layerItem.getItemType();\n        String id = layerItem.getID();\n\n        switch (businessType) {\n            default: {\n                CommonUtil.showShortToast("onNotifyClick: " + businessType + ", id: " + layerItem.getID());\n                break;\n            }\n        }\n    }\n}\n

业务图层类

import com.autonavi.gbl.layer.model.BizPointBusinessInfo;\nimport com.autonavi.gbl.map.MapView;\nimport com.autonavi.gbl.map.layer.BaseLayer;\nimport com.autonavi.gbl.map.layer.LayerItem;\nimport com.autonavi.gbl.map.layer.PointLayerItem;\nimport java.util.ArrayList;\n\npublic class PointLayerDemo extends BaseLayer {\n    public PointLayerDemo(String name, MapView mapView) {\n        super(name, mapView);\n    }\n\n    /**< 初始化图层 */\n    public void init() {\n        MapView mapView = getMapView();\n        if (mapView != null) {\n            PrepareLayerStyleDemo.getInstance().init(mapView);\n            setStyle(PrepareLayerStyleDemo.getInstance()); //设置图元样式回调\n            addClickObserver(LayerClickObserverDemo.getInstance());\n            setClickable(true); //设置图层为可点击\n\n            enableCollision(true); //启用图层的图元间的碰撞功能\n            enablePoiFilter(true); //启用图元的避让功能\n        }\n    }\n\n    /**< 反初始化图层 */\n    public void unInit() {\n        MapView mapView = getMapView();\n        if (mapView != null) {\n            setStyle(null);\n            removeClickObserver(LayerClickObserverDemo.getInstance());\n            enableCollision(false);\n            enablePoiFilter(false); //关闭避让,否则底图上被避让的元素无法重新显示\n        }\n    }\n\n    /**< 业务接口 */\n    public void updatePointInfo(ArrayList<BizPointBusinessInfo> pointList) {\n        if (getMapView() == null || pointList.size() == 0) {\n            return;\n        }\n\n        clearAllItems();//清除旧的数据,根据业务也可以不清除\n        ArrayList<LayerItem> items = new ArrayList<>();\n        for (int i = 0; i < pointList.size(); i++) {\n            PointLayerItemDemo item = new PointLayerItemDemo("left", ItemDirection.ItemDirectionLeft);\n            if (item != null) {\n                String id = pointList.get(i).id;\n                if (id.isEmpty()) {\n                    id = String.valueOf(i);\n                }\n\n                item.setID(id); //id必须唯一\n                item.setBusinessType(DemoConstant.BusinessTypePoint);\n                item.setPriority(i);//根据业务特性,设置优先级\n                item.setPosition(pointList.get(i).mPos3D);\n\n                items.add(item);\n            }\n        }\n\n        addItems(items); //添加图元到图层中,会自动调用updateStyle更新图元样式\n    }\n}\n

业务图层样式

    /**\n     * @brief                       图元样式JSON串回调接口\n     * @param[in] pLayer            图元所在图层\n     * @param[in] layerItem         需要更新样式的具体图元,通过GetBusinessType返回值判断具体图层\n     * @param[in] forJava           参数暂时无用,只是标示当前接口用于支持Java端,传递Stirng而非cJSON*\n     * @return String               返回的样式JSON内容字符串,由客户端构造\n     * @note thread:main\n     */\n    @Override\n    public String getLayerStyle(final BaseLayer pLayer, LayerItem layerItem, boolean forJava) {\n        String strStyleJson = "";\n        if (pLayer == null || layerItem == null) {\n            return strStyleJson;\n        }\n\n        int itemType = layerItem.getItemType();\n        int businessType = layerItem.getBusinessType();\n\n        switch (itemType) {\n            case LayerItemType.LayerItemPointType:\n                switch (businessType) {\n                    case DemoConstant.BusinessTypePoint:\n                        PointLayerItemDemo pointItem = (PointLayerItemDemo)layerItem;//转为图层对应的业务图元\n                        if (pointItem.mDirection == ItemDirection.ItemDirectionLeft) {\n                            strStyleJson = CommonUtil.getDemoStyleBeanJsonWithNightMode("point_left_demo_style", mIsNightMode);\n                        } else {\n                            strStyleJson = CommonUtil.getDemoStyleBeanJsonWithNightMode("point_right_demo_style", mIsNightMode);\n                        }\n                        break;\n                }\n                break;\n\t\t\t\t}\n\n        return strStyleJson;\n\t\t}

业务图层及接口调用

\n    /**< 图层最后不再使用时,从图层管理器中删除,同时图层会被delete释放掉 */\n    public void updatePointInfoDemo() {\n        MapView mapView = getMapView();\n        PointLayerDemo demo = new PointLayerDemo("layer demo", mapView);\n        \n        if (mapView != null) {\n            mapView.getLayerMgr().addLayer(demo); //把图层添加到图层管理器中\n        }\n        \n        demo.init();\n        demo.updatePointInfo();\n        demo.uninit();\n        \n        if (mapView != null) {\n            mapView.getLayerMgr().removeLayer(demo);\n        }\n    }\n

JSON配置

\t\t"point_left_demo_style": {\n\t\t\t"point_layer_item_style": {\n\t\t\t\t"normal_style": {\n\t\t\t\t\t"poi_marker_id": "global_image_guide_camera_surveillance_left_day",\n\t\t\t\t\t"poi_marker_info": "point_camera_left_x_y"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t"point_right_demo_style": {\n\t\t\t"point_layer_item_style": {\n\t\t\t\t"normal_style": {\n\t\t\t\t\t"poi_marker_id": "global_image_guide_camera_surveillance_right_day",\n\t\t\t\t\t"poi_marker_info": "point_camera_right_x_y"\n\t\t\t\t}\n\t\t\t}\n\t\t},

注意事项

自定义图层不允许存储item

  1. layer添加item,基类会存储item,如果自定义图层也存储item,当基类释放item,自定义图层的item就变成野指针,如有在JAVA中,c++的item被释放,Java的item对象被引用,会引起内存泄露。
  2. item的访问存在多线程操作,碰撞,更新都会操作item,所以需要使用item,可以通过GetAllItems,并且要加锁(LockItems,UnLockItems)。
","body_lake":null,"pub_level":null,"status":"0","updated_at":"2022-04-06 07:04:34","deleted_at":null,"nameSpace":"mnlcaa/v610","browseCount":92,"collectCount":0,"estimateDate":17,"docStatus":0,"permissions":true,"overView":false}}