tmmaps

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 10 Imported by: 0

README

tm-maps

WGS84 (EPSG:4326) GeoJSON boundaries and geographic data for Turkmenistan, with a Go API for easy access.

GeoJSON

  • data/geojson/turkmenistan-welayatlar.geojson — all welaýats in a single FeatureCollection
  • data/geojson/turkmenistan-etraplar.geojson — available ADM2 district boundaries
  • data/geojson/yerlesim-noktalari.geojson — 1,485 settlements with available coordinates
  • data/regions.json — all 2,711 region and settlement records
  • data/regions/*.json — records grouped by Ahal, Balkan, Daşoguz, Lebap, Mary, Aşgabat, and Arkadag
  • data/regions/unassigned.json — 96 records that could not be assigned to a welaý
  • data/geojson/welayatlar/ahal.geojson
  • data/geojson/welayatlar/balkan.geojson
  • data/geojson/welayatlar/dasoguz.geojson
  • data/geojson/welayatlar/lebap.geojson
  • data/geojson/welayatlar/mary.geojson

Each boundary feature contains:

  • slug
  • name_tm
  • name_en
  • iso_3166_2
  • admin_level

GeoJSON coordinates follow the standard [longitude, latitude] order.

Go API

Install the package:

go get github.com/turkmenos/tm-maps

Import it with:

import tmmaps "github.com/turkmenos/tm-maps"

All data is embedded in the Go package. Every function works offline and does not require external files, databases, or network services.

Geographic lookup functions accept coordinates in (latitude, longitude) order. Raw GeoJSON follows the GeoJSON standard [longitude, latitude] order.

Welaýat
func Welaýat(name string) ([]byte, error)

Returns the raw GeoJSON FeatureCollection for one welaýat. Supported names are ahal, balkan, dasoguz, lebap, and mary.

data, err := tmmaps.Welaýat("ahal")
if err != nil {
	panic(err)
}
fmt.Println(string(data))
Regions
func Regions() ([]Region, error)

Returns all bundled country, welaýat, district, council, and settlement records as structured Region values.

regions, err := tmmaps.Regions()
if err != nil {
	panic(err)
}
for _, region := range regions {
	fmt.Println(region.Slug, region.NameTM, region.Type)
}
FindRegion
func FindRegion(slug string) (*Region, error)

Finds one record by its full slug.

region, err := tmmaps.FindRegion("turkmenistan-mary")
if err != nil {
	panic(err)
}
fmt.Println(region.NameTM) // Mary
Children
func Children(parentSlug string) ([]Region, error)

Returns records whose direct parent matches parentSlug.

children, err := tmmaps.Children("turkmenistan-dasoguz")
if err != nil {
	panic(err)
}
for _, child := range children {
	fmt.Println(child.NameTM, child.Type)
}
func Search(query string) ([]Settlement, error)

Searches settlement names in Turkmen, English, and Russian. Matching is case-insensitive and NFC-normalized. A query with no matches returns an empty slice.

results, err := tmmaps.Search("Mary")
if err != nil {
	panic(err)
}
for _, place := range results {
	fmt.Println(place.NameTM, place.Type)
	if place.Latitude != nil && place.Longitude != nil {
		fmt.Println(*place.Latitude, *place.Longitude)
	}
	if place.Region != nil {
		fmt.Println(place.Region.NameTM)
	}
}

Equivalent Unicode representations match the same settlement:

results, _ := tmmaps.Search("Änew")
results, _ = tmmaps.Search("äNEW")
results, _ = tmmaps.Search("A\u0308new")
SearchWithOptions
func SearchWithOptions(query string, options SearchOptions) ([]Settlement, error)

Searches settlements with an optional result limit, settlement-type filter, and region filter. A zero limit means unlimited results. Supported types are city, town, village, and independent_city. RegionSlug uses a full slug.

results, err := tmmaps.SearchWithOptions("a", tmmaps.SearchOptions{
	Limit:      10,
	Types:      []string{"city", "village"},
	RegionSlug: "turkmenistan-mary",
})
if err != nil {
	panic(err)
}
for _, place := range results {
	fmt.Println(place.NameTM)
}

A negative limit or unsupported type returns ErrInvalidSearchOptions.

RegionAt
func RegionAt(latitude, longitude float64) (*Region, error)

Returns the welaýat that covers a coordinate. Polygon boundary points count as contained.

region, err := tmmaps.RegionAt(37.960077, 58.326063)
if err != nil {
	panic(err)
}
fmt.Println(region.NameTM) // Ahal in the current boundary dataset

Invalid coordinates return ErrInvalidCoordinate. A coordinate outside the available boundaries returns ErrRegionNotFound.

Contains
func Contains(slug string, latitude, longitude float64) (bool, error)

Reports whether a coordinate is covered by a specific welaýat. Use the short slug: ahal, balkan, dasoguz, lebap, or mary. Boundary points return true.

inside, err := tmmaps.Contains("ahal", 37.960077, 58.326063)
if err != nil {
	panic(err)
}
fmt.Println(inside) // true

An unsupported slug returns ErrUnknownRegion. Invalid coordinates return ErrInvalidCoordinate.

Nearest
func Nearest(latitude, longitude float64) (*NearestResult, error)

Returns the nearest settlement with known coordinates. DistanceKM contains the Haversine distance in kilometres.

place, err := tmmaps.Nearest(37.960077, 58.326063)
if err != nil {
	panic(err)
}
fmt.Println(place.NameTM)     // Aşgabat
fmt.Println(place.DistanceKM) // approximately 0

Invalid coordinates return ErrInvalidCoordinate. If no settlement coordinate is available, the function returns ErrNoSettlementCoordinates.

WithinRadius
func WithinRadius(latitude, longitude, radiusKM float64) ([]NearbySettlement, error)

Returns settlements within radiusKM, ordered from nearest to farthest. Each result includes DistanceKM. No matches produce an empty slice.

places, err := tmmaps.WithinRadius(37.960077, 58.326063, 25)
if err != nil {
	panic(err)
}
for _, place := range places {
	fmt.Println(place.NameTM, place.DistanceKM)
}

Invalid coordinates return ErrInvalidCoordinate. A zero, negative, NaN, or infinite radius returns ErrInvalidRadius.

Result types
  • Region represents any administrative or settlement record.
  • Settlement represents a populated place and its optional coordinates and containing region.
  • SettlementRegion describes the top-level welaýat or independent city for a settlement.
  • NearestResult embeds Settlement and adds DistanceKM.
  • NearbySettlement embeds Settlement and adds DistanceKM.
  • SearchOptions provides Limit, Types, and RegionSlug filters.

Coordinate fields are pointers because some source records do not have known coordinates. Check them for nil before dereferencing.

Errors

Errors can be checked with errors.Is:

place, err := tmmaps.Nearest(91, 0)
if errors.Is(err, tmmaps.ErrInvalidCoordinate) {
	fmt.Println("invalid latitude or longitude")
}
Error Meaning
ErrInvalidCoordinate Latitude or longitude is outside its valid range, NaN, or infinite.
ErrUnknownRegion Contains received an unsupported welaýat slug.
ErrRegionNotFound A coordinate is outside the available boundary polygons.
ErrNoSettlementCoordinates No settlement with usable coordinates is available.
ErrInvalidRadius Radius is zero, negative, NaN, or infinite.
ErrInvalidSearchOptions Search limit or settlement type is invalid.

Data Coverage

The administrative boundaries are sourced from the geoBoundaries TKM-ADM1-27578892 dataset and represent boundaries from 2007.

Aşgabat is not represented as a separate ADM1 polygon in the source dataset and appears within Ahal. Arkadag, established as a city in 2023, is also not represented separately because the geometry dataset predates its creation.

For this reason, the current dataset includes boundary geometries for five welaýats:

  • Ahal
  • Balkan
  • Daşoguz
  • Lebap
  • Mary

Aşgabat and Arkadag may still appear in the geographic/settlement datasets where data is available, but they do not have separate ADM1 boundary geometries in this release.

License

The source boundary dataset is released under the Public Domain.

See DATA_LICENSE.md for data licensing and attribution details.

Documentation

Overview

Package tmmaps provides Türkmenistan administrative boundary GeoJSON data.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidCoordinate indicates latitude or longitude outside its valid range.
	ErrInvalidCoordinate = errors.New("invalid coordinate")
	// ErrUnknownRegion indicates that no boundary exists for a requested welaýat slug.
	ErrUnknownRegion = errors.New("unknown welaýat")
	// ErrRegionNotFound indicates a coordinate outside the available welaýat boundaries.
	ErrRegionNotFound = errors.New("coordinate is outside available boundaries")
)
View Source
var ErrInvalidRadius = errors.New("invalid radius")

ErrInvalidRadius indicates a radius that is not finite and greater than zero.

View Source
var ErrInvalidSearchOptions = errors.New("invalid search options")

ErrInvalidSearchOptions indicates an invalid limit or settlement type.

View Source
var ErrNoSettlementCoordinates = errors.New("no settlement coordinates available")

ErrNoSettlementCoordinates indicates that the bundled dataset contains no settlement with usable coordinates.

Functions

func Contains added in v0.3.0

func Contains(slug string, latitude, longitude float64) (bool, error)

Contains reports whether latitude and longitude are covered by the requested welaýat. Boundary points are treated as contained. The lookup is entirely offline and slug must be one of ahal, balkan, dasoguz, lebap, or mary.

func Welaýat

func Welaýat(name string) ([]byte, error)

Types

type NearbySettlement added in v0.3.0

type NearbySettlement struct {
	Settlement
	DistanceKM float64 `json:"distance_km"`
}

NearbySettlement contains a settlement and its distance from the requested coordinate in kilometres.

func WithinRadius added in v0.3.0

func WithinRadius(latitude, longitude, radiusKM float64) ([]NearbySettlement, error)

WithinRadius returns settlements no farther than radiusKM from latitude and longitude. Results are ordered from nearest to farthest.

type NearestResult added in v0.3.0

type NearestResult struct {
	Settlement
	DistanceKM float64 `json:"distance_km"`
}

NearestResult contains the nearest settlement and its great-circle distance from the requested coordinate in kilometres.

func Nearest added in v0.3.0

func Nearest(latitude, longitude float64) (*NearestResult, error)

Nearest finds the closest known settlement to latitude and longitude using coordinates from the embedded dataset. DistanceKM is calculated with the Haversine formula.

type Region

type Region struct {
	Slug               string   `json:"slug"`
	NameTM             string   `json:"name_tm"`
	NameEN             string   `json:"name_en"`
	NameRU             string   `json:"name_ru"`
	Type               string   `json:"type"`
	ParentSlug         string   `json:"parent_slug"`
	Latitude           *float64 `json:"latitude"`
	Longitude          *float64 `json:"longitude"`
	VerificationStatus string   `json:"verification_status"`
}

func Children

func Children(parentSlug string) ([]Region, error)

func FindRegion

func FindRegion(slug string) (*Region, error)

func RegionAt

func RegionAt(latitude, longitude float64) (*Region, error)

RegionAt returns the welaýat containing latitude and longitude. Boundary points are treated as contained. The lookup is entirely offline.

func Regions

func Regions() ([]Region, error)

type SearchOptions added in v0.3.0

type SearchOptions struct {
	Limit      int
	Types      []string
	RegionSlug string
}

SearchOptions controls settlement search filtering. A zero Limit means no limit. RegionSlug uses the full region slug, for example turkmenistan-mary.

type Settlement added in v0.3.0

type Settlement struct {
	Slug      string            `json:"slug"`
	NameTM    string            `json:"name_tm"`
	NameEN    string            `json:"name_en"`
	NameRU    string            `json:"name_ru"`
	Type      string            `json:"type"`
	Latitude  *float64          `json:"latitude"`
	Longitude *float64          `json:"longitude"`
	Region    *SettlementRegion `json:"region,omitempty"`
}

Settlement is a named populated place in the bundled geographic dataset. Latitude and Longitude are nil when coordinates are not available.

func Search(query string) ([]Settlement, error)

Search finds settlements whose Turkmen, English, or Russian name contains query. Matching is case-insensitive and uses only the embedded dataset.

func SearchWithOptions added in v0.3.0

func SearchWithOptions(query string, options SearchOptions) ([]Settlement, error)

SearchWithOptions finds settlements by name and applies result, type, and region filters. Matching is case-insensitive and Unicode-normalized.

type SettlementRegion added in v0.3.0

type SettlementRegion struct {
	Slug   string `json:"slug"`
	NameTM string `json:"name_tm"`
	NameEN string `json:"name_en"`
	NameRU string `json:"name_ru"`
	Type   string `json:"type"`
}

SettlementRegion identifies the top-level welaýat or independent city that contains a settlement. It is nil when the source record has no region assigned.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL