百度地图二次开发实现添加覆盖物的功能

我用的是andoid studio4.0,打开百度地图后设计点击一个按纽后添加覆盖物的功能时,实现不了,求指点一下

一. 自定义覆盖物:继承Overlay类

这个例子是在地图中间添加了一个覆盖物

//1、定义构造函数并继承Overlay      定义自定义覆盖物的构造函数

function SquareOverlay(center, length, color) {

this._center = center;

this._length = length;

this._color = color;

}

// 继承API的BMap.Overlay

SquareOverlay.prototype = new BMap.Overlay();

//2、初始化自定义覆盖物

// 实现初始化方法

SquareOverlay.prototype.initialize = function (map) {

// 保存map对象实例

this._map = map;

// 创建div元素,作为自定义覆盖物的容器

var div = document.createElement("div");

div.style.position = "absolute";

// 可以根据参数设置元素外观

div.style.width = this._length + "px";

div.style.height = this._length + "px";

div.style.background = this._color;

div.appendChild(document.createTextNode("覆盖物测试"));

// 将div添加到覆盖物容器中         map.getPanes().markerPane.appendChild(div);

// 保存div实例

this._div = div;

// 需要将div元素作为方法的返回值,当调用该覆盖物的show、

// hide方法,或者对覆盖物进行移除时,API都将操作此元素。

return div;

}

//3、绘制覆盖物

// 实现绘制方法

SquareOverlay.prototype.draw = function () {

// 根据地理坐标转换为像素坐标,并设置给容器

var position = this._map.pointToOverlayPixel(this._center);

this._div.style.left = position.x - this._length / 2 + "px";

this._div.style.top = position.y - this._length / 2 + "px";

}

//4、显示和隐藏覆盖物

// 实现显示方法

SquareOverlay.prototype.show = function () {

if (this._div) {

this._div.style.display = "";

}

}

// 实现隐藏方法

SquareOverlay.prototype.hide = function () {

if (this._div) {

this._div.style.display = "none";

}

}

//5、添加其他覆盖物方法

//比如,改变颜色

SquareOverlay.prototype.yellow = function () {

if (this._div) {

this._div.style.background = "yellow";

}

}

//6、自定义覆盖物添加事件方法

SquareOverlay.prototype.addEventListener = function (event, fun) {

this._div['on' + event] = fun;

}

//7、添加自定义覆盖物

var mySquare = new SquareOverlay(map.getCenter(), 100, "red");

map.addOverlay(mySquare);

//8、 为自定义覆盖物添加点击事件

mySquare.addEventListener('click', function () {

alert('haveTest');

});

二. 自定义控件:继承Control类

这里是在地图右上角添加了一个工具栏(三个按钮)

function StaticsControl() {         // 设置默认停靠位置和偏移量           this.defaultAnchor = BMAP_ANCHOR_TOP_RIGHT;         this.defaultOffset = new BMap.Size(10, 10);     }     // 通过JavaScript的prototype属性继承于BMap.Control       StaticsControl.prototype = new BMap.Control();     StaticsControl.prototype.initialize = function (map) {         // 创建一个DOM元素           var div = document.createElement("div");         // 添加文字说明           var e1 = document.createElement("input");         e1.type = "button";         e1.value = "专题统计";         e1.onclick = function () {             Statics();         }         var object = div.appendChild(e1);         var e2 = document.createElement("input");         e2.type = "button";         e2.value = "结束统计";         e2.onclick = function () {             EndStatics();         }         var object = div.appendChild(e2);         var e3 = document.createElement("input");         e3.type = "button";         e3.value = "统计设置";         e3.onclick = function () {             SetStatics();         }         var object = div.appendChild(e3);         // 添加DOM元素到地图中           map.getContainer().appendChild(div);         // 将DOM元素返回           return div;     }     // 创建控件实例       var staticsCtrl = new StaticsControl();     // 添加到地图当中       map.addControl(staticsCtrl);     function SetStatics() {         alert("SetStatics");     }     function EndStatics() {         alert("EndStatics");     }     function Statics() {         alert("Statics");     }

一,和实现显示导航的图标一样,我们需要实例化一个BitmapDescriptor实例,然后调用BitmapDescriptorFactory的fromSource()方法,传入资源文件,这样的话,我们就可以在地图上出现覆盖物图标的第一步。
二,在Toolbar标题栏上面添加一个item选项,然后在 public boolean onOptionsItemSelected(MenuItem item){
}里面添加点击item之后的逻辑事件。不过在这之前,我们要准备好另外一个类,这个类里面放上我们覆盖物需要的一些参数。
//添加覆盖物图片
比如我新建了一个info类,然后在这个类里面来设置一些覆盖物的参数。

 private void addOverlays(List<info> infos)
    {
        baiduMap.clear();
        LatLng latLng = null;
        Marker marker = null;
        OverlayOptions options;
        for (info info : infos)
        {
            latLng = new LatLng(info.getLatitude(), info.getLongitude());// 经纬度

            options = new MarkerOptions()
                    .position(latLng)
                    .icon(mMarker)// 图标
                    .zIndex(5);
            marker = (Marker) baiduMap.addOverlay(options);
            Bundle arg0 = new Bundle();
            arg0.putSerializable("info", info);
            marker.setExtraInfo(arg0);
        }
        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
        baiduMap.setMapStatus(msu);
    }

这样的话,我们就把点击item,就可以显示出marker。

android 百度地图批量添加标注,参考:
https://blog.csdn.net/weixin_42513616/article/details/117520740


官方提供了添加覆盖物的接口和样例
你可以把这部分代码贴出来看看

遇到什么问题了,可以把代码贴出来吗?你这样问没法帮你解决问题啊!

建议将你的报错和操作步骤截图分享出来,这样才能得到更多优质解决方案

百度地图的文档上有相关资料可以看一下,通过标注可以设置显示什么图形,如果不满足也可以自己通过css设置学

据我了解,百度Android地图SDK支持是自定义图片图层(图片覆盖物GroundOvelay)及标注功能;这一功能,官方文档也提供了详细的描述,
可以把这部分代码集成到你项目里面看看呢

//定义Ground的显示地理范围
LatLng southwest = new LatLng(39.92235, 116.380338);
LatLng northeast = new LatLng(39.947246, 116.414977);
LatLngBounds bounds = new LatLngBounds.Builder()
        .include(northeast)
        .include(southwest)
        .build();

//定义Ground显示的图片
BitmapDescriptor bdGround = BitmapDescriptorFactory.fromResource(R.drawable.ground_overlay);
//定义GroundOverlayOptions对象
OverlayOptions ooGround = new GroundOverlayOptions()
        .positionFromBounds(bounds)
        .image(bdGround)
        .transparency(0.8f); //覆盖物透明度

//在地图中添加Ground覆盖物
mBaiduMap.addOverlay(ooGround);

img


Ground覆盖物,是一种位于底图和底图标注层之间的特殊Overlay,该图层不会遮挡地图标注信息。通过GroundOverlayOptions类来设置,开发者可以通过GroundOverlayOptions类设置一张图片,该图片可随地图的平移、缩放、旋转等操作做相应的变换。

androidsdk | 百度地图API SDK

设置点击事件
点击事件中实现下列方法

    private void addMarkerOverlay() {
            //创建坐标点对象             天安门的经纬度
            LatLng point=new LatLng(39.915, 116.404);
            //创建OverlayOptions对象
            BitmapDescriptor descriptor= BitmapDescriptorFactory
                    .fromResource(R.drawable.marker);//
            MarkerOptions markerOptions = new MarkerOptions()
                    .position(point)//标注覆盖物的位置
                    .icon(descriptor)//标注覆盖物的图标
                    .alpha(0.5f);//透明度  0.5是半透明
            //添加到地图进行显示
           Marker marker= (Marker) baiduMap.addOverlay(markerOptions);

            marker.setDraggable(true);//设置标注覆盖物可以拖拽
            //添加所以标注覆盖物的点击事件监听器
            baiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
                @Override
                public boolean onMarkerClick(Marker marker) {
                    Log.e("位置","维度:"+marker.getPosition().latitude +
                            "经度"+marker.getPosition().longitude);
                    return false;
                }
            });
            //处理拖拽事件 打印拖拽到的地点的经纬度
        baiduMap.setOnMarkerDragListener(new BaiduMap.OnMarkerDragListener() {
            @Override
            public void onMarkerDrag(Marker marker) {
                Log.e("位置","维度:"+marker.getPosition().latitude +
                        "经度"+marker.getPosition().longitude);
            }

            @Override
            public void onMarkerDragEnd(Marker marker) {
                Log.e("位置","维度:"+marker.getPosition().latitude +
                        "经度"+marker.getPosition().longitude);
            }

            @Override
            public void onMarkerDragStart(Marker marker) {
                Log.e("位置","维度:"+marker.getPosition().latitude +
                        "经度"+marker.getPosition().longitude);
            }
        });
    }

实现给固定点(天安门)标记覆盖物,也可以拖拽覆盖物到其他地点
其中 R.drawable.marker 是覆盖物图片资源

亲测有效

img

望采纳

步骤如下
1定义构造函数并继承Overlay

首先您需要定义自定义覆盖物的构造函数,通过构造函数参数可以传递一些自由的变量。设置自定义覆盖物对象的prototype属性为http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference.html#a3b0的实例,以便继承覆盖物基类。

如下示例,我们定义一个名为SquareOverlay的构造函数,它包含中心点和边长两个参数,用来在地图上创建一个方形覆盖物。

// 定义自定义覆盖物的构造函数  
function SquareOverlay(center, length, color){
    this._center = center;
    this._length = length;
    this._color = color;
}
// 继承API的BMap.Overlay
SquareOverlay.prototype = new BMap.Overlay();

2初始化自定义覆盖物

实现http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference.html#a3b0方法,当调用map.addOverlay方法时,API会调用此方法。

当调用map.addOverlay方法添加自定义覆盖物时,API会调用该对象的initialize方法用来初始化覆盖物,在初始化过程中需要创建覆盖物所需要的DOM元素,并添加到地图相应的容器中。这里我们选择添加在容器markerPane上。

// 实现初始化方法  
SquareOverlay.prototype.initialize = function(map){
    // 保存map对象实例
    this._map = map;
    // 创建div元素,作为自定义覆盖物的容器
    var div = document.createElement("div");
    div.style.position = "absolute";
    // 可以根据参数设置元素外观
    div.style.width = this._length + "px";
    div.style.height = this._length + "px";
    div.style.background = this._color;
    // 将div添加到覆盖物容器中
    map.getPanes().markerPane.appendChild(div);
    // 保存div实例
    this._div = div;
    // 需要将div元素作为方法的返回值,当调用该覆盖物的show、
    // hide方法,或者对覆盖物进行移除时,API都将操作此元素。
    return div;
}

地图提供了若干容器供覆盖物展示,通过http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference.html#a3b0方法可以得到这些容器元素,它们包括:

floatPane

markerMouseTarget

floatShadow

labelPane

markerPane

mapPane

这些对象代表了不同的覆盖物容器元素,它们之间存在着覆盖关系,最上一层为floatPane,用于显示信息窗口内容,下面依次为标注点击区域层、信息窗口阴影层、文本标注层、标注层和矢量图形层。

我们自定义的方形覆盖物可以添加到任意图层上,如上示例,我们选择添加到markerPane上,作为其一个子结点。

3绘制覆盖物

实现http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference.html#a3b0方法。

到目前为止,我们仅仅把覆盖物添加到了地图上,但是并没有将它放置在正确的位置上。

您需要在draw方法中设置覆盖物的位置,每当地图状态发生变化(比如:位置移动、级别变化)时,API都会调用覆盖物的draw方法,用于重新计算覆盖物的位置。

通过map.pointToOverlayPixel方法可以将地理坐标转换到覆盖物的所需要的像素坐标。

// 实现绘制方法   
SquareOverlay.prototype.draw = function(){    
// 根据地理坐标转换为像素坐标,并设置给容器    
    var position = this._map.pointToOverlayPixel(this._center);    
    this._div.style.left = position.x - this._length / 2 + "px";    
    this._div.style.top = position.y - this._length / 2 + "px";    
}

4移除覆盖物

当调用map.removeOverlay或者map.clearOverlays方法时,API会自动将initialize方法返回的DOM元素进行移除。

5显示和隐藏覆盖物

自定义覆盖物会自动继承Overlay的show和hide方法,方法会修改由initialize方法返回的DOM元素的style.display属性。

如果自定义覆盖物元素较为复杂,您也可以自己实现show和hide方法。

// 实现显示方法    
SquareOverlay.prototype.show = function(){    
    if (this._div){    
        this._div.style.display = "";    
    }    
}      
// 实现隐藏方法  
SquareOverlay.prototype.hide = function(){    
    if (this._div){    
        this._div.style.display = "none";    
    }    
}

自定义其他方法 通过构造函数的prototype属性,您可以添加任何自定义的方法,比如下面这个方法每调用一次就能改变覆盖物的显示状态:

// 添加自定义方法   
SquareOverlay.prototype.toggle = function(){    
    if (this._div){    
        if (this._div.style.display == ""){    
            this.hide();    
        }    
        else {    
            this.show();    
        }    
    }    
}

6添加覆盖物

您现在已经完成了一个完整的自定义覆盖物的编写,可以添加到地图上了。

// 初始化地图  
var map = new BMap.Map("container");    
var point = new BMap.Point(116.404, 39.915);    
map.centerAndZoom(point, 15);    
// 添加自定义覆盖物   
var mySquare = new SquareOverlay(map.getCenter(), 100, "red");    
map.addOverlay(mySquare);

参考:

一,和实现显示导航的图标一样,我们需要实例化一个BitmapDescriptor实例,然后调用BitmapDescriptorFactory的fromSource()方法,传入资源文件,这样的话,我们就可以在地图上出现覆盖物图标的第一步。
二,在Toolbar标题栏上面添加一个item选项,然后在 public boolean onOptionsItemSelected(MenuItem item){
}里面添加点击item之后的逻辑事件。不过在这之前,我们要准备好另外一个类,这个类里面放上我们覆盖物需要的一些参数。
//添加覆盖物图片
比如我新建了一个info类,然后在这个类里面来设置一些覆盖物的参数。

public class info implements Serializable{
    //private static final long serialVersionUID = -1010711775392052966L;
    private double latitude;
    private double longitude;
    private int zan;
    private String name;
    private int imgId;
    private String distance;
    public static List<info> infos = new ArrayList<info>();
    static
    {
        infos.add(new info(34.242652, 108.971171, R.drawable.a01, "英伦贵族小旅馆",
                "距离209米", 1456));
        infos.add(new info(34.242952, 108.972171, R.drawable.a02, "沙井国际洗浴会所",
                "距离897米", 456));
        infos.add(new info(34.242852, 108.973171, R.drawable.a03, "五环服装城",
                "距离249米", 1456));
       infos.add(new info(34.242152, 108.971971, R.drawable.a04, "老米家泡馍小炒",
               "距离679米", 1456));
    }
    public info(double latitude, double longitude, int imgId, String name,
                String distance, int zan)
    {
        this.latitude = latitude;
        this.longitude = longitude;
        this.imgId = imgId;
        this.name = name;
        this.distance = distance;
        this.zan = zan;
    }
    public double getLatitude()
    {
        return latitude;
    }
    public void setLatitude(double latitude)
    {
        this.latitude = latitude;
    }
    public double getLongitude()
    {
        return longitude;
    }
    public void setLongitude(double longitude)
    {
        this.longitude = longitude;
    }
    public int getImgId()
    {
        return imgId;
    }
    public void setImgId(int imgId)
    {
        this.imgId = imgId;
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public String getDistance()
    {
        return distance;
    }
    public void setDistance(String distance)
    {
        this.distance = distance;
    }
    public int getZan()
    {
        return zan;
    }
    public void setZan(int zan)
    {
        this.zan = zan;
    }
}

三,准备好info类以后,我们就开始写点击item后的逻辑事件。

 case R.id.id_add:
                addOverlays(info.infos);
                break;
 private void addOverlays(List<info> infos)
    {
        baiduMap.clear();
        LatLng latLng = null;
        Marker marker = null;
        OverlayOptions options;
        for (info info : infos)
        {
            latLng = new LatLng(info.getLatitude(), info.getLongitude());// 经纬度

            options = new MarkerOptions()
                    .position(latLng)
                    .icon(mMarker)// 图标
                    .zIndex(5);
            marker = (Marker) baiduMap.addOverlay(options);
            Bundle arg0 = new Bundle();
            arg0.putSerializable("info", info);
            marker.setExtraInfo(arg0);
        }
        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
        baiduMap.setMapStatus(msu);
    }

这样的话,我们就把点击item,就可以显示出marker。
四,准备布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="220dp"
    android:background="#cc4e5a6b" >

    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="150dp"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="12dp"
        android:layout_marginRight="12dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/img_border"
        android:scaleType="fitXY"
        android:src="@drawable/a01" >
    </ImageView>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:background="@drawable/bg_map_bottom" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="20dp"
            android:orientation="vertical" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="老米家泡馍"
                android:textColor="#fff5eb" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="距离200米"
                android:textColor="#fff5eb" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="20dp"
            android:orientation="horizontal" >

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/map_zan"
                android:clickable="true" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="789"
                android:layout_gravity="center"
                android:textColor="#fff5eb" />
        </LinearLayout>
    </RelativeLayout>

</RelativeLayout>

五,点击marker的逻辑事件

//设置marker的点击事件
        baiduMap.setOnMarkerClickListener(new OnMarkerClickListener()
        {
            @Override
            public boolean onMarkerClick(Marker marker)
            {
                Bundle extraInfo = marker.getExtraInfo();
                info info = (info) extraInfo.getSerializable("info");
                ImageView iv = (ImageView) mMarkerLy
                        .findViewById(R.id.id_info_img);
                TextView distance = (TextView) mMarkerLy
                        .findViewById(R.id.id_info_distance);
                TextView name = (TextView) mMarkerLy
                        .findViewById(R.id.id_info_name);
                TextView zan = (TextView) mMarkerLy
                        .findViewById(R.id.id_info_zan);
                iv.setImageResource(info.getImgId());
                distance.setText(info.getDistance());
                name.setText(info.getName());
                zan.setText(info.getZan() + "");//把赞的类型由int 变成String
                 mMarkerLy.setVisibility(View.VISIBLE);
                return true;
            }
        });

不过,我们同样也要设置点击地图其他位置时候,让marker消失。

baiduMap.setOnMapClickListener(new OnMapClickListener()
        {

            @Override
            public boolean onMapPoiClick(MapPoi arg0)
            {
                return false;
            }

            @Override
            public void onMapClick(LatLng arg0)
            {
                mMarkerLy.setVisibility(View.GONE);
            }
        });

六,我们还希望在点击marker的时候,还希望在marker上面添加一行文字说明。
这时候我们需要实例化一个infowindow对象,然后给infowindow实例添加一些参数。

InfoWindow infoWindow;
                TextView tv = new TextView(context);
                tv.setBackgroundResource(R.drawable.location_tips);
                tv.setPadding(30, 20, 30, 50);
                tv.setText(info.getName());
                tv.setTextColor(Color.parseColor("#ffffff"));
                BitmapDescriptor tips = BitmapDescriptorFactory.fromView(tv);
                final LatLng latLng = marker.getPosition();
                Point p = baiduMap.getProjection().toScreenLocation(latLng);
                p.y -= 47;
                LatLng ll = baiduMap.getProjection().fromScreenLocation(p);
                infoWindow = new InfoWindow(tips, ll,p.y,
                        new OnInfoWindowClickListener()
                        {
                            @Override
                            public void onInfoWindowClick()
                            {
                                baiduMap.hideInfoWindow();
                            }
                        });
                baiduMap.showInfoWindow(infoWindow);

这样的话,我们离大功告成就只有一步之遥了。我们需要在 baiduMap.setOnMapClickListener(new OnMapClickListener(){
}方法里面添加一句baiduMap.hideInfoWindow();用来隐藏infowindow.