安卓应用开发学习:腾讯地图SDK应用改进,实现定位、搜索、路线规划功能集成

您所在的位置:网站首页 腾讯导航功能 安卓应用开发学习:腾讯地图SDK应用改进,实现定位、搜索、路线规划功能集成

安卓应用开发学习:腾讯地图SDK应用改进,实现定位、搜索、路线规划功能集成

2024-07-10 18:28| 来源: 网络整理| 查看: 265

一、引言

我的上一篇学习日志《安卓应用开发学习:通过腾讯地图SDK实现定位功能》记录了利用腾讯地图SDK实现手机定位功能,并能获取地图中心点的经纬度信息。这之后的几天里,我对《Android  App 开发进阶与项目实战》一书第九章的内容深入解读,看明白了其中关于地点搜索和路线规划功能。原书中的这些功能都是分别做成不同的Activity,我则通过自己的努力尝试,将这些功能都集成到一个Activity中(见下图),在一些具体细节上,我花了一些心思,也收获了不少开发经验。

 

(路线规划功能)                                               (搜索功能)  

(之前就实现的定位功能)

二、新增的功能

1.界面调整

其实我很想照着专业的地图软件设计界面,奈何能力有限,只能保持之前的风格了,但由于增加了新的功能,如果把这些组件都显示在页面中,就没法看了。因此,我在界面上做一些调整,首先是将界面顶部放置定位功能组件的区域改成了放置“出行”、“搜索”、“图层”三个按钮。分别对应路线规划、搜索和定位三个功能模块。这三个功能模块则放置在了一个可隐藏的LinearLayout布局中,通过点击不同的按钮, 显示不同的组件。

1.1 xml文件代码

1.2 java文件中的逻辑代码

点击其中一个按钮后,其对应的功能组件设置为显示状态,其它功能组件设置为隐藏状态。

@Override public void onClick(View v) { ll_pop.setVisibility(View.INVISIBLE); if (v.getId() == R.id.btn_travel) { // 出行按钮 if (isTravelPop) { ll_pop.setVisibility(View.INVISIBLE); } else { // 对出行、搜索、图层功能的相关组件的显示、隐藏进行设置 ll_pop.setVisibility(View.VISIBLE); rg_travel.setVisibility(View.VISIBLE); ll_search1.setVisibility(View.GONE); ll_search2.setVisibility(View.GONE); ll_search3.setVisibility(View.GONE); ll_layer.setVisibility(View.GONE); travelModeOn = true; // 出行模式开 } isTravelPop = !isTravelPop; isSearchPop = false; isLayerPop = false; } else if (v.getId() == R.id.btn_search) { // 搜索按钮 if (isSearchPop) { ll_pop.setVisibility(View.INVISIBLE); } else { // 对出行、搜索、图层功能的相关组件的显示、隐藏进行设置 ll_pop.setVisibility(View.VISIBLE); rg_travel.setVisibility(View.GONE); ll_search1.setVisibility(View.VISIBLE); ll_search2.setVisibility(View.VISIBLE); ll_search3.setVisibility(View.VISIBLE); ll_layer.setVisibility(View.GONE); travelModeOn = false; // 出行模式关,转为搜索模式 } isSearchPop = !isSearchPop; isTravelPop = false; isLayerPop = false; } else if (v.getId() == R.id.btn_layer) { // 图层按钮 if (isLayerPop) { ll_pop.setVisibility(View.INVISIBLE); } else { // 对出行、搜索、图层功能的相关组件的显示、隐藏进行设置 ll_pop.setVisibility(View.VISIBLE); rg_travel.setVisibility(View.GONE); ll_search1.setVisibility(View.GONE); ll_search2.setVisibility(View.GONE); ll_search3.setVisibility(View.GONE); ll_layer.setVisibility(View.VISIBLE); } isLayerPop = !isLayerPop; isTravelPop = false; isSearchPop = false; }

2.增加的搜索功能

这个功能模块是参照的书上第9章 9.3.3 小节开发的。主要功能有:

2.1 分两种方式(搜城市、搜周边)进行搜索。

 

                        (搜城市)                                                                (搜周边)

搜城市,可以任意指定一座城市,输入关键字进行搜索;搜周边着在手机定位附近进行搜索。

2.2选点、测距、生成闭合多边形

在搜索模式下,点击地图上的非POI,会绘制一个红色的点,再次点击另外一处会生成第二个点,两点间有连线,连线旁显示两点距离。

多次点击,可以形成闭合多边形。

 

2.3点击POI(兴趣点)显示标识

这一功能是根据腾讯位置服务官网上的资料,由我自己添加的。点击地图上有名称的地点,就会显示一个标识。

2.4搜索功能有配额限制

这个模块刚设计完成后进行搜索地点测试时,出现了“此Key每日调用量已打上限”的提示,导致搜索功能不能正常使用。

我在腾讯位置服务官网的“Android地图SDK / 开发指南 / 检索功能概述”页面找到了答案。原来,Android地图SDK提供的检索能力依托于腾讯地图开放平台提供的 WebService API,所有的检索接口都有配额限制。而我在添加Key的时候并没有勾选WebService API。需要对key进行编辑,并分配额度。

(登录自己的用户进入我的应用,点key对应的编辑按钮)

(勾选WebService API,默认选中域的白名单不用修改,点保存)

(进入账户额度页面,给应用分配额度,将所有的项目都进行分配)

(分配了额度立即生效,再次运行搜索,能正常使用,且可以在调用统计中查看额度使用情况)

3.增加的出行功能

这个功能模块是参照书上第9章 9.3.4 小节开发的。出行功能具有步行和驾车两种模式。选好模式后,在地图上选两个点,会在两点间显示连线。点击“出发”按钮,软件就会对出行轨迹进行动画演示。

 

                (步行模式)                                                        (驾车模式)        

三、效果展示

演示动画 

腾讯地图SDK应用展示

四、关键代码

最后把部分代码贴出来。

1.activity文件

import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RadioGroup; import android.widget.SearchView; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import com.bahamutjapp.util.MapTencentUtil; import com.tencent.lbssearch.TencentSearch; import com.tencent.lbssearch.httpresponse.BaseObject; import com.tencent.lbssearch.httpresponse.HttpResponseListener; import com.tencent.lbssearch.object.param.DrivingParam; import com.tencent.lbssearch.object.param.SearchParam; import com.tencent.lbssearch.object.param.WalkingParam; import com.tencent.lbssearch.object.result.DrivingResultObject; import com.tencent.lbssearch.object.result.SearchResultObject; import com.tencent.lbssearch.object.result.WalkingResultObject; import com.tencent.map.geolocation.TencentLocation; import com.tencent.map.geolocation.TencentLocationListener; import com.tencent.map.geolocation.TencentLocationManager; import com.tencent.map.geolocation.TencentLocationRequest; import com.tencent.tencentmap.mapsdk.maps.CameraUpdate; import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory; import com.tencent.tencentmap.mapsdk.maps.MapView; import com.tencent.tencentmap.mapsdk.maps.TencentMap; import com.tencent.tencentmap.mapsdk.maps.UiSettings; import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptor; import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory; import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition; import com.tencent.tencentmap.mapsdk.maps.model.LatLng; import com.tencent.tencentmap.mapsdk.maps.model.LatLngBounds; import com.tencent.tencentmap.mapsdk.maps.model.MapPoi; import com.tencent.tencentmap.mapsdk.maps.model.Marker; import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions; import com.tencent.tencentmap.mapsdk.maps.model.PolygonOptions; import com.tencent.tencentmap.mapsdk.maps.model.PolylineOptions; import com.tencent.tencentmap.mapsdk.vector.utils.animation.MarkerTranslateAnimator; import java.util.ArrayList; import java.util.List; public class MapNavigationActivity extends AppCompatActivity implements TencentLocationListener, TencentMap.OnMapClickListener, TencentMap.OnMapPoiClickListener, View.OnClickListener { private final static String TAG = "MapNavigationActivity"; private TencentLocationManager mLocationManager; // 声明一个腾讯定位管理器对象 private MapView mMapView; // 声明一个地图视图对象 private TencentMap mTencentMap; // 声明一个腾讯地图对象 private boolean isFirstLoc = true; // 是否首次定位 private LatLng mMyLatLng; // 我的位置 private MarkerOptions mooMarker; // 手机定位处的标记 private MapPoi mSelectMapPoi; // 选中的Poi // 出行功能 private Boolean isTravelPop = false; private Boolean travelModeOn = false; // 出行和搜索模式切换开关 private RadioGroup rg_travel; // 出行方式单选按钮组(同时也作为布局器) private final List mSaEPosList = new ArrayList(); // 起点和终点 private final List mRouteList = new ArrayList(); // 导航路线列表 // 搜索功能 private Boolean isSearchPop = false; private TencentSearch mTencentSearch; // 搜索-声明一个腾讯搜索对象 private int mLoadIndex = 1; // 搜索-搜索结果的第几页 private EditText et_scope; // 搜索-声明一个编辑框对象 private TextView tv_scope_desc; // 搜索-声明一个文本视图对象 private SearchView sv_searchPoi; // 搜索-搜索组件 private int mSearchType; // 下列选框选中项索引号 private String mKeyWord = ""; // 获取搜索框中的内容 private final int SEARCH_CITY = 0; // 搜城市 private final int SEARCH_NEARBY = 1; // 搜周边 // 图层功能 private Boolean isLayerPop = false; private Button btn_getCenter; // 图层-获取中心点按钮 private TextView tv_centerPoint; // 图层-中心点标记 private LatLng mCenterLatLng; // 地图中心位置 // 布局 private LinearLayout ll_pop, ll_search1, ll_search2, ll_search3, ll_layer; // 面板布局,搜索、图层 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map_navigation); initLocation(); // 初始化定位服务 initView(); // 初始化视图 } // 初始化视图 private void initView() { // 出行、搜索、图层菜单对应面板初始化 ll_pop = findViewById(R.id.ll_pop); // 包含出行、搜索、图层功能的布局 rg_travel = findViewById(R.id.rg_travel); // 出行方式单选按钮组(附带布局功能) ll_search1 = findViewById(R.id.ll_search1); // 搜索功能布局1 ll_search2 = findViewById(R.id.ll_search2); // 搜索功能布局2 ll_search3 = findViewById(R.id.ll_search3); // 搜索功能布局3 ll_layer = findViewById(R.id.ll_layer); // 图层功能布局 ll_pop.setVisibility(View.INVISIBLE); // 将此布局设置为不可见 // 中心点初始化 tv_centerPoint = findViewById(R.id.tv_centerPoint); // 中心点图标 tv_centerPoint.setVisibility(View.INVISIBLE); // 中心点图标不可见 btn_getCenter = findViewById(R.id.btn_getCenter); // 中心点按钮 btn_getCenter.setEnabled(false); // 中心点按钮不可用 // 出行功能初始化 rg_travel.setOnCheckedChangeListener((group, checkedId) -> showRoute()); // 出行方式监听 findViewById(R.id.btn_start).setOnClickListener(v -> { // 出发按钮 if (mSaEPosList.size() < 2) { Toast.makeText(this, "请选中起点和终点后再出发", Toast.LENGTH_SHORT).show(); } else { playDriveAnim(); // 播放行驶过程动画 } }); findViewById(R.id.btn_redo).setOnClickListener(v -> { // 重来按钮 mTencentMap.clearAllOverlays(); // 清除所有覆盖物 mSaEPosList.clear(); // 清除起点和终点位置 mRouteList.clear(); // 清除路线 showMyMarker(); // 显示我的位置标记 }); // 搜索功能初始化 mTencentSearch = new TencentSearch(this); // 腾讯地图搜索 // 搜索-下拉列表框 Spinner sp_searchType = findViewById(R.id.sp_searchType); // 搜索方式下列选框 sp_searchType.setSelection(0); // 设置默认选择项 sp_searchType.setOnItemSelectedListener(new MethodSelectedListener()); et_scope = findViewById(R.id.et_scope); // 搜索范围输入框 tv_scope_desc = findViewById(R.id.tv_scope_desc); // 搜索范围文本描述 sv_searchPoi = findViewById(R.id.sv_searchPoi); // 搜索框 sv_searchPoi.setOnQueryTextListener(new SearchView.OnQueryTextListener() { // 当点击搜索按钮时触发该方法 @Override public boolean onQueryTextSubmit(String s) { //Toast.makeText(this, "您选择的是:" + s, Toast.LENGTH_SHORT).show(); sv_searchPoi.clearFocus(); // 移除焦点 mKeyWord = s; searchPoi(); // 搜索兴趣点 return false; } // 当搜索内容改变时触发该方法 @Override public boolean onQueryTextChange(String s) { return false; } }); findViewById(R.id.btn_next_data).setOnClickListener(v -> { // 下一组按钮 mLoadIndex++; mTencentMap.clearAllOverlays(); // 清除所有覆盖物 mTencentMap.addMarker(mooMarker); // 往地图添加手机定位标记 searchPoi(); // 搜索指定的地点列表 }); findViewById(R.id.btn_clearMarked).setOnClickListener(v -> { // 清除标记按钮 et_scope.setText(""); // 清除范围文本输入框内容 sv_searchPoi.setQuery("", false); // 清除搜索框内容 mTencentMap.clearAllOverlays(); // 清除所有覆盖物 mPosList.clear(); // 清除标记点列表 mSaEPosList.clear(); // 清除起点和终点列表 mRouteList.clear(); // 清除路线列表 isPolygon = false; mTencentMap.addMarker(mooMarker); // 往地图添加手机定位标记 }); // 图层功能初始化 RadioGroup rg_layer = findViewById(R.id.rg_layer); // 地图类型单选按钮组 rg_layer.setOnCheckedChangeListener((group, checkedId) -> { if (checkedId == R.id.rb_common) { mTencentMap.setMapType(TencentMap.MAP_TYPE_NORMAL); // 设置普通地图 } else if (checkedId == R.id.rb_satellite) { mTencentMap.setMapType(TencentMap.MAP_TYPE_SATELLITE); // 设置卫星地图 } }); CheckBox ck_traffic = findViewById(R.id.ck_traffic); // 交通情况复选框 ck_traffic.setOnCheckedChangeListener((buttonView, isChecked) -> { mTencentMap.setTrafficEnabled(isChecked); // 是否显示交通拥堵状况 }); CheckBox ck_centerPoint = findViewById(R.id.ck_centerPoint); // 中心点复选框 ck_centerPoint.setOnCheckedChangeListener((buttonView, isChecked) -> { if (isChecked) { tv_centerPoint.setVisibility(View.VISIBLE); // 显示中心点图标 btn_getCenter.setEnabled(true); // 中心点按钮可用 } else { tv_centerPoint.setVisibility(View.INVISIBLE); btn_getCenter.setEnabled(false); } }); // 设置点击监听器 findViewById(R.id.btn_travel).setOnClickListener(this); // 出行按钮 findViewById(R.id.btn_search).setOnClickListener(this); // 搜索按钮 findViewById(R.id.btn_layer).setOnClickListener(this); // 图层按钮 findViewById(R.id.tv_enlarge).setOnClickListener(this); // 放大地图 findViewById(R.id.tv_narrow).setOnClickListener(this); // 缩小地图 findViewById(R.id.img_btn_goMyPlace).setOnClickListener(this); // 回到我的位置 btn_getCenter.setOnClickListener(this); // 获取中心点 } // initView-end // 初始化定位服务 private void initLocation() { mMapView = findViewById(R.id.mapView); mTencentMap = mMapView.getMap(); // 获取腾讯地图对象 UiSettings mysetting = mTencentMap.getUiSettings(); mysetting.setCompassEnabled(true); // 开启指南针 mTencentMap.setOnMapClickListener(this); // 设置地图的点击监听器 mTencentMap.setOnMapPoiClickListener(this); // 设置地图POI点击监听器 mLocationManager = TencentLocationManager.getInstance(this); // 创建腾讯定位请求对象 TencentLocationRequest request = TencentLocationRequest.create(); request.setInterval(30000).setAllowGPS(true); request.setRequestLevel(TencentLocationRequest.REQUEST_LEVEL_ADMIN_AREA); mLocationManager.requestLocationUpdates(request, this); // 开始定位监听 } // 定位变更监听 @Override public void onLocationChanged(TencentLocation location, int resultCode, String resultDesc) { if (resultCode == TencentLocation.ERROR_OK) { // 定位成功 if (location != null && isFirstLoc) { // 首次定位 isFirstLoc = false; // 创建一个经纬度对象 mMyLatLng = new LatLng(location.getLatitude(), location.getLongitude()); showMyMarker(); // 显示我的位置标记 } } else { // 定位失败 Log.d(TAG, "定位失败,错误代码为"+resultCode+",错误描述为"+resultDesc); } } @Override public void onStatusUpdate(String s, int i, String s1) { } // 腾讯地图生命周期方法 @Override protected void onStart() { super.onStart(); mMapView.onStart(); } @Override protected void onStop() { super.onStop(); mMapView.onStop(); } @Override public void onPause() { super.onPause(); mMapView.onPause(); } @Override public void onResume() { super.onResume(); mMapView.onResume(); } @Override protected void onDestroy() { super.onDestroy(); mLocationManager.removeUpdates(this); // 移除定位监听 mMapView.onDestroy(); } // 显示我的位置标记 private void showMyMarker() { CameraUpdate update = CameraUpdateFactory.newLatLngZoom(mMyLatLng, 12); mTencentMap.moveCamera(update); // 把相机视角移动到指定地点 showPosMarker(mMyLatLng, R.drawable.ic_my_location_32, "这是您的当前位置"); // 显示位置标记 } // 显示位置标记 private void showPosMarker(LatLng latLng, int imageId, String desc) { // 从指定图片中获取位图描述 BitmapDescriptor bitmapDesc = BitmapDescriptorFactory.fromResource(imageId); mooMarker = new MarkerOptions(latLng).draggable(false) // 不可拖动 .visible(true).icon(bitmapDesc).title("手机定位").snippet(desc); mTencentMap.addMarker(mooMarker); // 往地图添加手机定位标记 } // 出行功能 private Marker mCarMarker; // 声明一个小车标记 // 播放行驶过程动画 private void playDriveAnim() { if (mSaEPosList.size() < 2) { return; } if (mCarMarker != null) { mCarMarker.remove(); // 移除小车标记 } int imageId; if (rg_travel.getCheckedRadioButtonId() == R.id.rb_walk) { imageId = R.drawable.icon_locate; // 步行 } else { imageId = R.drawable.car; // 驾车 } // 从指定图片中获取位图描述 BitmapDescriptor bitmapDesc = BitmapDescriptorFactory.fromResource(imageId); MarkerOptions ooMarker = new MarkerOptions(mRouteList.get(0)) .anchor(0.5f, 0.5f).icon(bitmapDesc).flat(true).clockwise(false); mCarMarker = mTencentMap.addMarker(ooMarker); // 往地图添加标记 LatLng[] routeArray = mRouteList.toArray(new LatLng[0]); // 创建平移动画 MarkerTranslateAnimator anim = new MarkerTranslateAnimator(mCarMarker, 50 * 1000, routeArray, true); // 动态调整相机视角 mTencentMap.animateCamera(CameraUpdateFactory.newLatLngBounds( LatLngBounds.builder().include(mRouteList).build(), 50)); anim.startAnimation(); // 开始播放动画 } // 出行功能-展示导航路线 private void showRoute() { if (mSaEPosList.size() >= 2) { mRouteList.clear(); LatLng beginPos = mSaEPosList.get(0); // 获取起点 LatLng endPos = mSaEPosList.get(mSaEPosList.size()-1); // 获取终点 mTencentMap.clearAllOverlays(); // 清除所有覆盖物 mTencentMap.addMarker(mooMarker); // 往地图添加手机定位标记 showPosMarker(beginPos, R.drawable.icon_geo, "起点"); // 显示位置标记 showPosMarker(endPos, R.drawable.icon_geo, "终点"); // 显示位置标记 if (rg_travel.getCheckedRadioButtonId() == R.id.rb_walk) { getWalkingRoute(beginPos, endPos); // 规划步行导航 } else { getDrivingRoute(beginPos, endPos); // 规划行车导航 } } } // 出行功能-规划步行导航 private void getWalkingRoute(LatLng beginPos, LatLng endPos) { WalkingParam walkingParam = new WalkingParam(); walkingParam.from(beginPos); // 指定步行的起点 walkingParam.to(endPos); // 指定步行的终点 // 创建一个腾讯搜索对象 TencentSearch tencentSearch = new TencentSearch(getApplicationContext()); Log.d(TAG, "checkParams:" + walkingParam.checkParams()); // 根据步行参数规划导航路线 tencentSearch.getRoutePlan(walkingParam, new HttpResponseListener() { @Override public void onSuccess(int statusCode, WalkingResultObject object) { if (object==null || object.result==null || object.result.routes==null) { Log.d(TAG, "导航路线为空"); return; } Log.d(TAG, "message:" + objecssage); for (WalkingResultObject.Route result : object.result.routes) { mRouteList.addAll(result.polyline); // 往地图上添加一组连线 mTencentMap.addPolyline(new PolylineOptions().addAll(mRouteList) .color(0x880000ff).width(20)); } } @Override public void onFailure(int statusCode, String responseString, Throwable throwable) { Log.d(TAG, statusCode + " " + responseString); } }); } // 出行功能-规划行车导航 private void getDrivingRoute(LatLng beginPos, LatLng endPos) { // 创建导航参数 DrivingParam drivingParam = new DrivingParam(beginPos, endPos); // 指定道路类型为主路 drivingParam.roadType(DrivingParam.RoadType.ON_MAIN_ROAD); // 道路类型-主路 drivingParam.heading(90); // 起点位置的车头方向 drivingParam.accuracy(5); // 行车导航的精度,单位米 // 创建一个腾讯搜索对象 TencentSearch tencentSearch = new TencentSearch(this); // 根据行车参数规划导航路线 tencentSearch.getRoutePlan(drivingParam, new HttpResponseListener() { @Override public void onSuccess(int statusCode, DrivingResultObject object) { if (object==null || object.result==null || object.result.routes==null) { Log.d(TAG, "导航路线为空"); return; } Log.d(TAG, "message:" + objecssage); for (DrivingResultObject.Route route : object.result.routes){ mRouteList.addAll(route.polyline); // 往地图上添加一组连线 mTencentMap.addPolyline(new PolylineOptions().addAll(mRouteList) .color(0x880000ff).width(20)); } } @Override public void onFailure(int statusCode, String responseString, Throwable throwable) { Log.d(TAG, statusCode + " " + responseString); } }); } // 搜索功能-搜索方式下列选框选择监听器 class MethodSelectedListener implements AdapterView.OnItemSelectedListener { public void onItemSelected(AdapterView arg0, View arg1, int arg2, long arg3) { mSearchType = arg2; if (mSearchType == SEARCH_CITY) { tv_scope_desc.setText("市内找"); } else if (mSearchType == SEARCH_NEARBY) { tv_scope_desc.setText("米内找"); } et_scope.setText(""); sv_searchPoi.setQuery("", false); // 清除搜索框内容 } public void onNothingSelected(AdapterView arg0) {} } // 搜索功能-搜索指定的地点列表 public void searchPoi() { Log.d(TAG, "et_scope=" + et_scope.getText().toString() + ", SearchKey=" + mKeyWord + ", mLoadIndex=" + mLoadIndex); String scope = et_scope.getText().toString(); // 获取输入的范围 // 测试时发现scope为空时附近查询会闪退,需要对scope进行发现bug,如果,就会导致程序闪退,需要添加判断语句 if (TextUtils.isEmpty(scope)) { Toast.makeText(this, "搜索的范围为空", Toast.LENGTH_SHORT).show(); return; } SearchParam searchParam = new SearchParam(); if (mSearchType == SEARCH_CITY) { // 城市搜索 SearchParam.Region region = new SearchParam .Region(scope) // 设置搜索城市 .autoExtend(false); // 设置搜索范围不扩大 searchParam = new SearchParam(mKeyWord, region); // 构建地点检索 } else if (mSearchType == SEARCH_NEARBY) { // 周边搜索 int radius; try { radius = Integer.parseInt(scope); // scope必须是有效值,否则不使用try会闪退 } catch (Exception e){ e.printStackTrace(); Toast.makeText(this, "搜索范围不是有效数字", Toast.LENGTH_SHORT).show(); return; } SearchParam.Nearby nearby = new SearchParam .Nearby(mMyLatLng, radius).autoExtend(false); // 不扩大搜索范围 searchParam = new SearchParam(mKeyWord, nearby); // 构建地点检索 } searchParam.pageSize(10); // 每页大小 searchParam.pageIndex(mLoadIndex); // 第几页 // 根据搜索参数查找符合条件的地点列表 mTencentSearch.search(searchParam, new HttpResponseListener() { @Override public void onFailure(int arg0, String arg2, Throwable arg3) { Toast.makeText(getApplicationContext(), arg2, Toast.LENGTH_LONG).show(); } @Override public void onSuccess(int arg0, BaseObject arg1) { // 搜索成功 if (arg1 == null) { return; } SearchResultObject obj = (SearchResultObject) arg1; if(obj.data==null || obj.data.size()==0){ return; } // 将地图中心坐标移动到检索到的第一个地点 CameraUpdate update = CameraUpdateFactory.newLatLngZoom(obj.data.get(0).latLng, 12); mTencentMap.moveCamera(update); // 把相机视角移动到指定地点 // 将其他检索到的地点在地图上用 marker 标出来 for (SearchResultObject.SearchResultData data : obj.data){ Log.d(TAG,"title:"+data.title + ";" + data.address); // 往地图添加标记 mTencentMap.addMarker(new MarkerOptions(data.latLng) .title(data.title).snippet(data.address)); } } }); } // 下面是绘图代码 // 功能:在地图上点击后,会添加一个点,再次点击,添加第二个点,在两点间添加连线,并显示两点距离,以此类推 // 通过“清除标记”按钮,可将添加的点和连线清除 private final int lineColor = 0x55FF0000; // 红色-线段颜色 private final int textColor = 0x990000FF; // 蓝色-字体颜色 private final int polygonColor = 0x77FFFF00; // 黄色-多边形底色 private final int radiusLimit = 100; // 当前点与第一个点的距离限定 private final List mPosList = new ArrayList(); // 创建列表,保存用户在地图上点击的位置 private boolean isPolygon = false; // 往地图上添加一个点 private void addDot(LatLng pos) { if (isPolygon) { mPosList.clear(); isPolygon = false; } boolean isFirst = false; LatLng thisPos = pos; // 将当前点与第一个点和前一个点进行比较 if (mPosList.size() > 0) { LatLng firstPos = mPosList.get(0); int distance = (int) Math.round(MapTencentUtil.getShortDistance( thisPos.longitude, thisPos.latitude, firstPos.longitude, firstPos.latitude)); // 当前点与第一个点的距离 if (mPosList.size() == 1 && distance 1) { LatLng lastPos = mPosList.get(mPosList.size() - 1); int lastDistance = (int) Math.round(MapTencentUtil.getShortDistance( thisPos.longitude, thisPos.latitude, lastPos.longitude, lastPos.latitude)); // 当前点与前一个点的距离 if (lastDistance 1000) { disText = Math.round(distance * 10.0f / 1000) / 10d + "公里"; } else { disText = distance + "米"; } PolylineOptions.SegmentText segment = new PolylineOptions.SegmentText(0, 1, disText); PolylineOptions.Text text = new PolylineOptions.Text.Builder(segment) .color(textColor).size(15).build(); ooPolyline.text(text); mTencentMap.addPolyline(ooPolyline); // 往地图上添加一组连线 } if (!isFirst) { // 从指定图片中获取位图描述 BitmapDescriptor bitmapDesc = BitmapDescriptorFactory.fromResource(R.drawable.icon_geo); MarkerOptions ooMarker = new MarkerOptions(thisPos).draggable(false) // 不可拖动 .visible(true).icon(bitmapDesc); mTencentMap.addMarker(ooMarker); // 往地图添加标记 // 设置地图标记的点击监听器 mTencentMap.setOnMarkerClickListener(marker -> { LatLng markPos = marker.getPosition(); addDot(markPos); // 往地图上添加一个点 marker.showInfoWindow(); // 显示标记的信息窗口 return true; }); } else { // isFirst为真,mPosList中的点已形成闭环 if (mPosList.size() < 3) { // 可能存在地图与标记同时响应点击事件的情况 mPosList.clear(); isPolygon = false; return; } // 画多边形 PolygonOptions ooPolygon = new PolygonOptions().addAll(mPosList) .strokeColor(0xFF00FF00).strokeWidth(3) .fillColor(polygonColor); // 多边形为绿边 mTencentMap.addPolygon(ooPolygon); // 往地图上添加多边形 isPolygon = true; } mPosList.add(thisPos); } // 地图点击响应 @Override public void onMapClick(LatLng latLng) { if (travelModeOn) { // 出行模式 if (mSaEPosList.size() < 2) { mSaEPosList.add(latLng); } else { mSaEPosList.set(mSaEPosList.size()-1, latLng); } if (mSaEPosList.size() == 1) { showPosMarker(latLng, R.drawable.icon_geo, "起点"); // 显示位置标记 } showRoute(); // 展示导航路线 } else { // 非出行模式(搜索模式)执行添加点操作 addDot(latLng); // 往地图上添加一个点 Log.d(TAG, "当前点击位置的经纬度:" + latLng.longitude + " ;" + latLng.altitude); } } // 点击地图上的POI响应 @Override public void onClicked(MapPoi mapPoi) { if (!travelModeOn) { Log.d(TAG, "选中的Poi为:" + mapPoi.name); Toast.makeText(this, mapPoi.name + "\n" + mapPoi.getLongitude() + ", " + mapPoi.getLatitude(), Toast.LENGTH_SHORT).show(); // 清除之前的标记 mTencentMap.clearAllOverlays(); mTencentMap.addMarker(mooMarker); // 往地图添加手机定位标记 mSelectMapPoi = mapPoi; // 从指定图片中获取位图描述 BitmapDescriptor bitmapDesc = BitmapDescriptorFactory.fromResource(R.drawable.icon_current); MarkerOptions ooMarker = new MarkerOptions(mSelectMapPoi.position).draggable(false) // 不可拖动 .visible(true).icon(bitmapDesc); mTencentMap.addMarker(ooMarker); // 往地图添加标记 } else { addDot(mapPoi.position); // 往地图上添加一个点 } } @Override public void onClick(View v) { ll_pop.setVisibility(View.INVISIBLE); if (v.getId() == R.id.btn_travel) { // 出行按钮 if (isTravelPop) { ll_pop.setVisibility(View.INVISIBLE); } else { // 对出行、搜索、图层功能的相关组件的显示、隐藏进行设置 ll_pop.setVisibility(View.VISIBLE); rg_travel.setVisibility(View.VISIBLE); ll_search1.setVisibility(View.GONE); ll_search2.setVisibility(View.GONE); ll_search3.setVisibility(View.GONE); ll_layer.setVisibility(View.GONE); travelModeOn = true; // // 出行模式开 } isTravelPop = !isTravelPop; isSearchPop = false; isLayerPop = false; } else if (v.getId() == R.id.btn_search) { // 搜索按钮 if (isSearchPop) { ll_pop.setVisibility(View.INVISIBLE); } else { // 对出行、搜索、图层功能的相关组件的显示、隐藏进行设置 ll_pop.setVisibility(View.VISIBLE); rg_travel.setVisibility(View.GONE); ll_search1.setVisibility(View.VISIBLE); ll_search2.setVisibility(View.VISIBLE); ll_search3.setVisibility(View.VISIBLE); ll_layer.setVisibility(View.GONE); travelModeOn = false; // 出行模式关,转为搜索模式 } isSearchPop = !isSearchPop; isTravelPop = false; isLayerPop = false; } else if (v.getId() == R.id.btn_layer) { // 图层按钮 if (isLayerPop) { ll_pop.setVisibility(View.INVISIBLE); } else { // 对出行、搜索、图层功能的相关组件的显示、隐藏进行设置 ll_pop.setVisibility(View.VISIBLE); rg_travel.setVisibility(View.GONE); ll_search1.setVisibility(View.GONE); ll_search2.setVisibility(View.GONE); ll_search3.setVisibility(View.GONE); ll_layer.setVisibility(View.VISIBLE); } isLayerPop = !isLayerPop; isTravelPop = false; isSearchPop = false; } else if (v.getId() == R.id.tv_enlarge) { // 放大地图 mTencentMap.moveCamera(CameraUpdateFactory.zoomIn()); // 放大一级 // Toast.makeText(this, "放大地图", Toast.LENGTH_SHORT).show(); } else if (v.getId() == R.id.tv_narrow) { // 缩小地图 mTencentMap.moveCamera(CameraUpdateFactory.zoomOut()); // 缩小一级 // Toast.makeText(this, "缩小地图", Toast.LENGTH_SHORT).show(); } else if (v.getId() == R.id.img_btn_goMyPlace) { // 回到我的位置 CameraUpdate update = CameraUpdateFactory.newLatLng(mMyLatLng); mTencentMap.moveCamera(update); // 把相机视角移动到指定地点 // Toast.makeText(this, "回到我的位置", Toast.LENGTH_SHORT).show(); } else if (v.getId() == R.id.btn_getCenter) { // 获取中心点坐标 CameraPosition cameraPosition = mTencentMap.getCameraPosition(); mCenterLatLng = cameraPosition.target; Toast.makeText(this, "中心点坐标:" + mCenterLatLng.latitude + ";" + mCenterLatLng.longitude, Toast.LENGTH_LONG).show(); } } }

2. mxl文件



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3