OpenPOIs
A unified, open dataset for points of interest across the United States. Built from OpenStreetMap and
Overture Maps , with per-POI confidence scores
produced by the OpenPOIs turnover model.
Repository layout
Each refresh writes a new versioned folder. Inside every version:
1 <YYYY-MM-DD-vN>/
2 ├── README.md # version metadata (OSM date, Overture release, model)
3 ├── osm-parquet/ # OSM-only snapshot, hive-partitioned by primary_tag
4 ├── osm-pmtiles/osm.pmtiles # OSM snapshot as a single PMTiles archive
5 ├── conflated-parquet/ # OSM × Overture conflated snapshot, hive-partitioned by shared_label
6 └── conflated-pmtiles/conflated.pmtiles
1 <YYYY-MM-DD-vN>/
2 ├── README.md # version metadata (OSM date, Overture release, model)
3 ├── osm-parquet/ # OSM-only snapshot, hive-partitioned by primary_tag
4 ├── osm-pmtiles/osm.pmtiles # OSM snapshot as a single PMTiles archive
5 ├── conflated-parquet/ # OSM × Overture conflated snapshot, hive-partitioned by shared_label
6 └── conflated-pmtiles/conflated.pmtiles
latest/ is a server-side mirror of the most recently published version —
use it for live demos and tutorials, and pin a dated folder
(e.g. 2026-04-23-v0/) when you need a stable, reproducible reference.
Browse all versions at
https://source.coop/henryspatialanalysis/openpois .
What's in the conflated dataset
One row per real-world POI after matching OpenStreetMap features against
Overture Maps places. Key columns:
The osm-parquet/ files contain the same OSM rows before conflation. This data retains the original OSM tags.
Quickstart
Read directly from Source Cooperative's S3 mirror (no authentication):
pyarrow / GeoPandas use pyarrow.fs.S3FileSystem(anonymous=True) and a
bucket-qualified path (no scheme prefix).
DuckDB uses an s3:// URL plus an anonymous SECRET so its glob
expansion works over the bucket listing.
Every example uses VERSION = "latest"; swap in a dated folder (e.g.
"2026-04-23-v0") when you need a reproducible pin.
Python: pyarrow
1 import pyarrow.dataset as ds
2 import pyarrow.fs as pafs
3
4 BASE = "us-west-2.opendata.source.coop/henryspatialanalysis/openpois"
5 VERSION = "latest" # or pin a specific dated folder, e.g. "2026-04-23-v0"
6
7 fs = pafs.S3FileSystem( anonymous = True , region = "us-west-2" )
8 pois = ds.dataset(
9 f " {BASE} / {VERSION} /conflated-parquet/" ,
10 filesystem = fs,
11 format = "parquet" ,
12 partitioning = "hive" ,
13 )
14 print (pois.schema)
15 print ( f " { pois.count_rows() :, } POIs" )
1 import pyarrow.dataset as ds
2 import pyarrow.fs as pafs
3
4 BASE = "us-west-2.opendata.source.coop/henryspatialanalysis/openpois"
5 VERSION = "latest" # or pin a specific dated folder, e.g. "2026-04-23-v0"
6
7 fs = pafs.S3FileSystem( anonymous = True , region = "us-west-2" )
8 pois = ds.dataset(
9 f " {BASE} / {VERSION} /conflated-parquet/" ,
10 filesystem = fs,
11 format = "parquet" ,
12 partitioning = "hive" ,
13 )
14 print (pois.schema)
15 print ( f " { pois.count_rows() :, } POIs" )
Python: DuckDB
1 import duckdb
2
3 BASE = "s3://us-west-2.opendata.source.coop/henryspatialanalysis/openpois"
4 VERSION = "latest" # or pin a specific dated folder, e.g. "2026-04-23-v0"
5
6 con = duckdb.connect()
7 con.execute( "INSTALL httpfs; LOAD httpfs;" )
8 con.execute( """
9 CREATE OR REPLACE SECRET srccoop (
10 TYPE s3, PROVIDER config,
11 REGION 'us-west-2', URL_STYLE 'path',
12 KEY_ID '', SECRET ''
13 );
14 """ )
15 df = con.execute( f """
16 SELECT shared_label, COUNT(*) AS n
17 FROM read_parquet(' {BASE} / {VERSION} /conflated-parquet/**/*.parquet',
18 hive_partitioning = true)
19 GROUP BY shared_label
20 ORDER BY n DESC
21 LIMIT 20
22 """ ).df()
23 print (df)
1 import duckdb
2
3 BASE = "s3://us-west-2.opendata.source.coop/henryspatialanalysis/openpois"
4 VERSION = "latest" # or pin a specific dated folder, e.g. "2026-04-23-v0"
5
6 con = duckdb.connect()
7 con.execute( "INSTALL httpfs; LOAD httpfs;" )
8 con.execute( """
9 CREATE OR REPLACE SECRET srccoop (
10 TYPE s3, PROVIDER config,
11 REGION 'us-west-2', URL_STYLE 'path',
12 KEY_ID '', SECRET ''
13 );
14 """ )
15 df = con.execute( f """
16 SELECT shared_label, COUNT(*) AS n
17 FROM read_parquet(' {BASE} / {VERSION} /conflated-parquet/**/*.parquet',
18 hive_partitioning = true)
19 GROUP BY shared_label
20 ORDER BY n DESC
21 LIMIT 20
22 """ ).df()
23 print (df)
Python: GeoPandas
1 import geopandas as gpd
2 import pyarrow.fs as pafs
3
4 BASE = "us-west-2.opendata.source.coop/henryspatialanalysis/openpois"
5 VERSION = "latest" # or pin a specific dated folder, e.g. "2026-04-23-v0"
6
7 fs = pafs.S3FileSystem( anonymous = True , region = "us-west-2" )
8 # conflated-parquet is hive-partitioned by shared_label.
9 gdf = gpd.read_parquet(
10 f " {BASE} / {VERSION} /conflated-parquet/shared_label=Cafe/part-0.parquet" ,
11 filesystem = fs,
12 )
13 print (gdf.head())
1 import geopandas as gpd
2 import pyarrow.fs as pafs
3
4 BASE = "us-west-2.opendata.source.coop/henryspatialanalysis/openpois"
5 VERSION = "latest" # or pin a specific dated folder, e.g. "2026-04-23-v0"
6
7 fs = pafs.S3FileSystem( anonymous = True , region = "us-west-2" )
8 # conflated-parquet is hive-partitioned by shared_label.
9 gdf = gpd.read_parquet(
10 f " {BASE} / {VERSION} /conflated-parquet/shared_label=Cafe/part-0.parquet" ,
11 filesystem = fs,
12 )
13 print (gdf.head())
Browser / vector-tile map
The *-pmtiles/*.pmtiles archives can be loaded directly by any PMTiles
client (MapLibre + pmtiles://, OpenLayers + ol-pmtiles, etc.). See
site/ in the GitHub repo for a working example.
The snippet below is a self-contained HTML page that renders the conflated
PMTiles over MapLibre, coloured by the model's conf_mean. Save it as
openpois.html and open it in a browser — no build step, no server needed.
PMTiles are authored at zoom 14, so zoom in past z14 to see points.
1 <! doctype html >
2 < meta charset = "utf-8" />
3 < title >OpenPOIs — conflated</ title >
4 < link href = "https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.css" rel = "stylesheet" />
5 < style > html , body , #map { height : 100 % ; margin : 0 ; }</ style >
6 < div id = "map" ></ div >
7 < script src = "https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.js" ></ script >
8 < script src = "https://unpkg.com/pmtiles@3/dist/pmtiles.js" ></ script >
9 < script >
10 const BASE = "https://data.source.coop/henryspatialanalysis/openpois" ;
11 const VERSION = "latest" ; // or pin a specific dated folder, e.g. "2026-04-23-v0"
12
13 const protocol = new pmtiles. Protocol ();
14 maplibregl. addProtocol ( "pmtiles" , protocol.tile);
15
16 const map = new maplibregl. Map ({
17 container: "map" ,
18 style: "https://tiles.openfreemap.org/styles/positron" ,
19 center: [ - 73.9855 , 40.758 ], // Times Square
20 zoom: 16 ,
21 });
22
23 map. on ( "load" , () => {
24 map. addSource ( "openpois" , {
25 type: "vector" ,
26 url: `pmtiles://${ BASE }/${ VERSION }/conflated-pmtiles/conflated.pmtiles` ,
27 minzoom: 14 ,
28 });
29 map. addLayer ({
30 id: "openpois-points" ,
31 type: "circle" ,
32 source: "openpois" ,
33 "source-layer" : "conflated_pois" , // set by publish.pmtiles.conflated_layer_name
34 paint: {
35 "circle-radius" : 4 ,
36 "circle-stroke-width" : 1 ,
37 "circle-stroke-color" : "#ffffff" ,
38 // Red when stale (conf_mean ≈ 0), green when fresh (≈ 1).
39 "circle-color" : [
40 "interpolate" , [ "linear" ], [ "get" , "conf_mean" ],
41 0.0 , "#d73027" ,
42 0.3 , "#fee08b" ,
43 0.7 , "#1a9850" ,
44 ],
45 },
46 });
47 map. on ( "click" , "openpois-points" , ( e ) => {
48 const p = e.features[ 0 ].properties;
49 new maplibregl. Popup ()
50 . setLngLat (e.lngLat)
51 . setHTML (
52 `<b>${ p . name ?? "(no name)"}</b><br>` +
53 `${ p . shared_label } · source=${ p . source }<br>` +
54 `conf_mean = ${ Number ( p . conf_mean ). toFixed ( 3 )}`
55 )
56 . addTo (map);
57 });
58 });
59 </ script >
1 <! doctype html >
2 < meta charset = "utf-8" />
3 < title >OpenPOIs — conflated</ title >
4 < link href = "https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.css" rel = "stylesheet" />
5 < style > html , body , #map { height : 100 % ; margin : 0 ; }</ style >
6 < div id = "map" ></ div >
7 < script src = "https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.js" ></ script >
8 < script src = "https://unpkg.com/pmtiles@3/dist/pmtiles.js" ></ script >
9 < script >
10 const BASE = "https://data.source.coop/henryspatialanalysis/openpois" ;
11 const VERSION = "latest" ; // or pin a specific dated folder, e.g. "2026-04-23-v0"
12
13 const protocol = new pmtiles. Protocol ();
14 maplibregl. addProtocol ( "pmtiles" , protocol.tile);
15
16 const map = new maplibregl. Map ({
17 container: "map" ,
18 style: "https://tiles.openfreemap.org/styles/positron" ,
19 center: [ - 73.9855 , 40.758 ], // Times Square
20 zoom: 16 ,
21 });
22
23 map. on ( "load" , () => {
24 map. addSource ( "openpois" , {
25 type: "vector" ,
26 url: `pmtiles://${ BASE }/${ VERSION }/conflated-pmtiles/conflated.pmtiles` ,
27 minzoom: 14 ,
28 });
29 map. addLayer ({
30 id: "openpois-points" ,
31 type: "circle" ,
32 source: "openpois" ,
33 "source-layer" : "conflated_pois" , // set by publish.pmtiles.conflated_layer_name
34 paint: {
35 "circle-radius" : 4 ,
36 "circle-stroke-width" : 1 ,
37 "circle-stroke-color" : "#ffffff" ,
38 // Red when stale (conf_mean ≈ 0), green when fresh (≈ 1).
39 "circle-color" : [
40 "interpolate" , [ "linear" ], [ "get" , "conf_mean" ],
41 0.0 , "#d73027" ,
42 0.3 , "#fee08b" ,
43 0.7 , "#1a9850" ,
44 ],
45 },
46 });
47 map. on ( "click" , "openpois-points" , ( e ) => {
48 const p = e.features[ 0 ].properties;
49 new maplibregl. Popup ()
50 . setLngLat (e.lngLat)
51 . setHTML (
52 `<b>${ p . name ?? "(no name)"}</b><br>` +
53 `${ p . shared_label } · source=${ p . source }<br>` +
54 `conf_mean = ${ Number ( p . conf_mean ). toFixed ( 3 )}`
55 )
56 . addTo (map);
57 });
58 });
59 </ script >
License & attribution
The OpenPOIs dataset is released under the Open Database License (ODbL) v.1.0 . Any public use must credit OpenStreetMap contributors, the Overture Maps Foundation, and OpenPOIs. Any derivative database must be shared under the same license. See https://www.openstreetmap.org/copyright and https://docs.overturemaps.org/attribution/ for upstream attribution
requirements.
Citation
If you use this data in research, please cite:
Henry Spatial Analysis (2026). OpenPOIs: a unified, confidence-scored
dataset of U.S. points of interest. https://openpois.henryspatialanalysis.com
Questions, bug reports, and contributions welcome via https://github.com/henryspatialanalysis/openpois/issues .