[Power Apps – Geospatial features] How to implement a radius-based location search ?

Today, we’re going to look at some of the geospatial features offered by Power Apps. In particular, we will implement a radius-based location search. In other words, we will implement a filter that returns records that are around a location according to a given distance.

To make the learning experience less boring, we will implement an application that will display Vinyl’s sellers in Detroit (#detroittechno)

The app features 3 functionalities:

  • Display all vinyl sellers in a map
  • Display a circle with a given radius and center
  • Filter the records so that their location must be within the search radius.

Before going to the implementation, let’s first look at the data source. In this scenario, I used Dataverse as a data source, and it’s the account table that represents Vinyl stores. The location of each store is stored in the two columns address1_longitude and address1_latitude. Below is a screenshot of the account table data:

Show stores on the map:

Here, nothing special, we will use the OOB feature of the Map control that Power Apps offers. Indeed, just pass a collection to the Map control at the level of the “Items” property. Then specify the columns that contain the name, Lat and Lon of the store.

The Show All button allows to load the Collection from Dataverse:

Display a circle with a given radius and center

Now things are getting interesting! Indeed, the control Map supports the addition of shapes on a map. All shapes added to the control map must respect a certain format called GeoJSON format. For more details on adding shapes to the control map, I highly recommend the following documentation, which I find quite rich in information.

To display a circle on the map with center C and radius R. Just pass the following parameters:

  • Shapes_items: A collection of Shapes. Each Shape is defined by a GeoJSON Column.
  • ShapeGeoJSONObjects: GeoJSON definition of the shape.
  • ShapeColors (Optional): the color of the shape.

Below is the JSON definition for a circle with a center C = (Lon,Lat) and a radius in meters: 2000:

{
    "type": "Feature",
    "properties": {
        
        "subType": "Circle",
        "radius": 2000   
    },
    "geometry": {
        "type": "Point",
        "coordinates": [
            currentLocation.Lon,
            currentLocation.Lat
        ]
    }
}

Now just build the Circle Collection as follows:

ClearCollect(
             Circle,
             {
               color: Your Favorite color,
               geoJson: Circle JSON definition (As text),
             }
)

As you can see, the GeoJson definition must be text. To escape the special characters like the accolades ‘{}’ and the double quote ‘”‘ I used the following expression. Please feel free to share other ways to build the json!

ClearCollect(Circle,
{color: "rgb(116,39,116)",geoJson:$"{Char(123)}{Char(34)}type{Char(34)}:{Char(34)}Feature{Char(34)},{Char(34)}properties{Char(34)}:{Char(123)}{Char(34)}subType{Char(34)}:{Char(34)}Circle{Char(34)},{Char(34)}radius{Char(34)}:{Value(RadiusInput.Text)*1000}{Char(125)},{Char(34)}geometry{Char(34)}:{Char(123)}{Char(34)}type{Char(34)}:{Char(34)}Point{Char(34)},{Char(34)}coordinates{Char(34)}: [{currentLocation.lon},{currentLocation.lat}
]{Char(125)
}{Char(125)
}"})

Finally, you just have to bind the right variables, expressions and buttons to display a nice circle.

Filter the records so that their location must be within the search radius:

Now, the goal is to filter the accounts (100% Delegable) so that their geolocation must be inside the circle. For this, I was inspired by the following implementation made with php and node js.

Below is the filter that was used:

UpdateContext(
    {
        minLat: currentLocation.lat - RadiusInput.Text / 6371 * 180/Pi(),
        maxLat: currentLocation.lat + RadiusInput.Text / 6371 * 180 / Pi(),
        minLon: currentLocation.lon - RadiusInput.Text / 6371 * 180 / Pi()/Cos(currentLocation.lat * Pi() / 180),
        maxLon: currentLocation.lon + RadiusInput.Text / 6371 * 180 / Pi()/Cos(currentLocation.lat * Pi() / 180)
    }
);

ClearCollect(
    AccountsCollections,
    Filter(
        Accounts,
        Latitude < maxLat And Latitude > minLat And Longitude < maxLon And Longitude > minLon
    )
);

Important note: If you notice, I did not use the standard address1_latitude and address1_longitude columns at the filter. In fact, I created two new columns of decimal type that take the same values. Indeed, the use of the two OOB columns raises an error at runtime.

I hope the description of these steps is clear enough. Feel free to leave a comment or contact me directly for more information. Hope it helps and enjoy the music …

One thought on “[Power Apps – Geospatial features] How to implement a radius-based location search ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s