如何实现地图App中附近地点搜索及聚合标记功能

原创
2021/06/23 17:38
阅读数 3.1K

在日常的应用中,经常有需要展示地图,并且在地图上显示地图标记的需求。华为HMS的Map Kit提供了这样的能力。可以先绘制地图,然后在地图上绘制标记点,并按不同比例尺实现不同的标记聚合。本文将具体展示如何结合定位、位置、地图服务的相关能力,实现附近服务搜素,并在地图上显示出来。

应用场景

  • 旅行类应用,可以搜索景点,然后在地图上显示各个景点。
  • 共享类应用,比如共享单车,可以在地图上绘制附件的单车。

项目用到的关键功能点

定位服务: 使用定位服务获取当前设备经纬度坐标。
关键字搜索:使用位置服务关键字搜索能力通过指定的关键字和可选的地理范围,查询诸如旅游景点、企业和学校之类的地点。
地图显示:使用地图服务地图显示能力在界面上绘制地图。
聚合标记:使用地图服务聚合标记能力在显示的地图上绘制标记,且不同比例尺可以对标记进行不同程度的聚合。

集成准备

1.  AGC账号注册,项目创建
1)    注册成为开发者 
注册地址:https://developer.huawei.com/consumer/en/service/josp/agc/index.html?ha_source=hms1

2)    创建应用,添加sha256,开启map/site开关,下载json文件

2.  集成Map + Site SDK

1)    将“agconnect-services.json”文件拷贝到应用级根目录下
•    在“allprojects > repositories”中配置HMS Core SDK的Maven仓地址。
•    在“buildscript > repositories”中配置HMS Core SDK的Maven仓地址。
•    如果App中添加了“agconnect-services.json”文件则需要在“buildscript > dependencies”中增加agcp配置。

buildscript {
    repositories {
        maven { url 'https://developer.huawei.com/repo/' }
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.2'
        classpath 'com.huawei.agconnect:agcp:1.3.1.300'
    }
}
allprojects {
    repositories {
        maven { url 'https://developer.huawei.com/repo/' }
        google()
        jcenter()
    }
}

2)    在“dependencies ”中添加如下编译依赖

    implementation 'com.huawei.hms:maps:{version}'
    implementation 'com.huawei.hms:site:{version}'
	implementation 'com.huawei.hms:location:{version}'
}

3)    在文件头添加配置

apply plugin: 'com.huawei.agconnect'

4)    在android中配置签名。将生成签名证书指纹用的签名文件复制到您工程的app目录下,并在“build.gradle”文件中配置签名

signingConfigs {
    release {
        // 签名证书
            storeFile file("**.**")
            // 密钥库口令
            storePassword "******"
            // 别名
            keyAlias "******"
            // 密钥口令
            keyPassword "******"
            v2SigningEnabled true
        v2SigningEnabled true
    }
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        debuggable true
    }
    debug {
        debuggable true
    }
}

项目中用到的主要代码及功能

1. 定位服务获取定位

private void getMyLoction() {

        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        SettingsClient settingsClient = LocationServices.getSettingsClient(this);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        mLocationRequest = new LocationRequest();
        builder.addLocationRequest(mLocationRequest);
        LocationSettingsRequest locationSettingsRequest = builder.build();
//检查设备定位设置
        settingsClient.checkLocationSettings(locationSettingsRequest)
                .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
                    @Override
                    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                        //设置满足定位条件,再发起位置请求
                        fusedLocationProviderClient
                                .requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
                                .addOnSuccessListener(new OnSuccessListener<Void>() {
                                    @Override
                                    public void onSuccess(Void aVoid) {
                                        //接口调用成功的处理
                                        Log.d(TAG, "onSuccess: " + aVoid);
                                    }
                                });
                    }
                }) 

2. 文本搜索:通过实现位置服务中的TextSearch功能实现文本内容搜索,获取附近服务点。

SearchResultListener<TextSearchResponse> resultListener = new SearchResultListener<TextSearchResponse>() {
    // Return search results upon a successful search.
    @Override
    public void onSearchResult(TextSearchResponse results) {
        List<Site> siteList;
        if (results == null || results.getTotalCount() <= 0 || (siteList = results.getSites()) == null
                || siteList.size() <= 0) {
            resultTextView.setText("Result is Empty!");
            return;
        }
	updateClusterData(siteList);//更新服务点到地图标记
    }

    // Return the result code and description upon a search exception.
    @Override
    public void onSearchError(SearchStatus status) {
        resultTextView.setText("Error : " + status.getErrorCode() + " " + status.getErrorMessage());
    }
};
// Call the place search API.
searchService.textSearch(request, resultListener);

3. 地图绘制 

@Override
    public void onMapReady(HuaweiMap huaweiMap) {
        hMap = huaweiMap;
        hMap.moveCamera(CameraUpdateFactory.newLatLngZoom(Constants.sMylatLng, 1));
        hMap.setMyLocationEnabled(true);
        hMap.getUiSettings().setMyLocationButtonEnabled(true);
        initCluster(huaweiMap);

    }

4. 和在地图上绘制聚合标记

private ClusterManager<MyItem> mClusterManager;
List<MyItem> items = new ArrayList<>();

private void initCluster(HuaweiMap hMap) {
    mClusterManager = new ClusterManager<>(this, hMap);
    hMap.setOnCameraIdleListener(mClusterManager);
    // Add a custom InfoWindowAdapter by setting it to the MarkerManager.Collection object from
    // ClusterManager rather than from GoogleMap.setInfoWindowAdapter
//refer: https://github.com/billtom20/3rd-maps-utils  
    mClusterManager.getMarkerCollection().setInfoWindowAdapter(new HuaweiMap.InfoWindowAdapter() {
        @Override
        public View getInfoWindow(Marker marker) {
            final LayoutInflater inflater = LayoutInflater.from(SearchClusterActivity.this);
            final View view = inflater.inflate(R.layout.custom_marker_window, null);
            final TextView textView = view.findViewById(R.id.textViewTitle);
            String text = (marker.getTitle() != null) ? marker.getTitle() : "Cluster Item";
            textView.setText(text);
            return view;
        }

        @Override
        public View getInfoContents(Marker marker) {
            return null;
        }
    });
   
}
//更新聚合标记
private void updateClusterData(List<Site> siteList) {
    items  = new ArrayList<>();
    mClusterManager.clearItems();
    for (Site s:
            siteList) {
        Coordinate location = s.getLocation();
        MyItem myItem = new MyItem(location.lat,location.lng,s.name,s.formatAddress);
        items.add(myItem);
    }
    mClusterManager.addItems(items);
    Coordinate coordinate =  siteList.get(0).getLocation();
    LatLng latLng = new LatLng(coordinate.lat,coordinate.lng);
    mClusterManager.cluster();
    hMap.animateCamera(CameraUpdateFactory.newLatLngZoom (latLng,14 ));
}

项目成果展示

Query中输入想搜索的地点、服务, 点击search 按钮,下方地图显示相应的聚合坐标

>>访问华为地图服务官网,了解更多相关内容
>>获取华为地图服务开发指导文档
>>华为HMS Core官方论坛
>>华为地图服务开源仓库地址:GitHubGitee

点击右上角头像右方的关注,第一时间了解华为移动服务最新技术~

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部