NaNoBotCo/mot-dang-chiang-mai-chiang-rai
มดแดง Mot Dang — Chiang Mai & Chiang Rai city directory 88,161 places in and around Chiang Mai (62,772) and Chiang Rai (25,389), in Thai and English, with coordinates, categories, opening hours, and the channels a place actually answers on — phone, LINE, Facebook, a website that still resolves. The name is มดแดง, mot daeng, the red ant: the thing that knows every soi because it has walked all of them. That is the ambition. The directory exists because mainstream mapping is thin… See the full description on the dataset page: https://huggingface.co/datasets/NaNoBotCo/mot-dang-chiang-mai-chiang-rai.
มดแดง Mot Dang — Chiang Mai & Chiang Rai city directory
88,161 places in and around Chiang Mai (62,772) and Chiang Rai (25,389), in Thai and English, with coordinates, categories, opening hours, and the channels a place actually answers on — phone, LINE, Facebook, a website that still resolves.
The name is มดแดง, mot daeng, the red ant: the thing that knows every soi because it has walked all of them. That is the ambition. The directory exists because mainstream mapping is thin here in ways that matter — a clinic with no hours, a market under a name nobody local uses, a wat with the wrong spelling and no Thai at all — and thin data is worst for the person who most needs it to be good.
Live at https://motdang.net/ · built 2026-09-08
If you want to ask it questions instead of holding it
This snapshot is the whole corpus as typed columns. If what you actually want is the clinics open right now within two kilometres, there is a live public API over the same records — no key, no sign-up, open to every origin, same licence:
- https://motdang.net/api/ — documentation
GET https://motdang.net/api/v1/places?cat=medical&near=18.7883,98.9853&radius=2000&open_now=1- https://motdang.net/api/v1/openapi.json — the spec
- https://motdang.net/api/v1/schema.json — the key contract; v1 keys may be added to
- https://motdang.net/terms.html — the terms, which are: take it, credit มดแดง Mot Dang
Read openNow: null as UNKNOWN and never as closed, exactly as the hours column here is empty rather than false where nobody holds the hours.
What is in a row
attrs is a JSON string rather than a column per key, because the key set is wide and sparse — a temple's register code and a noodle shop's wifi fee do not belong in the same schema. Parse it if you need it.
Ant rank
Nine things make a listing useful to someone standing in the street holding a phone. Each one present earns an ant. The count is the whole scoring system — no weighting, no secret sauce, nothing an owner cannot read off the page and go fix themselves:
Thai name · English name · phone · LINE · opening hours · a website that still answers · a photo · owner-confirmed · recently walked (within 180 days).
ant_bits lists which of the nine this record has, so you can filter on the specific gap rather than the total.
A low rank is a to-do, not a judgement. Most of the corpus came off the map and has never been walked.
Categories
Where it came from
16,944 of 88,161 rows are OSM-derived. 87,573 have coordinates; the rest are known to exist but not yet pinned, and are marked needs-pin rather than dropped — a clinic you cannot yet put on a map is still a clinic.
Per-field provenance
sources says where a record came from. On a record with four sources that does not tell you which one gave the phone number, so 75,318 of the 88,161 rows also carry provenance: a table keyed by field name.
{"phone": {"source": "directory:overture", "how": "stated", "at": "2026-09-07"},
"address": {"source": "derived:address-parse", "how": "derived"},
"lat": {"source": "osm:mot-dang overpass", "how": "stated"}}how is the part worth filtering on. stated — a source asserted this value (365,944 fields). derived — we computed it from something else, such as an address parsed into road and tambon, or a pin geocoded from a written address (174,258 fields). fields_stated and fields_derived carry the same split as plain lists.
A field absent from the table has unknown provenance. It does not mean ours and it does not mean OSM. Most first-hand and curated fields predate the receipt system and are simply not stamped yet; the table is a floor, not a census.
Known limits
- Coverage is uneven by design. Food and lodging are dense because that is what gets mapped; repair shops, community groups and home services are thin because they are not.
- Most of it is unwalked.
confidence: crawledmeans the map said so and nobody has been to check. Opening hours especially go stale. - Prices are not in this dataset. Where the site shows a price it is stamped with when it was seen, and that belongs on the page, not in a column that would be wrong within a season.
- Photos are not here — only external references, by URL, in
attrs. - This is a directory, not a review site. There are no ratings and no ranking by quality, only by completeness of the record.
Licence
Dual, and the split is mechanical — filter on osm_derived:
- The compilation — selection, categories, ant rank, blurbs, field-collected fields, and the arrangement: CC BY 4.0.
- Map-derived fields, on rows where
osm_derived = true: © OpenStreetMap contributors, ODbL 1.0. ODbL is share-alike on the database — publish a derived database from these rows and that database carries ODbL too.
Data on this page is CC BY 4.0 — reuse it, train on it, quote it. Map-derived fields remain © OpenStreetMap contributors (ODbL). Attribution to motdang.net is all we ask.
Full text in LICENSE.
Citation
@misc{motdang2026,
title = {{มดแดง Mot Dang: a Chiang Mai and Chiang Rai city directory}},
author = {{Mot Dang}},
year = {2026},
url = {https://motdang.net/},
note = {88,161 places, built 2026-09-08}
}Also served directly
https://motdang.net/llms.txt— what the site is, for a machine arriving coldhttps://motdang.net/llms-full.txt— the same 88,161 places as plain lines, one each- Corrections: every page has a door. If a row here is wrong, the fix goes in at the source and lands in the next build.
