Life Hacking 2.0: Adding Geographical Filters to Flat Search Websites with QGIS and Python
Contents
Create sophisticated walking isochrones for Milan’s metro stops and search for flats with immobiliare! Reproducible for all of Italy!
Intro
Looking for a flat, I encountered the problem before: if you live in a big city, good public transport is a must. However, search engines for housing seldomly offer necessary geographic filters like “max 7 mins to the next metro stop”. It’s for sure a knock-out criterion but time-consuming to check individual ads for their location.
That’s the reason why already last year I took on idealista.it and implemented a pure frontend geographical filter function with turf.js, all in javascript. If you didn’t read it yet go ahead and take a look: Life Hacking: Adding Geographical Filters to Flat Search Websites with Turf.js
This time I will focus on a different platform: immobiliare.it.
Idea
Find all offers on immobiliare
- within your custom area of interest and more importantly
- within 7 minutes walking distance of multiple metro stops
Isochrones
Immobiliare already offers an open end-point for walking/driving isochrones (the accessible area from a given point in a certain time) or a radius which is indeed quite useful.
How does immobiliare's filter API work?
Their isochrone API is publicly available and delivers good (simplified) results. A request for the metro stop Missori
with the coordinate 9.1896, 45.45986
with a range of 7 minutes by foot looks like this:
|
|
You can see this request to their API by simply opening your browser console with F12
and switching to network
tab. After generating a new isochrone you should see the request popping up.
Metro Stops Buffer
While writing this post, immobiliare actually implemented a big part of what I wanted to do - bad luck for me but good for everyone in the end. 😄
You can simply select the metro stops you like to be buffered with a fixed radius of ~500m. Definitely a cool feature and for me the first time I see it on any platform!
However our aim is more complex as we would like a geometry filter with customizable walking isochrones for all desired metro stops or other points of interest like schools or supermarkets within our area of interest.
In order to keep it simple, I will use their dedicated API endpoint for custom AOIs. This offers the big advantage that by the end of this tutorial you can create your own filter polygon once (or use mine) and check it regularly on immobiliare if you like!
No external software or coding required - do it once, bookmark the link and use it until you hopefully find a nice flat!
Trial and Error
I tried to find a way to combine multiple geometries in their API but it’s either not (yet) implemented or not allowed, i.e. you cannot combine either of the following parameters.
Metro stop parameter:
fkMetro[0]=10&fkMetroStation[0]=1173
Radius:
raggio=500¢ro=45.47829%2C9.156734
Custom area of interest:
vrt=45.468919%2C9.167576%3B45.454592%2C9.183025%3B45.464465%2C9.20002%3B45.474698%2C9.172554%3B45.468919%2C9.167576
E.g. not working:
fkMetro[0]=10&fkMetroStation[0]=1173&vrt=45.468919%2C9.167576%3B45.454592%2C9.183025%3B45.464465%2C9.20002%3B45.474698%2C9.172554%3B45.468919%2C9.167576
Hands on in QGIS!
Enough web dev stuff, let’s get into QGIS!
OpenStreetMap or Open Source Data
Let’s get some data. Either you could retrieve the data from OSM or in this case directly from Milan’s open data portal.
Find the metro data sets here or download the GeoJSON directly here.
If the link might break over time, download my 💾 local copy.
|
|
Limits
Before processing we need to know what the result needs to look like. There are certain limits:
- As later we will use a normal GET-Request in immobiliare for the final results, the URL length is limited to ~2000 characters.
- Apart from that, immobiliare can only digest a normal polygon not a multi-polygon or similar which means that the individual geometries must be connected and “holes” are not permitted.
Geo-Processing in QGIS
1. Load all your points of interest (POIs)
Load the GeoJSON in QGIS. At this point you could add any other POIs like schools for your kids, supermarkets or you work place. If so, add the layer to QGIS and Merge vector layers
. After doing so you will end up with a point geometry layer. Add an OSM base map for better overview e.g. with Quick Map Services Plugin.
2. Isochrones for all your POIs As immobiliare provides an open API for those isochrones one could use it and create individual isochrones for each metro stop coordinate.
|
|
The script saves all isochrones to individual GeoJSON files in isochrones
directory. You should end up with a folder of 110 (at the time of writing) metro stop isochrones.
When loading them in QGIS, you end up with a nice confetti map.
3. Processing isochrones
Merge vector layers
anddissolve
the geometries.
Nicer, high-res version made with mapbox for #30daymapchallenge 2022
- Enter editing mode and clean up the geometry and remove tiny holes with
vertex tools
.
Most of the holes are relatively tiny and wouldn’t make a big difference. So for simplicity just remove them.
- Simplify inner hole.
Piazza Sempione is relatively far away from the closest metro stop and hence must be kept.
- A surgical cut
Piazza Sempione is surrounded by accessible areas. In order to create a normal polygon, we need to make a tiny surgical cut.
Create a New Layer
and switch to Edit Mode
and Add Line Feature
. Buffer
the line and Clip
the former dissolved layer with the buffered line.
- Link separate geometries
Milan’s city center has a high density of metro stops whereas in the periphery it becomes more sparse.
Again, create a New Layer
and switch to Edit Mode
and Add Line Feature
. This time, link all polygons with a line, then Buffer
, Merge vector layers
, Dissolve
.
- Clip to your area of interest
Theoretically, this polygon could be used to filter immobiliares database. However, there way too many vertices - to be exact 1191 in my version. Remember that the URL has a limit of 2000 characters and that you might need additional filter criteria reducing the limit further.
Download the full polygon 💾 here for your own processing.
Hence, add a new layer and clip to your area of interest, e.g. the center. Simplify your polygon to well below 100 vertices maximum and export as GeoJSON with coordinate precision
6.
Download the center isochrones file 💾 here.
Convert GeoJSON to URL
The geometry is finished but we still need to transform the geometry to the URL parameter. As GeoJSON’s standard is lon lat but the URL requires lat lon, they need to be switched - how could it ever be any different? 😅
Python offers the quickest solution through a simple list comprehension.
|
|
Output
|
|
Now, simply replace the brackets with a semicolon and remove white spaces.
|
|
Output
|
|
Perfect, now set all filter criteria in immobiliare as you would usually, draw a random area, confirm and copy the link from the adress bar, e.g.
Now just replace the parameter vrt
value with your polygon. In my case with 1967 characters it’s quite close to the limit of 2000 but that’s fine. If does not work for you, go back to step 6 and delete a few vertices.
And there you go! Enter the link and see all the filtered results. You can simply bookmark the link or even edit the nodes directly in the online editor!
Use your own POIs!
As mentioned in the intro, instead of only using metro stops, one could mix up different POIs like e.g. schools or tram/bus stops, your workplace or the sport facilities as well. It’s a powerful workflow that hopefully helps you to find a flat sooner and with less overhead! Also, if you don’t want to use walking isochrones, you can use driving isochrones or even mix them up. If you want to keep it simple, you could always work with a normal QGIS buffer
in meters instead.
If you like this tutorial, if it helped you or if you have more ideas on how to improve the workflow let me know on Twitter or LinkedIn!