Leveraging Google Places API and Google Maps API for custom area management solutions

As a custom software development company, we face the challenge of developing tailored solutions to meet various requirements. One such solution is a B2B order management application for a pharmaceutical company. The business needs to assign custom geographical areas to area managers responsible for managing orders from customers within their designated areas. In this article, […]

Google Places API custom area management scaled 1 - Leveraging Google Places API and Google Maps API for custom area management solutions

As a custom software development company, we face the challenge of developing tailored solutions to meet various requirements. One such solution is a B2B order management application for a pharmaceutical company. The business needs to assign custom geographical areas to area managers responsible for managing orders from customers within their designated areas. In this article, we will delve into the technical solutions we used to address this problem.

To meet the requirements, we identified the following key components:

  • A map for assigning areas to area managers and allowing customers to select their locations.
  • Services for verifying whether a location falls within a designated area.

To fulfil these needs, we opted for Google services, specifically the Maps JavaScript API, Places API, and Geocoding API. Along with these, we used GeometryFactory for some geometrical calculations.

Selecting customer location

To determine whether a customer is within an area managed by an area manager, the customer needs a location. We implemented this in two ways:

Placing a pin on the map:

Zov5SjZ7VVdLIU9Xv4fC91TZx0nhdxj1E pvB43e3q6ykujzCeH4VHaqBkfFUWm7npMj xFMPxzuO57pbBXL3R8p - Leveraging Google Places API and Google Maps API for custom area management solutions

When a user places a pin on the map, our frontend sends our backend the longitude and latitude coordinates of the pin. We’ll tell you how to get the coordinates in the second part of the article, which is about Google Maps in React. For now, the backend leverages Google Reverse Geocoding, a feature provided by the Geocoding API, to find the corresponding Google Place for these coordinates.

GeocodingResult[] results = GeocodingApi.reverseGeocode(context, new LatLng(latitude, longitude)).await();

  • The context parameter is an instance of the GeoApiContext class, which provides the necessary configuration for the API request.
  • The LatLng parameter represents the coordinates (latitude and longitude) for which you want to retrieve the address information.
  • Each GeocodingResult object represents a result of the reverse geocoding process and contains various information about the location, such as the formatted address, coordinates, and additional details like street name, city, country, and more.

Using the Google Places Autocomplete search bar:

RQMCgs jBhmDbRpm4aX3Cffue7RIcioeltywQ5V7buqExdqRXhFXKAjaW72b ti TFjqEr1CL6kU9tWPBIvB9sNR6AcZ5L JvcEk9aZTSStzF56jivErBdkoVHETWgTX5cpWf4lbeoqdx DuE08G AU - Leveraging Google Places API and Google Maps API for custom area management solutions

Alternatively, customers can use the Google Places Autocomplete search bar to find their desired location. Once a user has selected a place, our backend receives the Google Place ID and retrieves the details, including the coordinates, through the Places API.

PlaceDetails placeDetails = PlacesApi.placeDetails(context, placeId).await();

  • The placeId parameter represents a unique identifier for the place you want to retrieve details for. The placeId is obtained from a previous API call – an autocomplete request in the frontend which we will explain in the second part of the article.
  • The PlaceDetails object represents the detailed information about the specified place. It contains various attributes such as the place’s name, address, phone number, website, rating, reviews, opening hours, and more.

Assigning manager area

The next step in the process is to assign areas to sales managers. The client needed to accomplish this in two ways:

Assigning area by drawing a polygon on the map:

Wg572gm9EM5NEiXny8AQqA - Leveraging Google Places API and Google Maps API for custom area management solutions
  • The user can draw a polygon on the map, encompassing the desired area for a sales manager. The polygon is sent to our backend as a series of coordinates along with their position. We will explain how we did this functionality with React in the second part of the article.
  • The backend utilizes the org.locationtech.jts.geom.GeometryFactory library to verify that the provided series of coordinates does indeed form a valid polygon. This library provides the necessary functionality to create and manipulate geometric objects.
  • Once the polygon is validated, the system proceeds with associating the sales manager with the defined area. This can be done by storing the Polygon object or its coordinates in the database or data structure linked to the respective sales manager.

Assigning area using Google Places Autocomplete search bar:

Alternatively, the system provides the option to use the Google Autocomplete functionality. With this approach, the user can search for an existing Google Place such as a neighbourhood, district, city, zone, etc. and assign it to a sales manager. This functionality is the same as the one used for selecting a customer’s location.

By offering these two methods, placing pins and drawing polygons on the map and utilizing the Google Autocomplete functionality, the system provides flexibility in assigning locations to customers and sales managers. This allows for precise customization based on the client’s preferences and requirements.

Checking whether a location is inside an area

The next challenge we faced was checking whether a customer’s location is inside a sales manager’s area. We used two methods to do this based on the type of the area:

Checking for areas defined by coordinates:

  • For custom areas defined by a set of coordinates, we utilize the GeometryFactory library to perform the necessary calculations.
  • First, the coordinates of the manager’s area are used to create a Polygon object using the createPolygon() method of the GeometryFactory. This Polygon represents the defined area.
  • Similarly, the coordinates of the customer’s location are used to create a Point object using the createPoint() method of the GeometryFactory. This Point represents the customer’s location.
  • To determine if the customer’s location falls within the manager’s area, we use the contains() method of the Polygon object. This method checks whether the Point object representing the customer’s location is inside the Polygon object representing the manager’s area.

Checking for areas defined by Google Place ID:

  • Checking for areas defined by Google Place ID requires a custom solution since Google APIs don’t provide a direct method for this.
  • To address this, we leverage the available information provided by Google Places API, such as place types and address components.
  • Each Google Place has types defining it and hierarchically ordered address components, each of them also with types. Some of the types are continent, country, city, administrative levels, sublocality levels, neighbourhood, etc. You can find all of them in the documentation.
  • We compare the place types and address components of the customer’s location with the manager’s area to determine if the location contains the area in one of its components. If we have a match, then the area contains the location.
  • For example, imagine we have a customer’s location set as The Eiffel Tower, with components Europe, France, Paris, 7th arrondissement and so on. And we have the sales manager area set to 7th arrondissement, which is the neighborhood where the Eiffel tower is located.
  • Additionally, to avoid false positive results, we utilize the fact that each Google place has coordinates of a rectangle that surrounds it. While these coordinates are not precise, they can be used as an additional check.
  • By combining the comparison of place types and address components with the check against the surrounding rectangle’s coordinates, we can determine if the customer’s location is within the manager’s area defined by a Google Place ID.

By employing these two different methods, the system allows for accurate checking of whether a customer’s location falls within a manager’s area, regardless of whether the area is defined by custom coordinates or a Google Place ID. This enables efficient management and accurate assignment of customers to the appropriate sales managers based on their geographical proximity.

Now, let’s explore how we implemented the frontend part in React.

Google Maps integration with React

In React applications, there are multiple ways to incorporate maps. They can be used to display specific locations, areas, routes, and more. One popular approach is to integrate Google Maps, which provides powerful mapping capabilities.

In our project, we utilized the @react-google-maps/api library to implement various functionalities. We’ll highlight a few examples, such as setting address locations with autocomplete functionality, displaying markers on the map, and drawing specific areas using polygons.

To begin, let’s explore how to display a map on the screen using the @react-google-maps/api library. To achieve this, several steps are required:

  • Obtain a Google Maps API key from the Google developers console, ensuring it has access to the Maps JavaScript API.
  • Load the Google Maps API script into the project. This can be easily done using the useJsApiLoader hook provided by the library. Refer to the library’s documentation for alternative methods.
  • Define the necessary map libraries based on the desired features. For our examples, we need the ‘drawing’, ‘places’, and ‘geometry’ libraries.
  • Specify the height and width of the map’s container, as well as the center coordinates and zoom level for the initial view.

Here’s an example of a map component implemented in React:

import React from "react";
import { useJsApiLoader, GoogleMap } from "@react-google-maps/api";
const googleMapLibraries = ["drawing", "places", "geometry"];
const Map = () => {
 const { isLoaded } = useJsApiLoader({
   googleMapsApiKey: "YOUR_GOOGLE_MAPS_API_KEY",
   libraries: googleMapLibraries
   // ...otherOptions
 });
 if (!isLoaded) {
   return null;
 }
 return (
   <GoogleMap
     mapContainerStyle={{
       height: "600px",
       width: "900px"
     }}
     center={{ lat: 0, lng: 0 }}
     zoom={2}
   ></GoogleMap>
 );
};
export default Map;

Once the map is loaded, we can enhance it using the autocomplete functionality. This feature allows users to search for specific addresses or places on the map using the Google Maps database. The Autocomplete component from the library can be employed, either with default styles or customized styles.

It’s important to note that the autocomplete object stored in the state doesn’t provide only the place’s coordinates. It is a complex object containing a lot more data. To obtain the location coordinates, we can utilize the getPlace() function. Once we have the latitude and longitude of the place, we can use the Marker component to display it on the map.

Here’s an example of an autocomplete component:

import React, { useState } from "react";
import { Autocomplete, Marker } from "@react-google-maps/api";


const GoogleMapsAutocomplete = ({ handleAutocomplete }) => {
 const [autocomplete, setAutocomplete] = useState();
 const [position, setPosition] = useState();


 const onLoad = (loaded) => setAutocomplete(loaded);


 const onPlaceChanged = () => {
   const {
     geometry: { location: loc }
   } = autocomplete.getPlace();
   const position = { lat: loc.lat(), lng: loc.lng() };


   setPosition(position);
   handleAutocomplete(position);
 };


 return (
   <div>
     <Autocomplete onLoad={onLoad} onPlaceChanged={onPlaceChanged}>
       <input
         type="text"
         placeholder="Find a place"
         style={autoCompleteStyles}
       />
     </Autocomplete>


     {position && <Marker position={position} />}
   </div>
 );
};


export default GoogleMapsAutocomplete;

Please bear in mind that the default integration of the map lacks certain features. If you wish to enable automatic zoom on the found place, additional code is required. One solution is to implement a function that updates the map’s center and zoom level based on the coordinates of the found place.

const handleAutocomplete = (place) => manageMap({ center: place, zoom: 7 });

Next, we implemented the functionality to define different areas on the map. Google Maps offers various tools for drawing on the map, including shapes like circles, rectangles, lines, and polygons. In our case, polygons were the most suitable shape, and we restricted users to drawing only polygons.

The @react-google-maps/api library provides the DrawingManager object, which simplifies the drawing process. By configuring the drawingManagerOptions object, you can specify the desired shapes, their styles, and other options.

const drawingManagerOptions = {
 drawingControl: true,
 drawingControlOptions: {
   drawingModes: ["polygon"]
 },
 polygonOptions
};

If you need to work with the drawn areas, it’s recommended to store them in the state and utilize the Polygon component for management. When an area is completed, the DrawingManager generates an object containing extensive data. To avoid unnecessary storage, it’s advisable to extract only the required data from the object.

Once the new area is drawn and we have its data, it’s good to remove the draw from the DrawingManager state to avoid duplicated shapes on the map.In our case we would like to keep only the path of the polygon and its center. We will use the center position to display an info window with some information about the area. All this happens in the onAddNewArea function.

 const onAddNewArea = (newArea) => {
   const path = newArea.getPath();


   const bounds = new google.maps.LatLngBounds();


   path.forEach(function (element, index) {
     bounds.extend(element);
   });


   const center = bounds.getCenter();


   setAreas([
     ...areas,
     {
       path: newArea.getPath(),
       center: { lat: center.lat(), lng: center.lng() }
     }
   ]);


   newArea.setMap(null);
 };

Feel free to define custom styles for your areas according to your preferences.

By combining these functionalities, we created a comprehensive solution for assigning areas to managers and managing customer locations within those areas. The React frontend, powered by the @react-google-maps/api library, provided a user-friendly interface for interacting with maps, searching for locations, and visualizing assigned areas.

Check out the React demo here:

Categories