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

一、引言

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

 

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

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

二、新增的功能

1.界面调整

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

1.1 xml文件代码

    <!-- ll_pop布局中包含的是出行、搜索、图层按钮对应的功能 --><!-- 出行、搜索、图层三个组件的显示互斥 --><LinearLayoutandroid:id="@+id/ll_pop"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="15dp"android:orientation="vertical"android:background="@drawable/radius_border_15"app:layout_constraintEnd_toEndOf="@id/mapView"app:layout_constraintStart_toStartOf="@id/mapView"app:layout_constraintTop_toTopOf="@id/mapView"><!-- 此RadioGroup组件对应出行按钮 --><RadioGroupandroid:id="@+id/rg_travel"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="5dp"android:orientation="horizontal" ><RadioButtonandroid:id="@+id/rb_walk"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:checked="true"android:text="步行"android:textColor="@color/black"android:textSize="17sp" /><RadioButtonandroid:id="@+id/rb_drive"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:checked="false"android:text="驾车"android:textColor="@color/black"android:textSize="17sp" /><Buttonandroid:id="@+id/btn_start"android:layout_width="80dp"android:layout_height="wrap_content"android:text="出发"tools:ignore="ButtonStyle" /><Buttonandroid:id="@+id/btn_redo"android:layout_width="80dp"android:layout_marginStart="5dp"android:layout_marginEnd="5dp"android:layout_height="wrap_content"android:text="重来"tools:ignore="ButtonStyle" /></RadioGroup><!-- 以下的三个LinearLayout布局ll_search1、ll_search2、ll_search3对应搜索按钮 --><LinearLayoutandroid:id="@+id/ll_search1"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="5dp"android:orientation="horizontal"><TextViewandroid:id="@+id/tv_searchType"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginStart="10dp"android:textColor="@color/black"android:textSize="16sp"android:text="搜索方式:" /><Spinnerandroid:id="@+id/sp_searchType"android:layout_width="wrap_content"android:layout_height="wrap_content"android:entries="@array/searchType" /><TextViewandroid:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:text="在"android:textColor="@color/black"android:textSize="17sp" /><EditTextandroid:id="@+id/et_scope"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center"android:background="@drawable/editext_selector"android:textColor="@color/black"android:textSize="17sp"android:hint="  "android:autofillHints="范围"android:inputType="none"/><TextViewandroid:id="@+id/tv_scope_desc"android:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:layout_marginEnd="5dp"android:text="市内找"android:textColor="@color/black"android:textSize="17sp" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_search2"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:layout_marginEnd="10dp"android:orientation="horizontal"><SearchViewandroid:id="@+id/sv_searchPoi"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/gray_245" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_search3"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"android:layout_marginBottom="5dp"android:orientation="horizontal"><Buttonandroid:id="@+id/btn_next_data"android:layout_width="100dp"android:layout_height="wrap_content"android:layout_marginEnd="5dp"android:text="下一组"tools:ignore="ButtonStyle" /><Buttonandroid:id="@+id/btn_clearMarked"android:layout_width="100dp"android:layout_marginStart="5dp"android:layout_height="wrap_content"android:text="清除标记"tools:ignore="ButtonStyle" /></LinearLayout><!-- 以下的ll_layer对应图层按钮 --><LinearLayoutandroid:id="@+id/ll_layer"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><RadioGroupandroid:id="@+id/rg_layer"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:layout_marginBottom="5dp"android:orientation="horizontal" ><RadioButtonandroid:id="@+id/rb_common"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:checked="true"android:text="普通"android:textColor="@color/black"android:textSize="17sp" /><RadioButtonandroid:id="@+id/rb_satellite"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:checked="false"android:text="卫星"android:textColor="@color/black"android:textSize="17sp" /><CheckBoxandroid:id="@+id/ck_traffic"android:layout_width="wrap_content"android:layout_height="wrap_content"android:checked="false"android:text="交通情况"android:textColor="@color/black"android:textSize="17sp" /><CheckBoxandroid:id="@+id/ck_centerPoint"android:layout_width="30dp"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:checked="false"android:text=""android:textColor="@color/black"android:textSize="17sp" /><Buttonandroid:id="@+id/btn_getCenter"android:layout_width="78dp"android:layout_height="wrap_content"android:layout_marginEnd="5dp"android:text="中心点"/></RadioGroup></LinearLayout>

1.2 java文件中的逻辑代码

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

    @Overridepublic 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<LatLng> mSaEPosList = new ArrayList<>(); // 起点和终点private final List<LatLng> 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;  // 面板布局,搜索、图层@Overrideprotected 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);  // 搜索功能布局1ll_search2 = findViewById(R.id.ll_search2);  // 搜索功能布局2ll_search3 = findViewById(R.id.ll_search3);  // 搜索功能布局3ll_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() {// 当点击搜索按钮时触发该方法@Overridepublic boolean onQueryTextSubmit(String s) {//Toast.makeText(this, "您选择的是:" + s, Toast.LENGTH_SHORT).show();sv_searchPoi.clearFocus();  // 移除焦点mKeyWord = s;searchPoi();  // 搜索兴趣点return false;}// 当搜索内容改变时触发该方法@Overridepublic 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); // 开始定位监听}// 定位变更监听@Overridepublic 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);}}@Overridepublic void onStatusUpdate(String s, int i, String s1) { }// 腾讯地图生命周期方法@Overrideprotected void onStart() {super.onStart();mMapView.onStart();}@Overrideprotected void onStop() {super.onStop();mMapView.onStop();}@Overridepublic void onPause() {super.onPause();mMapView.onPause();}@Overridepublic void onResume() {super.onResume();mMapView.onResume();}@Overrideprotected 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<WalkingResultObject>() {@Overridepublic void onSuccess(int statusCode, WalkingResultObject object) {if (object==null || object.result==null || object.result.routes==null) {Log.d(TAG, "导航路线为空");return;}Log.d(TAG, "message:" + object.message);for (WalkingResultObject.Route result : object.result.routes) {mRouteList.addAll(result.polyline);// 往地图上添加一组连线mTencentMap.addPolyline(new PolylineOptions().addAll(mRouteList).color(0x880000ff).width(20));}}@Overridepublic 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<DrivingResultObject>() {@Overridepublic void onSuccess(int statusCode, DrivingResultObject object) {if (object==null || object.result==null || object.result.routes==null) {Log.d(TAG, "导航路线为空");return;}Log.d(TAG, "message:" + object.message);for (DrivingResultObject.Route route : object.result.routes){mRouteList.addAll(route.polyline);// 往地图上添加一组连线mTencentMap.addPolyline(new PolylineOptions().addAll(mRouteList).color(0x880000ff).width(20));}}@Overridepublic 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<BaseObject>() {@Overridepublic void onFailure(int arg0, String arg2, Throwable arg3) {Toast.makeText(getApplicationContext(), arg2, Toast.LENGTH_LONG).show();}@Overridepublic 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<LatLng> 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 <= 0) { // 多次点击起点,要忽略之return;} else if (mPosList.size() > 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 <= 0) { // 重复响应当前位置的点击,要忽略之return;}}if (distance < radiusLimit * 2) {  // 当前点与第一个点的距离小于限定值,形成闭环thisPos = firstPos;isFirst = true;}Log.d(TAG, "distance=" + distance + ", radiusLimit=" + radiusLimit + ", isFirst=" + isFirst);// 在当前点与前一个点间画直线LatLng lastPos = mPosList.get(mPosList.size() - 1);List<LatLng> pointList = new ArrayList<>();pointList.add(lastPos);pointList.add(thisPos);PolylineOptions ooPolyline = new PolylineOptions().width(2).color(lineColor).addAll(pointList);// 计算两点之间距离distance = (int) Math.round(MapTencentUtil.getShortDistance(thisPos.longitude, thisPos.latitude,lastPos.longitude, lastPos.latitude));String disText;if (distance > 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);}// 地图点击响应@Overridepublic 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响应@Overridepublic 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); // 往地图上添加一个点}}@Overridepublic 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文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_height="match_parent"tools:context=".MapNavigationActivity"><LinearLayoutandroid:id="@+id/ll_toolBar"android:layout_width="match_parent"android:layout_height="45dp"android:layout_marginStart="5dp"android:layout_marginEnd="5dp"android:gravity="center_horizontal"android:orientation="horizontal"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"><Buttonandroid:id="@+id/btn_travel"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="出行"tools:ignore="ButtonStyle" /><Buttonandroid:id="@+id/btn_search"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="15dp"android:layout_marginEnd="15dp"android:text="搜索"tools:ignore="ButtonStyle" /><Buttonandroid:id="@+id/btn_layer"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="图层"tools:ignore="ButtonStyle" /></LinearLayout><com.tencent.tencentmap.mapsdk.maps.MapViewandroid:id="@+id/mapView"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/ll_toolBar"><TextViewandroid:id="@+id/tv_centerPoint"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_gravity="center"android:gravity="center"android:text="+"android:textColor="@color/red"android:textSize="48sp" /></com.tencent.tencentmap.mapsdk.maps.MapView><LinearLayoutandroid:id="@+id/ll_zoom"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginEnd="20dp"android:layout_marginBottom="120dp"android:orientation="vertical"android:background="@drawable/radius_border_15"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"><TextViewandroid:id="@+id/tv_enlarge"android:layout_width="50dp"android:layout_height="50dp"android:layout_gravity="center_horizontal"android:layout_marginTop="10dp"android:layout_marginBottom="5dp"android:gravity="center"android:text="+"android:textColor="@color/black"android:textSize="32sp"android:textStyle="bold" /><TextViewandroid:id="@+id/tv_narrow"android:layout_width="50dp"android:layout_height="50dp"android:layout_gravity="center_horizontal"android:layout_marginTop="5dp"android:layout_marginBottom="10dp"android:gravity="center"android:text="-"android:textColor="@color/black"android:textSize="32sp"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_goMyPlace"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="20dp"android:layout_marginBottom="55dp"android:orientation="horizontal"android:background="@drawable/radius_border_15"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintStart_toStartOf="parent"><ImageButtonandroid:id="@+id/img_btn_goMyPlace"android:layout_width="54dp"android:layout_height="54dp"android:backgroundTint="@color/white"android:src="@drawable/ic_go_my_place"tools:ignore="ContentDescription" /></LinearLayout><!-- ll_pop布局中包含的是出现、搜索、图层按钮对应的功能 --><!-- 显示互斥布局rg_travel;ll_search1、sv_searchPoi、ll_search2;ll_layer --><LinearLayoutandroid:id="@+id/ll_pop"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="15dp"android:orientation="vertical"android:background="@drawable/radius_border_15"app:layout_constraintEnd_toEndOf="@id/mapView"app:layout_constraintStart_toStartOf="@id/mapView"app:layout_constraintTop_toTopOf="@id/mapView"><RadioGroupandroid:id="@+id/rg_travel"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="5dp"android:orientation="horizontal" ><RadioButtonandroid:id="@+id/rb_walk"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:checked="true"android:text="步行"android:textColor="@color/black"android:textSize="17sp" /><RadioButtonandroid:id="@+id/rb_drive"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:checked="false"android:text="驾车"android:textColor="@color/black"android:textSize="17sp" /><Buttonandroid:id="@+id/btn_start"android:layout_width="80dp"android:layout_height="wrap_content"android:text="出发"tools:ignore="ButtonStyle" /><Buttonandroid:id="@+id/btn_redo"android:layout_width="80dp"android:layout_marginStart="5dp"android:layout_marginEnd="5dp"android:layout_height="wrap_content"android:text="重来"tools:ignore="ButtonStyle" /></RadioGroup><LinearLayoutandroid:id="@+id/ll_search1"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="5dp"android:orientation="horizontal"><TextViewandroid:id="@+id/tv_searchType"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginStart="10dp"android:textColor="@color/black"android:textSize="16sp"android:text="搜索方式:" /><Spinnerandroid:id="@+id/sp_searchType"android:layout_width="wrap_content"android:layout_height="wrap_content"android:entries="@array/searchType" /><TextViewandroid:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:text="在"android:textColor="@color/black"android:textSize="17sp" /><EditTextandroid:id="@+id/et_scope"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center"android:background="@drawable/editext_selector"android:textColor="@color/black"android:textSize="17sp"android:hint="  "android:autofillHints="范围"android:inputType="none"/><TextViewandroid:id="@+id/tv_scope_desc"android:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:layout_marginEnd="5dp"android:text="市内找"android:textColor="@color/black"android:textSize="17sp" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_search2"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:layout_marginEnd="10dp"android:orientation="horizontal"><SearchViewandroid:id="@+id/sv_searchPoi"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/gray_245" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_search3"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"android:layout_marginBottom="5dp"android:orientation="horizontal"><Buttonandroid:id="@+id/btn_next_data"android:layout_width="100dp"android:layout_height="wrap_content"android:layout_marginEnd="5dp"android:text="下一组"tools:ignore="ButtonStyle" /><Buttonandroid:id="@+id/btn_clearMarked"android:layout_width="100dp"android:layout_marginStart="5dp"android:layout_height="wrap_content"android:text="清除标记"tools:ignore="ButtonStyle" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_layer"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><RadioGroupandroid:id="@+id/rg_layer"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:layout_marginBottom="5dp"android:orientation="horizontal" ><RadioButtonandroid:id="@+id/rb_common"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:checked="true"android:text="普通"android:textColor="@color/black"android:textSize="17sp" /><RadioButtonandroid:id="@+id/rb_satellite"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:checked="false"android:text="卫星"android:textColor="@color/black"android:textSize="17sp" /><CheckBoxandroid:id="@+id/ck_traffic"android:layout_width="wrap_content"android:layout_height="wrap_content"android:checked="false"android:text="交通情况"android:textColor="@color/black"android:textSize="17sp" /><CheckBoxandroid:id="@+id/ck_centerPoint"android:layout_width="30dp"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:checked="false"android:text=""android:textColor="@color/black"android:textSize="17sp" /><Buttonandroid:id="@+id/btn_getCenter"android:layout_width="78dp"android:layout_height="wrap_content"android:layout_marginEnd="5dp"android:text="中心点"/></RadioGroup></LinearLayout></LinearLayout></androidx.constraintlayout.widget.ConstraintLayout>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/43513.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习实战(44)】Anchor based and Anchor free(无锚VS有锚)

1 anchor-based 深度学习目标检测通常都被建模成对一些候选区域进行分类和回归的问题。在单阶段检测器中&#xff0c;这些候选区域就是通过滑窗方式产生的 anchor&#xff1b;在两阶段检测器中&#xff0c;候选区域是 RPN 生成的 proposal&#xff0c;但是 RPN 本身仍然是对滑窗…

leetcode--层数最深叶子节点的和

leetcode地址&#xff1a;层数最深叶子节点的和 给你一棵二叉树的根节点 root &#xff0c;请你返回 层数最深的叶子节点的和 。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,4,5,null,6,7,null,null,null,null,8] 输出&#xff1a;15 示例 2&#xff1a; 输入&#xff…

多点GRE over IPsecVPN模式下nhrp的调优

一、实验目的 在多点GRE over IPsecVPN模式下对nhrp进行调优&#xff0c;在总部开启重定向、在分支开启shortcut 网络拓扑&#xff1a; 二、基础设置 &#xff08;一&#xff09;如图所示配置接口地址和区域&#xff0c;连接PC的接口位于trust区域、连接路由器的接口位于unt…

qt5.15关于qradiobutton遇到的坑

前言 不知道是只有我遇到了&#xff0c;还是qt本身就存在这个bug 当将2个qradiobutton放入到一个布局内&#xff0c;然后进行来回切换&#xff0c;若无数据刷新的情况下&#xff0c;切换无异常&#xff0c;当窗体内有数据开始刷新了&#xff0c;则点击其中一个qradiobutton&am…

语法糖:代码中的甜品

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

以太网电路相关功能说明

RJ45模块用于PHY芯片之间的互连&#xff0c;如图1所示&#xff0c;RJ45有两种组合形式&#xff0c;一种是分立式&#xff0c;网口变压器和RJ45连接座是分开的&#xff0c;另一种是网口变压器和RJ45集成在一起。 图1 RJ45两种主要形式 接下来以分立式RJ45的百兆网电路做个说明&a…

基于springboot+vue养老院管理系统+lw+源码+讲解+调试+演示视频

第3章 系统分析 用户的需求以及与本系统相似的在市场上存在的其它系统可以作为系统分析中参考的资料&#xff0c;分析人员可以根据这些信息确定出本系统具备的功能&#xff0c;分析出本系统具备的性能等内容。 3.1可行性分析 尽管系统是根据用户的要求进行制作&#xff0c;但…

Matlab基础语法篇(上)

Matlab基础语法&#xff08;上&#xff09; 一、基知&#xff08;一&#xff09;界面介绍&#xff08;二&#xff09;常用快捷键&#xff08;三&#xff09;常用指令&#xff08;四&#xff09;Matlab帮助系统 二、运算基础&#xff08;一&#xff09;变量&#xff08;二&#…

【初阶数据结构】深入解析队列:探索底层逻辑

初阶数据结构相关知识点可以通过点击以下链接进行学习一起加油&#xff01;时间与空间复杂度的深度剖析深入解析顺序表:探索底层逻辑深入解析单链表:探索底层逻辑深入解析带头双向循环链表:探索底层逻辑深入解析栈:探索底层逻辑深入解析队列:探索底层逻辑深入解析循环队列:探索…

熬了一晚上,我从零实现了 Transformer 模型,把代码讲给你听

自从彻底搞懂Self_Attention机制之后&#xff0c;笔者对Transformer模型的理解直接从地下一层上升到大气层&#xff0c;瞬间打通任督二脉。夜夜入睡之前&#xff0c;那句柔情百转的"Attention is all you need"时常在耳畔环绕&#xff0c;情到深处不禁拍床叫好。于是…

客户案例|某大型证券公司数据库运维场景数据安全实践

证券行业涉及股票、债券、基金等金融产品的发行、交易和监管&#xff0c;业务具有数据规模大、数据价值高、数据应用场景复杂的显著特点&#xff0c;其中高速流转的业务系统中含有海量的客户个人信息、交易、行情、咨询等高敏感高价值信息。由于证券期货业务场景所具有的特殊性…

初中生物知识点总结(人教版)

第一章 认识生物 一、 生物的特征&#xff1a; 1&#xff0e; 生物的生活需要营养 2&#xff0e; 生物能进行呼吸 3&#xff0e; 生物能排出身体内产生的废物 4&#xff0e; 生物能对外界的刺激做出反应 5&#xff0e; 生物能生长和繁殖 除病毒以外&#xff0c;生物都是由细胞构…

单例模式(大话设计模式)C/C++版本

单例模式 C 饿汉 /* HM hungry man 饿汉 */ #include <iostream> using namespace std; class Singleton { private:Singleton() { cout << "单例对象创建&#xff01;" << endl; };Singleton(const Singleton &);Singleton &operator(c…

C++ 十进制与十六进制之间相互转换

十进制与十六进制之间相互转换 10_to_16 与二进制类似&#xff0c;十进制转十六进制对16整除&#xff0c;得到的余数的倒序即为转换而成的十六进制&#xff0c;特别地&#xff0c;如果超过10以后&#xff0c;分别用ABCDEF或abcdef来代替10、11、12、13、14、15。 代码1: #in…

【密码学基础】基于LWE(Learning with Errors)的全同态加密方案

学习资源&#xff1a; 全同态加密I&#xff1a;理论与基础&#xff08;上海交通大学 郁昱老师&#xff09; 全同态加密II&#xff1a;全同态加密的理论与构造&#xff08;Xiang Xie老师&#xff09; 现在第二代&#xff08;如BGV和BFV&#xff09;和第三代全同态加密方案都是基…

Git 快速上手

这个文档适用于需要快速上手 Git 的用户&#xff0c;本文尽可能的做到简单易懂 ❤️❤️❤️ git 的详细讲解请看这篇博客 Git 详解&#xff08;原理、使用&#xff09; 1. 什么是 Git Git 是目前最主流的一个版本控制器&#xff0c;并且是分布式版本控制系统&#xff0c;可…

合规与安全双重护航:ADVANCE.AI让跨境支付更无忧

近年来&#xff0c;随着全球化进程的加速和跨境贸易的蓬勃发展&#xff0c;跨境支付的需求大幅增加。根据Grand View Research的报告&#xff0c;2021年全球跨境支付市场规模估计为22.09万亿美元。到2025年&#xff0c;全球跨境支付市场预计将达到35.9万亿美元&#xff0c;较20…

rfid资产管理系统解决方案 rfid固定资产管理系统建设方案

在现代化的仓库储备中&#xff0c;仅仅完成对货物进出的简单批次处理已经不再足够&#xff0c;对库内货品的种类、数量、生产属性、垛位等信息的清晰记录变得至关重要。然而&#xff0c;传统的资产管理方式如条形码在长期使用中逐渐暴露出不耐脏、数据存储量小、读取间隔短、不…

优质可视化大屏模板+动态图表+科技感原件等

优质可视化大屏模板动态图表科技感原件等 软件版本&#xff1a;Axure RP 9 作品类型&#xff1a;高保真 作品内容&#xff1a; 1、大屏可视化模版&#xff08;100套&#xff09;&#xff1a;包含智慧城市、智慧社区、智慧园区、智慧农业、智慧水务、智慧警务、城市交通、电…

新加坡工作和生活指北:教育篇

文章首发于公众号&#xff1a;Keegan小钢 新加坡的基础教育在东南亚处于领先地位&#xff0c;这点基本是人尽皆知&#xff0c;但很多人对其教育体系只是一知半解&#xff0c;今日我们就来深入了解一下。 新加坡的学校主要分为三大类&#xff1a;政府学校、国际学校、私立学校。…