最近接到公司一个项目,需要根据给定的所有经纬度批量生成Marker点,在点击某一个Marker点时,更改当前选中的Marker点的图标,并显示当前选中点的详细地址信息,并且提供点击"到这去"能够打开手机已安装的百度地图进行导航
首先来看效果图吧:
默认刚进去程序的效果 这时我随便添加的3个标记
当点击标记点时 更改当前Marker点的图标 并显示当前标记点的详细位置信息
点击到这去时打开手机百度地图进行导航
//批量生成Marker点标记
LatLng point1 = new LatLng(25.92235, 116.380338);
LatLng point2 = new LatLng(13.947246, 116.414977);
LatLng point3 = new LatLng(39.937246, 116.314977);
LatLng point4 = new LatLng(59.937246, 116.314977);
List<LatLng> points = new ArrayList<>();
points.add(point1);
points.add(point2);
points.add(point3);
points.add(point4);
mDefaultBitmap = BitmapDescriptorFactory
.fromResource(R.drawable.biaoji);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (LatLng p : points) {
builder = builder.include(p);
}
latlngBounds = builder.build();
for(int i=0;i<points.size();i++){
OverlayOptions optiona = new MarkerOptions()
.position(points.get(i))
.icon(mDefaultBitmap);
//生成Bundle对象存放我们的LatLng 数据
Bundle mBundle = new Bundle();
mBundle.putParcelable("content", points.get(i));
Marker marker = (Marker) mBaiduMap.addOverlay(optiona);
marker.setExtraInfo(mBundle);
}
这里我们用List 来存放我们的经纬度,然后分别根据经纬度生成Marker点显示在地图上,然后将我们的LatLng对象进行传递
private void initListener() {
mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
//marker被点击时回调的方法
//若响应点击事件,返回true,否则返回false
//默认返回false
@Override
public boolean onMarkerClick(Marker marker) {
//让所有的标记都恢复默认图标
//拿到所有的标记列表
List<Marker> markersInBounds = mBaiduMap.getMarkersInBounds(latlngBounds);
//点击时将已经变化的图标进行回复默认
for (Marker markersInBound : markersInBounds) {
if(markersInBound.getIcon() != mDefaultBitmap){
markersInBound.setIcon(mDefaultBitmap);
}
}
//修改当前选中的图标
BitmapDescriptor bitmap = BitmapDescriptorFactory
.fromResource(R.drawable.location);
marker.setIcon(bitmap);
//获取当前选中的经纬度
Bundle bundle = marker.getExtraInfo();
LatLng latLng = bundle.getParcelable("content");
Log.i("sadjklasdlas","@"+latLng.latitude);
return true;
}
});
}
这里我们调用Marker的点击事件,然后拿到我们添加的所有Marker集合,将当前不为默认图标的进行图标的修改(初始化 ) 然后修改当前选中的Marker的图标,获取上面传递过来的LatLng 对象
private void updateWithNewLocation(LatLng latLng) {
//获取相关位置信息
String coordinate;
String addressStr = "no address \n";
if (latLng != null) {
mMBeiwei = latLng.latitude -0.004;
mDongjing = latLng.longitude - 0.01;
//double lat = 39.25631486;
//double lng = 115.63478961;
coordinate = "Latitude:" + mMBeiwei + "\nLongitude:" + mDongjing;
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(mMBeiwei,
mDongjing, 1);
StringBuilder sb = new StringBuilder();
if (addresses.size() > 0) {
Address address = addresses.get(0);
for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
sb.append(address.getAddressLine(i)).append(" ");
}
sb.append(address.getLocality()).append(" ");
Log.i("location", "address.getLocality()==" + address.getLocality());//城市名
sb.append(address.getSubLocality());
Log.i("location", "address.getSubLocality()=2=" + address.getSubLocality());//---区名
Log.i("location","all"+addressStr);
Log.i("location", "address.getSubLocality()=3=" + address.getAddressLine(0) + "");//---区名
//addressStr = sb.toString();
addressStr= address.getAddressLine(0) + "";
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
//如果用户没有允许app访问位置信息 则默认取上海松江经纬度的数据
/*lat = 39.25631486;
lng = 115.63478961;*/
coordinate = "no coordinate!\n";
}
Log.i("location", "经纬度为===" + coordinate);
Log.i("location", "地址为====" + addressStr);
address.setText(addressStr);
}
根据点击Marker点,获取上面传递过来的LatLng 对象,然后调用LatLng里面的属性来获取当前位置信息详细的地方可以看打印日志
private static final String PN_BAIDU_MAP = "com.baidu.BaiduMap"; // 百度地图包名
public void gothere(View v){
boolean installBaidu = isInstallPackage(PN_BAIDU_MAP);
if(installBaidu){
openBaiDuNavi(this,startwei,startjing,"起始位置",mMBeiwei,mDongjing,"终点站");
}
}
private static boolean isInstallPackage(String packageName) {
return new File("/data/data/" + packageName).exists();
}
/**
* 打开百度地图导航功能(默认坐标点是高德地图,需要转换)
*
* @param context
* @param slat 起点纬度
* @param slon 起点经度
* @param sname 起点名称 可不填(0,0,null)
* @param dlat 终点纬度
* @param dlon 终点经度
* @param dname 终点名称 必填
*/
public static void openBaiDuNavi(Context context, double slat, double slon, String sname, double dlat, double dlon, String dname) {
String uriString = null;
//终点坐标转换 需要实现的在此处进行坐标转换
StringBuilder builder = new StringBuilder("baidumap://map/direction?mode=driving&");
if (slat != 0) {
//起点坐标转换
builder.append("origin=latlng:")
.append(slat)
.append(",")
.append(slon)
.append("|name:")
.append(sname);
}
builder.append("&destination=latlng:")
.append(dlat)
.append(",")
.append(dlon)
.append("|name:")
.append(dname);
uriString = builder.toString();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setPackage(PN_BAIDU_MAP);
intent.setData(Uri.parse(uriString));
context.startActivity(intent);
}
首先判断当前手机是否已经下载过百度地图,然后根据传入的起始位置经纬度以及目的地经纬度来打开第三方导航
以上就是今天要分享的内容,来看整体代码:
MainActivity.class
public class MainActivity extends Activity {
private static final String PN_BAIDU_MAP = "com.baidu.BaiduMap"; // 百度地图包名
private MapView mMapView = null;
private BaiduMap mBaiduMap;
private Boolean isfirstLocate = true;
private LocationClient mLocationClient;
private LatLngBounds latlngBounds;
private BitmapDescriptor mDefaultBitmap;
private TextView address;
private double startwei;
private double startjing;
private double mMBeiwei;
private double mDongjing;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
address = findViewById(R.id.addressa);
//获取地图控件引用
mMapView = findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
//显示卫星图层
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
//开启定位图层
mBaiduMap.setMyLocationEnabled(true);
//定位初始化
mLocationClient = new LocationClient(this);
//通过LocationClientOption设置LocationClient相关参数
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true); // 打开gps
option.setCoorType("bd09ll"); // 设置坐标类型
option.setScanSpan(1000);
//设置locationClientOption
mLocationClient.setLocOption(option);
//注册LocationListener监听器
MyLocationListener myLocationListener = new MyLocationListener();
mLocationClient.registerLocationListener(myLocationListener);
//开启地图定位图层
mLocationClient.start();
//批量生成Marker点标记
LatLng point1 = new LatLng(25.92235, 116.380338);
LatLng point2 = new LatLng(13.947246, 116.414977);
LatLng point3 = new LatLng(39.937246, 116.314977);
LatLng point4 = new LatLng(59.937246, 116.314977);
List<LatLng> points = new ArrayList<>();
points.add(point1);
points.add(point2);
points.add(point3);
points.add(point4);
mDefaultBitmap = BitmapDescriptorFactory
.fromResource(R.drawable.biaoji);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (LatLng p : points) {
builder = builder.include(p);
}
latlngBounds = builder.build();
for(int i=0;i<points.size();i++){
OverlayOptions optiona = new MarkerOptions()
.position(points.get(i))
.icon(mDefaultBitmap);
//生成Bundle对象存放我们的LatLng 数据
Bundle mBundle = new Bundle();
mBundle.putParcelable("content", points.get(i));
Marker marker = (Marker) mBaiduMap.addOverlay(optiona);
marker.setExtraInfo(mBundle);
}
//Marker点击事件
initListener();
}
private void initListener() {
mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
//marker被点击时回调的方法
//若响应点击事件,返回true,否则返回false
//默认返回false
@Override
public boolean onMarkerClick(Marker marker) {
//让所有的标记都恢复默认图标
//拿到所有的标记列表
List<Marker> markersInBounds = mBaiduMap.getMarkersInBounds(latlngBounds);
//点击时将已经变化的图标进行回复默认
for (Marker markersInBound : markersInBounds) {
if(markersInBound.getIcon() != mDefaultBitmap){
markersInBound.setIcon(mDefaultBitmap);
}
}
//修改当前选中的图标
BitmapDescriptor bitmap = BitmapDescriptorFactory
.fromResource(R.drawable.location);
marker.setIcon(bitmap);
//获取当前选中的经纬度
Bundle bundle = marker.getExtraInfo();
LatLng latLng = bundle.getParcelable("content");
Log.i("sadjklasdlas","@"+latLng.latitude);
updateWithNewLocation(latLng);
return true;
}
});
}
private void updateWithNewLocation(LatLng latLng) {
//获取相关位置信息
String coordinate;
String addressStr = "no address \n";
if (latLng != null) {
mMBeiwei = latLng.latitude -0.004;
mDongjing = latLng.longitude - 0.01;
//double lat = 39.25631486;
//double lng = 115.63478961;
coordinate = "Latitude:" + mMBeiwei + "\nLongitude:" + mDongjing;
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(mMBeiwei,
mDongjing, 1);
StringBuilder sb = new StringBuilder();
if (addresses.size() > 0) {
Address address = addresses.get(0);
for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
sb.append(address.getAddressLine(i)).append(" ");
}
sb.append(address.getLocality()).append(" ");
Log.i("location", "address.getLocality()==" + address.getLocality());//城市名
sb.append(address.getSubLocality());
Log.i("location", "address.getSubLocality()=2=" + address.getSubLocality());//---区名
Log.i("location","all"+addressStr);
Log.i("location", "address.getSubLocality()=3=" + address.getAddressLine(0) + "");//---区名
//addressStr = sb.toString();
addressStr= address.getAddressLine(0) + "";
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
//如果用户没有允许app访问位置信息 则默认取上海松江经纬度的数据
/*lat = 39.25631486;
lng = 115.63478961;*/
coordinate = "no coordinate!\n";
}
Log.i("location", "经纬度为===" + coordinate);
Log.i("location", "地址为====" + addressStr);
address.setText(addressStr);
}
public class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
//mapView 销毁后不在处理新接收的位置
if (location == null || mMapView == null){
return;
}
//移动到指定位置
navagitto(location);
startwei = location.getLatitude();
startjing = location.getLongitude();
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(location.getDirection()).latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
mBaiduMap.setMyLocationData(locData);
}
}
//移动到指定位置
private void navagitto(BDLocation location) {
if(isfirstLocate){
// mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().zoom(5).build()));//设置缩放级别
//更新到指定的经纬度
LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(latLng);
mBaiduMap.animateMapStatus(update);
//设置缩放值
update = MapStatusUpdateFactory.zoomTo(6f);
mBaiduMap.animateMapStatus(update);
isfirstLocate = false;
}
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时必须调用mMapView. onResume ()
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时必须调用mMapView. onPause ()
mMapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时必须调用mMapView.onDestroy()
mMapView.onDestroy();
}
public void gothere(View v){
boolean installBaidu = isInstallPackage(PN_BAIDU_MAP);
if(installBaidu){
openBaiDuNavi(this,startwei,startjing,"起始位置",mMBeiwei,mDongjing,"终点站");
}
}
private static boolean isInstallPackage(String packageName) {
return new File("/data/data/" + packageName).exists();
}
/**
* 打开百度地图导航功能(默认坐标点是高德地图,需要转换)
*
* @param context
* @param slat 起点纬度
* @param slon 起点经度
* @param sname 起点名称 可不填(0,0,null)
* @param dlat 终点纬度
* @param dlon 终点经度
* @param dname 终点名称 必填
*/
public static void openBaiDuNavi(Context context, double slat, double slon, String sname, double dlat, double dlon, String dname) {
String uriString = null;
//终点坐标转换 需要实现的在此处进行坐标转换
StringBuilder builder = new StringBuilder("baidumap://map/direction?mode=driving&");
if (slat != 0) {
//起点坐标转换
builder.append("origin=latlng:")
.append(slat)
.append(",")
.append(slon)
.append("|name:")
.append(sname);
}
builder.append("&destination=latlng:")
.append(dlat)
.append(",")
.append(dlon)
.append("|name:")
.append(dname);
uriString = builder.toString();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setPackage(PN_BAIDU_MAP);
intent.setData(Uri.parse(uriString));
context.startActivity(intent);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clickable="true" />
<LinearLayout
android:orientation="vertical"
android:background="@color/white"
android:layout_width="match_parent"
android:layout_height="100dp">
<TextView
android:layout_margin="10dp"
android:text="你好啊"
android:id="@+id/addressa"
android:textColor="@color/black"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:text="到这去"
android:onClick="gothere"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
看到最后喜欢的话 点一个小赞鼓励一下啦 爱你~