Developer docs menu

Neighbourhood grid with map rectangles

Advanced

Split a city into grid cells, query each with a bounding box and export GeoJSON for a map.

Setup

This tutorial uses the jokerprice.py helper from the quickstart. Save it next to your script and set JOKERPRICE_API_KEY.

Bounding-box queries

/api/v1/metrics accepts north, south, east and west instead of city. The rectangle must be at most 5 degrees across, with south below north and west below east.

Python
from jokerprice import api

box = {"north": 24.85, "south": 24.70, "east": 46.80, "west": 46.60}   # central and north Riyadh
m = api("GET", "/api/v1/metrics", params={**box, "past_days": 60})["metrics"]
print(m["listings"]["tracked"], "tracked listings |", m["maturity"], "| occupancy", m["past"]["occupancy"])

Build a grid

Each cell is one request. A 4 × 4 grid is 16 requests; the helper waits automatically if you reach 120 per minute.

Python
def grid(box, rows, cols):
    lat_step = (box["north"] - box["south"]) / rows
    lng_step = (box["east"] - box["west"]) / cols
    for r in range(rows):
        for c in range(cols):
            south, west = box["south"] + r * lat_step, box["west"] + c * lng_step
            yield {"south": round(south, 5), "north": round(south + lat_step, 5), "west": round(west, 5), "east": round(west + lng_step, 5)}

cells = []
for cell in grid(box, 4, 4):
    m = api("GET", "/api/v1/metrics", params={**cell, "past_days": 60})["metrics"]
    cells.append({**cell, "tracked": m["listings"]["tracked"], "maturity": m["maturity"],
                  "occupancy": m["past"]["occupancy"], "adr": m["past"]["adr"]})

Export GeoJSON

Write the cells as polygons. Open the file in geojson.io, QGIS or kepler.gl and colour by occupancy. Cells that are still collecting are kept but marked, so empty areas stay visible.

Python
import json

features = []
for c in cells:
    ring = [[c["west"], c["south"]], [c["east"], c["south"]], [c["east"], c["north"]], [c["west"], c["north"]], [c["west"], c["south"]]]
    ok = c["maturity"] == "estimating"
    features.append({"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [ring]},
                     "properties": {"tracked": c["tracked"], "maturity": c["maturity"],
                                    "occupancy": round(c["occupancy"], 3) if ok else None,
                                    "adr": round(c["adr"]) if ok and c["adr"] else None}})
json.dump({"type": "FeatureCollection", "features": features}, open("riyadh-grid.geojson", "w"))

Listings inside a rectangle

/api/v1/listings filters by city only, so filter coordinates yourself.

Python
from jokerprice import all_listings

inside = lambda l, b: l.get("latitude") is not None and b["south"] <= l["latitude"] <= b["north"] and b["west"] <= l["longitude"] <= b["east"]
listings = [l for l in all_listings("riyadh") if inside(l, box)]
print(len(listings), "listings in the box")