利用百度地图开源代码实现定位和实时路径跟踪

您所在的位置:网站首页 实时记录轨迹的软件 利用百度地图开源代码实现定位和实时路径跟踪

利用百度地图开源代码实现定位和实时路径跟踪

2024-07-03 05:54:03| 来源: 网络整理| 查看: 265

利用百度地图开源代码实现定位和实时路径跟踪

更新更新(2020.8.19) 今天刚调试出来了,关于把前面的模拟实时路径跟踪部分修改成了监听手机内部GPS的实时跟踪,能拿着手机在室外跑来跑去,然后定时回调定位监听器的方法,获取到新的经纬度信息,然后边画线,能实现实时路径跟踪的功能了!!!

先给大家演示一下效果

在这里插入图片描述 这里最左边的点,是因为一开始跟踪的时候,会接收一个经纬度,但是可能是因为一开始接收GPS信号的时候不太准确,所以会有一个偏差,而且还是偏差有点大的,但是后面的话,相对来说还是大致可以描绘出来我行走的路线的,这个也是GPS定位本来就不太精准的原因吧?

实现实时路径跟踪,我这里是把原来调用模拟位置的函数,改成了回调监听定位函数的代码,就是不断通过重新获取当前经纬度的监听函数,再把这个获取到的点跟前一个点通过画线的方法进行连线;大概这样就能实现实时监听了。

上代码:(这个就是mainActivity文件,其他的xml文件啥的都没变化)

package com.example.map_track; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.content.DialogInterface; import android.content.pm.PackageManager; import android.graphics.Color; import android.location.Address; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.EditText; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; import com.baidu.location.BDAbstractLocationListener; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.mapapi.CoordType; import com.baidu.mapapi.SDKInitializer; import com.baidu.mapapi.map.BaiduMap; import com.baidu.mapapi.map.BitmapDescriptor; import com.baidu.mapapi.map.BitmapDescriptorFactory; import com.baidu.mapapi.map.InfoWindow; import com.baidu.mapapi.map.MapStatusUpdate; import com.baidu.mapapi.map.MapStatusUpdateFactory; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.Marker; import com.baidu.mapapi.map.MarkerOptions; import com.baidu.mapapi.map.MyLocationConfiguration; import com.baidu.mapapi.map.MyLocationData; import com.baidu.mapapi.map.Overlay; import com.baidu.mapapi.map.OverlayOptions; import com.baidu.mapapi.map.Polyline; import com.baidu.mapapi.map.PolylineOptions; import com.baidu.mapapi.model.LatLng; import com.baidu.mapapi.search.core.SearchResult; import com.baidu.mapapi.search.geocode.GeoCodeResult; import com.baidu.mapapi.search.geocode.GeoCoder; import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener; import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption; import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import android.os.Bundle; import android.widget.Toast; public class MainActivity extends AppCompatActivity { public static final int PLAYBACK_OVER = 1; private MapView mapView; private BaiduMap baiduMap; private LocationClient mLocationClient = null; //定义一个监听器对象 private MyLocationListener myLocationListener; private double currentLat, currentLng; //当前的经纬度 private String currentAddr; //当前所在的地址 private DatabaseAdapter dbAdapter; private GeoCoder geoCoder; private int currentTrackLineID; //当前跟踪的路线ID // BDLocation location; boolean flag = true; boolean isFirstLocation = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_main); mapView = (MapView) findViewById(R.id.bmapView); initBaiduMap(); //初始化地图,显示我的当前位置 dbAdapter = new DatabaseAdapter(this); } /** * 初始化百度地图 */ LocationClientOption option = new LocationClientOption(); private void initBaiduMap() { baiduMap = mapView.getMap(); baiduMap.setMyLocationEnabled(true); //打开定位图层,允许定位 mLocationClient = new LocationClient(getApplicationContext()); //声明LocationClient类 myLocationListener = new MyLocationListener(); mLocationClient.registerLocationListener(myLocationListener); //注册监听函数 //LocationClientOption option = new LocationClientOption(); option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy); //设置定位模式 option.setOpenGps(true); option.setCoorType("bd09ll"); //返回的定位结果是百度经纬度,默认值gcj02 option.setScanSpan(1000); //设置发起定位请求的间隔为5000ms option.setIsNeedAddress(true); //返回的定位结果包含地址信息 option.setNeedDeviceDirect(true); //返回的定位结果包含手机机头方向 option.setWifiCacheTimeOut(5*60*1000); option.setNeedNewVersionRgc(true); mLocationClient.setLocOption(option); mLocationClient.start(); //启动SDK定位 mLocationClient.requestLocation(); //发起定位请求 isFirstLocation = true; //用于转换地理编码的监听器 geoCoder = GeoCoder.newInstance(); geoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() { @Override public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) { if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) { //没有检索结果 } else { //获取地理编码结果 //System.out.println(result.getAddress()); currentAddr = result.getAddress(); //更新线路的结束位置 dbAdapter.updateEndLoc(currentAddr, currentTrackLineID); } } @Override public void onGetGeoCodeResult(GeoCodeResult arg0) { } }); } double cur_Lat = 0; double cur_Lng = 0; BDLocation location1; /** * 定位的监听 */ class MyLocationListener extends BDAbstractLocationListener { @Override public void onReceiveLocation(BDLocation location) { if (location != null && flag) { flag = false; currentLat = location.getLatitude(); //当前的纬度 currentLng = location.getLongitude(); //当前的经度 currentAddr = location.getAddrStr(); //当前位置的地址 // cur_Lat = currentLat; // cur_Lng = currentLng; Log.i("定位的纬度 = ", String.valueOf(currentLat)); Log.i("定位的经度 = ", String.valueOf(currentLng)); if (isFirstLocation) { isFirstLocation = false; //System.out.println("currentAddr=" + currentAddr); //构造我的当前位置信息 MyLocationData.Builder builder = new MyLocationData.Builder(); builder.latitude(location.getLatitude()); //设置纬度 builder.longitude(location.getLongitude()); //设置经度 builder.accuracy(location.getRadius()); //设置精度(半径) builder.direction(location.getDirection()); //设置方向 builder.speed(location.getSpeed()); //设置速度 MyLocationData locationData = builder.build(); //把我的位置信息设置到地图上 baiduMap.setMyLocationData(locationData); //配置我的位置 LatLng latlng = new LatLng(currentLat , currentLng); baiduMap.setMyLocationConfiguration(new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING,true,null)); //设置我的位置为地图的中心点,并且把地图放大16倍(缩放级别为3-20) baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngZoom(latlng, 20)); System.out.println("地址:"+currentAddr+"---纬度:"+currentLat+"---经度:"+currentLng+"\n"); Log.i("hello2",currentAddr); Log.i("hello3", String.valueOf(currentLat)); Log.i("hello4", String.valueOf(currentLng)); Log.i("hello1", String.valueOf(location)); } } } private void getlocation() { // currentLat = cur_Lat; // currentLng = cur_Lng; Log.i("现在纬度 = ", String.valueOf(cur_Lat)); Log.i("现在经度 = ", String.valueOf(cur_Lng)); // baiduMap.setMyLocationEnabled(false); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } //功能菜单项 @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.mylocation : mylocation(); //我的位置 break; case R.id.start_track : startTrack(); //开始跟踪 break; case R.id.end_track : endTrack(); //结束跟踪 break; // case R.id.track_back : // trackBack(); //跟踪回放 // break; default: break; } return true; } /** * 结束跟踪 */ private void endTrack() { isTracking = false; //结束线程 Toast.makeText(MainActivity.this, "跟踪结束...", Toast.LENGTH_SHORT).show(); //转换地理编码,把最后的一个经纬度转换成地址(把经纬度转化成对应的地名地址,或者把地名地址转换成对应的经纬度) geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(new LatLng(currentLat, currentLng))); } /** * 我的位置 */ private void mylocation() { Toast.makeText(MainActivity.this, "正在定位中...", Toast.LENGTH_SHORT).show(); flag = true; baiduMap.clear(); //清除地图上自定义的图层 baiduMap.setMyLocationEnabled(true); mLocationClient.requestLocation(); //发起定位请求 } /** * 开始跟踪功能 */ private void startTrack() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("线路跟踪"); builder.setCancelable(true); final View view = getLayoutInflater().inflate(R.layout.add_track_line_dialog, null); builder.setView(view); builder.setPositiveButton("添加", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText et_track_name = (EditText) view.findViewById(R.id.editText1_track_name); String trackName = et_track_name.getText().toString(); System.out.println(trackName); createTrack(trackName); //创建线路跟踪 Toast.makeText(MainActivity.this, "跟踪开始...", Toast.LENGTH_SHORT).show(); } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.show(); } private boolean isTracking = false; //创建一条线路跟踪 private void createTrack(String trackName) { Track track = new Track(); track.setTrack_name(trackName); track.setCreate_date(DateUtils.toDate(new Date())); //创建时间为当前的时间 track.setStart_loc(currentAddr); currentTrackLineID = dbAdapter.addTrack(track); //添加线路,返回线路ID dbAdapter.addTrackDetail(currentTrackLineID, currentLat, currentLng); //添加明细信息 baiduMap.clear(); addOverlay(); list.add(new LatLng(currentLat, currentLng)); isTracking = true; //线程模拟的标记 System.out.println(list); new Thread(new TrackThread()).start(); } //在地图上添加图层(线路的每一个点) private void addOverlay() { //--------添加一个标注覆盖物在当前位置-------- //构建Marker图标 baiduMap.setMyLocationEnabled(false); //关闭定位图层 BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.mipmap.icon_markx); //构建MakerOption,用于在地图上添加Marker LatLng latlng = new LatLng(currentLat, currentLng); OverlayOptions option = new MarkerOptions().position(latlng).icon(bitmap); //在地图上添加Marker,并显示 baiduMap.addOverlay(option); //把当前添加的地图位置作为地图的中心点 baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(latlng)); } //用于存储两个相邻点的经纬度,再画线 private ArrayList list = new ArrayList(); //模拟跟踪的线程 class TrackThread implements Runnable { @Override public void run() { while (isTracking) { // BDLocation location3 = new BDLocation(); //myLocationListener.getlocation(); baiduMap.setMyLocationEnabled(true); flag = true; myLocationListener.onReceiveLocation(location1); baiduMap.setMyLocationEnabled(false); Log.i("准备画线前的纬度 = ", String.valueOf(currentLat)); Log.i("准备画线前的经度 = ", String.valueOf(currentLng)); dbAdapter.addTrackDetail(currentTrackLineID, currentLat, currentLng); addOverlay(); list.add(new LatLng(currentLat, currentLng)); drawLine(); //画线 System.out.println("drawLine"); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("线程休眠失败"); } // Log.i("hello", String.valueOf(location5)); } } } //在两个点之间画线 private void drawLine() { OverlayOptions lineOptions = new PolylineOptions().points(list).color(0xFFFF0000); baiduMap.addOverlay(lineOptions); list.remove(0); //这里是为了移除两个点之间的前一个,因为在第一次画线之后,每一次画线都只需要添加第二个点,但是它这里是默认把两个点都添加进去,再画线,所以需要删除第一个点 } @Override protected void onDestroy() { super.onDestroy(); //在Activity执行onResume时执行mMapView.onResume(),实现地图生命周期管理 mapView.onDestroy(); } @Override protected void onResume() { super.onResume(); //在Activity执行onResume时执行mMapView.onResume(),实现地图生命周期管理 mapView.onResume(); } @Override protected void onPause() { super.onPause(); //在Activity执行onPause时执行mMapView.onPause(),实现地图生命周期管理 mapView.onPause(); } }

程序还是有一点问题的,我这里设置了一个标志位isFirstLocation,这样每次回调定位监听函数的时候,就只会接收新的经纬度信息,但是因为设置了这个标志位,所以后面结束跟踪之后,就不能重新把当前的位置定位到地图的中心点;

这个问题的话,我是想着可以设置一个按钮,每次点击这个按钮的时候,就把地图clear一下,把图层都清除了,然后再重新初始化一下定位的方法,这样大概就能实现重新定位到当前位置了。

以上是我这几天调程序的思路,有什么不对的地方,还需要大神们帮忙指出来呀!!网上有demo是采用的鹰眼服务的,但是怎么去调用鹰眼服务这一块,我还没有搞懂,所以我是直接通过的定时回调定位监听函数的方法实现的。

如果有大神知道怎么使用鹰眼服务的话,可以给我提供一些思路吗?

8月18更新: 现在还在卡着,对于怎么把模拟经纬度变化的函数转换成监听手机内部GPS信号的回调函数,这一块我还是没有想明白,我后面是加上了鹰眼服务,但是运行起来还是调用逻辑上有问题,一开始跟踪就会闪退,有大神可以给我提供一些意见和思路吗?

这段时间需要用Android Studio做一个基于百度地图的app,记录一下过程,主要实现了定位和实时路径跟踪。

先演示一下效果:(视频放不了,图片凑凑数) 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

实时路径的思想和步骤: 思想:如果需要在地图上实现实时跟踪,那么首先就需要实现定位功能,在实现了定位功能的基础上,需要在地图上画出行走轨迹,那么如何画出行走轨迹?就需要实时地记录行走的经纬度,两点之间画一条直线,中间设置定位的频率高的话,那么记录的经纬度就越多,这样就可以让记录的行走路径光滑一些。 如果需要回放功能,就需要建立一个数据库将行走线路存储下来,数据库就应该要一条线路对应多个点的关系,所以需要两张表,一个表是记录的线路,另一个表是记录的一条线路对应的多个点。(回放功能我还没有实现)

先添加一下权限和密钥之类的吧,先修改好manifests.xml文件:

再就是设置一下布局文件activity_main.xml文件

(以下几个类都是在app/java/com.example.map_track包中完成) 在这里插入图片描述

首先就要建立一个线路类Track,用于存储每条线路的信息;

package com.example.map_track; import java.util.ArrayList; /** *线路跟踪对象 **/ public class Track { //线路 private int id; private String track_name; private String create_date; private String start_loc; private String end_loc; private ArrayList trackDetails; public ArrayList getTrackDetails() { return trackDetails; } public void setTrackDetails(ArrayList trackDetails) { this.trackDetails = trackDetails; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTrack_name() { return track_name; } public void setTrack_name(String track_name) { this.track_name = track_name; } public String getCreate_date() { return create_date; } public void setCreate_date(String create_date) { this.create_date = create_date; } public String getStart_loc() { return start_loc; } public void setStart_loc(String start_loc) { this.start_loc = start_loc; } public String getEnd_loc() { return end_loc; } public void setEnd_loc(String end_loc) { this.end_loc = end_loc; } public Track(int id, String track_name, String create_date,String start_loc, String end_loc) { super(); this.id = id; this.track_name = track_name; this.create_date = create_date; this.start_loc = start_loc; this.end_loc = end_loc; } public Track(String track_name, String create_date, String start_loc, String end_loc) { super(); this.track_name = track_name; this.create_date = create_date; this.start_loc = start_loc; this.end_loc = end_loc; } public Track() { super(); } }

线路类Track建立好了之后,还需要建立一个路线结点类TrackDetail,用于存储线路上每个点的信息;

package com.example.map_track; public class TrackDetail { private int id; private double lat; private double lng; private Track track; public int getId() { return id; } public void setId(int id) { this.id = id; } public double getLat() { return lat; } public void setLat(double lat) { this.lat = lat; } public double getLng() { return lng; } public void setLng(double lng) { this.lng = lng; } public Track getTrack() { return track; } public void setTrack(Track track) { this.track = track; } public TrackDetail(int id, double lat, double lng) { super(); this.id = id; this.lat = lat; this.lng = lng; } }

还需要设置一个数据库助手类DatabaseHelper:

package com.example.map_track; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; /** 数据助手类 **/ public class DatabaseHelper extends SQLiteOpenHelper { private static String DB_NAME = "track.db"; //表名 public static String TABLE_TRACK = "track"; public static String TABLE_TRACK_DETAIL = "track_detail"; //字段 public static String ID = "_id"; //跟踪表 public static String TRACK_NAME = "track_name"; public static String CREATE_DATE = "create_date"; public static String START_LOC = "start_loc"; public static String END_LOC = "end_loc"; //明细表 public static String TID = "tid"; //线路的ID public static String LAT = "lat"; //纬度 public static String LNG = "lng"; //经度 private static String CREATE_TABLE_TRACK = "create table track(_id integer primary key autoincrement,track_name text,create_date text,start_loc text,end_loc text)"; private static String CREATE_TABLE_TRACK_DETAIL = "create table track_detail(_id integer primary key autoincrement,tid integer not null,lat real,lng real)"; private static int VERSION = 1; public DatabaseHelper(Context context) { super(context,DB_NAME,null,VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_TABLE_TRACK); db.execSQL(CREATE_TABLE_TRACK_DETAIL); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (newVersion > oldVersion) { db.execSQL("drop table if exists track"); db.execSQL("drop table if exists track_detail"); db.execSQL(CREATE_TABLE_TRACK); db.execSQL(CREATE_TABLE_TRACK_DETAIL); } } }

再需要建立一个databaseAdapter类,用于数据库的增删改查:

package com.example.map_track; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import java.util.ArrayList; /** *数据库适配器 **/ public class DatabaseAdapter { private DatabaseHelper dbHelper; public DatabaseAdapter(Context context) { dbHelper = new DatabaseHelper(context); } //添加线路跟踪 public int addTrack(Track track) { SQLiteDatabase db = dbHelper.getWritableDatabase(); //String sql = "insert to track(track_name,create_date,start_loc,end_loc) values(?,?,?,?)"; //db.exceSQL(sql,new Object[]{track.getTrack_name(),track.getCreate_date(),track.getStart_loc(),track.getEnd_loc()}); ContentValues values = new ContentValues(); values.put(DatabaseHelper.TRACK_NAME, track.getTrack_name()); values.put(DatabaseHelper.CREATE_DATE, track.getCreate_date()); values.put(DatabaseHelper.START_LOC, track.getStart_loc()); values.put(DatabaseHelper.END_LOC, track.getEnd_loc()); long id = db.insertOrThrow(DatabaseHelper.TABLE_TRACK, null, values); db.close(); return (int) id; } /** *更新终点地址 **/ //刚开始走的时候,起点和终点是同一个位置,当结束的时候,终点才变了,这个时候需要一个更新终点位置的函数 public void updateEndLoc(String endLoc, int id) { String sql = "update track set end_loc=? where _id=?"; SQLiteDatabase db = dbHelper.getWritableDatabase(); db.execSQL(sql, new Object[] {endLoc, id}); db.close(); } //添加路线跟踪明细 public void addTrackDetail(int tid, double lat, double lng ) { //tid为外键 SQLiteDatabase db= dbHelper.getWritableDatabase(); String sql = "insert into track_detail(tid,lat,lng) values(?,?,?)"; db.execSQL(sql, new Object[] {tid ,lat, lng}); db.close(); } //根据ID查询线路跟踪 public ArrayList getTrackDetails(int id) { String sql = "select _id,lat,lng from track_detail where tid=? order by _id desc"; ArrayList list = new ArrayList(); SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor c= db.rawQuery(sql, new String[] { String.valueOf(id) }); if (c != null) { TrackDetail detail = null; while (c.moveToNext()) { detail = new TrackDetail(c.getInt(0), c.getDouble(1),c.getDouble(2)); list.add(detail); } c.close(); } return list; } /** 查询所有线路 **/ public ArrayList getTracks() { ArrayList tracks = new ArrayList(); String sql = "select _id,track_name,create_date,start_loc,end_loc from track "; SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor c = db.rawQuery(sql, null); Track t = null; if (c != null) { while (c.moveToNext()) { t = new Track(c.getInt(0), c.getString(1), c.getString(2), c.getString(3), c.getString(4)); tracks.add(t); } c.close(); } db.close(); return tracks; } //根据ID删除线路跟踪 public void delTrack(int id) { SQLiteDatabase db = dbHelper.getWritableDatabase(); String sql1 = "delete from track where _id=?"; String sql2 = "delete from track_detail where tid=?"; try { db.beginTransaction(); db.execSQL(sql2, new Object[] { id }); db.execSQL(sql1, new Object[] { id }); db.setTransactionSuccessful(); } catch (Exception e) { e.printStackTrace(); } finally { db.endTransaction(); if( db != null) db.close(); } } }

再需要设置一个DateUtils类,用于日期转换:

package com.example.map_track; import java.text.SimpleDateFormat; import java.util.Date; /** *日期转换的工具类 **/ public class DateUtils { private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public static String toDate(Date date) { return sdf.format(date); } }

接下来就是核心的类MainActivity:

package com.example.map_track; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.content.DialogInterface; import android.content.pm.PackageManager; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.EditText; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; import com.baidu.location.BDAbstractLocationListener; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.mapapi.CoordType; import com.baidu.mapapi.SDKInitializer; import com.baidu.mapapi.map.BaiduMap; import com.baidu.mapapi.map.BitmapDescriptor; import com.baidu.mapapi.map.BitmapDescriptorFactory; import com.baidu.mapapi.map.InfoWindow; import com.baidu.mapapi.map.MapStatusUpdate; import com.baidu.mapapi.map.MapStatusUpdateFactory; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.Marker; import com.baidu.mapapi.map.MarkerOptions; import com.baidu.mapapi.map.MyLocationConfiguration; import com.baidu.mapapi.map.MyLocationData; import com.baidu.mapapi.map.Overlay; import com.baidu.mapapi.map.OverlayOptions; import com.baidu.mapapi.map.Polyline; import com.baidu.mapapi.map.PolylineOptions; import com.baidu.mapapi.model.LatLng; import com.baidu.mapapi.search.core.SearchResult; import com.baidu.mapapi.search.geocode.GeoCodeResult; import com.baidu.mapapi.search.geocode.GeoCoder; import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener; import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption; import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import android.os.Bundle; import android.widget.Toast; public class MainActivity extends AppCompatActivity { public static final int PLAYBACK_OVER = 1; private MapView mapView; private BaiduMap baiduMap; private LocationClient mLocationClient = null; //定义一个监听器对象 private MyLocationListener myLocationListener; private double currentLat, currentLng; //当前的经纬度 private String currentAddr; //当前所在的地址 private DatabaseAdapter dbAdapter; private GeoCoder geoCoder; private int currentTrackLineID; //当前跟踪的路线ID @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_main); mapView = (MapView) findViewById(R.id.bmapView); initBaiduMap(); //初始化地图,显示我的当前位置 dbAdapter = new DatabaseAdapter(this); } /** * 初始化百度地图 */ private void initBaiduMap() { baiduMap = mapView.getMap(); baiduMap.setMyLocationEnabled(true); //打开定位图层,允许定位 mLocationClient = new LocationClient(getApplicationContext()); //声明LocationClient类 myLocationListener = new MyLocationListener(); mLocationClient.registerLocationListener(myLocationListener); //注册监听函数 LocationClientOption option = new LocationClientOption(); option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy); //设置定位模式 option.setCoorType("bd09ll"); //返回的定位结果是百度经纬度,默认值gcj02 option.setScanSpan(5000); //设置发起定位请求的间隔为5000ms option.setIsNeedAddress(true); //返回的定位结果包含地址信息 option.setNeedDeviceDirect(true); //返回的定位结果包含手机机头方向 mLocationClient.setLocOption(option); mLocationClient.start(); //启动SDK定位 mLocationClient.requestLocation(); //发起定位请求 //用于转换地理编码的监听器 geoCoder = GeoCoder.newInstance(); geoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() { @Override public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) { if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) { //没有检索结果 } else { //获取地理编码结果 //System.out.println(result.getAddress()); currentAddr = result.getAddress(); //更新线路的结束位置 dbAdapter.updateEndLoc(currentAddr, currentTrackLineID); } } @Override public void onGetGeoCodeResult(GeoCodeResult arg0) { } }); } boolean flag = true; /** * 定位的监听 */ class MyLocationListener extends BDAbstractLocationListener { @Override public void onReceiveLocation(BDLocation location) { if (location != null && flag) { flag = false; currentLat = location.getLatitude(); //当前的纬度 currentLng = location.getLongitude(); //当前的经度 currentAddr = location.getAddrStr(); //当前位置的地址 //System.out.println("currentAddr=" + currentAddr); //构造我的当前位置信息 MyLocationData.Builder builder = new MyLocationData.Builder(); builder.latitude(location.getLatitude()); //设置纬度 builder.longitude(location.getLongitude()); //设置经度 builder.accuracy(location.getRadius()); //设置精度(半径) builder.direction(location.getDirection()); //设置方向 builder.speed(location.getSpeed()); //设置速度 MyLocationData locationData = builder.build(); //把我的位置信息设置到地图上 baiduMap.setMyLocationData(locationData); //配置我的位置 LatLng latlng = new LatLng(currentLat , currentLng); baiduMap.setMyLocationConfiguration(new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING,true,null)); //设置我的位置为地图的中心点,并且把地图放大16倍(缩放级别为3-20) baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngZoom(latlng, 20)); //System.out.println("地址:"+currentAddr+"---纬度:"+currentLat+"---经度:"+currentLng+"\n"); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } //功能菜单项 @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.mylocation : mylocation(); //我的位置 break; case R.id.start_track : startTrack(); //开始跟踪 break; case R.id.end_track : endTrack(); //结束跟踪 break; // case R.id.track_back : // trackBack(); //跟踪回放 // break; default: break; } return true; } /** * 结束跟踪 */ private void endTrack() { isTracking = false; //结束线程 Toast.makeText(MainActivity.this, "跟踪结束...", Toast.LENGTH_SHORT).show(); //转换地理编码,把最后的一个经纬度转换成地址(把经纬度转化成对应的地名地址,或者把地名地址转换成对应的经纬度) geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(new LatLng(currentLat, currentLng))); } /** * 我的位置 */ private void mylocation() { Toast.makeText(MainActivity.this, "正在定位中...", Toast.LENGTH_SHORT).show(); flag = true; baiduMap.clear(); //清除地图上自定义的图层 baiduMap.setMyLocationEnabled(true); mLocationClient.requestLocation(); //发起定位请求 } /** * 开始跟踪功能 */ private void startTrack() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("线路跟踪"); builder.setCancelable(true); final View view = getLayoutInflater().inflate(R.layout.add_track_line_dialog, null); builder.setView(view); builder.setPositiveButton("添加", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText et_track_name = (EditText) view.findViewById(R.id.editText1_track_name); String trackName = et_track_name.getText().toString(); System.out.println(trackName); createTrack(trackName); //创建线路跟踪 Toast.makeText(MainActivity.this, "跟踪开始...", Toast.LENGTH_SHORT).show(); } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.show(); } //创建一条线路跟踪 private void createTrack(String trackName) { Track track = new Track(); track.setTrack_name(trackName); track.setCreate_date(DateUtils.toDate(new Date())); //创建时间为当前的时间 track.setStart_loc(currentAddr); currentTrackLineID = dbAdapter.addTrack(track); //添加线路,返回线路ID dbAdapter.addTrackDetail(currentTrackLineID, currentLat, currentLng); //添加明细信息 // baiduMap.clear(); addOverlay(); list.add(new LatLng(currentLat, currentLng)); isTracking = true; //线程模拟的标记 System.out.println(list); new Thread(new TrackThread()).start(); } private boolean isTracking = false; //模拟跟踪的线程 class TrackThread implements Runnable { @Override public void run() { while (isTracking) { getLocation(); //获取模拟位置 dbAdapter.addTrackDetail(currentTrackLineID, currentLat, currentLng); addOverlay(); list.add(new LatLng(currentLat, currentLng)); drawLine(); //画线 System.out.println("drawLine"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } //用于存储两个相邻点的经纬度,再画线 private ArrayList list = new ArrayList(); //在地图上添加图层(线路的每一个点) private void addOverlay() { //--------添加一个标注覆盖物在当前位置-------- //构建Marker图标 baiduMap.setMyLocationEnabled(false); //关闭定位图层 BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher_round); //构建MakerOption,用于在地图上添加Marker LatLng latlng = new LatLng(currentLat, currentLng); OverlayOptions option = new MarkerOptions().position(latlng).icon(bitmap); //在地图上添加Marker,并显示 baiduMap.addOverlay(option); //把当前添加的地图位置作为地图的中心点 baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(latlng)); } //在两个点之间画线 private void drawLine() { OverlayOptions lineOptions = new PolylineOptions().points(list).color(0xFFFF0000); baiduMap.addOverlay(lineOptions); list.remove(0); //这里是为了移除两个点之间的前一个,因为在第一次画线之后,每一次画线都只需要添加第二个点,但是它这里是默认把两个点都添加进去,再画线,所以需要删除第一个点 } /** * 模拟位置,真实的时候应该使用监听器来获取地理位置信息 */ private void getLocation() { currentLat = currentLat + Math.random() / 1000; currentLng = currentLng + Math.random() / 1000; } @Override protected void onDestroy() { super.onDestroy(); //在Activity执行onResume时执行mMapView.onResume(),实现地图生命周期管理 mapView.onDestroy(); } @Override protected void onResume() { super.onResume(); //在Activity执行onResume时执行mMapView.onResume(),实现地图生命周期管理 mapView.onResume(); } @Override protected void onPause() { super.onPause(); //在Activity执行onPause时执行mMapView.onPause(),实现地图生命周期管理 mapView.onPause(); } }

这里要设置一个菜单项,当点击菜单项的时候,就可以弹出多个选项,实现对应的功能: 需要在app/res下创建一个menu文件夹,在menu下再创建一个main.xml文件;

MainActivity的大致执行过程: 首先就是SDK的初始化,然后初始化地图,也就是调用initBaiduMap方法,设置定位的模式,发起定位请求, 在请求的MyLocationListener回调方法里面,就可以得到经纬度信息,并显示在我的位置上; 接下来就是点击startTrack(),这是开始跟踪的方法,这里会调用add_track_line_dialog布局文件,所以还需要在res/layout文件夹中创建一个add_track_line_dialog.xml文件:

接下来会调用createTrack方法,这是一个创建线路跟踪的方法;然后会去调用addOverlay方法,这个是添加一个标注覆盖物在当前位置,每在线路上画一个线段的时候,就把当前的经纬度用一个覆盖物标注出来; 再创建一个模拟线程TrackThread(),这时候会去调用getLocation()方法,这里是采取的模拟位置,即利用当前位置和一个随机数来确定一个新的经纬度; 确定好新的位置之后,就调用画线方法drawLine(),把两个点用线连接起来;

(其他的功能还没有实现,例如跟踪回放,这个在类中已经写好了,剩下的就是需要在MainActivity中添加对应的回调函数) 我这里的线路,是采用的模拟线路,还需要把它给改好,改成监听手机内部GPS的方法,大概就可以拿着手机到外面实际测试一下是否可行了

这是刚开始学的,有什么错误的地方还需要大佬们帮忙指出来呀



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭