How to Plan Routes to Nearby Places in an App?
Tags: java, programming
Published: 2022-06-08 02:33:41

Route planning is a very common thing that all of us do in our daily lives. Route planning in apps allows users to enter a location that they want to go to and then select an appropriate route based on various factors such as the estimated time of arrival (ETA), and is applicable to a wide range of scenarios. In a travel app for example, travelers can select a starting point and destination and then select an appropriate route. In a lifestyle app, users can search for nearby services within the specified scope and then view routes to these service locations. In a delivery app, delivery riders can plan optimal routes to facilitate order pickup and delivery.

So, how do we go about implementing such a useful function in an app? That's exactly what I'm going to introduce to you today. In this article, I'll show you how to use HMS Core [Site Kit](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-sdk-introduction-0000001050158571?ha_source=hms1) (place service) and [Map Kit](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-sdk-brief-introduction-0000001061991343?ha_source=hms1) (map service) to build the route planning function into an app. First, I will use the place search capability in the place service to build the function of searching for nearby places in a specific geographical area by entering keywords. During actual implementation, you can choose whether to specify a geographical area for place search. Then, I will use the route planning capability in the map service to build the function of planning routes to destination places and showing the planned routes on an in-app map. In order to quickly pinpoint the precise location of a user device, I will use the fused location capability which implements precise positioning by combining GNSS, Wi-Fi, and base station data. In addition, the map service provides map data covering over 200 countries and regions and supports hundreds of languages, helping provide the best user experience possible for users all over the world. On top of this, the map service can plan routes for different modes of transport based on the real-time traffic conditions, and calculate the ETAs of the planned routes.

## Demo
The map service supports three transport modes: driving, cycling, and walking. It can quickly plan several appropriate routes based on the selected transport mode, and show the distances and ETAs of these routes. The figure below shows the route planning effects for different transport modes.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5bjospeum6uqr3861vru.png)
_Route planning effects for different transport modes_

On top of this, the map service allows users to choose the shortest route or fastest route based on the traffic conditions, greatly improving user experience.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f7zctwnylom9p7w6gctg.png)
_Preferred route choosing_

## Integration Procedure
1) Register as a developer and create an app in AppGallery Connect.
i. Visit [AppGallery Connect](https://developer.huawei.com/consumer/en/service/josp/agc/index.html%20?ha_source=hms1#/) to register as a developer.
ii. Create an app, add the SHA-256 signing certificate fingerprint, enable Map Kit and Site Kit, and download the **agconnect-services.json** file of your app.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6hjpd1sdwwtuvqi41uj0.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zbmclmx6h4tdqak402bx.png)

2) Integrate the Map SDK and Site SDK.
i. Copy the **agconnect-services.json** file to the app's root directory of your project.

- Go to **allprojects** > **repositories** and configure the Maven repository address for the SDK.
- Go to **buildscript** > **repositories** and configure the Maven repository address for the SDK.
- If you have added the **agconnect-services.json** file to your app, go to **buildscript** > **dependencies** and add the AppGallery Connect plugin configuration.

```
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()
    }
}
```
ii. Add build dependencies in the **dependencies** block.

```
dependencies {
    implementation 'com.huawei.hms:maps:{version}'
    implementation 'com.huawei.hms:site:{version}'
}
```
iii. Add the following configuration to the file header:

```
apply plugin: 'com.huawei.agconnect'
```
iv. Copy your signing certificate file to the **app** directory of your project, and configure the signing information in **android** in the **build.gradle** file.

```
signingConfigs {
    release {
        // Signing certificate.
            storeFile file("**.**")
            // KeyStore password.
            storePassword "******"
            // Key alias.
            keyAlias "******"
            // Key password.
            keyPassword "******"
            v2SigningEnabled true
        v2SigningEnabled true
    }
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        debuggable true
    }
    debug {
        debuggable true
    }
}
```

## Main Code and Used Functions
1) Keyword search: Call the keyword search function in the place service to search for places based on entered keywords and display the matched places.

```
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;
        }

        mFirstAdapter.refresh(siteList);

        StringBuilder response = new StringBuilder("\n");
        response.append("success\n");
        int count = 1;
        AddressDetail addressDetail;
        Coordinate location;
        Poi poi;
        CoordinateBounds viewport;
        for (Site site : siteList) {
            addressDetail = site.getAddress();
            location = site.getLocation();
            poi = site.getPoi();
            viewport = site.getViewport();
            response.append(String.format(
                    "[%s] siteId: '%s', name: %s, formatAddress: %s, country: %s, countryCode: %s, location: %s, poiTypes: %s, viewport is %s \n\n",
                    "" + (count++), site.getSiteId(), site.getName(), site.getFormatAddress(),
                    (addressDetail == null ? "" : addressDetail.getCountry()),
                    (addressDetail == null ? "" : addressDetail.getCountryCode()),
                    (location == null ? "" : (location.getLat() + "," + location.getLng())),
                    (poi == null ? "" : Arrays.toString(poi.getPoiTypes())),
                    (viewport == null ? "" : viewport.getNortheast() + "," + viewport.getSouthwest())));
        }
        resultTextView.setText(response.toString());
        Log.d(TAG, "onTextSearchResult: " + response.toString());
    }

    // 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);
```
2) Walking route planning: Call the [route planning API](https://developer.huawei.com/consumer/en/doc/development/HMSCore-References-V5/directions-walking-0000001050161494-V5?ha_source=hms1) in the map service to plan walking routes and display the planned routes on a map.

```
NetworkRequestManager.getWalkingRoutePlanningResult(latLng1, latLng2,
        new NetworkRequestManager.OnNetworkListener() {
            @Override
            public void requestSuccess(String result) {
                generateRoute(result);
            }

            @Override
            public void requestFail(String errorMsg) {
                Message msg = Message.obtain();
                Bundle bundle = new Bundle();
                bundle.putString("errorMsg", errorMsg);
                msg.what = 1;
                msg.setData(bundle);
                mHandler.sendMessage(msg);
            }
        });
```

## Conclusion
Route planning is a very useful function for mobile apps in various industries. With this function, mobile apps can provide many useful services for users, thus improving the stickiness of their users.

In this article I demonstrated how integrating Map Kit and Site Kit is an effective way to implement route planning into an app. The whole implementation process is straightforward, empowering developers to implement route planning for their apps with ease.