Exploring Google Map Compose For Android

An introduction to a brand new period for map-based Compose purposes

Picture by Will H McMahan on Unsplash

With the recent release of the Map Compose library, it was excellent timing to attempt it out for the undertaking I’m constructing with Jetpack Compose. On this utility, I fetch an inventory of factors of curiosity (POIs) from my server round a given space and mark them on the map.

I may have caught with the View-based GoogleMap and wrapped it inside a AndroidView to invoke it within the Compose world. Particularly in the event you’d want some superior options because the Compose library nonetheless suffers from some limitations (extra on this later).

However I anticipate a few of you’re as excited as I’m to find this new library made in Compose, for Compose.

This text will stroll you thru render a map with dynamic markers. We’ll additionally cowl refresh these POIs whereas interacting with the map (panning, zooming, rotating).

To render a map in your cellular utility, you’ll have to undergo this tedious half coated on this documentation. To summarize, you need to:

  • Create (or hyperlink) your Google Cloud Billing account to your undertaking. In 2018, Google migrated to a pay-as-you-go plan that requires each undertaking to configure upfront your fee particulars. On this tutorial, we’ll use a static map with the cellular SDK so we’ll keep beneath the radar. However relying on what you later plan to your app, there’s a potential price to contemplate. Extra info here.
  • Allow the Map SDK to your undertaking.
  • Create an API key. You may prohibit it to keep away from malicious utilization by linking it to the SHA-1 certificates you’re utilizing to signal your app.
  • Add the required dependencies and hyperlink your API key to your AndroidManifest file.

The enjoyable half begins when you’ve accomplished the above steps.

The library exposes a GoogleMap Composable as an entry level to render your map. A number of elective arguments allow you to customise your map expertise.

Should you don’t present any arguments, you’ll see a world map centered on the equator and the prime meridian.

The world map from lat/lng 0

Should you have a look at the constructor particulars, the GoogleMap takes a CameraPositionState with a default place on the latitude and longitude 0.

We’ll wish to place our map round a particular location — or your present location however I gained’t cowl it on this article.

The map is pushed by a single supply of fact: the digicam’s state CameraPositionState . Everytime you work together with the map, the state will get up to date and a recomposition happens.

For example, I’ll heart the digicam round Bordeaux 🍷🥖🇫🇷. We’ll keep in mind these coordinates utilizing the rememberCameraPositionState perform and cross them to the GoogleMap Composable. Right here, I’ve arbitrarily set the zoom degree to 12 to miss the entire Bordeaux space.

After we run the app, that is what we get:

Bordeaux space

That’s all it is advisable to show a map with Map Compose! Spectacular no? Now, it might be nice to show some POIs.

The GoogleMap Composable accepts a content material lambda as its final parameter to allow you to draw on the map. For that, we’ll wish to have a look at the Marker Composable. It accepts a MarkerState — a wrapper for a LatLng object.

By default, the Marker will present a basic pink pinpoint. You may customise it with its different parameters.

For my functions, I’ve developed an API with a route that returns an inventory of objects round a sure location. It takes three parameters:

  • a latitude
  • a longitude
  • a radius (in meters)

From the CameraPositionState, we are able to retrieve the middle place from the map’s digicam:

val centerLocation = cameraPositionState.place.goal
val latitude = centerLocation.latitude
val longitude = centerLocation.longitude

We’ll want some assist computing the radius. The trick lies in changing the zoom degree given by the map — a digit ranging from 0 (the entire planet) to greater than 21 — right into a extra human-friendly radius in meters. Should you’d prefer to be taught extra about how Google renders the map, you’ll discover this article very attention-grabbing.

Google offers a maps utility library that computes this distance for us by taking one nook of the map (high left for example) with the middle place.

val topLeftLocation = cameraPositionState.projection?.visibleRegion?.farLeft
val radius = SphericalUtil.computeDistanceBetween(topLeftLocation, centerLocation)

You’ll have to have your map able to retrieve the above values (or the projection might be null). A superb place to request them could be inside the onMapLoaded lambda. That’s the place I’ll ask my ViewModel to retrieve the places of the POIs inside the computed radius.

Lastly, I iterate by my marker coordinates to generate all my Marker Composables.

To simulate this, you’ll be able to create a set of coordinates and provides it to your GoogleMap Composable the identical approach you’d fetch them from an API.

Here’s what you’ll see with the coordinates my server yields:

An inventory of markers within the Bordeaux space

However that is solely a snapshot of some POIs from what the digicam sees. Finally, you’ll wish to refresh these POIs whereas interacting along with your map.

The map helps you to management what to show by gestures akin to panning, zooming, and even rotating. These interactions are certain to vary what the digicam sees. Therefore, your POIs should change accordingly.

With Map Compose, you’ll as soon as once more depend on your single supply of fact: the CameraPositionState. It has a property referred to as isMoving that can flip to true as quickly because the map strikes. And it goes again to false when the digicam turns into idle.

It’s possible you’ll be tempted to easily wrap your fetching technique inside an if-condition like this:

Though that will work, you’ll create extreme requests to your server!

That’s because of the nature of how the recomposition works. As an example, in the event you pan the map, the digicam’s heart location will change. Because the map strikes, you’ll refresh your POIs with the newly noticed centered place. The fetched POIs are more likely to differ, so your state will change, resulting in a recomposition.

It means you’ll hit once more the situation and refresh your POIs till your state stops altering — that would result in an amazing quantity of requests!

As an alternative, you need to deal with this interplay as a side-effect and wrap it accordingly. Because you’d prefer to set off such an impact when the isMoving state modifications, you should utilize LaunchEffect and cross this worth as its key. Lastly, refresh your POIs when the map stops shifting.

I’ve made a brief video as an example how the refresh behaves. Even after I fling quick the map — the map blurs till the animation stops — the POIs get displayed when the map turns into idle.

Refreshing POIs whereas panning and zooming the map

And what’s attention-grabbing with this Compose strategy is the efficiency behind it! Due to the recomposition system, you’ll be able to cross the checklist of POIs and the map will show solely these markers. No have to maintain the lifecycle nor to be sure you’ve correctly cleared your earlier markers that the digicam not shows. To not point out the code is extremely readable and simply requires just a few traces of code.

Should you’re nonetheless right here, congratulations! We’ve coated some fundamentals on use the Map Compose and displayed POIs whereas interacting with the map.

Despite the fact that that is likely to be sufficient for a few of you, there are some issues value mentioning earlier than a full dive into this library.

There are issues that you could be anticipate to have however should not but prepared with Map Compose. That’s the case with clustering.

This mechanism gathers a set of POIs inside the similar space. With out it, chances are you’ll find yourself having a map filled with markers!

Can you see what you’re searching for amongst these 10 000 POIs?

Not solely you’ll be able to’t see a lot on the map, however you’ll be able to think about how poor the efficiency might be when making an attempt to attract all these markers.

You may obtain clustering due to the ClusterManager from the util library talked about above. But, this supervisor wants a GoogleMap from the View library — it may be complicated for the reason that title matches, however it’s not the GoogleMap from the Compose library.

In order I’m writing these traces, the Map Compose library doesn’t help but clustering. You may comply with the open challenge here.

Within the meantime, you’re left with a few choices:

  1. Maintain utilizing the previous map API till clustering is supported.
  2. Limit your zoom degree to an affordable worth. That would forestall rendering numerous POIs as a lot as holding the map from lagging. However this gained’t substitute an excellent clustering since your density of POIs might range from one space to a different. Your consumer expertise could also be degraded relying on the info you wish to show.

With that in thoughts, you’re all set to start out utilizing the Map Compose library. I’m optimistic it’ll turn out to be a game-changer for the map-based utility as quickly as it can meet up with the lacking options.

Within the meantime, hold monitor of their GitHub repository for the upcoming releases. Have enjoyable with the Map Compose!

More Posts