Skip to main content

turkmenistan_addresses 1.1.0 copy "turkmenistan_addresses: ^1.1.0" to clipboard
turkmenistan_addresses: ^1.1.0 copied to clipboard

Offline address search for Turkmenistan: cities and villages, streets, houses and public places. The database ships inside the package, no network needed.

turkmenistan_addresses #

English · Русский

pub package

Offline address search for Turkmenistan: 1,941 settlements (52 of them cities), 3,166 streets, 7,091 houses and 3,282 public places — airports, stations, hospitals, ministries, markets. The database is built from OpenStreetMap and ships inside the package — no network is used at load time or at query time.

The asset is 391 KB.

On pub.dev: https://pub.dev/packages/turkmenistan_addresses

Installation #

dependencies:
  turkmenistan_addresses: ^1.1.0

Usage #

import 'package:turkmenistan_addresses/turkmenistan_addresses.dart';

final db = await loadTurkmenistanAddresses();
db.warmUp(); // optional; moves 30 ms off the first query

for (final hit in db.search('par 2/4 1')) {
  print('${hit.title} — ${hit.place?.name}  ${hit.lat}, ${hit.lon}');
}
// Parahat 2/4, 1 — Aşgabat  37.8981436, 58.385109

A result is destructured by kind:

switch (hit) {
  case PlaceHit(:final value):   // city, village, neighbourhood
    print('${value.name}, ${value.type}');
  case StreetHit(:final value):  // street
    print(db.housesOn(value.id).length);
  case AddressHit(:final value): // house
    print('${value.street.name}, ${value.number}');
}

There is also nearestAddress(lat, lon), addressesNear(lat, lon) and housesOn(streetId).

Public places #

What people search for instead of an address — howa menzili (the airport), Gulistan bazary, Altyn Asyr — has a search of its own:

for (final poi in db.searchPublicPlaces('howa asgabat')) {
  print('${poi.name} (${poi.category.name}) — ${poi.place?.name}');
}
// Aşgabat Halkara Howa Menzili (airport) — Aşgabat

It is kept apart from search on purpose: a new kind of SearchHit would break every exhaustive switch over the results. Show the two lists side by side, or merge them the way your screen needs — by distance from the user, for instance.

PublicPlaceCategory has thirty categories, from airport and railwayStation to pharmacy and fuel; the order is the ranking (an airport before a pharmacy of the same name). No label comes with a category — word it in the language you display. Also there: publicPlacesNear(lat, lon), publicPlacesOf(category) and a categories: filter on both searches.

Cafés and ordinary shops are left out: there are thousands of them and nobody searches the country for one.

A working example lives in example/: search as you type, the list of houses on a street, and a house card showing where its street came from.

cd example && flutter run

How the search works #

Every word of the query must be the start of some word in the entry, and their order does not matter. That is why par 2/4 1 finds Parahat 2/4, 1: demanding the comma and the exact spelling is no good when people type from memory, on the move.

Matching from mid-word is rejected on purpose — rahat will not find Parahat, or the results fill up with accidental hits.

Diacritics are folded: Turkmen names use ä, ç, ň, ö, ş, ü, ý and nobody is going to type them, so gorogly finds Görogly köçesi. The slash and the hyphen survive folding — they are part of house numbers: 2/4, 12-а.

A street's search key carries its settlement, so gorogly kocesi gyzylarbat separates one Görogly köçesi from the nine others in different towns and villages.

Ranking, in order: an exact prefix of the whole entry → a match in the name versus a match in the settlement → the weight of the entry (city → village → street → house) → shorter name before longer. That is why mary gives you the city of Mary first, not houses on a street named Mary in Ashgabat.

There is deliberately no spatial or prefix index: with thirteen thousand entries a full scan takes about a millisecond — less than one frame. Loading copies nothing; the sections stay views over the asset's buffer.

Measured under flutter test (JIT; release is faster):

parsing the file 4 ms
first query (builds the keys) 33 ms, removed by warmUp()
query 0.8–1.4 ms
query over public places 0.4 ms
nearestAddress 0.2 ms

What to expect from the data #

The data is OSM, with everything that implies.

For 23% of houses the street was inferred, not recorded. addr:street is present on 5,452 houses out of 7,091; the rest got their street from the nearest road within 150 m. The flag is Address.streetIsExact — showing the address is fine either way, but claiming that OSM says so is only fine in the first case.

Houses whose street could not be determined were dropped — 390 of them. A bare number is unsearchable: "house 12" exists in every block.

The country has far more houses than this. The extract holds 160,149 buildings and 95% of them carry no addr:housenumber at all. No amount of processing will show a number that is not in OSM.

Only what lies inside the border is kept. The extract reaches across it, and its bounding box holds Mashhad and half of Khorezm; the builder checks the country's border polygon itself.

A public place without a name is dropped — 1,875 of them: an unnamed pharmacy cannot be searched for. One mapped twice (an airport's outline and its terminal node, a station node and its building) is kept once.

Identical numbers on different houses are kept — they are more than half the database. Collapsing them would be wrong: Parahat 4 has seven different buildings numbered "2". What is collapsed is a single house mapped twice — a building outline plus an address node inside it — otherwise every such house appears in the results twice.

Rebuilding #

The finished database is in assets/; you only need to rebuild it to pick up fresher OSM data. You will need a Turkmenistan extract in .pbf format (from download.geofabrik.de, for instance). It is not kept in the repository: 25 MB of input against 391 KB of output.

python3 -m venv tool/.venv && tool/.venv/bin/pip install osmium   # once
tool/.venv/bin/python tool/build_address_db.py turkmenistan.pbf \
    assets/turkmenistan.adb

The build takes about a minute — most of it stitching the border — and prints exactly what it dropped and why.

The format is described in tool/address_db_format.py; lib/src/address_db.dart is a paired implementation of the same layout. Change one and you must change the other, raising FORMAT_VERSION / AddressDatabase.formatVersion together: the loader refuses a version it does not know rather than reading garbage (version 1 files, from before public places, still open). The same goes for diacritic folding and the kept-punctuation set — let them drift apart and typed text stops meeting the stored names, silently and completely.

License #

Code — MIT, see LICENSE.

The data in assets/turkmenistan.adb comes from OpenStreetMap and is distributed under the ODbL — see NOTICE. An application using it must credit © OpenStreetMap contributors.

4
likes
160
points
269
downloads

Documentation

API reference

Publisher

verified publisherpetyaas.online

Weekly Downloads

Offline address search for Turkmenistan: cities and villages, streets, houses and public places. The database ships inside the package, no network needed.

Repository (GitHub)
View/report issues

Topics

#geocoding #offline #openstreetmap #addresses #turkmenistan

License

MIT (license)

Dependencies

flutter

More

Packages that depend on turkmenistan_addresses