Hands On

Find your perfect apartment with HERE and BCX20

By Stefanie Schwartz, David Stürmer, Nils Jannasch, Tom Stein and Catalina Müller | 08 May 2020

On February 17 - 19 2020, team Place2Be participated in BCX 2020 - Europe's biggest IoT hackathon! During the hackathon we developed a prototype for a web service which helps you to find an apartment based on multiple criteria. In combination with HERE Technologies as an API provider for location services it was possible to ramp up the project in short time.

What is Place2Be?

"Time is what we want most, but what we use worst." - William Penn

Have you ever been looking for an apartment? Well, you can certainly call yourself lucky if your search took less than half a year. Finding an apartment is already a hassle, and when you have finally found an apartment big enough and within the budget, you realize: "What? 1h 30 to work - one way? I don't want that!" - What if...

  • ... you would live nearby your office?
  • ... the kindergarden would be on the way to work?
  • ... your friends and familiy would live nearby?

Place2Be: Finding the best apartment based on your daily life mobility

We don't only seek to find the best apartment for you, but also to fundamentally decrease the overall need for mobility by living closer to the locations you visit regulary. We designed a web page that allows the user to search housing market platforms such as Immoscout24 and additionally provide addresses that matter in their daily life, e.g.

  • 🏢 Their office
  • 🏫 The school of their child
  • 🏡 Or their parents' home

Our solution calculates then a mobility rating based on the user input and ranks the appartments accordingly.

Gif of the website homepage

How does our solution work? 🚀

In our hackathon-prototype, we gathered data from different housing market platforms via web scraping. The addresses of available appartments as well as the user inputs are the basis of our calculations.
As our solution is heavily based on location data we made use of several HERE REST APIs to enrich our results. Our tech stack during this project included:

  • Python for our backend logic and custom REST API
  • JavaScript/React as a framework for our easy to use frontend applications
  • AWS to deploy our service with CloudFront, Lambda & EC2
  • Sketch to design our UI/UX

Integration of the HERE Geocoder API to find text-input-addresses

First of all, we have to tansform the plaintext addresses into geocodes. This applies to both the data from the housing market platforms as well as the addresses the user visits in daily life. In order to do so, we use the HERE Geocoding and Search API .


 HTTP GET 
 https://geocode.search.hereapi.com/v1/geocode?q=Luckenwalder+Str.+4-6%2C+10963+Berlin&apiKey={api-key}
Selection of important locations

The HERE Geocoding and Search API acceptes a search string as query parameter q and returns a geocode (latitude and longitude) that can be used for further processing.

Integration of the HERE Routing API to calculate fastest routes

To calculate the mobility ratings, we want to find out how fast a user can reach their desired destinations from any apartment. We use the HERE Routing API to get the fastest routes between to geocoded locations. The API allows us to specify different waypoints as query parameters.


HTTP GET 
https://route.ls.hereapi.com/routing/7.2/calculateroute.json?
waypoint0=geo!52.5,13.4
&waypoint1=geo!52.5,13.45
&mode=fastest;car;traffic:disabled
&apiKey={api-key}

Additionally, you can specify different transportation modes with the mode parameter. We were always looking for the fastest route independently of the current traffic situation (traffic:disabled). Additionally, the parameter allows to choose a means of transportation:

  • 🚗 Car
  • 👣 Pedestrian
  • 🚃 Public transport
  • 🚲 Bycicle
Selection of transportation type

This allows us to find fastest routes for all means of transportation available to the user of our platform. For each apartment, we retrieve the route to each desired destination with each means of transportation. This leads to quite a few API requests:

  1. Calculating the routes for three destinations e.g.:
    • The user's office
    • Parents
    • School
  2. Calculating the routes for two means of transportation e.g.:
    • Bicycle
    • Public transport

This already leads to 2 * 3 = 6 requests per apartment — this adds up pretty quickly if we want to analyze tens or hundreds of apartments at the same time. Hence, we executed the request concurrently using the Python package aiohttp - a potential caching approach is described in the outlook. The following code snippet shows our function which initializes the requests to the HERE Routing API.


 async def init_requests(origin, destinations, means_of_transportation, results):

This function initializes the single requests and tracks their completion.
param origin: geo-coordinates for the origin.
param destination: a list of geo-coordinates for the destinations.
param mean: a string specifying a single means of transportation.
param results: The list to append the results to.


    async with aiohttp.ClientSession() as session:
        await asyncio.gather(
            *[make_request(session, origin, d, m, results[d]) for m in means_of_transportation for d in destinations]

The function `init_requests` creates an `aiohttp.ClientSession()` and gathers the requests made on this session. The actual request is invoked by calling the function `make_request` which encapsulates building the request URL, executing the request and handling the response. The function looks as follows:


async def make_request(session, origin, destination, mean, results):

This helper funciton executes a single aiohttp request to query the here API and saves the result.
param session: The session to execute the requests on.
param origin: geo-coordinates for the origin.
param destination: a list of geo-coordinates for the destinations.
param mean: a string specifying a single means of transportation.
param results: The list to append the results to.


    params = {
        "apiKey": API_KEY,
        "waypoint0": origin,
        "waypoint1": destination,
        "mode": f"fastest;{mean};traffic:disabled"
    }
    query = urllib.parse.urlencode(params)
    url = BASE_PATH + "?" + query

    async with session.get(url) as resp:
        if resp.status == 200:
            json = await resp.json()
            results.append(
                {
                    "time": json["response"]["route"][0]["summary"]["travelTime"],
                    "distance": json["response"]["route"][0]["summary"]["distance"],
                    "transporation": json["response"]["route"][0]["mode"]["transportModes"][0]
                })
        ...

By executing the requests concurrently, we attempt to reduce the time required to wait for HTTP responses. Moreover, not only the single requests are executed like this, but also the code one layer above: The function init_requests encapsulates the requests necessary for one apartment, represented by the origin parameter. One layer above, init_requests has to be called for each apartment, and this is also handled asynchronously.
For each apartment that matches the user's search requirements (i.e. the city they are looking for etc.) we calculate these routes and based on this, the mobility rating. A high rating means: the apartment's location is best suitable in order to travel to the desired locations. All this data is combined and sent backto the frontend application as an ordered list. We expose this logic to our frontend application via an REST endpoint using Starlette. Starlette allows to execute asynchronous code from the thread which handles the incoming HTTP request. This is required to include all the asynchronous code described above into the request handling.

Further thoughts

In our current design, we use the HERE Routing API. The calculated routes always depend on one means of transportation from start to destination. However, especially in modern city life, routes are often covered by a multitude of transportation options. For instance, a person might drive to the train station by car, take the train into the city and go the "last mile" to their office by e-scooter. The HERE Intermodal Routing API offers such a solution for intermodal mobility. For our use case of calculating mobility ratings for apartments, we would first have to evaluate how the need of switching between different means of transportation could be factored in to the rating. Then the usage of this API (as a replacement or in addition) could provide further benefits for accurate and modern mobility ratings.
To further improve the project we thought about reducing the amout of necessery API requests by applying an intelligent caching. A promising solution is to use caching in combination of rasterization. Futhermore it would be good to preprocess data for the most common residential areas. On the frontend side we thought about integrating the HERE JavaScript Maps API to visualize our results in a more interactive manner.
The BOSCH Connected Experience 2020 was a great experience to build a brand new web service with a new team in a short time, and HERE maps made it even more fun.