More
This commit is contained in:
parent
cd34ee693f
commit
05a1f316e1
58 changed files with 3113 additions and 1277 deletions
173
README.md
173
README.md
|
|
@ -1,43 +1,174 @@
|
|||
# Property Map
|
||||
|
||||
## Area
|
||||
uv run python scripts/remove_bg.py house-og.png 200 house.png
|
||||
Interactive UK property intelligence map. The app combines transaction, EPC,
|
||||
postcode, neighbourhood, transport, POI, and travel-time data into local parquet
|
||||
files, serves fast geospatial aggregations from Rust, and renders the result as
|
||||
a React/deck.gl map.
|
||||
|
||||
The public product is branded as Perfect Postcodes, while this repository is
|
||||
still named `property-map`.
|
||||
|
||||
interesting links
|
||||
- https://propertydata.co.uk/videos/quick-overview
|
||||
- https://osdatahub.os.uk/data/downloads/open
|
||||
## What Is In Here
|
||||
|
||||
https://xploria.co.uk/data-sources/
|
||||
- `frontend/` - React 18, TypeScript, Tailwind, MapLibre, and deck.gl. The app
|
||||
has a landing page, map dashboard, saved searches/properties, account pages,
|
||||
pricing, invites, and shareable URLs.
|
||||
- `server-rs/` - Rust Axum API. It loads the generated parquet data into memory,
|
||||
builds spatial indexes, serves H3/postcode aggregations, proxies PocketBase,
|
||||
serves PMTiles, handles AI filter parsing, screenshots, exports, checkout, and
|
||||
telemetry.
|
||||
- `pipeline/` - Python/Polars download and transform pipeline. `Makefile.data`
|
||||
orchestrates the data DAG.
|
||||
- `r5-java/` - Batch travel-time generator using Conveyal R5. It writes sparse
|
||||
per-destination parquet files for car, bicycle, walking, and transit.
|
||||
- `screenshot/` - Playwright/Express service used by the Rust API for map
|
||||
screenshots and Open Graph images.
|
||||
- `property-data/` and `manual-data/` - Local generated/downloaded data. These
|
||||
are runtime inputs, not source code.
|
||||
|
||||
## Runtime Data
|
||||
|
||||
The Rust server expects these files or directories to exist:
|
||||
|
||||
- Why hexagons?
|
||||
- Why the price tag?
|
||||
- contact support
|
||||
-
|
||||
```text
|
||||
property-data/properties.parquet
|
||||
property-data/postcode.parquet
|
||||
property-data/filtered_uk_pois.parquet
|
||||
property-data/places.parquet
|
||||
property-data/uk.pmtiles
|
||||
property-data/postcode_boundaries/
|
||||
property-data/travel-times/
|
||||
```
|
||||
|
||||
Most data can be downloaded or generated through `Makefile.data`. Some inputs
|
||||
are deliberately manual:
|
||||
|
||||
- `manual-data/certificates.csv` from the EPC register
|
||||
- `manual-data/crime/` CSV exports from police.uk
|
||||
- postcode boundaries, generated from OA boundaries, INSPIRE polygons, and UPRN
|
||||
lookup data
|
||||
|
||||
Build the main property datasets with:
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
make -f Makefile.data prepare
|
||||
make -f Makefile.data tiles
|
||||
make -f Makefile.data download-places
|
||||
make -f Makefile.data generate-postcode-boundaries
|
||||
```
|
||||
|
||||
load tests with grafana
|
||||
`generate-postcode-boundaries` writes to `manual-data/postcode_boundaries/`.
|
||||
The running server expects the same structure under
|
||||
`property-data/postcode_boundaries/`; copy or symlink it if needed.
|
||||
|
||||
house reposession
|
||||
Travel times are built separately because they are expensive:
|
||||
|
||||
## execution
|
||||
```bash
|
||||
make -f Makefile.data download-transit-network
|
||||
./r5-java/run.sh --threads 8 --heap 40g
|
||||
```
|
||||
|
||||
enum colour coding
|
||||
For a quick R5 smoke test:
|
||||
|
||||
Better school searchs
|
||||
```bash
|
||||
./r5-java/run.sh --demo
|
||||
```
|
||||
|
||||
fix links to markets,
|
||||
## Local Development
|
||||
|
||||
404,
|
||||
With the required files in `property-data/`, the full stack can be started with
|
||||
Docker Compose:
|
||||
|
||||
Make prop density smaller
|
||||
```bash
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
Test on safari
|
||||
Services:
|
||||
|
||||
Test on android
|
||||
- frontend: http://localhost:3001
|
||||
- API: http://localhost:8001
|
||||
- PocketBase: http://localhost:8090
|
||||
- screenshot service: http://localhost:8002
|
||||
|
||||
check rendered index html,
|
||||
The frontend dev server proxies `/api` and `/s` to the Rust API and `/pb` to
|
||||
PocketBase.
|
||||
|
||||
To run pieces directly:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Export the server's service configuration first:
|
||||
|
||||
```bash
|
||||
export SCREENSHOT_URL=http://localhost:8002
|
||||
export PUBLIC_URL=http://localhost:3001
|
||||
export POCKETBASE_URL=http://localhost:8090
|
||||
export POCKETBASE_ADMIN_EMAIL=...
|
||||
export POCKETBASE_ADMIN_PASSWORD=...
|
||||
export GEMINI_API_KEY=...
|
||||
export GEMINI_MODEL=...
|
||||
export GOOGLE_MAPS_API_KEY=...
|
||||
export STRIPE_SECRET_KEY=...
|
||||
export STRIPE_WEBHOOK_SECRET=...
|
||||
export STRIPE_REFERRAL_COUPON_ID=...
|
||||
export GOOGLE_OAUTH_CLIENT_ID=...
|
||||
export GOOGLE_OAUTH_CLIENT_SECRET=...
|
||||
```
|
||||
|
||||
```bash
|
||||
cd server-rs
|
||||
cargo run -- \
|
||||
--properties ../property-data/properties.parquet \
|
||||
--postcode-features ../property-data/postcode.parquet \
|
||||
--pois ../property-data/filtered_uk_pois.parquet \
|
||||
--places ../property-data/places.parquet \
|
||||
--tiles ../property-data/uk.pmtiles \
|
||||
--postcodes ../property-data/postcode_boundaries \
|
||||
--travel-times ../property-data/travel-times
|
||||
```
|
||||
|
||||
## Checks
|
||||
|
||||
Run the combined local check script:
|
||||
|
||||
```bash
|
||||
./check.sh
|
||||
```
|
||||
|
||||
It runs Python lint/tests, frontend lint/format/typecheck/tests, screenshot
|
||||
service tests, and Rust clippy/format/tests.
|
||||
|
||||
Useful focused commands:
|
||||
|
||||
```bash
|
||||
uv run ruff check .
|
||||
uv run pytest
|
||||
|
||||
cd frontend
|
||||
npm run lint
|
||||
npm run typecheck
|
||||
npm run test
|
||||
npm run build
|
||||
|
||||
cd ../server-rs
|
||||
cargo clippy --all-targets -- -D warnings
|
||||
cargo fmt --all --check
|
||||
cargo test
|
||||
```
|
||||
|
||||
## Production Build
|
||||
|
||||
The root `Dockerfile` builds the frontend and Rust server into a runtime image.
|
||||
Data is mounted at `/app/data`; it is not baked into the image.
|
||||
|
||||
```bash
|
||||
docker build -t property-map .
|
||||
```
|
||||
|
||||
The container entrypoint runs `property-map-server` with the expected data paths
|
||||
under `/app/data` and serves `frontend/dist` when `--dist` is present.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue