Skip to content

Tutorial: Getting Started with poiidx

This tutorial will guide you through setting up and using poiidx for the first time. By the end, you'll be able to query Points of Interest and administrative boundaries from OpenStreetMap data.

What You'll Learn

  • How to install and configure poiidx
  • How to set up a PostgreSQL database with PostGIS
  • How to find nearby Points of Interest
  • How to retrieve administrative boundaries

Prerequisites

  • Python 3.8 or higher
  • Basic knowledge of Python
  • Access to install PostgreSQL on your system

Step 1: Install PostgreSQL and PostGIS

First, you need a PostgreSQL database with PostGIS extension.

sudo apt update
sudo apt install postgresql postgis
brew install postgresql@16 postgis
brew services start postgresql@16
sudo pacman -S postgresql postgis
sudo -u postgres initdb -D /var/lib/postgres/data
sudo systemctl start postgresql

Step 2: Create Database and User

Create a dedicated database and user for poiidx:

# Create user
sudo -u postgres createuser -P poiidx_user
# Enter password when prompted: your_secure_password

# Create database
sudo -u postgres createdb -O poiidx_user poiidx_db

# Enable PostGIS extension
sudo -u postgres psql -d poiidx_db -c "CREATE EXTENSION postgis;"

Step 3: Install poiidx

Install poiidx using pip:

pip install poiidx

Step 4: Configure POI Filters

Create a configuration file to specify which types of POIs you want to index. Save this as poi_config.yaml:

- symbol: restaurant
  description: Restaurants and dining
  filters:
    - amenity: restaurant
    - amenity: cafe
    - amenity: bar
    - amenity: pub

- symbol: tourism
  description: Tourist attractions and hotels
  filters:
    - tourism: hotel
    - tourism: museum
    - tourism: attraction

- symbol: shop
  description: Shops and stores
  filters:
    - shop: supermarket
    - shop: bakery

Step 5: Initialize the Database

Database Data is Temporary

poiidx automatically monitors for schema changes (from library updates or filter configuration changes). When it detects that the schema or filter configuration is outdated, it will automatically drop and recreate all database tables and data. This ensures consistency but means you should treat the database as a cache that can be regenerated at any time. Never rely on this database for persistent storage of your own data.

Create a Python script to initialize poiidx:

import yaml
import poiidx

# Load filter configuration
with open('poi_config.yaml') as f:
    filter_config = yaml.safe_load(f)

# Initialize database connection
poiidx.init(
    filter_config=filter_config,
    host='localhost',
    database='poiidx_db',
    user='poiidx_user',
    password='your_secure_password',
    port=5432
)

print("Database initialized successfully!")

Run this script. The first time you run it, poiidx will:

  1. Create the necessary database tables
  2. Download OpenStreetMap data for regions
  3. Index POIs based on your filter configuration

First Run Takes Time

The first initialization may take several minutes as it downloads and processes OpenStreetMap data.

Step 6: Find Nearby POIs

Now let's find POIs near a location:

from shapely.geometry import Point
import poiidx
import yaml

# Initialize (assuming you've already run step 5)
with open('poi_config.yaml') as f:
    filter_config = yaml.safe_load(f)

poiidx.init(
    filter_config=filter_config,
    host='localhost',
    database='poiidx_db',
    user='poiidx_user',
    password='your_secure_password',
    port=5432
)

# Create a point for Berlin city center
berlin = Point(13.4050, 52.5200)

# Find the 5 nearest POIs within 1000 meters
nearest_pois = poiidx.get_nearest_pois(
    berlin,
    max_distance=1000,  # meters
    limit=5
)

# Display results
for poi in nearest_pois:
    print(f"{poi['name']} ({poi['symbol']})")
    print(f"  Region: {poi['region']}")
    print(f"  Rank: {poi['rank']}")
    print()

Step 7: Get Administrative Boundaries

You can also retrieve administrative boundary information:

from shapely.geometry import Point
import poiidx

# Use the same initialization as before
berlin = Point(13.4050, 52.5200)

# Get administrative hierarchy
admin_hierarchy = poiidx.get_administrative_hierarchy(berlin)

for admin in admin_hierarchy:
    print(f"Level {admin['admin_level']}: {admin['name']}")

# Get as formatted string
admin_string = poiidx.get_administrative_hierarchy_string(berlin)
print(admin_string)

# Get in different language (if available)
admin_string_fr = poiidx.get_administrative_hierarchy_string(berlin, lang='fr')
print(admin_string_fr)

Step 8: Clean Up

When you're done, close the database connection:

poiidx.close()

What's Next?

Now that you've completed the tutorial, you can:

Troubleshooting

Database connection error
Make sure PostgreSQL is running and the credentials are correct.
No POIs found
The first query might trigger data download for that region. Wait and try again.
PostGIS extension error
Ensure PostGIS is installed and the extension is created in your database.