f4b431bb03
Phase 1 server side, gated on OXICLOUD_ENABLE_PLACES (off by default): - migration: partial index on storage.file_metadata(longitude, latitude). - FileBlobReadRepository::list_geo_clusters — plain-SQL grid aggregation (no PostGIS) scoped to the caller's own non-trashed photos, returning a centroid, count and a representative file id per non-empty cell. - PlacesService (caller_id-scoped; user-scoped data needs no authz check, mirroring RecentService) with a zoom→cell-size mapping. - GET /api/photos/geo?bbox=w,s,e,n&zoom=N returning GeoCluster[]. The route is mounted only when the Places service is present, and is registered in the OpenAPI path list. The map frontend (PMTiles serving + MapLibre module) is deferred pending the basemap-sourcing and vendoring decision. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JW6ghFMDtnRYuYNzZhb47M
11 lines
876 B
SQL
11 lines
876 B
SQL
-- ════════════════════════════════════════════════════════════════════════
|
|
-- Places (photo map): partial index for fast bounding-box scans over the
|
|
-- caller's geotagged photos. Plain B-tree on (longitude, latitude); no
|
|
-- PostGIS required. The partial predicate keeps the index small — only rows
|
|
-- that actually carry GPS coordinates are indexed.
|
|
-- ════════════════════════════════════════════════════════════════════════
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_file_metadata_geo
|
|
ON storage.file_metadata (longitude, latitude)
|
|
WHERE latitude IS NOT NULL AND longitude IS NOT NULL;
|