Skip to content

naufalprakoso/nusantara-data-flutter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nusantara Data Flutter

A comprehensive Flutter library for Indonesia location data. Complete data for all 38 provinces, 514 cities/regencies, 7,265 districts (kecamatan), 83,202 villages (kelurahan/desa), and 83,762 postal codes.

pub package License

Features

  • Complete Data: All Indonesian administrative regions from province to village level
  • Offline: All data is embedded, no network required
  • Fast Lookup: O(1) lookup by ID using HashMap indexes
  • Smart Search: Typo-tolerant search using Levenshtein distance algorithm
  • Type-Safe: Full Dart null safety and type checking
  • Well-Tested: Comprehensive unit tests
  • BPS Standard: Uses official Badan Pusat Statistik (BPS) codes

Data Statistics

Type Count
Provinces 38
Cities/Regencies 514
Districts (Kecamatan) 7,265
Villages (Kelurahan/Desa) 83,202
Postal Codes 83,762

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  nusantara_data: ^1.0.0

Then run:

flutter pub get

Usage

Initialize

Call initialize() once at app startup:

import 'package:nusantara_data/nusantara_data.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize the library
  await NusantaraData.initialize();

  runApp(MyApp());
}

Province Operations

// Get all provinces
final provinces = NusantaraData.getAllProvinces();
// Returns: [ProvinceSummary(id: "11", name: "Aceh"), ...]

// Get province by ID (BPS code)
final jakarta = NusantaraData.getProvinceById('31');
// Returns: Province(id: "31", name: "DKI Jakarta", cities: [...])

// Get province by name
final jawaBarat = NusantaraData.getProvinceByName('Jawa Barat');

// Search with typo tolerance
final results = NusantaraData.searchProvinces('Jakrta');
// Finds "DKI Jakarta" despite typo

City Operations

// Get all cities
final cities = NusantaraData.getAllCities();

// Get cities in a province
final jakartaCities = NusantaraData.getCitiesByProvinceId('31');

// Get city by ID
final jakartaPusat = NusantaraData.getCityById('3171');

// Search cities
final results = NusantaraData.searchCities('bandung');

// Search within a province
final results = NusantaraData.searchCities('jakarta', provinceId: '31');

District Operations (Kecamatan)

// Get all districts
final districts = NusantaraData.getAllDistricts();

// Get districts in a city
final jakpusDistricts = NusantaraData.getDistrictsByCityId('3171');

// Get district by ID
final gambir = NusantaraData.getDistrictById('317101');

// Search districts
final results = NusantaraData.searchDistricts('menteng');

Village Operations (Kelurahan/Desa)

// Get villages in a district
final villages = NusantaraData.getVillagesByDistrictId('317101');

// Get village by ID
final village = NusantaraData.getVillageById('3171012001');

// Search villages (districtId required for performance)
final results = NusantaraData.searchVillages('cideng', districtId: '317101');

Postal Code Operations

// Get postal codes for a village
final codes = NusantaraData.getPostalCodesByVillageId('3171012001');
// Returns: ['10110']

// Get postal codes for a district
final codes = NusantaraData.getPostalCodesByDistrictId('317101');

// Reverse lookup - find location by postal code
final locations = NusantaraData.getLocationByPostalCode('10110');
for (final location in locations) {
  print(location.getFullAddress());
  // "Gambir, Gambir, Jakarta Pusat, DKI Jakarta 10110"
}

Metadata

// Get version
final version = NusantaraData.getVersion();
// Returns: "1.0.0"

// Get last updated date
final date = NusantaraData.getLastUpdated();
// Returns: "2026-01-29"

// Get statistics
final stats = NusantaraData.getStatistics();
print('Provinces: ${stats.provinceCount}');     // 38
print('Cities: ${stats.cityCount}');            // 514
print('Districts: ${stats.districtCount}');     // 7,265
print('Villages: ${stats.villageCount}');       // 83,202
print('Postal Codes: ${stats.postalCodeCount}'); // 83,762

BPS Code Format

All IDs follow the BPS (Badan Pusat Statistik) standard:

Level Digits Example Description
Province 2 31 DKI Jakarta
City 4 3171 Kota Jakarta Pusat
District 6 317101 Gambir
Village 10 3171012001 Kelurahan Gambir
Postal Code 5 10110 Postal code

Data Models

Province & ProvinceSummary

class Province {
  final String id;        // BPS code (2 digits)
  final String name;      // e.g., "DKI Jakarta"
  final List<City> cities;
}

class ProvinceSummary {
  final String id;
  final String name;
  final int cityCount;
}

City & CitySummary

enum CityType { kota, kabupaten }

class City {
  final String id;          // BPS code (4 digits)
  final String provinceId;
  final String name;        // e.g., "Kota Jakarta Pusat"
  final CityType type;
  final List<District> districts;
}

District & DistrictSummary

class District {
  final String id;      // BPS code (6 digits)
  final String cityId;
  final String name;    // e.g., "Gambir"
  final List<Village> villages;
}

Village & VillageSummary

class Village {
  final String id;            // BPS code (10 digits)
  final String districtId;
  final String name;
  final List<String> postalCodes;
}

PostalCodeDetail

class PostalCodeDetail {
  final String postalCode;
  final String villageId;
  final String villageName;
  final String districtId;
  final String districtName;
  final String cityId;
  final String cityName;
  final CityType cityType;
  final String provinceId;
  final String provinceName;

  String getFullAddress(); // Returns formatted address
}

Smart Search (Fuzzy Matching)

The library includes typo-tolerant search using the Levenshtein distance algorithm:

// Typo in "Jakarta" -> "Jakrta"
final results = NusantaraData.searchProvinces('Jakrta');
// Finds "DKI Jakarta"

// Typo in "Bandung" -> "Bandug"
final results = NusantaraData.searchCities('Bandug');
// Finds "Kota Bandung", "Kabupaten Bandung", etc.

How It Works

  1. Exact Match: Highest priority for exact substring matches
  2. Word-Start Match: High priority for matches at word boundaries
  3. Fuzzy Match: Uses Levenshtein distance for typo tolerance
  4. Adaptive Tolerance: Shorter queries get less tolerance

Advanced Usage

Using FuzzySearch Directly

import 'package:nusantara_data/nusantara_data.dart';

// Calculate Levenshtein distance
final distance = FuzzySearch.levenshteinDistance('hello', 'hallo');
// Returns: 1

// Calculate similarity ratio (0.0 to 1.0)
final ratio = FuzzySearch.similarityRatio('hello', 'hello');
// Returns: 1.0

// Rank items by similarity
final items = ['Jakarta', 'Bandung', 'Surabaya'];
final ranked = FuzzySearch.rankBySimilarity(
  query: 'jakrta',
  items: items,
  selector: (item) => item,
  minSimilarity: 0.6,
);
// Returns: ['Jakarta']

Using Repository Directly

import 'package:nusantara_data/nusantara_data.dart';

// After initialization
final repository = NusantaraData.repository; // Access internal repository

Data Source

  • Kepmendagri No 300.2.2-2138 Tahun 2025 - Official Indonesian government regulation
  • Badan Pusat Statistik (BPS) - Official Statistics Indonesia codes
  • cahyadsn/wilayah - GitHub Repository
  • cahyadsn/wilayah_kodepos - Postal Code Data

Performance

  • O(1) Lookup: ID lookups use HashMap for constant-time access
  • Lazy Loading: Data loaded on first initialize() call
  • Cached: Subsequent access uses cached data
  • Indexed: Pre-built indexes for fast hierarchical queries

Requirements

  • Flutter SDK >= 3.10.0
  • Dart SDK >= 3.0.0

License

Copyright 2026 Naufal Prakoso

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Contributing

Contributions are welcome! Please read our Contributing Guide first.

Changelog

See CHANGELOG.md for version history.

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published