- 浏览: 131363 次
- 性别:
- 来自: Ottawa
最新评论
-
God一冰魄:
jcs130 写道thebest 写道感觉保存JSON数据会很 ...
MongoDB 3.0 速上手教程(JAVA) -
xiuxiuxiu:
膨胀腐蚀大概是什么意思,能留个微信吗
结合OPENNI2,Aruco与OPENCV进行视觉定位 -
jcs130:
thebest 写道感觉保存JSON数据会很浪费空间啊。如果每 ...
MongoDB 3.0 速上手教程(JAVA) -
thebest:
感觉保存JSON数据会很浪费空间啊。如果每个记录的标签都是重复 ...
MongoDB 3.0 速上手教程(JAVA) -
jcs130:
liuyar 写道更新很快嘛。加油。谢谢啦,不过接下来要继续研 ...
WiFi遥控小车(三):搭建嵌入式Linux开发环境
前一阵子我们物联网编程课老师要求班上每个人都要做一个地图应用,说是要利用起来安卓的GPS信息什么什么的……不过昨晚后觉得这根本就是在学Android开发嘛。。。
之前接触过一点安卓,也有JAVA基础,所以这次做东西还是比较快的,虽然已钱没有做过类似应用(其实都没有做过什么安卓应用),两天下来差不多把老师的要求都实现了,今天也顺利通过验收了。地图API我选的是百度的,支持国产~哈~全部的文件上传到附件了,有需要的同学可以下载~~
先看下Logo~哈~
按照百度地图开发者文档的指示一步一步做还是很顺利的~里面说的很清楚,我就直接贴代码了:
主界面
package com.micro.mymaps; import android.app.AlertDialog; import android.content.Intent; import android.location.Location; import android.os.Bundle; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.widget.Button; import android.widget.Toast; import android.widget.ToggleButton; import com.baidu.mapapi.BMapManager; import com.baidu.mapapi.GeoPoint; import com.baidu.mapapi.LocationListener; import com.baidu.mapapi.MKLocationManager; import com.baidu.mapapi.MapActivity; import com.baidu.mapapi.MapController; import com.baidu.mapapi.MapView; import com.baidu.mapapi.MyLocationOverlay; public class MyMapActivity extends MapActivity { public static BMapManager mBMapMan = null; private MKLocationManager mLocationManager; private static MyLocationOverlay myLocationOverlay; private MapController mMapController; // 位置变化监听器 private MyLocationListener mllis; static MapView mMapView; // 卫星视图、交通视图按键 private ToggleButton WX_But, JT_But, FL_But; // 返回自己位置按键 private Button Return_But; // 按键监听器 private OnClickListener wx_but_lis; private OnClickListener jt_but_lis; private OnClickListener fl_but_lis; private OnClickListener Re_Lis; // 我的位置 protected static GeoPoint myLocation; // 地图是否随位置变化而变化 private boolean isFollow = false; // 是否是第一次定位 private boolean isFirst = true; // 退出事件监听器 private ExitButLinstener exitlis; // 标注点的数量 private int Pnum = 0; private boolean ceFlag = false; protected GeoPoint FirP; protected GeoPoint SecP; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* * 初始化地图 */ mBMapMan = new BMapManager(getApplication()); mBMapMan.init("百度KEY", null);// KEY super.initMapActivity(mBMapMan); mMapView = (MapView) findViewById(R.id.bmapsView); // 初始化位置监听器 mllis = new MyLocationListener(); mLocationManager = mBMapMan.getLocationManager(); // 注册位置更新事件 mLocationManager.requestLocationUpdates(mllis); // 优先使用用GPS定位 mLocationManager .enableProvider((int) MKLocationManager.MK_GPS_PROVIDER); mLocationManager.setNotifyInternal(3, 1); // 优先使用网络来定位 // mLocationManager.enableProvider((int)MKLocationManager.MK_NETWORK_PROVIDER); // 添加定位图层 myLocationOverlay = new MyLocationOverlay(this, mMapView); // 注册GPS位置更新的事件,让地图能实时显示当前位置 myLocationOverlay.enableMyLocation(); // 开启磁场感应传感器 myLocationOverlay.enableCompass(); mMapView.getOverlays().add(myLocationOverlay); // 设置在缩放动画过程中也显示overlay,默认为不绘制 mMapView.setDrawOverlayWhenZooming(true);// 在缩放的时候显示覆盖物 mMapView.setBuiltInZoomControls(true); // 设置启用内置的缩放控件 mMapController = mMapView.getController(); // 得到mMapView的控制权,可以用它控制和驱动平移和缩放 // GeoPoint point = new GeoPoint((int) (39.915 * 1E6), // (int) (116.404 * 1E6)); // 用给定的经纬度构造一个GeoPoint,单位是微度 (度 * 1E6) 天,安。门坐标 mMapController.setZoom(12); // 设置地图zoom级别 mMapView.setSatellite(false);// 设置卫星视图 mMapView.setTraffic(false);// 设置交通状况视图 // mMapView.getOverlays().add(new MyOverlay());// 在地图上添加自己设置的覆盖物 // 初始化按键及监听器 WX_But = (ToggleButton) findViewById(R.id.WX_But); JT_But = (ToggleButton) findViewById(R.id.JT_But); FL_But = (ToggleButton) findViewById(R.id.FL_But); Return_But = (Button) findViewById(R.id.ReturnMyPlace); // 卫星视图按键监听器 wx_but_lis = new OnClickListener() { public void onClick(View v) { if (WX_But.isChecked()) { mMapView.setSatellite(true); } else { mMapView.setSatellite(false); } } }; WX_But.setOnClickListener(wx_but_lis); // 交通视图按键监听器 jt_but_lis = new OnClickListener() { public void onClick(View v) { if (JT_But.isChecked()) { mMapView.setTraffic(true); } else { mMapView.setTraffic(false); } } }; JT_But.setOnClickListener(jt_but_lis); // 地图跟随按键监听器 fl_but_lis = new OnClickListener() { public void onClick(View v) { if (JT_But.isChecked()) { isFollow = true; } else { isFollow = false; } } }; FL_But.setOnClickListener(fl_but_lis); // 返回我的位置按钮监听器 Re_Lis = new OnClickListener() { public void onClick(View v) { if (myLocation == null) { DisplayToast("暂未获取到位置信息~"); } else { mMapController.setZoom(15); mMapController.animateTo(myLocation); // 设置地图中心点 } } }; Return_But.setOnClickListener(Re_Lis); exitlis = new ExitButLinstener(); mMapView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if (ceFlag) if (event.getAction() == MotionEvent.ACTION_DOWN) { if (Pnum == 0) { System.out.println("第一次"); FirP = mMapView.getProjection().fromPixels( (int) event.getX(), (int) event.getY()); mMapView.getOverlays().add(new PointOverLay(FirP)); Pnum++; } else if (Pnum == 1) { System.out.println("第二次"); SecP = mMapView.getProjection().fromPixels( (int) event.getX(), (int) event.getY()); mMapView.getOverlays().add(new PointOverLay(SecP)); mMapView.getOverlays().add( new LineOverLay(FirP, SecP)); Distence dis = new Distence(); double dist = dis.GetShortDistance( FirP.getLongitudeE6(), FirP.getLatitudeE6(), SecP.getLongitudeE6(), SecP.getLatitudeE6()); DisplayToast("距离为" + ((int) dist / 1000000) + "米"); Pnum++; } else { DisplayToast("请清空后继续测量"); } } return false; } }); } @Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } @Override protected void onDestroy() { if (mBMapMan != null) { mBMapMan.destroy(); mBMapMan = null; } super.onDestroy(); } @Override protected void onPause() { if (mBMapMan != null) { // 移除listener mBMapMan.getLocationManager().removeUpdates(mllis); mBMapMan.stop(); } super.onPause(); } @Override protected void onResume() { if (mBMapMan != null) { // 注册Listener mBMapMan.getLocationManager().requestLocationUpdates(mllis); mBMapMan.start(); } super.onResume(); } /** * 根据MyLocationOverlay配置的属性确定是否在地图上显示当前位置 */ @Override protected boolean isLocationDisplayed() { return myLocationOverlay.isMyLocationEnabled(); } // @Override // public boolean onCreateOptionsMenu(Menu menu) { // // 调用父类方法来加入系统菜单 // // 虽然目前android还没有系统菜单,但是为了兼容到以后的版本,最好加上 // super.onCreateOptionsMenu(menu); // // // 添加菜单项(多种方式) // // 1.直接指定标题 // menu.add("菜单项1"); // // 2.通过资源指定标题 // menu.add(R.string.jiaotong); // // 3.显示指定菜单项的组号、ID、排序号、标题 // menu.add(1, // 组号 // Menu.FIRST, // 唯一的ID号 // Menu.FIRST, // 排序号 // "菜单项3"); // 标题 // // // 如果希望显示菜单,请返回true // return true; // } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); // 添加4个菜单项,分成2组 int group1 = 1; int gourp2 = 2; int gourp3 = 3; menu.add(group1, 1, 1, "地图查询"); menu.add(group1, 2, 2, "线路搜索"); menu.add(gourp2, 3, 3, "距离测量"); menu.add(gourp2, 4, 4, "地图复位"); menu.add(gourp3, 5, 5, "关于软件"); menu.add(gourp3, 6, 6, "退出应用"); // 显示菜单 return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { Intent intent = null; switch (item.getItemId()) { // 响应每个菜单项(通过菜单项的ID) case 1: // do something here // DisplayToast("地图查询"); intent = null; intent = new Intent(MyMapActivity.this, SearchActivity.class); this.startActivity(intent); break; case 2: // do something here // DisplayToast("线路搜索"); intent = null; intent = new Intent(MyMapActivity.this, RoutePlan.class); this.startActivity(intent); break; case 3: // do something here // DisplayToast("距离测量"); clearMap(); Pnum = 0; ceFlag = true; break; case 4: // do something here DisplayToast("地图复位"); clearMap(); JT_But.setChecked(false); mMapView.setTraffic(false); WX_But.setChecked(false); mMapView.setSatellite(false); FL_But.setChecked(false); isFollow = false; mMapController.setZoom(15); if (myLocation != null) mMapController.animateTo(myLocation); Pnum = 0; ceFlag = false; break; case 5: // do something here DisplayToast("关于软件"); new AlertDialog.Builder(this).setTitle("关于软件") .setMessage("制作:中南大学——李众力\n谢谢使用本软件~O(∩_∩)O~") .setPositiveButton("确定", null).show(); break; case 6: // do something here // DisplayToast("退出应用"); new AlertDialog.Builder(this).setTitle("确认退出") .setMessage("是否退出本应用?").setPositiveButton("是", exitlis) .setNegativeButton("否", null).show(); break; default: // 对没有处理的事件,交给父类来处理 return super.onOptionsItemSelected(item); } // 返回true表示处理完菜单项的事件,不需要将该事件继续传播下去了 return true; } // 显示提示 public void DisplayToast(String str) { Toast.makeText(this, str, Toast.LENGTH_SHORT).show(); } // 将当前位置转换成地理坐标点 public GeoPoint Lo2Gp(Location location) { if (location == null) return null; return new GeoPoint((int) (location.getLatitude() * 1000000), (int) (location.getLongitude() * 1000000)); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub switch (keyCode) { case KeyEvent.KEYCODE_BACK: AlertDialog.Builder build = new AlertDialog.Builder(this); build.setTitle("注意").setMessage("确定要退出吗?") .setPositiveButton("确定", exitlis) .setNegativeButton("取消", null).show(); break; default: break; } return false; // return super.onKeyDown(keyCode, event); } // 清除多余overlay方法 public static void clearMap() { mMapView.getOverlays().clear(); mMapView.getOverlays().add(myLocationOverlay); } /** * 内部类,实现位置变化监听 * * @author Micro * */ class MyLocationListener implements LocationListener { /** * 位置变化监听器 */ public void onLocationChanged(Location location) { System.out.println("位置变化!\n"); if (location != null) { // 将当前位置转换成地理坐标点 final GeoPoint pt = new GeoPoint( (int) (location.getLatitude() * 1000000), (int) (location.getLongitude() * 1000000)); myLocation = pt; if (isFirst) { mMapController.setZoom(15); mMapController.animateTo(myLocation); isFirst = false; } if (isFollow) { mMapController.animateTo(myLocation); } } } } }
界面的xml文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <com.baidu.mapapi.MapView android:id="@+id/bmapsView" android:layout_width="fill_parent" android:layout_height="400dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:clickable="true" > </com.baidu.mapapi.MapView> <Button android:id="@+id/ReturnMyPlace" style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:text="@string/returnMyP" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" > <ToggleButton android:id="@+id/JT_But" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="30dp" android:textOff="@string/jiaotong" android:textOn="@string/jiaotong" /> <ToggleButton android:id="@+id/WX_But" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/JT_But" android:layout_alignBottom="@+id/JT_But" android:layout_centerHorizontal="true" android:textOff="@string/weixing" android:textOn="@string/weixing" /> <ToggleButton android:id="@+id/FL_But" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/WX_But" android:layout_alignBottom="@+id/WX_But" android:layout_marginLeft="28dp" android:layout_toRightOf="@+id/WX_But" android:textOff="@string/Follow" android:textOn="@string/Follow" /> </RelativeLayout> </LinearLayout>
因为响应按钮操作的OnClickLinstener和View里面的方法名字一样,我救另外建了一个类来实现监听方法:
退出按钮:
package com.micro.mymaps; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; public class ExitButLinstener implements OnClickListener { @Override public void onClick(DialogInterface dialog, int which) { System.exit(0); } }
搜索界面:我把MapView设置为了静态的全局变量,搜索结果显示在主界面上,另外设这个这个界面是透明的,这样看起来就像是之前被隐藏起来了一样,另外这个界面是通过百度提供的Demo修改来的,其中有个Suggestion的方法我没有用到,但是也没删除,而是在界面的XML文件里把相应的组件隐藏起来了,这样一后可以接着学~
java文件:
package com.micro.mymaps; import com.baidu.mapapi.MKAddrInfo; import com.baidu.mapapi.MKBusLineResult; import com.baidu.mapapi.MKDrivingRouteResult; import com.baidu.mapapi.MKPoiResult; import com.baidu.mapapi.MKSearch; import com.baidu.mapapi.MKSearchListener; import com.baidu.mapapi.MKSuggestionResult; import com.baidu.mapapi.MKTransitRouteResult; import com.baidu.mapapi.MKWalkingRouteResult; import com.baidu.mapapi.PoiOverlay; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.Toast; public class SearchActivity extends Activity { Button mBtnSearch = null; // 搜索按钮 Button mSuggestionSearch = null; // suggestion搜索 ListView mSuggestionList = null; public static String mStrSuggestions[] = {}; MKSearch mSearch = null; // 搜索模块,也可去掉地图模块独立使用 protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.searchact); // 初始化搜索模块,注册事件监听 mSearch = new MKSearch(); mSearch.init(MyMapActivity.mBMapMan, new MKSearchListener() { public void onGetPoiResult(MKPoiResult res, int type, int error) { // 错误号可参考MKEvent中的定义 if (error != 0 || res == null) { Toast.makeText(SearchActivity.this, "抱歉,未找到结果", Toast.LENGTH_LONG).show(); return; } // 将地图移动到第一个POI中心点 if (res.getCurrentNumPois() > 0) { // 将poi结果显示到地图上 PoiOverlay poiOverlay = new PoiOverlay(SearchActivity.this, MyMapActivity.mMapView); poiOverlay.setData(res.getAllPoi()); MyMapActivity.clearMap(); MyMapActivity.mMapView.getOverlays().add(poiOverlay); MyMapActivity.mMapView.invalidate(); MyMapActivity.mMapView.getController().setCenter( res.getPoi(0).pt); closeit(); } else if (res.getCityListNum() > 0) { String strInfo = "在"; for (int i = 0; i < res.getCityListNum(); i++) { strInfo += res.getCityListInfo(i).city; strInfo += ","; } strInfo += "找到结果"; Toast.makeText(SearchActivity.this, strInfo, Toast.LENGTH_LONG).show(); } } public void onGetDrivingRouteResult(MKDrivingRouteResult res, int error) { } public void onGetTransitRouteResult(MKTransitRouteResult res, int error) { } public void onGetWalkingRouteResult(MKWalkingRouteResult res, int error) { } public void onGetAddrResult(MKAddrInfo res, int error) { } public void onGetBusDetailResult(MKBusLineResult result, int iError) { } public void onGetSuggestionResult(MKSuggestionResult res, int arg1) { // TODO Auto-generated method stub if (arg1 != 0 || res == null) { Toast.makeText(SearchActivity.this, "抱歉,未找到结果", Toast.LENGTH_LONG).show(); return; } int nSize = res.getSuggestionNum(); mStrSuggestions = new String[nSize]; for (int i = 0; i < nSize; i++) { mStrSuggestions[i] = res.getSuggestion(i).city + res.getSuggestion(i).key; } ArrayAdapter<String> suggestionString = new ArrayAdapter<String>( SearchActivity.this, android.R.layout.simple_list_item_1, mStrSuggestions); mSuggestionList.setAdapter(suggestionString); Toast.makeText(SearchActivity.this, "suggestion callback", Toast.LENGTH_LONG).show(); } }); mSuggestionList = (ListView) findViewById(R.id.listView1); // 设定搜索按钮的响应 mBtnSearch = (Button) findViewById(R.id.search); OnClickListener clickListener = new OnClickListener() { public void onClick(View v) { SearchButtonProcess(v); } }; mBtnSearch.setOnClickListener(clickListener); // 设定suggestion响应 mSuggestionSearch = (Button) findViewById(R.id.suggestionsearch); OnClickListener clickListener1 = new OnClickListener() { public void onClick(View v) { SuggestionSearchButtonProcess(v); } }; mSuggestionSearch.setOnClickListener(clickListener1); } void SearchButtonProcess(View v) { if (mBtnSearch.equals(v)) { // Intent intent = null; // intent = new Intent(SearchActivity.this, MyMapActivity.class); // this.startActivity(intent); EditText editCity = (EditText) findViewById(R.id.city); EditText editSearchKey = (EditText) findViewById(R.id.searchkey); mSearch.poiSearchInCity(editCity.getText().toString(), editSearchKey.getText().toString()); } } void SuggestionSearchButtonProcess(View v) { EditText editSearchKey = (EditText) findViewById(R.id.suggestionkey); mSearch.suggestionSearch(editSearchKey.getText().toString()); } private void closeit() { this.finish(); } @Override protected void onPause() { MyMapActivity.mBMapMan.stop(); super.onPause(); } @Override protected void onResume() { MyMapActivity.mBMapMan.start(); super.onResume(); } }
地图查询XML文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:visibility="visible" tools:ignore="HardcodedText,TextFields" > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/translucent_background" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="在" > </TextView> <EditText android:id="@+id/city" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="北京" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="市内找" > </TextView> <EditText android:id="@+id/searchkey" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="清华大学" /> <Button android:id="@+id/search" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="搜索" /> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/translucent_background" android:orientation="horizontal" android:visibility="invisible" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="关键词" > </TextView> <EditText android:id="@+id/suggestionkey" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="清华大学" /> <Button android:id="@+id/suggestionsearch" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="关键词搜索" /> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/translucent_background" android:visibility="invisible" > </ListView> </LinearLayout> </LinearLayout>
下面是路线规划界面,也是直接从百度提供的Demo修改而来,这个功能有缺陷,比如说当起点和终点名称有歧义的时候就不能返回查询线路信息,但是由于时间比较紧,我救只把界面写出来了,相应的功能还没实现,接下来再做吧。
java代码:
package com.micro.mymaps; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.Toast; import com.baidu.mapapi.MKAddrInfo; import com.baidu.mapapi.MKBusLineResult; import com.baidu.mapapi.MKDrivingRouteResult; import com.baidu.mapapi.MKGeocoderAddressComponent; import com.baidu.mapapi.MKPlanNode; import com.baidu.mapapi.MKPoiResult; import com.baidu.mapapi.MKSearch; import com.baidu.mapapi.MKSearchListener; import com.baidu.mapapi.MKSuggestionResult; import com.baidu.mapapi.MKTransitRouteResult; import com.baidu.mapapi.MKWalkingRouteResult; import com.baidu.mapapi.MapActivity; import com.baidu.mapapi.RouteOverlay; import com.baidu.mapapi.TransitOverlay; public class RoutePlan extends MapActivity { private Button mBtnDrive = null; // 驾车搜索 private Button mBtnTransit = null; // 公交搜索 private Button mBtnWalk = null; // 步行搜索 private MKSearch mSearch = null; // 搜索模块,也可去掉地图模块独立使用 private static String MyCity = "长沙市";// 默认为长沙市 private EditText editSt;// 输入起点的输入框 private EditText editEn;// 输入终点的输入框 Button ckStr;// 确认起点按钮 Button ckEnd;// 确认起点按钮 ListView list;// 如果结果不唯一,显示结果 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.routeplan); // 初始化搜索模块,注册事件监听 mSearch = new MKSearch(); mSearch.init(MyMapActivity.mBMapMan, new MKSearchListener() { public void onGetDrivingRouteResult(MKDrivingRouteResult res, int error) { // 错误号可参考MKEvent中的定义 if (error != 0 || res == null) { // if (error == 4/* 线路起点终点有歧义 */) { // Toast.makeText(RoutePlan.this, "线路起点终点有歧义", // Toast.LENGTH_SHORT).show(); // } // if (res == null) Toast.makeText(RoutePlan.this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show(); return; } RouteOverlay routeOverlay = new RouteOverlay(RoutePlan.this, MyMapActivity.mMapView); // 此处仅展示一个方案作为示例 routeOverlay.setData(res.getPlan(0).getRoute(0)); MyMapActivity.clearMap(); MyMapActivity.mMapView.getOverlays().add(routeOverlay); MyMapActivity.mMapView.invalidate(); MyMapActivity.mMapView.getController().animateTo( res.getStart().pt); } public void onGetTransitRouteResult(MKTransitRouteResult res, int error) { if (error != 0 || res == null) { // if (error == 4/* 线路起点终点有歧义 */) { // Toast.makeText(RoutePlan.this, "线路起点终点有歧义", // Toast.LENGTH_SHORT).show(); // } // if (res == null) Toast.makeText(RoutePlan.this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show(); return; } TransitOverlay routeOverlay = new TransitOverlay( RoutePlan.this, MyMapActivity.mMapView); // 此处仅展示一个方案作为示例 routeOverlay.setData(res.getPlan(0)); MyMapActivity.clearMap(); MyMapActivity.mMapView.getOverlays().add(routeOverlay); MyMapActivity.mMapView.invalidate(); MyMapActivity.mMapView.getController().animateTo( res.getStart().pt); } public void onGetWalkingRouteResult(MKWalkingRouteResult res, int error) { if (error != 0 || res == null) { // if (error == 4/* 线路起点终点有歧义 */) { // Toast.makeText(RoutePlan.this, "线路起点终点有歧义", // Toast.LENGTH_SHORT).show(); // } // if (res == null) Toast.makeText(RoutePlan.this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show(); return; } RouteOverlay routeOverlay = new RouteOverlay(RoutePlan.this, MyMapActivity.mMapView); // 此处仅展示一个方案作为示例 routeOverlay.setData(res.getPlan(0).getRoute(0)); MyMapActivity.clearMap(); MyMapActivity.mMapView.getOverlays().add(routeOverlay); MyMapActivity.mMapView.invalidate(); MyMapActivity.mMapView.getController().animateTo( res.getStart().pt); } public void onGetAddrResult(MKAddrInfo res, int error) { MKGeocoderAddressComponent kk = res.addressComponents; MyCity = kk.city; Toast.makeText(RoutePlan.this, "所在城市:" + MyCity, Toast.LENGTH_SHORT).show(); } public void onGetPoiResult(MKPoiResult res, int arg1, int arg2) { } public void onGetBusDetailResult(MKBusLineResult result, int iError) { } public void onGetSuggestionResult(MKSuggestionResult res, int arg1) { // TODO Auto-generated method stub } }); // 查询当先所在城市 mSearch.reverseGeocode(MyMapActivity.myLocation); // 设定搜索按钮的响应 mBtnDrive = (Button) findViewById(R.id.drive); mBtnTransit = (Button) findViewById(R.id.transit); mBtnWalk = (Button) findViewById(R.id.walk); OnClickListener clickListener = new OnClickListener() { public void onClick(View v) { SearchButtonProcess(v); } }; mBtnDrive.setOnClickListener(clickListener); mBtnTransit.setOnClickListener(clickListener); mBtnWalk.setOnClickListener(clickListener); ckStr = (Button) findViewById(R.id.strCon); ckEnd = (Button) findViewById(R.id.endCon); list = (ListView) findViewById(R.id.listView1); // 处理搜索按钮响应 editSt = (EditText) findViewById(R.id.start); editEn = (EditText) findViewById(R.id.end); } private void SearchButtonProcess(View v) { // 对起点终点的name进行赋值,也可以直接对坐标赋值,赋值坐标则将根据坐标进行搜索 MKPlanNode stNode = new MKPlanNode(); String stName = editSt.getText().toString(); if (stName.equals("")) { if (MyMapActivity.myLocation == null) { Toast.makeText(RoutePlan.this, "暂未获取到位置信息~", Toast.LENGTH_SHORT) .show(); return; } stNode.pt = MyMapActivity.myLocation; Toast.makeText(RoutePlan.this, "以自身作为起点", Toast.LENGTH_SHORT) .show(); } else { stNode.name = stName; } String enName = editEn.getText().toString(); if (enName.equals("")) { Toast.makeText(RoutePlan.this, "请输入目的地", Toast.LENGTH_SHORT).show(); return; } MKPlanNode enNode = new MKPlanNode(); enNode.name = enName; // 实际使用中请对起点终点城市进行正确的设定 if (mBtnDrive.equals(v)) { mSearch.drivingSearch(MyCity, stNode, MyCity, enNode); } else if (mBtnTransit.equals(v)) { mSearch.transitSearch(MyCity, stNode, enNode); } else if (mBtnWalk.equals(v)) { mSearch.walkingSearch(MyCity, stNode, MyCity, enNode); } Toast.makeText(RoutePlan.this, MyCity + "从" + editSt.getText() + "到" + editEn.getText(), Toast.LENGTH_SHORT).show(); } @Override protected void onPause() { MyMapActivity.mBMapMan.stop(); super.onPause(); } @Override protected void onResume() { MyMapActivity.mBMapMan.start(); super.onResume(); } @Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } /** * 查询起点和终点,确定线路起终点唯一 */ class CkStrListener implements OnClickListener { @Override public void onClick(View v) { Button but = (Button) v; if (but.getText().equals("确认起点")) { } } } }
路线规划XML文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" tools:ignore="TextFields,HardcodedText" > <LinearLayout android:id="@+id/LinearLayout1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/translucent_background" > <TableRow android:id="@+id/tableRow1" android:layout_width="wrap_content" android:layout_height="match_parent" > </TableRow> <EditText android:id="@+id/start" android:layout_width="240dp" android:layout_height="wrap_content" android:ems="10" android:hint="起点(默认为用户当前位置)" tools:ignore="HardcodedText" > <requestFocus /> </EditText> <Button android:id="@+id/strCon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="确认起点" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/translucent_background" > <EditText android:id="@+id/end" android:layout_width="240dp" android:layout_height="match_parent" android:ems="10" android:hint="终点" tools:ignore="HardcodedText" /> <Button android:id="@+id/endCon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="确认终点" /> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/translucent_background" android:orientation="horizontal" > <Button android:id="@+id/drive" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="驾车搜索" /> <Button android:id="@+id/transit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="公交搜索" /> <Button android:id="@+id/walk" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="步行搜索" /> </LinearLayout> <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/translucent_background" > </ListView> </LinearLayout>
最后一个功能就是测距,百度也提供了示例代码:
package com.micro.mymaps; public class Distence { static double DEF_PI = 3.14159265359; // PI static double DEF_2PI = 6.28318530712; // 2*PI static double DEF_PI180 = 0.01745329252; // PI/180.0 static double DEF_R = 6370693.5; // radius of earth public double GetShortDistance(double lon1, double lat1, double lon2, double lat2) { double ew1, ns1, ew2, ns2; double dx, dy, dew; double distance; // 角度转换为弧度 ew1 = lon1 * DEF_PI180; ns1 = lat1 * DEF_PI180; ew2 = lon2 * DEF_PI180; ns2 = lat2 * DEF_PI180; // 经度差 dew = ew1 - ew2; // 若跨东经和西经180 度,进行调整 if (dew > DEF_PI) dew = DEF_2PI - dew; else if (dew < -DEF_PI) dew = DEF_2PI + dew; dx = DEF_R * Math.cos(ns1) * dew; // 东西方向长度(在纬度圈上的投影长度) dy = DEF_R * (ns1 - ns2); // 南北方向长度(在经度圈上的投影长度) // 勾股定理求斜边长 distance = Math.sqrt(dx * dx + dy * dy); return distance; } public double GetLongDistance(double lon1, double lat1, double lon2, double lat2) { double ew1, ns1, ew2, ns2; double distance; // 角度转换为弧度 ew1 = lon1 * DEF_PI180; ns1 = lat1 * DEF_PI180; ew2 = lon2 * DEF_PI180; ns2 = lat2 * DEF_PI180; // 求大圆劣弧与球心所夹的角(弧度) distance = Math.sin(ns1) * Math.sin(ns2) + Math.cos(ns1) * Math.cos(ns2) * Math.cos(ew1 - ew2); // 调整到[-1..1]范围内,避免溢出 if (distance > 1.0) distance = 1.0; else if (distance < -1.0) distance = -1.0; // 求大圆劣弧长度 distance = DEF_R * Math.acos(distance); return distance; } double mLat1 = 39.90923; // point1纬度 double mLon1 = 116.357428; // point1经度 double mLat2 = 39.90923;// point2纬度 double mLon2 = 116.397428;// point2经度 double distance = GetShortDistance(mLon1, mLat1, mLon2, mLat2); }
然后在主界面设置一个标志变量,当选择测量距离的时候监听触摸屏幕事件,当第一次触摸的时候画一个五角星并记录该点的地理坐标,第二次触摸则画一条线加一个五角星,并计算两点间的距离,现在计算出来的距离貌似偏差有点大,可能是数据处理的不对吧。下面是自己重写的两个Overlay:
package com.micro.mymaps; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Point; import com.baidu.mapapi.GeoPoint; import com.baidu.mapapi.MapView; import com.baidu.mapapi.Overlay; public class PointOverLay extends Overlay { GeoPoint geoPoint; Paint paint = new Paint(); public PointOverLay(GeoPoint geoPoint){ this.geoPoint=geoPoint; } @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { Point point = mapView.getProjection().toPixels(geoPoint, null); canvas.drawText("★", point.x, point.y, paint); } }
package com.micro.mymaps;
import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Point; import com.baidu.mapapi.GeoPoint; import com.baidu.mapapi.MapView; import com.baidu.mapapi.Overlay; public class LineOverLay extends Overlay { GeoPoint geoPoint1; GeoPoint geoPoint2; Paint paint = new Paint(); public LineOverLay(GeoPoint geoPoint1, GeoPoint geoPoint2) { this.geoPoint1 = geoPoint1; this.geoPoint2 = geoPoint2; } @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { Point point1 = mapView.getProjection().toPixels(geoPoint1, null); Point point2 = mapView.getProjection().toPixels(geoPoint2, null); canvas.drawLine(point1.x, point1.y, point2.x, point2.y, paint); } }
两天时间几乎都在搞这个,感觉利用API做程序还是挺简单的,就是写界面什么的比较麻烦,主要还是要加上自己的创意吧~
发表评论
-
MongoDB 3.0 速上手教程(JAVA)
2015-08-18 08:34 18535最近做项目想用一下NoSQL数据库,由于项目需要保存大量的 ... -
WiFi遥控小车(四):简单直流电机驱动及UDP通信程序
2012-10-22 20:12 3112之前说过只要能控制高低电平就可以控制电机的正反转,我想通过修 ... -
WiFi遥控小车(三):搭建嵌入式Linux开发环境
2012-10-22 00:21 5207我是在暑假前买的开发板,本来想这暑假就开始学,但是 ... -
WiFi遥控小车(三):搭建嵌入式Linux开发环境
2012-10-22 00:08 3我是在暑假前买的开发板,本来想这暑假就开始学,但是跟着 ... -
WiFi遥控小车(二):选择学习&开发平台
2012-10-21 01:50 5005前面说到我想自己 ... -
WiFi遥控小车(一):基于wicam模块的小车
2012-10-20 13:20 9040小的时候很喜欢玩四驱车,看动画片《四驱兄弟2》 ... -
推荐几个前端开发很容易上手的软件~~
2012-08-07 23:13 1245今天终于做了WEB阶段的项目总结~我们的微博项目差不多的基本 ... -
想把网页做漂亮了真不容易~美工们~你们辛苦了——菜鸟学WEB有感
2012-07-22 03:28 2816这几天学Web,我们小组 ... -
我就是喜欢界面~~可视化打印哈弗曼树(二叉树)~JAVA实现
2012-07-09 05:03 6257课程设计有一个哈夫曼编码解码的题,其他的一般要求还好说~就是最 ... -
探究C语言中的getchar()与getch()的区别
2012-03-10 14:58 1728最近大家 ... -
菜鸟说:哈夫曼压缩的解压缩~~(附源代码)
2011-08-13 10:37 1228解压就是压缩的逆过程……真是说起来容易做起来难啊…… ... -
菜鸟说:哈夫曼压缩的问题
2011-08-12 01:46 1171搞了一天终于把哈夫曼压缩搞好了,自己想了很多,也参照了别人的代 ... -
菜鸟说:哈夫曼树及哈弗曼编码
2011-08-11 14:52 1176终于把哈夫曼树及哈弗曼编码弄好了~ 哈夫曼树就是最优二 ... -
初识“树”——搜索二叉树
2011-08-10 23:51 1072今天第一次接触了“树 ... -
菜鸟说java里的链表(一)
2011-08-10 00:52 1535先说点题外话: 不知道为什么,我们学校还有别的好多学校的软件 ...
相关推荐
在基于百度地图API的Web开发中,开发者可以利用Baidu Maps JavaScript API来构建丰富的地图应用。这个API提供了各种功能,包括地图展示、定位、标注、路线规划、地理编码、覆盖物管理等,使得Web应用程序能够无缝...
**周边搜索**是基于百度地图API实现的另一项重要功能。开发者可以通过关键词搜索,获取指定范围内的餐馆、酒店、公交站等地点信息,为用户提供生活服务推荐。同时,API还支持自定义POI(Point of Interest)数据,...
使用百度地图API(源代码+截图)微信小程序demo:精品天气预报;使用百度地图API(源代码+截图)微信小程序demo:精品天气预报;使用百度地图API(源代码+截图)微信小程序demo:精品天气预报;使用百度地图API(源代码+...
基于百度地图API的GPS定位系统简介 本文主要介绍了基于百度地图API的GPS定位系统的简介,涵盖了安卓系统和百度地图API的概述、GPS定位系统的意义和前景。本文首先介绍了安卓系统的发展历史和特点,包括其开源性和可...
百度地图API是为开发者免费提供的一套基于百度地图服务的应用接口,包括JavaScript API、Web服务API、Android SDK、iOS SDK、定位SDK、车联网API、LBS云等多种开发工具与服务,提供基本地图展现、搜索、定位、逆/...
Android平台下基于百度地图API的地图导航设计 在本文中,我们将讨论基于百度地图API的地图导航设计在Android平台下的实现。该设计主要涉及到地图搜索、位置定位、附近搜索、路线规划、公交线路查询、GPS导航等功能...
标题中的“一款基于百度地图API做成的地区地图”揭示了这个项目的核心——它是一个利用百度地图应用程序编程接口(API)创建的,专用于展示和操作地理区域的地图工具。百度地图API是一个强大的服务,允许开发者在...
百度地图API是一组基于HTTP协议的RESTful接口,开发者可以通过发送HTTP请求来获取地图相关的数据和服务。主要包括定位服务、地图展示、地理编码、路径规划、兴趣点搜索等模块。 要开始使用百度地图API,你需要在...
在本文中,我们将深入探讨如何使用C#编程语言与百度地图API进行交互,实现一系列实用功能,如在C#窗体上显示百度地图、测量距离、设置标记、框选区域以及规划路线。这个实例项目源码是学习和实践C#与地图服务集成的...
百度地图API是百度公司提供的一种基于Web的应用程序接口,允许开发者将百度地图集成到自己的应用程序中。百度地图API提供了丰富的功能,包括地图显示、地址解析、路线规划、地理编码等。 二、开发思路 在开发百度...
在本项目中,我们探索的是一个基于百度地图API构建的天气预报小应用。这个应用能够集成地图展示功能和实时天气信息,为用户提供便利的城市天气查询服务。以下将详细阐述涉及的技术点、实现方法以及可能遇到的问题。 ...
本实例是基于百度地图API进行的二次开发,旨在展示如何利用百度地图API来构建功能丰富的地图应用。百度地图API是百度提供的一项服务,允许开发者集成地图、定位、路线规划等地理信息服务到自己的网站或应用程序中。 ...
百度地图API是百度提供的地图服务接口,它允许开发者将地图、定位、路线规划等功能集成到自己的网站或应用程序中。API包括JavaScript API、Web服务API(如地理编码、逆地理编码)、离线地图SDK等,支持多种开发语言...
"基于百度地图API的房地产展示系统的实现.pdf" 本文主要讲解了基于百度地图API的房地产展示系统的实现,系统架构、开发步骤和技术支持。该系统旨在解决房地产行业的信息量大、可视化能力差的问题,为房地产企业和...
1. **百度地图API**:百度地图API是百度提供的一套开放接口,允许开发者在自己的应用程序中集成百度地图功能,如地图展示、定位、路径规划、地理编码等。在这个系统中,开发者利用API实现了地图的标注、区域获取等...
标题中的“地图数据-基于百度.zip_GNDI_fhr_地图 _百度地图_百度地图API”揭示了这个压缩包文件包含的是与地图相关的数据,特别是使用百度地图API开发的应用示例。GNDI(可能代表地理信息系统网络数据接口)和fhr...
百度地图API支持Android 1.5及以上系统。 <1>API添加到Andoid工程中 必须显得下载API开发包:点击下载 解压之后包括两个文件baidumapapi.jar和libBMapApiEngine.so。在工程根目录下创建ibs\armeabi目录,并拷贝...