android 百度地图描绘POI
2012-10-17 10:02:54      我来说两句       作者:jj120522
收藏     我要投稿

首先还是一贯作风,请大家先看一些图例:

在上一篇介绍了地图显示自己的位置,在这一篇呢,我简单介绍下在地图如何show出来一系列POI(兴趣点)
      首先我们从服务器拉取要标记POI的信息如(lat,lon,Tag等信息)然后就是根据经纬度创建ItemizedOverlay.这个是用于显示一系列的POI.
     代码片段:
  在onLocationChanged调用:
[java] 
/***
     * Location 监听
     * 
     * @param arg0
     */ 
    @Override 
    public void onLocationChanged(Location location) { 
        if (location != null) { 
            // 获取自己的经纬度点 
            GeoPoint geoPoint = new GeoPoint( 
                    (int) (location.getLatitude() * 1e6), 
                    (int) (location.getLongitude() * 1e6)); 
            mMapController.setCenter(geoPoint); 
 
            addItemizedOverlay(geoPoint.getLatitudeE6() / 1e6, 
                    geoPoint.getLongitudeE6() / 1e6);// 定位一系列点 
 
            // addOverLay(geoPoint); 
        } 
 
    } 
[java] 
/***
 * 添加一系列的overlay 范围在5000米内
 * 
 * @param lat
 *            纬度
 * @param lon
 *            经度
 */ 
void addItemizedOverlay(double lat, double lon) { 
    arrayList = new ArrayList<MarkInfo>(); 
    // 获取服务器返回的一系列点 
    ArrayList<MarkInfo> markInfos = Constent.getArrayListPoint(); 
    for (int i = 0; i < markInfos.size(); i++) { 
        MarkInfo markInfo = markInfos.get(i); 
        Double dis = MyUtil.getGeoPointDistance(lat, lon, markInfo.lat, 
                markInfo.lon); 
        if (dis <= distance) 
            arrayList.add(markInfo); 
    } 
 
    Drawable marker = getResources().getDrawable(R.drawable.item); 
    marker.setBounds(0, 0, marker.getIntrinsicWidth(), 
            marker.getIntrinsicHeight()); // 为maker定义位置和边界 
 
    overlays = mMapView.getOverlays(); 
    myItemizedOverlay = new MyItemizedOverlay(marker, this, arrayList); 
 
    myItemizedOverlay.setMapView(mMapView); 
 
    overlays.add(myItemizedOverlay); 
    mPopView = createMarkView();// 获取冒泡view 
    myItemizedOverlay.setmPopView(mPopView); 
    // 将泡泡添加到mMapView上 
    mMapView.addView(mPopView, new MapView.LayoutParams( 
            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, null, 
            MapView.LayoutParams.WRAP_CONTENT)); 
    mPopView.setVisibility(View.GONE); 

[java] 
/***
     * 创建点击mark时的弹出泡泡
     */ 
 
    public View createMarkView() { 
        layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
        mPopView = layoutInflater.inflate(R.layout.popview, null); 
        TextView textView = (TextView) mPopView.findViewById(R.id.snippet); 
        mPopView.setTag(textView); 
        return mPopView; 
    } 
这里我简单模拟获取服务器的一系列的poi. 并计算自身与这些poi的位置距离,如果小于5000.则显示出来.
在这里说明一下:首先服务器边的处理,不能把所有的poi数据都返回给我们,如果是这样,那么手机就会很耗时会吃不消,不符合移动项目的需求,服务器端:应该对这一系列的poi进行处理,比如根据地区划分开来,如:我传给服务器参数上海浦东,那么只返回给我浦东一系列的poi,这样就解决了这个问题,另外,最好的办法是这段逻辑最好在服务器端,我们请求服务器的参数把距离5000也带过去,返回给我们直接就是要show的poi,这样设计最好了.扯了有点偏了,不过我是初学者,就简单记录下来,如有不妥或着更简单的方法,还请您指示一二,谢谢在先了.
MyItemizedOverlay.java
[java]
package com.jj.baidu; 
 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Point; 
import android.graphics.drawable.Drawable; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup.LayoutParams; 
import android.widget.TextView; 
import android.widget.Toast; 
 
import com.baidu.mapapi.GeoPoint; 
import com.baidu.mapapi.ItemizedOverlay; 
import com.baidu.mapapi.MapView; 
import com.baidu.mapapi.OverlayItem; 
import com.baidu.mapapi.Projection; 
import com.jj.modle.MarkInfo; 
 
/***
 * 系列覆盖物
 * 
 * @author zhangjia
 * 
 */ 
public class MyItemizedOverlay extends ItemizedOverlay<OverlayItem> { 
 
    private List<OverlayItem> overlayItems; 
    private OverlayItem overlayItem, overlayItem2, overlayItem3, overlayItem4, 
            overlayItem5, overlayItem6; 
 
    private Context mContext; 
    private Drawable marker;// 覆盖物图标 
 
    private View mPopView = null; // 点击mark时弹出的气泡View 
 
    private MapView mapView; 
 
    private ArrayList<MarkInfo> markInfos;// 一系列经纬度点 
 
    // 注入地图map 
    public void setMapView(MapView mapView) { 
        this.mapView = mapView; 
    } 
 
    // 注入泡泡view 
    public void setmPopView(View mPopView) { 
        this.mPopView = mPopView; 
    } 
 
    public MyItemizedOverlay(Drawable marker, Context context, 
            ArrayList<MarkInfo> markInfos) { 
        super(boundCenterBottom(marker)); 
        this.mContext = context; 
        this.marker = marker; 
        this.markInfos = markInfos; 
        overlayItems = new ArrayList<OverlayItem>(); 
        for (int i = 0; i < markInfos.size(); i++) { 
            /***
             * 第一个参数是GeoPoint,第二个参数是title.通过overlayItem.getTitle()可以获取到,
             * 第三个参数是Snippet,通过overlayItem.getSnippet()获取到.
             */ 
            GeoPoint geoPoint = new GeoPoint( 
                    (int) (markInfos.get(i).lat * 1e6), 
                    (int) (markInfos.get(i).lon * 1e6)); 
            overlayItem = new OverlayItem(geoPoint, i + "", 
                    markInfos.get(i).Tag); 
            overlayItems.add(overlayItem); 
        } 
        populate(); // createItem(int)方法构造item。一旦有了数据,在调用其它方法前,首先调用这个方法 
 
    } 
 
    @Override 
    public void draw(Canvas canvas, MapView mapView, boolean shadow) { 
        // super.draw(canvas, mapView, shadow); 
 
        // Projection接口用于屏幕像素坐标和经纬度坐标之间的变换 
        // 这里可以在point旁边draw 一些文字. 
        // Projection projection = mapView.getProjection(); 
        // for (int i = 0; i < overlayItems.size(); i++) { 
        // OverlayItem overlayItem = overlayItems.get(i); 
        // String title = overlayItem.getTitle(); 
        // // 把经纬度变换到相对于MapView左上角的屏幕像素坐标 
        // Point point = projection.toPixels(overlayItem.getPoint(), null); 
        // 
        // // 可在此处添加您的绘制代码 
        // Paint paintText = new Paint(); 
        // paintText.setColor(Color.BLUE); 
        // paintText.setTextSize(15); 
        // canvas.drawText(title, point.x - 30, point.y, paintText); // 绘制文本 
        // } 
 
        super.draw(canvas, mapView, shadow); 
        // 调整一个drawable边界,使得(0,0)是这个drawable底部最后一行中心的一个像素 
        boundCenterBottom(marker); 
 
    } 
 
    @Override 
    protected OverlayItem createItem(int position) { 
        return overlayItems.get(position); 
    } 
 
    @Override 
    public int size() { 
        return overlayItems.size(); 
    } 
 
    // 处理当点击事件 
    @Override 
    protected boolean onTap(final int i) { 
        // 获取点击的GeoPoint 
        GeoPoint geoPoint = overlayItems.get(i).getPoint(); 
        // 获取大头针的宽高, 
        int x = marker.getIntrinsicHeight(); 
        int y = marker.getIntrinsicWidth(); 
        /***
         * 显示泡泡 参数是要显示的view 水平多少有些偏差,
         * 
         * 可以自己进行调整,垂直则让显示在大头针的中间部位即可.即-y/2.
         */ 
        mapView.updateViewLayout(mPopView, new MapView.LayoutParams( 
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, geoPoint, 
                -3, -y / 2, MapView.LayoutParams.BOTTOM_CENTER)); 
        mPopView.setVisibility(View.VISIBLE); 
        mapView.getController().animateTo(geoPoint);// 移动到中间 
        TextView textView = (TextView) mPopView.getTag(); 
        textView.setText(overlayItems.get(i).getSnippet()); 
        mPopView.setOnClickListener(new OnClickListener() { 
            @Override 
            public void onClick(View v) { 
                Toast.makeText(mContext, overlayItems.get(i).getSnippet(), 1) 
                        .show(); 
 
            } 
        }); 
 
        return super.onTap(i); 
    } 
 

注释已经很详细,这里不过多介绍.
在这里我简单说明一下:点击地图上的poi标记弹出来的气泡mPopView如何显示.
[java]
mapView.updateViewLayout(mPopView, new MapView.LayoutParams( 
            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, geoPoint, 
            -3, -y / 2, MapView.LayoutParams.BOTTOM_CENTER)); 
第4,5个参数是相对于(geopoint对应屏幕上point的点)来说的.如果不写则表示0,0,则那么mPopView的和poi点将重合,很不友好,你可以测试一下就明白了.因此我们要让mPopView显示在poi的中间,则让mPopView上移(poi的宽度/2)。相信大家都明白的.(你可以看下面运行结果)
在这里我给出如何根据两经纬度点计算之间的距离和方位方法:
[java]
public class MyUtil { 
    // 地球半径 
    private static final double EARTH_RADIUS = 6378137.0; 
 
    /***
     * 返回 两个GeoPoint之间的距离
     */ 
    public static double getGeoPointDistance(double lat_a, double lng_a, 
            double lat_b, double lng_b) { 
        double radLat1 = (lat_a * Math.PI / 180.0); 
        double radLat2 = (lat_b * Math.PI / 180.0); 
        double a = radLat1 - radLat2; 
        double b = (lng_a - lng_b) * Math.PI / 180.0; 
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) 
                + Math.cos(radLat1) * Math.cos(radLat2) 
                * Math.pow(Math.sin(b / 2), 2))); 
        s = s * EARTH_RADIUS; 
        s = Math.round(s * 10000) / 10000; 
        return s; 
    } 
 
    /***
     * 返回 两个GeoPoint之间的方位角
     */ 
    public static String getGeoPointCorner(double lat_a, double lng_a, 
            double lat_b, double lng_b) { 
        double d = 0; 
        lat_a = lat_a * Math.PI / 180; 
        lng_a = lng_a * Math.PI / 180; 
        lat_b = lat_b * Math.PI / 180; 
        lng_b = lng_b * Math.PI / 180; 
 
        d = Math.sin(lat_a) * Math.sin(lat_b) + Math.cos(lat_a) 
                * Math.cos(lat_b) * Math.cos(lng_b - lng_a); 
        d = Math.sqrt(1 - d * d); 
        d = Math.cos(lat_b) * Math.sin(lng_b - lng_a) / d; 
        d = Math.asin(d) * 180 / Math.PI; 
 
        // d = Math.round(d*10000); 
        return d + ""; 
 
    } 
 
}

        
                
    自身定位(嘿嘿,有兄弟一起的么)
                

这些数据没有任何联系,我是随便找的,大家可以根据项目需求进行适度调整,
另外点击左下角定位按钮会定位到自身方位.具体实现也很简单,我们直接引用为我们封装了一切的LocationOverLay类,
mMapView.getController().animateTo(locationOverlay.getMyLocation()); 即可.
如果想让箭头跟着自己位置进行移动:
[java] 
/***
         * 当位置变化时就会跟进
         */ 
        locationOverlay.runOnFirstFix(new Runnable() { 
            @Override 
            public void run() { 
                mMapView.getController().animateTo( 
                        locationOverlay.getMyLocation()); 
            } 
        }); 
测试没有问题,不过和百度地图相比逊色不是一点点,移动很不连贯.原因正在研究中,如有知道的朋友请指示一二.
先说道这里,以后慢慢补充添加.

APP应用一般就是这些功能.主要是show一系列的POI.简单说到这里.如有发现会及时更新.
如有问题请留言,Thanks for you 。

Android百度地图显示POI相关推荐

  1. android百度地图附近的poi,Android百度地图poi范围搜索

    我想大家可能都有过这样的经历:兜里揣着一张银行卡,在街上到处找自动取款机(ATM).在这个场景中,ATM就是的兴趣点,我们想做的事情就是找到离自己较近的一些ATM然后取款,此时我们并不关心附近有哪些超 ...

  2. Android百度地图POI检索无标记显示问题

    源码地址 Github:https://github.com/Abbylolo/BasicBaiduMap Gitee: https://gitee.com/wild-piglolo/basic-ba ...

  3. Android百度地图显示附近的位置

    效果如下图所示,可以使用手滑动上面的地图进行位置刷新, 主要实现思路是去掉原始的地图导航图层,再MapView的正中间放一张图片,给MapView添加手滑动地图的事件进行添加,再获取MapView的中 ...

  4. android百度地图显示某个地区,百度地图api只显示某个省市的行政区域

    有些时候我们只需要某个省份的行政区域,那么运用百度地图如何实现呢? 我们先上效果图: 步骤: 创建map实例 var map; createMap() { map = new BMap.Map('ma ...

  5. android百度开发显示多个点标记,android百度地图显示多个自定义标记

    一.配置相关参数 配置定位SDK参数 private int span = 5000; private void initLocationSDK() { LocationClientOption op ...

  6. Android百度地图显示空白(只有格子)的具体真实解决方法

    现象 如图 在申请的时候 下一步 最后一步,在 AndroidManifest.xml 中 ** 最后这两个key 必须一样. 经验.不行的话 多申请几次.吼吼 **就可以显示出地图啦!!! 上图

  7. Android 百度地图显示定位小蓝点

    这个问题肯定苦恼了很多人,那就直入主题吧.首先要保证一点你申请得AK是有效的! 1. 2. 2的代码是放在 MyLocationListener的作用就是用于接收定位返回的结果,定结果进行解析的地方. ...

  8. java安卓百度地图查找便利店_Android 百度地图POI搜索功能实例代码

    在没介绍正文之前先给大家说下poi是什么意思. 由于工作的关系,经常在文件中会看到POI这三个字母的缩写,但是一直对POI的概念和含义没有很详细的去研究其背后代表的意思.今天下班之前,又看到了POI这 ...

  9. android 百度地图 在线建议查询,Android 百度地图 SDK v3_3_0 (五) ---POI搜索和在线建议查询功能...

    目前百度地图SDK所集成的检索服务包括:POI检索.公交信息查询.线路规划.地理编码.在线建议查询.短串分享. 本篇博客将先介绍POI检索和在线建议查询(在地图地位功能基础上实现的,还不知道定位的童靴 ...

最新文章

  1. iptables中state模块的连接状态
  2. 第三讲:WCF介绍(3)
  3. iOS 查看崩溃日志
  4. vue +element 搭建项目,要求既支持pc端又支持移动端
  5. Python 技术篇-pip安装提示:‘pip‘ 不是内部或外部命令,也不是可运行的程序或批处理文件,问题解决方法
  6. html5 audio api 录音,如何使用HTML5 Web Audio API录制我的声音
  7. python逆序数的程序_计算逆序数(归并法)程序问题 (Python)
  8. C#完整的通信代码(点对点,点对多,同步,异步,UDP,TCP),多多宜善
  9. 致谢!华为全联接2020精彩回顾
  10. Mybatis的逆向工程,MySQL8的数据库,8.0.11驱动的逆向工程的坑的解决方法
  11. c 获取char*的长度_C/C++编程笔记:C语言字符串比较函数,超详细,值得收藏!...
  12. 51nod 1534 棋子游戏 博弈
  13. AcrelEMS-EV汽车制造能效管理系统解决方案
  14. 一个公务员的坎坷“仕途”,以及五光十色的沿途“风景”
  15. python实现word内容替换
  16. java魂斗罗_向经典致敬--跟我用Java写魂斗罗
  17. 计算思维是运用计算机科学的什么进行,什么是计算思维?
  18. WIN10下如何解决PL2303驱动不可用的问题或者com口显示黄色感叹号usb-to-serial
  19. 北京大学C语言学习第4天
  20. 关于微信公众号开发中扫码关注和关注之后继续扫码的不同点

热门文章

  1. 拉网小调(民歌介绍)
  2. Miles to go ... - Arun Gupta: Securing WebSocket using wss and HTTPS/TLS (Tech T
  3. sybase datediff mysql_Sybase中的日期时间函数_龙的天空
  4. 2021-09-252021年中式烹调师(中级)考试技巧及中式烹调师(中级)证考试
  5. 2022茶艺师(中级)考试题模拟考试题库及模拟考试
  6. java 多线程(四)—— 线程同步/互斥=队列+锁
  7. 山东专升本计算机知识点(中)
  8. 专用5G网络的7种部署方案
  9. 数据结构(1)—— 数据结构的三大结构
  10. 浅析Gompertz模型