Planetary-scale answers, unlocked.
A Hands-On Guide for Working with Large-Scale Spatial Data. Learn more.
Authors
POI (point of interest) data is a dataset of the places people visit or search for: shops, restaurants, hospitals, schools, parks, and landmarks. Each record pairs a location with attributes such as a name, a category, an address, opening hours, a phone number, and a website. Retailers, insurers, mobility analysts, and map applications use point of interest data to find where things are and what sits nearby. The hard problem in POI data is identity: deciding which records describe the same place, and keeping that identity stable as places open, move, and close. The Chicago walkthrough below tests the first half. It looks for duplicate records in one release of Overture Maps, an open map dataset.
A point of interest is a term from cartography. The OpenStreetMap wiki describes it as a feature shown with an icon at a single point, such as a post office, a shop, a pub, or a tourist attraction.
POI data turns those map icons into a table. Overture defines a place as "a concrete, physically identifiable, stationary destination in a publicly observable space." That definition leaves out administrative areas such as cities, movable things such as food carts, waypoints such as bus stops, and private residences.
In a geographic information system (GIS), a POI is a point feature with a name and a category. It is stored in a layer beside polygons such as parcels, census tracts, and building footprints. Apache POI is an unrelated Java library for reading and writing Microsoft Office files.
Sources fill these fields differently. Foursquare's OS Places schema adds dates. date_created is when a place entered the database. date_refreshed is the last time a crawl, a user, or a human check refreshed any reference to it. date_closed is when it was marked closed. OpenStreetMap stores hours in an opening_hours tag, and Google returns hours with a business status. Commercial schemas add more: SafeGraph's places schema includes a Placekey identifier, brand IDs, and a polygon geometry for each place.
date_created
date_refreshed
date_closed
opening_hours
Each provider keeps its own category list. Overture's Places Categories taxonomy has roughly 2,300 categories under 13 top-level groups. Each place's hierarchy array runs from the top level to its primary category, so a query can roll Cantonese restaurants up to Chinese restaurants, restaurants, and food and drink. A separate basic_category field holds about 280 labels, such as restaurant or museum. It draws on the basic-level categories that Rosch and colleagues described in Basic objects in natural categories (Cognitive Psychology, 1976). The basic level is the one people name first: "chair" before "furniture" or "kitchen chair".
hierarchy
basic_category
Foursquare Open Source Places uses more than 1,000 categories in a hierarchy up to six levels deep. OpenStreetMap has no closed list: mappers combine tags such as amenity=cafe or shop=bakery. Google gives each place a primary type and a list of place types drawn from two fixed tables. Moving between them takes a crosswalk, a table pairing categories across lists. Overture maps each provider's categories into its own taxonomy on load, with exact lookups and reviewed model-derived matches.
amenity=cafe
shop=bakery
Placekey gives a place a two-part ID, a "what" part for the address and POI and a "where" part that encodes an H3 hexagonal grid cell at resolution 10. Overture's GERS ID is a universally unique identifier (UUID), a random code with no location inside it. It stays the same across releases and is listed in a public registry.
POI data collection draws on five inputs. Business websites and store locators list every location of a chain. Registries hold business filings and licenses. Social networks and review sites hold business pages. Users contribute edits, for example in OpenStreetMap and through Foursquare's Placemaker tools. Field surveys record places in person.
The hard part is conflation, also called entity resolution: deciding which records describe the same place. Overture runs each provider feed through four stages: history matching, blocking, pairwise scoring, and clustering. History matching links about 90% of a known provider's records to places already in the corpus. Blocking narrows the rest to candidate pairs, using distance and embeddings of name, category, and address. An embedding is a list of numbers in which similar text gets similar values. A gradient-boosted classifier, a model built from many small decision trees, scores each pair on name, address, website, phone, category, distance, and how distinctive the name is in its area. Matched pairs form clusters. Overture keeps one source record per cluster and merges no attributes across sources.
POI data changes daily as businesses open, move, and close, so quality is a property of each record. The OpenStreetMap wiki names freshness, coverage, consistency, ease of use, and customization as the marks of good POI data. Overture manages quality with these tools:
Freshness is how recently a record was checked. It is recorded in Foursquare's date_refreshed and the update_time on each Overture source record.
update_time
POI data describes a place, and foot traffic data counts visits to it. Placer.ai draws a polygon around each venue and estimates visits from aggregated, de-identified mobile device location data.
Wherobots hosts Overture places as an Apache Iceberg table (an open table format for large datasets) in the Havasu catalog: wherobots_open_data.overture_maps_foundation.places_place. A count in October 2026 returned 81,455,423 places worldwide, 17,949,232 of them with a US address. Wherobots joined Overture Maps Foundation as a contributing member in July 2024.
wherobots_open_data.overture_maps_foundation.places_place
Overture places with isochrones holds precomputed 5, 10, 15, and 20 minute drive-time polygons for 13.3 million US places, described in the isochrones guide. Census tract boundaries, American Community Survey estimates, and Overture buildings sit in the same catalog.
This query counts food and drink places per 1,000 residents in each Cook County, Illinois census tract. It joins three Havasu tables in one query:
places_place
tiger_tract
acs_5yr_estimates
WITH tracts AS ( SELECT GEOID, NAMELSAD, geometry FROM wherobots_open_data.us_census.tiger_tract WHERE STATEFP = '17' AND COUNTYFP = '031' ), pop AS ( SELECT geoid, estimate AS population FROM wherobots_open_data.us_census.acs_5yr_estimates WHERE variable = 'B01003_001' AND geo_level = 'tract' AND vintage = '2020-2024' ), food AS ( SELECT geometry FROM wherobots_open_data.overture_maps_foundation.places_place WHERE taxonomy.hierarchy[0] = 'food_and_drink' AND confidence >= 0.7 AND bbox.xmin BETWEEN -88.27 AND -87.52 AND bbox.ymin BETWEEN 41.46 AND 42.16 ) SELECT t.GEOID, t.NAMELSAD, p.population, COUNT(f.geometry) AS food_places, ROUND(COUNT(f.geometry) * 1000.0 / p.population, 1) AS per_1000_residents FROM tracts t JOIN pop p ON p.geoid = t.GEOID LEFT JOIN food f ON ST_Contains(t.geometry, f.geometry) WHERE p.population >= 500 GROUP BY t.GEOID, t.NAMELSAD, p.population ORDER BY per_1000_residents DESC
The filter on bbox drops places outside the Cook County area before the point-in-polygon join, the step that tests which tract contains each point. The query ran in 18 seconds. Census Tract 8391 ranks first: 613 food and drink places for 8,355 residents, or 73.4 per 1,000. The next four tracts range from 53.1 to 49.4. With another category, or with drive-time isochrones in place of tracts, the same query screens candidate sites. The nearest-neighbor join pairs each record with its k nearest POIs.
bbox
This section profiles every Overture place inside one box: -87.66 to -87.60 longitude and 41.86 to 41.91 latitude. The box is about 5 km by 5.5 km. It covers the Loop, the West Loop, River North, Streeterville, and the South Loop. The three queries below read only the Overture places table.
WITH p AS ( SELECT COALESCE(taxonomy.hierarchy[0], '(no category)') AS top_category, confidence FROM wherobots_open_data.overture_maps_foundation.places_place WHERE bbox.xmin >= -87.66 AND bbox.xmax <= -87.60 AND bbox.ymin >= 41.86 AND bbox.ymax <= 41.91 ) SELECT top_category, COUNT(*) AS places, ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 1) AS pct_of_places, ROUND(AVG(confidence), 2) AS avg_confidence, SUM(CASE WHEN confidence >= 0.7 THEN 1 ELSE 0 END) AS confidence_07_plus FROM p GROUP BY top_category ORDER BY places DESC
The box holds 52,917 places, and the query ran in 6 seconds. Services and business is the largest group with 24,006 places (45.4%), followed by health care (4,451), food and drink (4,039), and shopping (3,198). 7,580 places (14.3%) have no category. They average a confidence of 0.31, against 0.79 for services and business and 0.89 for food and drink. Of the uncategorized places, 1,132 reach 0.7.
One pass over the same box counts the fields filled in each 0.1 confidence band:
WITH p AS ( SELECT LEAST(FLOOR(confidence * 10), 9) AS band, CASE WHEN size(websites) > 0 THEN 1 ELSE 0 END AS has_website, CASE WHEN size(phones) > 0 THEN 1 ELSE 0 END AS has_phone, CASE WHEN size(websites) > 0 OR size(phones) > 0 THEN 1 ELSE 0 END AS has_website_or_phone, CASE WHEN size(socials) > 0 THEN 1 ELSE 0 END AS has_social, CASE WHEN addresses[0].freeform IS NOT NULL THEN 1 ELSE 0 END AS has_address, CASE WHEN brand.names.primary IS NOT NULL THEN 1 ELSE 0 END AS has_brand, CASE WHEN operating_status <> 'open' THEN 1 ELSE 0 END AS not_open FROM wherobots_open_data.overture_maps_foundation.places_place WHERE bbox.xmin >= -87.66 AND bbox.xmax <= -87.60 AND bbox.ymin >= 41.86 AND bbox.ymax <= 41.91 ) SELECT CASE WHEN GROUPING(band) = 1 THEN 'all' ELSE CAST(band / 10 AS STRING) END AS confidence_from, COUNT(*) AS places, SUM(has_website) AS with_website, SUM(has_phone) AS with_phone, SUM(has_website_or_phone) AS with_website_or_phone, SUM(has_social) AS with_social, SUM(has_address) AS with_address, SUM(has_brand) AS with_brand, SUM(not_open) AS not_open FROM p GROUP BY ROLLUP(band) ORDER BY confidence_from
It ran in 4 seconds. 48,177 places (91.0%) have a website or a phone number: 43,297 a phone (81.8%) and 37,998 a website (71.8%). Almost all carry a street address (52,134), 22,036 a social profile, and 3,040 a brand. 3,902 are marked temporarily or permanently closed.
Of the 8,810 places below 0.3, 8,753 have a social profile, 7,179 a phone, and 2,036 a website. Above 0.9, 84.2% have a website.
Conflation leaves some duplicates behind. This self-join compares the places table with itself. It finds pairs of places within 25 m of each other with matching names. Two names match when they are equal after lowercasing and stripping punctuation. Names of eight or more characters also match when they differ by one character:
WITH p AS ( SELECT id, geometry, confidence, sources[0].dataset AS source, regexp_replace(lower(names.primary), '[^\\p{L}\\p{N}]', '') AS name_key FROM wherobots_open_data.overture_maps_foundation.places_place WHERE bbox.xmin >= -87.66 AND bbox.xmax <= -87.60 AND bbox.ymin >= 41.86 AND bbox.ymax <= 41.91 ), pairs AS ( SELECT a.id AS id_a, b.id AS id_b, ST_DistanceSphere(a.geometry, b.geometry) AS dist_m, CASE WHEN a.name_key = b.name_key THEN 'same name' ELSE 'one character apart' END AS match_type, CASE WHEN a.source = b.source THEN 1 ELSE 0 END AS same_source, CASE WHEN a.confidence >= 0.7 AND b.confidence >= 0.7 THEN 1 ELSE 0 END AS both_07_plus FROM p a JOIN p b ON ST_DWithin(a.geometry, b.geometry, 0.0004) -- coarse filter in degrees, about 33 m east-west AND a.id < b.id WHERE ST_DistanceSphere(a.geometry, b.geometry) <= 25 AND length(a.name_key) >= 4 AND (a.name_key = b.name_key OR (length(a.name_key) >= 8 AND levenshtein(a.name_key, b.name_key) = 1)) ), ids AS ( SELECT id_a AS id, match_type FROM pairs UNION SELECT id_b, match_type FROM pairs ) SELECT s.match_type, s.pairs, i.places, s.same_source_pairs, s.both_07_plus_pairs, s.median_dist_m FROM (SELECT COALESCE(match_type, 'all') AS match_type, COUNT(*) AS pairs, SUM(same_source) AS same_source_pairs, SUM(both_07_plus) AS both_07_plus_pairs, ROUND(percentile_approx(dist_m, 0.5), 1) AS median_dist_m FROM pairs GROUP BY ROLLUP(match_type)) s JOIN (SELECT COALESCE(match_type, 'all') AS match_type, COUNT(DISTINCT id) AS places FROM ids GROUP BY ROLLUP(match_type)) i ON s.match_type = i.match_type ORDER BY s.pairs DESC
With ST_DWithin in the join condition, EXPLAIN FORMATTED shows a broadcast index join. The engine copies one side of the join to every worker and searches it through an R-tree, a spatial index of nested bounding boxes. The exact spherical distance then filters the candidates. The query ran in 66 seconds and found 58 candidate pairs covering 116 places, 0.22% of the box. 57 pairs share a name and one differs by a character. The median distance is 6.3 m. In 42 pairs both records score 0.7 or higher, and in 38 pairs the two records list different source datasets. Among the pairs are a Starbucks recorded by both AllThePlaces and Meta, and The Bagel Spot from both Foursquare and Meta. The pattern \p{L}\p{N} keeps letters and digits in any script. A pattern limited to ASCII, the basic Latin character set, strips Chinese and Korean names to empty strings and pairs unrelated records. The count is a lower bound. Names that differ by a suffix, such as "Shannon Law Group" and "Shannon Law Group, Pc", fall outside it. Production matchers such as Overture's also compare addresses, phones, and websites.
ST_DWithin
EXPLAIN FORMATTED
\p{L}\p{N}
The models people use every day were trained on text, documents, databases, and the internet. Such a model can list popular restaurants in a city. Without a tool connection, it cannot count the pharmacies inside a 10-minute drive. An AI agent, a model that can call tools, can answer that with a spatial query when it is connected to the Wherobots Model Context Protocol (MCP) server.
Volunteered mapping and location-based social networks, both from the 2000s, produced today's open and platform POI datasets. Goodchild named volunteered geography in Citizens as sensors (GeoJournal, 2007): people with GPS devices and web maps contributing geographic facts, with OpenStreetMap as the leading case. On location-based social networks such as Foursquare, each check-in tied a person to a venue. Haklay's comparison of OpenStreetMap and Ordnance Survey data (Environment and Planning B, 2010) became an early model for judging volunteered data against an authoritative reference.
POI matching is a case of record linkage: finding the records in different datasets that describe the same thing. Fellegi and Sunter gave it a formal theory in A theory for record linkage (Journal of the American Statistical Association, 1969). Their method compares the fields of two records and weighs the agreements. It then classifies each pair as a match, a non-match, or a case for review. Places add geometry to the comparison. McKenzie, Janowicz, and Adams weighted several attribute similarities in multi-attribute matching of user-generated POIs (ACM SIGSPATIAL, 2013) and matched 97% of a sample of Yelp places to their Foursquare records. Deng, Luo, Liu, and Wang combined four attribute similarities to match Baidu and Gaode POIs in Beijing (ISPRS International Journal of Geo-Information, 2019). They used Dempster-Shafer evidence theory, a formal method for combining evidence. Low, Tekler, and Cheah built a six-step end-to-end POI conflation framework (ISPRS International Journal of Geo-Information, 2021) that reached 97.6% matching accuracy on more than 12,000 POIs.
Sun, Hu, and coauthors reviewed the field in a systematic review of POI matching methods (Computers, Environment and Urban Systems, 2023). It sorts the similarity measures and classifiers in use and lists six limitations. General entity matching moved to learned models in the same years. Mudgal and colleagues (SIGMOD 2018) found deep learning models strongest on text-heavy records and on dirty records, where values are missing or sit in the wrong field. Ditto (PVLDB, 2020) matched records with pre-trained language models. Overture applies both ideas to places with name embeddings and match labels from a large language model.
Completeness studies compare a POI source with ground truth, a reference dataset taken as correct. Klinkhardt and colleagues surveyed 49 areas in Germany and assessed OpenStreetMap POIs for travel demand models (Transportation Research Record, 2023). Completeness differed by activity type: shops were far better covered than private businesses. Yeow, Low, Tan, and Cheah catalogued 23 POI validation methods (ISPRS International Journal of Geo-Information, 2021). They applied nine of them to four datasets for one Singapore neighborhood. Spatial errors stayed under 60 m. Completeness was poor: the datasets missed real places (omission) and listed places that were not there (commission). Ballantyne and Berragan validated Overture's UK places against Geolytix supermarket locations (Environment and Planning B, 2024) and found store counts within 5% for three retailers.
POI data also feeds models of how people use cities. Ye, Yin, Lee, and Lee published a POI recommendation study (SIGIR 2011). It showed that the effect of distance on check-ins follows a power law. The authors combined that distance effect with user preference and social influence. Liu and colleagues later ran an experimental evaluation of POI recommendation models (PVLDB, 2017). Yuan, Zheng, and Xie inferred the functions of city regions from POI mixes and human mobility (KDD 2012). Yan, Janowicz, Mai, and Gao learned place type embeddings with Place2Vec (SIGSPATIAL 2017) from which categories occur near each other. Huff's trading area model (Journal of Marketing, 1964) is a gravity model. Chang and colleagues modeled COVID-19 spread (Nature, 2021) on hourly movements of 98 million people between census block groups and 552,758 POIs.
Overture's documentation names the open problems for its own data. They are duplicates, a high rate of junk records, and many empty attribute fields. The fourth is undermatching: records of one place that sit more than 100 m apart or have only moderately similar names stay unmatched.
The queries and studies above show that POI records vary in quality and identity by place and source, so each use of POI data needs its own checks.
Query Overture places, census tracts, and isochrones with a Wherobots free trial at cloud.wherobots.com.
POI data, short for points of interest data, is a dataset of places people visit or look for on a map: shops, restaurants, hospitals, schools, parks, and landmarks. Each record pairs a location, usually a latitude and longitude point, with attributes such as a name, a category, an address, a phone number, and a website.
POI stands for point of interest. The term comes from cartography, where a map shows a feature such as a post office or a gas station as an icon at a single point. The plural, points of interest, is often abbreviated POIs.
In GIS, a POI is a point feature that represents a place with a name and a category, such as a restaurant or a hospital. POI layers sit alongside polygon layers such as parcels, census tracts, and building footprints, and analysts join them by location to count, rank, and compare places.
Open POI datasets include Overture Maps places, Foursquare Open Source Places, and OpenStreetMap. Commercial POI data providers such as SafeGraph and Placer.ai add brand matching, building polygons, and foot traffic. Map APIs such as the Google Places API return details for one place per request.
Several large POI datasets are free to download and use. Overture Maps places is published under the CDLA Permissive 2.0 and Apache 2.0 licenses, and Foursquare Open Source Places under Apache 2.0. Commercial datasets with foot traffic, verified brands, or store polygons are licensed for a fee.
Providers collect POI data from business websites and store locators, government and business registries, social media pages, user contributions and edits, and field surveys. Open projects such as Overture then conflate the records: they compare name, address, phone, website, category, and location across providers and merge records that describe the same place.
POI data describes the place: its name, category, address, and location. Foot traffic data counts visits to that place over time, usually estimated from aggregated mobile device location data inside a polygon drawn around the venue. Foot traffic products depend on POI data, because visits are counted against each place’s boundary.
Common uses include retail site selection, market and competitor analysis, trade area and cannibalization studies, insurance exposure enrichment, logistics and delivery planning, advertising audiences, and map search. Each use joins POIs to other spatial data, such as census tracts, drive-time isochrones, or hazard layers.
In mapping and navigation software, POI means point of interest: a named place such as a fuel station or a restaurant that a map can show and search. In Java development, Apache POI is an unrelated open source library for reading and writing Microsoft Office files such as Excel spreadsheets.
A confidence score estimates how likely a POI record describes a place that exists. Overture places carry a score from 0 to 1. It measures existence only. Scores are not calibrated across providers, so a 0.8 from one source does not mean the same as a 0.8 from another. Use the score as a filter. Raising the threshold removes more junk records and also more real places. In downtown Chicago, 64.6% of Overture places score 0.7 or higher.
Deduplication, or conflation, compares candidate pairs of records that sit close together and scores how alike their names, addresses, phones, websites, and categories are. Pairs above a threshold are grouped into one place. A simple check in SQL is a distance self-join that flags records within 25 m of each other with the same normalized name.
Continuously, because businesses open, move, rename, and close every day. Overture and Foursquare OS Places both publish monthly releases. Overture adds a changelog that marks every place ID as added, removed, changed, or unchanged, and Foursquare records a date_refreshed for the last time each place was checked.
OpenStreetMap has detailed POIs where its volunteer community is active, with tags for opening hours, accessibility, and cuisine. Completeness varies by place and category. A survey of 49 areas in Germany found shops far better covered than private businesses. OpenStreetMap data is licensed under the Open Database License (ODbL), which carries share-alike terms for derived databases.
What is a Semantic Layer? Definition, Examples, Spatial Rules
A semantic layer defines business terms and metrics once, so every tool gives the same answer. For location data it must also set the boundary, the distance and what counts as inside.
What is a Geofence? How Geofencing Works, With Examples
A geofence is a virtual boundary that triggers an action when a device enters or leaves it. How geofencing works, its uses and limits, and a test on ship data.
What is Map Matching? GPS Traces, Methods and Examples
Map matching places each GPS record on the road a vehicle drove. How it works, nearest-road snapping vs hidden Markov models, and a test on Ann Arbor drives.
share this article
Awesome that you’d like to share our articles. Where would you like to share it to: