Detalhes do pacote

osm-kenya-boundaries

its-kios0950MIT1.0.3

Complete Kenya administrative boundaries data (47 Counties, 290+ Constituencies, 300+ Sub-Counties, 1,450+ Wards) with TypeScript support. Zero dependencies, tree-shakeable, and fully typed.

kenya, osm, openstreetmap, boundaries

readme (leia-me)

OSM Kenya Boundaries 🇰🇪

A comprehensive TypeScript/JavaScript library providing complete administrative boundary data for Kenya, including all 47 Counties, 290+ Constituencies, and 1,450+ Wards.

npm version License: MIT TypeScript GitHub Sponsors

✨ Features

  • Complete Data: All 47 counties, 290+ constituencies, and 1,450+ wards
  • 🎯 TypeScript Support: Full type definitions included
  • 🔍 Search Functions: Easy search and lookup across all administrative levels
  • 📦 Zero Dependencies: Lightweight and fast (< 200KB)
  • 🌳 Tree-shakeable: Import only what you need
  • 📖 Well Documented: Comprehensive examples and API documentation
  • 🗺️ OSM Compatible: Data structure optimized for mapping applications
  • 🚀 Performance: Optimized for fast queries and low memory usage

📦 Installation

npm install osm-kenya-boundaries

Or using yarn:

yarn add osm-kenya-boundaries

Or using pnpm:

pnpm add osm-kenya-boundaries

🚀 Quick Start

import {
  getCounties,
  getCountyByName,
  getConstituenciesByCounty,
  searchWard
} from 'osm-kenya-boundaries';

// Get all counties
const counties = getCounties();
console.log(`Kenya has ${counties.length} counties`);

// Get specific county
const nairobi = getCountyByName('Nairobi');
console.log(nairobi);
// Output: { county_code: 47, county_name: 'Nairobi', constituencies: [...] }

// Get constituencies in a county
const constituencies = getConstituenciesByCounty(47);
console.log(`Nairobi has ${constituencies.length} constituencies`);

// Search for a ward
const results = searchWard('Kilimani');
console.log(results);

📚 API Reference

County Functions

getCounties(): County[]

Returns all 47 counties in Kenya.

const allCounties = getCounties();
console.log(allCounties.length); // 47

getCountyByCode(code: number): County | undefined

Get a county by its numeric code (1-47).

const mombasa = getCountyByCode(1);
const nairobi = getCountyByCode(47);

getCountyByName(name: string): County | undefined

Get a county by name (case-insensitive).

const mombasa = getCountyByName('Mombasa');
const kisumu = getCountyByName('KISUMU'); // Case insensitive
const county = getCountyByName('  Nairobi  '); // Handles whitespace

Constituency Functions

getAllConstituencies(): Array<Constituency & { county_name: string; county_code: number }>

Get all constituencies with their parent county information.

const allConstituencies = getAllConstituencies();
allConstituencies.forEach(c => {
  console.log(`${c.constituency_name} in ${c.county_name}`);
});

getConstituenciesByCounty(countyCode: number): Constituency[]

Get all constituencies in a specific county.

const nairobiConstituencies = getConstituenciesByCounty(47);
const mombasaConstituencies = getConstituenciesByCounty(1);

getConstituencyByName(name: string): SearchResult | undefined

Find a constituency by name and get its parent county.

const result = getConstituencyByName('Westlands');
console.log(result?.county.county_name); // "Nairobi"
console.log(result?.constituency.wards); // ["Kitisuru", "Parklands/Highridge", ...]

Ward Functions

getAllWards(): Array<{ ward: string; constituency: string; county: string }>

Get all wards with their parent constituency and county.

const allWards = getAllWards();
console.log(`Total wards: ${allWards.length}`);

getWardsByConstituency(constituencyName: string): string[]

Get all wards in a specific constituency.

const westlandsWards = getWardsByConstituency('Westlands');
console.log(westlandsWards);
// ["Kitisuru", "Parklands/Highridge", "Karura", "Kangemi", "Mountain View"]

searchWard(wardName: string): SearchResult[]

Search for wards by name. Returns all matches as some ward names may appear in multiple locations.

const results = searchWard('Central');
results.forEach(result => {
  console.log(`${result.ward} in ${result.constituency?.constituency_name}, ${result.county?.county_name}`);
});

Search & Utility Functions

search(query: string): SearchResult[]

Search across all administrative levels (counties, constituencies, and wards).

const results = search('Nairobi');
// Returns matches from counties, constituencies, and wards containing "Nairobi"

validateLocation(county?: string, constituency?: string, ward?: string): boolean

Validate if a location exists in the administrative hierarchy.

// Valid location
const isValid = validateLocation('Nairobi', 'Westlands', 'Kilimani');
console.log(isValid); // true

// Invalid constituency
const isInvalid = validateLocation('Nairobi', 'InvalidConstituency');
console.log(isInvalid); // false

// Partial validation
const countyExists = validateLocation('Mombasa');
console.log(countyExists); // true

getStatistics()

Get statistical information about Kenya's administrative divisions.

const stats = getStatistics();
console.log(stats);
// {
//   counties: 47,
//   constituencies: 290,
//   wards: 1450,
//   avgConstituenciesPerCounty: 6.17,
//   avgWardsPerConstituency: 5.0
// }

🎯 Use Cases

📝 Form Dropdowns (Cascading Selects)

import { getCounties, getConstituenciesByCounty, getWardsByConstituency } from 'osm-kenya-boundaries';

// Populate county dropdown
const countyOptions = getCounties().map(c => ({
  value: c.county_code,
  label: c.county_name
}));

// When county is selected
function onCountyChange(countyCode: number) {
  const constituencies = getConstituenciesByCounty(countyCode);
  // Update constituency dropdown
  return constituencies.map(c => ({
    value: c.constituency_name,
    label: c.constituency_name
  }));
}

// When constituency is selected
function onConstituencyChange(constituencyName: string) {
  const wards = getWardsByConstituency(constituencyName);
  // Update ward dropdown
  return wards.map(w => ({
    value: w,
    label: w
  }));
}

✅ Address Validation

import { validateLocation } from 'osm-kenya-boundaries';

interface KenyanAddress {
  county: string;
  constituency: string;
  ward: string;
  street?: string;
}

function validateKenyanAddress(address: KenyanAddress): boolean {
  const isValid = validateLocation(
    address.county,
    address.constituency,
    address.ward
  );

  if (!isValid) {
    throw new Error('Invalid Kenyan administrative location');
  }

  return true;
}

// Usage
try {
  validateKenyanAddress({
    county: 'Nairobi',
    constituency: 'Westlands',
    ward: 'Kilimani',
    street: 'Argwings Kodhek Road'
  });
  console.log('Address is valid!');
} catch (error) {
  console.error(error.message);
}

🔍 Search Autocomplete

import { search } from 'osm-kenya-boundaries';

function autocompleteLocation(query: string) {
  if (query.length < 2) return [];

  const results = search(query);

  return results.map(result => {
    if (result.ward) {
      return {
        label: `${result.ward} Ward, ${result.constituency?.constituency_name}, ${result.county?.county_name}`,
        type: 'ward',
        value: result
      };
    } else if (result.constituency) {
      return {
        label: `${result.constituency.constituency_name} Constituency, ${result.county?.county_name}`,
        type: 'constituency',
        value: result
      };
    } else {
      return {
        label: `${result.county?.county_name} County`,
        type: 'county',
        value: result
      };
    }
  });
}

// Usage
const suggestions = autocompleteLocation('Nai');
console.log(suggestions);

🗺️ Mapping Applications

import { getCounties, getConstituenciesByCounty } from 'osm-kenya-boundaries';
import L from 'leaflet';

// Create a choropleth map
const counties = getCounties();
const map = L.map('map').setView([-1.286389, 36.817223], 6);

counties.forEach(county => {
  const constituencies = county.constituencies;
  console.log(`${county.county_name}: ${constituencies.length} constituencies`);

  // Add markers or polygons for each county
  // You would need GeoJSON data for actual boundary rendering
});

⚛️ React Example

import { useState, useEffect } from 'react';
import { 
  getCounties, 
  getConstituenciesByCounty, 
  getWardsByConstituency,
  type County,
  type Constituency 
} from 'osm-kenya-boundaries';

export function LocationSelector() {
  const [selectedCounty, setSelectedCounty] = useState('');
  const [selectedConstituency, setSelectedConstituency] = useState('');
  const [selectedWard, setSelectedWard] = useState('');

  const [constituencies, setConstituencies] = useState<Constituency[]>([]);
  const [wards, setWards] = useState<string[]>([]);

  const counties = getCounties();

  useEffect(() => {
    if (selectedCounty) {
      const county = counties.find(c => c.county_name === selectedCounty);
      if (county) {
        const consts = getConstituenciesByCounty(county.county_code);
        setConstituencies(consts);
        setSelectedConstituency('');
        setSelectedWard('');
      }
    }
  }, [selectedCounty]);

  useEffect(() => {
    if (selectedConstituency) {
      const wardList = getWardsByConstituency(selectedConstituency);
      setWards(wardList);
      setSelectedWard('');
    }
  }, [selectedConstituency]);

  return (
    <div className="space-y-4">
      <div>
        <label className="block text-sm font-medium mb-1">County</label>
        <select
          value={selectedCounty}
          onChange={(e) => setSelectedCounty(e.target.value)}
          className="w-full border rounded px-3 py-2"
        >
          <option value="">Select County</option>
          {counties.map(county => (
            <option key={county.county_code} value={county.county_name}>
              {county.county_name}
            </option>
          ))}
        </select>
      </div>

      <div>
        <label className="block text-sm font-medium mb-1">Constituency</label>
        <select
          value={selectedConstituency}
          onChange={(e) => setSelectedConstituency(e.target.value)}
          className="w-full border rounded px-3 py-2"
          disabled={!selectedCounty}
        >
          <option value="">Select Constituency</option>
          {constituencies.map(constituency => (
            <option key={constituency.constituency_name} value={constituency.constituency_name}>
              {constituency.constituency_name}
            </option>
          ))}
        </select>
      </div>

      <div>
        <label className="block text-sm font-medium mb-1">Ward</label>
        <select
          value={selectedWard}
          onChange={(e) => setSelectedWard(e.target.value)}
          className="w-full border rounded px-3 py-2"
          disabled={!selectedConstituency}
        >
          <option value="">Select Ward</option>
          {wards.map(ward => (
            <option key={ward} value={ward}>
              {ward}
            </option>
          ))}
        </select>
      </div>

      {selectedWard && (
        <div className="p-4 bg-green-50 border border-green-200 rounded">
          <h3 className="font-semibold">Selected Location:</h3>
          <p>{selectedWard} Ward, {selectedConstituency}, {selectedCounty}</p>
        </div>
      )}
    </div>
  );
}

📊 TypeScript Types

interface County {
  county_code: number;
  county_name: string;
  constituencies: Constituency[];
}

interface Constituency {
  constituency_name: string;
  wards: string[];
}

interface SearchResult {
  county?: County;
  constituency?: Constituency;
  ward?: string;
}

📖 Data Structure

The package contains hierarchical administrative data:

Kenya (Country)
├── 47 Counties (e.g., Nairobi, Mombasa, Kisumu)
│   ├── 290+ Constituencies (e.g., Westlands, Langata, Dagoretti)
│   │   └── 1,450+ Wards (e.g., Kilimani, Karen, Kangemi)

Example County Structure:

{
  "county_code": 47,
  "county_name": "Nairobi",
  "constituencies": [
    {
      "constituency_name": "Westlands",
      "wards": [
        "Kitisuru",
        "Parklands/Highridge",
        "Karura",
        "Kangemi",
        "Mountain View"
      ]
    }
  ]
}

🌍 Data Source & Accuracy

This data is compiled from official sources:

  • IEBC (Independent Electoral and Boundaries Commission) - Official electoral boundaries
  • KNBS (Kenya National Bureau of Statistics) - Census and statistical data
  • OpenStreetMap Kenya - Community-maintained geospatial data

Last Updated: October 2024
Data Version: 1.0.0

Data Accuracy

If you notice any inaccuracies or outdated information, please:

  1. Open an issue with details
  2. Provide the official source/reference
  3. Submit a pull request with corrections

💖 Support This Project

If you find this package useful, please consider supporting its development:

GitHub Sponsors

Why Sponsor?

  • 🔄 Keep the data updated with latest changes
  • 🐛 Faster bug fixes and support
  • ✨ New features and improvements
  • 📚 Better documentation and examples
  • 🌍 Help the Kenyan developer community

Sponsorship Tiers

  • Coffee Supporter ($5/month) - Help keep the project maintained
  • 🥉 Bronze Sponsor ($25/month) - Priority support
  • 🥈 Silver Sponsor ($100/month) - Logo on README
  • 🥇 Gold Sponsor ($500/month) - Custom features

Become a sponsor →

🤝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.

Ways to Contribute

  • 🐛 Report bugs
  • 💡 Suggest new features
  • 📝 Improve documentation
  • 🔧 Submit pull requests
  • 📊 Update data if you find inaccuracies
  • ⭐ Star the repository
  • 🔀 Share with others

📝 License

MIT © its-kios09

See LICENSE for full details.

🙏 Acknowledgments

  • IEBC for official boundary data
  • KNBS for statistical information
  • OpenStreetMap Kenya community
  • All contributors and supporters

📞 Support & Contact

🔗 Related Projects

📈 Stats

GitHub stars GitHub forks npm downloads GitHub issues GitHub pull requests


Made with ❤️ for the Kenyan developer community

Keywords

kenya osm openstreetmap boundaries counties constituencies wards administrative geography geospatial africa typescript javascript open-source mapping gis location-data