{"id":37437750,"url":"https://github.com/ucid-foundation/ucid","last_synced_at":"2026-01-18T09:57:00.381Z","repository":{"id":332202394,"uuid":"1132573800","full_name":"ucid-foundation/ucid","owner":"ucid-foundation","description":"A standardized temporal-spatial identifier framework for urban context analysis with H3 indexing, multi-dimensional scoring, and ML-based quality assessment.","archived":false,"fork":false,"pushed_at":"2026-01-16T16:53:19.000Z","size":6700,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-16T18:44:16.971Z","etag":null,"topics":["accessibility","climate-resilience","geopandas","geospatial","gtfs","h3-indexing","machine-learning","openstreetmap","python","reproducible-research","smart-cities","spatial-analysis","temporal-analysis","transit-quality","urban-analytics","urban-planning"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/UCID/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"eupl-1.2","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ucid-foundation.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":".github/CODEOWNERS","security":".github/SECURITY.md","support":"SUPPORT.md","governance":"GOVERNANCE.md","roadmap":"ROADMAP.md","authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":".zenodo.json","notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"ucid-foundation","custom":["https://www.ucid.org/donate"]}},"created_at":"2026-01-12T06:40:45.000Z","updated_at":"2026-01-16T16:53:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"6a202b19-2d57-4898-993f-2c1c603ba423","html_url":"https://github.com/ucid-foundation/ucid","commit_stats":null,"previous_names":["ucid-foundation/ucid"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/ucid-foundation/ucid","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ucid-foundation%2Fucid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ucid-foundation%2Fucid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ucid-foundation%2Fucid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ucid-foundation%2Fucid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ucid-foundation","download_url":"https://codeload.github.com/ucid-foundation/ucid/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ucid-foundation%2Fucid/sbom","scorecard":{"id":1241804,"data":{"date":"2026-01-14T13:07:36Z","repo":{"name":"github.com/ucid-foundation/ucid","commit":"dc8fc7b1453a1381fa21e9b094af812c559e8930"},"scorecard":{"version":"v5.0.0","commit":"ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4"},"score":7,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#binary-artifacts"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#branch-protection"}},{"name":"CI-Tests","score":-1,"reason":"no pull request found","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#ci-tests"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#cii-best-practices"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#code-review"}},{"name":"Contributors","score":10,"reason":"project has 3 contributing companies or organizations -- score normalized to 10","details":["Info: skolyn contributor org/company found, unbihexium-oss contributor org/company found, technical university of denmark contributor org/company found, "],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#contributors"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#dangerous-workflow"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#dependency-update-tool"}},{"name":"Fuzzing","score":10,"reason":"project is fuzzed","details":["Info: ClusterFuzzLite integration found","Info: PythonAtherisFuzzer integration found: .clusterfuzzlite/fuzz_parser.py:13"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: European Union Public License 1.2: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#license"}},{"name":"Maintained","score":0,"reason":"project was created in last 90 days. please review its contents carefully","details":["Warn: Repository was created in last 90 days."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#maintained"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/publish.yml:39"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":3,"reason":"dependency not pinned by hash detected -- score normalized to 3","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/ucid-foundation/ucid/publish.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .clusterfuzzlite/Dockerfile:7","Warn: pipCommand not pinned by hash: Dockerfile:25","Warn: pipCommand not pinned by hash: .clusterfuzzlite/build.sh:4","Warn: pipCommand not pinned by hash: .clusterfuzzlite/build.sh:7","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:22","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:42","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:43","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:47","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:48","Warn: pipCommand not pinned by hash: .github/workflows/docs.yml:22","Warn: pipCommand not pinned by hash: .github/workflows/docs.yml:23","Warn: pipCommand not pinned by hash: .github/workflows/fuzzing.yml:22","Warn: pipCommand not pinned by hash: .github/workflows/fuzzing.yml:23","Warn: pipCommand not pinned by hash: .github/workflows/nightly.yml:21","Warn: pipCommand not pinned by hash: .github/workflows/nightly.yml:39","Warn: pipCommand not pinned by hash: .github/workflows/publish.yml:23","Warn: pipCommand not pinned by hash: .github/workflows/publish.yml:24","Warn: pipCommand not pinned by hash: .github/workflows/publish.yml:31","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:24","Warn: pipCommand not pinned by hash: .github/workflows/sbom.yml:23","Warn: pipCommand not pinned by hash: .github/workflows/sbom.yml:24","Warn: pipCommand not pinned by hash: .github/workflows/sbom.yml:24","Info:  34 out of  34 GitHub-owned GitHubAction dependencies pinned","Info:   4 out of   5 third-party GitHubAction dependencies pinned","Info:   3 out of   3 containerImage dependencies pinned","Info:   1 out of  23 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":10,"reason":"SAST tool detected: CodeQL","details":["Info: SAST configuration detected: CodeQL","Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#sast"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: .github/SECURITY.md:1","Info: Found linked content: .github/SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: .github/SECURITY.md:1","Info: Found text in security policy: .github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#security-policy"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#signed-releases"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:20","Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:19","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/release.yml:15","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/sbom.yml:15","Info: topLevel 'contents' permission set to 'read': .github/workflows/cflite.yml:12","Info: topLevel 'contents' permission set to 'read': .github/workflows/ci.yml:10","Info: topLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:12","Info: topLevel 'contents' permission set to 'read': .github/workflows/dependency-review.yml:8","Info: topLevel 'contents' permission set to 'read': .github/workflows/docs.yml:10","Info: topLevel 'contents' permission set to 'read': .github/workflows/fuzzing.yml:9","Info: topLevel 'contents' permission set to 'read': .github/workflows/nightly.yml:9","Info: topLevel 'contents' permission set to 'read': .github/workflows/publish.yml:8","Info: topLevel 'contents' permission set to 'read': .github/workflows/release.yml:9","Info: topLevel 'contents' permission set to 'read': .github/workflows/sbom.yml:9","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:9"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#token-permissions"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2026-01-16T20:45:52.656Z","repository_id":332202394,"created_at":"2026-01-16T20:45:52.666Z","updated_at":"2026-01-16T20:45:52.666Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28534203,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["accessibility","climate-resilience","geopandas","geospatial","gtfs","h3-indexing","machine-learning","openstreetmap","python","reproducible-research","smart-cities","spatial-analysis","temporal-analysis","transit-quality","urban-analytics","urban-planning"],"created_at":"2026-01-16T06:42:04.750Z","updated_at":"2026-01-18T09:57:00.370Z","avatar_url":"https://github.com/ucid-foundation.png","language":"Python","funding_links":["https://github.com/sponsors/ucid-foundation","https://www.ucid.org/donate"],"categories":[],"sub_categories":[],"readme":"# UCID: Urban Context Identifier\n\n[![CI](https://github.com/ucid-foundation/ucid/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/ucid-foundation/ucid/actions/workflows/ci.yml)\n[![Codecov](https://codecov.io/gh/ucid-foundation/ucid/graph/badge.svg)](https://codecov.io/gh/ucid-foundation/ucid)\n[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/ucid-foundation/ucid/badge)](https://securityscorecards.dev/viewer/?uri=github.com/ucid-foundation/ucid)\n[![PyPI](https://img.shields.io/pypi/v/UCID?logo=pypi\u0026logoColor=white\u0026label=PyPI)](https://pypi.org/project/UCID/)\n[![Status](https://img.shields.io/pypi/status/UCID?logo=pypi\u0026logoColor=white)](https://pypi.org/project/UCID/)\n[![Python](https://img.shields.io/pypi/pyversions/UCID?logo=python\u0026logoColor=white)](https://pypi.org/project/UCID/)\n[![Wheel](https://img.shields.io/pypi/wheel/UCID?logo=pypi\u0026logoColor=white)](https://pypi.org/project/UCID/)\n[![Downloads](https://img.shields.io/pypi/dm/UCID?logo=pypi\u0026logoColor=white)](https://pypi.org/project/UCID/)\n[![License](https://img.shields.io/github/license/ucid-foundation/ucid)](https://github.com/ucid-foundation/ucid/blob/main/LICENSE)\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.18244258.svg)](https://doi.org/10.5281/zenodo.18244258)\n[![Dataset DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.18246412.svg)](https://doi.org/10.5281/zenodo.18246412)\n[![arXiv](https://img.shields.io/badge/arXiv-submit%2F7155127-b31b1b?logo=arxiv\u0026logoColor=white)](https://arxiv.org/abs/submit/7155127)\n[![CodeQL](https://github.com/ucid-foundation/ucid/actions/workflows/codeql.yml/badge.svg)](https://github.com/ucid-foundation/ucid/actions/workflows/codeql.yml)\n[![SLSA 3](https://slsa.dev/images/gh-badge-level3.svg)](https://slsa.dev)\n[![Docs](https://github.com/ucid-foundation/ucid/actions/workflows/docs.yml/badge.svg)](https://github.com/ucid-foundation/ucid/actions/workflows/docs.yml)\n[![Scorecard](https://github.com/ucid-foundation/ucid/actions/workflows/scorecard.yml/badge.svg)](https://github.com/ucid-foundation/ucid/actions/workflows/scorecard.yml)\n[![ClusterFuzzLite](https://github.com/ucid-foundation/ucid/actions/workflows/cflite.yml/badge.svg)](https://github.com/ucid-foundation/ucid/actions/workflows/cflite.yml)\n[![Nightly](https://github.com/ucid-foundation/ucid/actions/workflows/nightly.yml/badge.svg)](https://github.com/ucid-foundation/ucid/actions/workflows/nightly.yml)\n[![SBOM](https://github.com/ucid-foundation/ucid/actions/workflows/sbom.yml/badge.svg)](https://github.com/ucid-foundation/ucid/actions/workflows/sbom.yml)\n[![Release](https://github.com/ucid-foundation/ucid/actions/workflows/release.yml/badge.svg)](https://github.com/ucid-foundation/ucid/actions/workflows/release.yml)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit\u0026logoColor=white)](https://pre-commit.com/)\n[![Security: bandit](https://img.shields.io/badge/security-bandit-yellow)](https://github.com/PyCQA/bandit)\n[![Type checked: mypy](https://img.shields.io/badge/type%20checked-mypy-blue)](https://mypy-lang.org/)\n[![GitHub Release](https://img.shields.io/github/v/release/ucid-foundation/ucid?logo=github)](https://github.com/ucid-foundation/ucid/releases)\n[![GitHub Tag](https://img.shields.io/github/v/tag/ucid-foundation/ucid?logo=github)](https://github.com/ucid-foundation/ucid/tags)\n[![GitHub Stars](https://img.shields.io/github/stars/ucid-foundation/ucid?logo=github)](https://github.com/ucid-foundation/ucid/stargazers)\n[![GitHub Forks](https://img.shields.io/github/forks/ucid-foundation/ucid?logo=github)](https://github.com/ucid-foundation/ucid/network)\n[![GitHub Watchers](https://img.shields.io/github/watchers/ucid-foundation/ucid?logo=github)](https://github.com/ucid-foundation/ucid/watchers)\n[![GitHub Issues](https://img.shields.io/github/issues/ucid-foundation/ucid?logo=github)](https://github.com/ucid-foundation/ucid/issues)\n[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/ucid-foundation/ucid?logo=github)](https://github.com/ucid-foundation/ucid/pulls)\n[![GitHub Contributors](https://img.shields.io/github/contributors/ucid-foundation/ucid?logo=github)](https://github.com/ucid-foundation/ucid/graphs/contributors)\n[![GitHub Last Commit](https://img.shields.io/github/last-commit/ucid-foundation/ucid?logo=github)](https://github.com/ucid-foundation/ucid/commits)\n[![GitHub Repo Size](https://img.shields.io/github/repo-size/ucid-foundation/ucid?logo=github)](https://github.com/ucid-foundation/ucid)\n[![GitHub Code Size](https://img.shields.io/github/languages/code-size/ucid-foundation/ucid?logo=github)](https://github.com/ucid-foundation/ucid)\n[![GitHub Top Language](https://img.shields.io/github/languages/top/ucid-foundation/ucid?logo=github)](https://github.com/ucid-foundation/ucid)\n[![Python](https://img.shields.io/badge/Python-3.11+-3776ab?logo=python\u0026logoColor=white)](https://www.python.org/)\n[![Pydantic](https://img.shields.io/badge/Pydantic-2.0+-e92063?logo=pydantic\u0026logoColor=white)](https://pydantic.dev/)\n[![FastAPI](https://img.shields.io/badge/FastAPI-0.100+-009688?logo=fastapi\u0026logoColor=white)](https://fastapi.tiangolo.com/)\n[![NumPy](https://img.shields.io/badge/NumPy-1.24+-013243?logo=numpy\u0026logoColor=white)](https://numpy.org/)\n[![Pandas](https://img.shields.io/badge/Pandas-2.0+-150458?logo=pandas\u0026logoColor=white)](https://pandas.pydata.org/)\n[![GeoPandas](https://img.shields.io/badge/GeoPandas-0.14+-139c5a)](https://geopandas.org/)\n[![H3](https://img.shields.io/badge/H3-4.0+-1e90ff)](https://h3geo.org/)\n[![Shapely](https://img.shields.io/badge/Shapely-2.0+-4caf50)](https://shapely.readthedocs.io/)\n[![ORCID](https://img.shields.io/badge/ORCID-0009--0006--5184--0810-a6ce39?logo=orcid\u0026logoColor=white)](https://orcid.org/0009-0006-5184-0810)\n[![SemVer](https://img.shields.io/badge/SemVer-2.0.0-blue?logo=semver\u0026logoColor=white)](https://semver.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow?logo=conventionalcommits\u0026logoColor=white)](https://conventionalcommits.org)\n[![SBOM](https://img.shields.io/badge/SBOM-CycloneDX-brightgreen)](https://cyclonedx.org/)\n[![REUSE](https://img.shields.io/badge/REUSE-compliant-green)](https://reuse.software/)\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa)](CODE_OF_CONDUCT.md)\n\n---\n\n\u003cimg src=\"assets/logo.svg\" alt=\"UCID Logo\" width=\"240\" height=\"80\"\u003e\n\n**UCID (Urban Context Identifier)** is a standardized, temporal identifier system and production-grade Python library for comprehensive urban context analysis. UCID provides a universal key for joining disparate urban datasets across global cities, enabling researchers, urban planners, and data scientists to perform reproducible, spatially-explicit, and temporally-aware urban analysis at scale.\n\n---\n\n## Document Information\n\n| Field | Value |\n|-------|-------|\n| Version | 1.0.5 |\n| Last Updated | 2026-01-16 |\n| Maintainer | UCID Foundation |\n| License | EUPL-1.2 |\n\n---\n\n## Library Statistics\n\nThe following statistics are derived from comprehensive testing of the UCID library:\n\n| Metric | Value | Source |\n|--------|-------|--------|\n| Total Cities | 403 | data/cities.json |\n| Countries Covered | 22 | data/cities.json |\n| Total Population Covered | 240,287,432 | data/cities.json |\n| Average City Population | 596,246 | data/cities.json |\n| Largest City Population | 15,519,267 | data/cities.json |\n| Smallest City Population | 1,659 | data/cities.json |\n| Context Algorithms | 8 (4 production, 4 planned) | data/contexts.json |\n| Grade Levels | 5 (A, B, C, D, F) | data/grading.json |\n| Python Source Files | 114 | src/ directory |\n| Total Python Lines | 12,717 | src/ directory |\n| Test Files | 27 | tests/ directory |\n| Academic Dataset Records | 1,000,000 | datasets/ |\n\n### Regional Distribution\n\n| Region | Cities | Percentage |\n|--------|--------|------------|\n| Europe | 276 | 68.5% |\n| Oceania | 21 | 5.2% |\n| Americas | 20 | 5.0% |\n| Asia-Pacific | 10 | 2.5% |\n| Other | 76 | 18.8% |\n\n### Country Distribution (Top 10)\n\n| Country | Code | Cities | Dataset Records |\n|---------|------|--------|-----------------|\n| Turkey | TR | 81 | 309,893 |\n| Germany | DE | 50 | 143,493 |\n| United States | US | 20 | 97,292 |\n| Australia | AU | 21 | 90,867 |\n| United Kingdom | GB | 15 | 60,509 |\n| France | FR | 20 | 57,988 |\n| Netherlands | NL | 12 | 34,898 |\n| Azerbaijan | AZ | 6 | 21,149 |\n| Luxembourg | LU | 4 | 22,320 |\n| Sweden | SE | 8 | 16,669 |\n\n---\n\n## Table of Contents\n\n1. [Overview](#overview)\n2. [Key Features](#key-features)\n3. [Installation](#installation)\n4. [Quick Start](#quick-start)\n5. [UCID Format Specification](#ucid-format-specification)\n6. [Context Algorithms](#context-algorithms)\n7. [City Registry](#city-registry)\n8. [Grading System](#grading-system)\n9. [API Reference](#api-reference)\n10. [Architecture](#architecture)\n11. [Performance Benchmarks](#performance-benchmarks)\n12. [Data Integration](#data-integration)\n13. [Academic Dataset](#academic-dataset)\n14. [Security](#security)\n15. [Testing](#testing)\n16. [Deployment](#deployment)\n17. [Contributing](#contributing)\n18. [Citation](#citation)\n19. [License](#license)\n20. [References](#references)\n\n---\n\n## Overview\n\n### The Urban Data Fragmentation Problem\n\nUrban data analysis faces a fundamental challenge: the fragmentation of spatial and temporal data across heterogeneous sources, formats, and coordinate systems. Modern cities generate vast amounts of data from transportation systems, infrastructure sensors, social media, government records, and commercial services. However, integrating these datasets for comprehensive urban analysis remains technically challenging due to:\n\n1. **Spatial Inconsistency**: Different datasets use varying coordinate reference systems, spatial resolutions, and geographic boundaries\n2. **Temporal Misalignment**: Data sources record information at different temporal granularities (seconds, hours, days, months)\n3. **Semantic Heterogeneity**: Similar concepts are represented differently across datasets (e.g., \"neighborhood\", \"district\", \"zone\")\n4. **Scale Variation**: Analysis requirements range from building-level to metropolitan-scale\n\n### The UCID Solution\n\nUCID (Urban Context Identifier) addresses these challenges by providing a standardized identifier that encapsulates location, time, and context into a single, parseable string that serves as a universal join key. The UCID format is designed to:\n\n- Provide deterministic spatial binning using H3 hexagonal hierarchical indexing\n- Enable ISO week-based temporal alignment with hourly precision\n- Support pluggable context scoring for multi-dimensional urban quality assessment\n- Maintain human readability while enabling machine parsing\n- Ensure reproducibility across systems and platforms\n\n### Mathematical Foundation\n\nThe UCID system is built on rigorous mathematical foundations:\n\n**Spatial Indexing**: UCID uses H3 hexagonal hierarchical spatial indexing developed by Uber. The H3 system provides:\n\n$$A_{hex} = \\frac{3\\sqrt{3}}{2} s^2$$\n\nwhere $s$ is the edge length of the hexagon. At resolution 9 (the UCID default), each hexagon covers approximately 0.11 km² with an edge length of 174 meters.\n\n**Temporal Encoding**: UCID uses ISO 8601 week-based temporal keys:\n\n$$T_{ucid} = Y \\cdot 52 + W + \\frac{H}{168}$$\n\nwhere $Y$ is the year, $W$ is the ISO week number (1-52/53), and $H$ is the hour (0-23).\n\n**Context Scoring**: Context scores are normalized to [0, 1]:\n\n$$S_{norm} = \\frac{S_{raw} - S_{min}}{S_{max} - S_{min}}$$\n\n**Grade Assignment**: Letter grades are assigned based on score thresholds:\n\n$$G = \\begin{cases}\nA \u0026 \\text{if } S \\geq 0.80 \\\\\nB \u0026 \\text{if } 0.60 \\leq S \u003c 0.80 \\\\\nC \u0026 \\text{if } 0.40 \\leq S \u003c 0.60 \\\\\nD \u0026 \\text{if } 0.20 \\leq S \u003c 0.40 \\\\\nF \u0026 \\text{if } S \u003c 0.20\n\\end{cases}$$\n\n### Design Principles\n\nUCID adheres to the following design principles:\n\n| Principle | Description |\n|-----------|-------------|\n| **Determinism** | Given the same inputs, UCID always produces identical outputs |\n| **Parsability** | UCID strings are human-readable and machine-parseable |\n| **Extensibility** | The context system supports custom scoring algorithms |\n| **Performance** | Optimized for batch processing of millions of identifiers |\n| **Type Safety** | Full type annotations with strict mypy compliance |\n| **Reproducibility** | Identical results across different systems and platforms |\n\n---\n\n## Key Features\n\n### Core Capabilities\n\n| Feature | Description |\n|---------|-------------|\n| UCID Creation | Generate standardized identifiers from coordinates |\n| UCID Parsing | Parse UCID strings into structured components |\n| UCID Validation | Validate UCID format and component values |\n| Batch Processing | Process millions of UCIDs efficiently |\n| Context Scoring | Apply urban context algorithms to locations |\n\n### City Registry\n\n| Feature | Description |\n|---------|-------------|\n| 403 Cities | Comprehensive coverage across 22 countries |\n| 240+ Million Population | Total population in covered cities |\n| Metadata | Coordinates, timezone, population for each city |\n| Extensible | Add custom cities to the registry |\n\n### Context Algorithms\n\n| Algorithm | Status | Description |\n|-----------|--------|-------------|\n| 15MIN | Production | 15-Minute City accessibility scoring |\n| TRANSIT | Production | Public transit accessibility |\n| WALK | Production | Walkability index |\n| NONE | Production | No context scoring |\n| CLIMATE | Planned | Climate resilience metrics |\n| EQUITY | Planned | Social equity assessment |\n| VITALITY | Planned | Urban vitality index |\n| SAFETY | Planned | Public safety metrics |\n\n### Data Integration\n\n| Format | Support | Description |\n|--------|---------|-------------|\n| JSON | Full | Native JSON serialization |\n| GeoJSON | Full | Geographic feature collections |\n| Parquet | Full | Columnar storage for analytics |\n| CSV | Full | Tabular data export |\n| PostGIS | Full | Spatial database integration |\n| GeoPackage | Full | OGC GeoPackage format |\n\n### API and Interfaces\n\n| Interface | Description |\n|-----------|-------------|\n| Python API | Core library with type hints |\n| REST API | FastAPI-based HTTP interface |\n| CLI | Command-line interface |\n| Jupyter | Native notebook integration |\n\n---\n\n## Installation\n\n### Requirements\n\n| Requirement | Version |\n|-------------|---------|\n| Python | 3.11, 3.12, 3.13 |\n| Operating System | Linux, macOS, Windows |\n| Memory | 512 MB minimum |\n| Disk Space | 100 MB minimum |\n\n### Basic Installation\n\n```bash\npip install ucid\n```\n\n### Installation with Optional Dependencies\n\n```bash\n# All features\npip install \"ucid[all]\"\n\n# Context algorithms only\npip install \"ucid[contexts]\"\n\n# REST API only\npip install \"ucid[api]\"\n\n# Development dependencies\npip install \"ucid[dev]\"\n\n# Testing dependencies\npip install \"ucid[test]\"\n```\n\n### Installation from Source\n\n```bash\ngit clone https://github.com/ucid-foundation/ucid.git\ncd ucid\npip install -e \".[dev]\"\n```\n\n### Verification\n\n```python\nimport ucid\nprint(f\"UCID version: {ucid.__version__}\")\nprint(f\"Cities available: {len(ucid.list_cities())}\")\n```\n\nExpected output:\n\n```\nUCID version: 1.0.5\nCities available: 403\n```\n\n---\n\n## Quick Start\n\n### Creating a UCID\n\n```python\nfrom ucid import create_ucid\n\n# Create a UCID for Istanbul\nucid = create_ucid(\n    city=\"IST\",\n    lat=41.015,\n    lon=28.979,\n    timestamp=\"2026W03T14\",\n    context=\"15MIN\",\n)\n\nprint(ucid)\n# Output: UCID-V1:IST:+41.015:+28.979:9:891f2ed6df7ffff:2026W03T14:15MIN:B:0.72\n```\n\n### Parsing a UCID\n\n```python\nfrom ucid import parse_ucid\n\nucid_string = \"UCID-V1:IST:+41.015:+28.979:9:891f2ed6df7ffff:2026W03T14:15MIN:B:0.72\"\nparsed = parse_ucid(ucid_string)\n\nprint(f\"City: {parsed.city}\")\nprint(f\"Coordinates: ({parsed.lat}, {parsed.lon})\")\nprint(f\"H3 Cell: {parsed.h3_index}\")\nprint(f\"Context: {parsed.context}\")\nprint(f\"Grade: {parsed.grade}\")\nprint(f\"Score: {parsed.score}\")\n```\n\n### Validating a UCID\n\n```python\nfrom ucid import validate_ucid, is_valid_ucid\n\n# Quick validation\nif is_valid_ucid(\"UCID-V1:IST:+41.015:+28.979:...\"):\n    print(\"Valid UCID\")\n\n# Detailed validation with error messages\ntry:\n    validate_ucid(\"UCID-V1:XXX:+41.015:+28.979:...\")\nexcept UCIDValidationError as e:\n    print(f\"Validation failed: {e}\")\n```\n\n### Listing Available Cities\n\n```python\nfrom ucid import list_cities\n\ncities = list_cities()\nprint(f\"Total cities: {len(cities)}\")\n\nfor city in cities[:10]:\n    print(f\"{city.code}: {city.name}, {city.country} (pop: {city.population:,})\")\n```\n\n### Batch Processing\n\n```python\nfrom ucid import create_ucid_batch\n\nlocations = [\n    {\"city\": \"IST\", \"lat\": 41.015, \"lon\": 28.979},\n    {\"city\": \"BER\", \"lat\": 52.520, \"lon\": 13.405},\n    {\"city\": \"LON\", \"lat\": 51.507, \"lon\": -0.128},\n]\n\nucids = create_ucid_batch(locations, context=\"TRANSIT\")\nfor u in ucids:\n    print(u)\n```\n\n---\n\n## UCID Format Specification\n\n### Format Structure\n\nA UCID string follows this format:\n\n```\nUCID-V{VERSION}:{CITY}:{LAT}:{LON}:{RES}:{H3}:{TIME}:{CTX}:{GRADE}:{SCORE}\n```\n\n### Component Specification\n\n| Component | Format | Example | Description |\n|-----------|--------|---------|-------------|\n| PREFIX | `UCID-V1` | `UCID-V1` | Protocol identifier and version |\n| CITY | 3 chars | `IST` | City code from registry |\n| LAT | Signed float | `+41.015` | Latitude in decimal degrees |\n| LON | Signed float | `+28.979` | Longitude in decimal degrees |\n| RES | Integer | `9` | H3 resolution (7-11) |\n| H3 | 15 hex chars | `891f2ed6df7ffff` | H3 cell index |\n| TIME | ISO week+hour | `2026W03T14` | Temporal key |\n| CTX | String | `15MIN` | Context algorithm ID |\n| GRADE | A-F | `B` | Letter grade |\n| SCORE | Float | `0.72` | Numeric score (0.00-1.00) |\n\n### Example UCID\n\n```\nUCID-V1:IST:+41.015:+28.979:9:891f2ed6df7ffff:2026W03T14:15MIN:B:0.72\n```\n\n### H3 Resolution Guide\n\n| Resolution | Edge Length | Area | Use Case |\n|------------|-------------|------|----------|\n| 7 | 5.16 km | 26.6 km² | Regional analysis |\n| 8 | 1.95 km | 3.8 km² | City-wide coverage |\n| 9 | 174 m | 0.11 km² | Default urban block |\n| 10 | 65 m | 0.015 km² | Detailed analysis |\n| 11 | 24 m | 0.002 km² | Building level |\n\n### Temporal Key Format\n\nThe temporal key uses ISO 8601 week notation with hour extension:\n\n```\n{YEAR}W{WEEK}T{HOUR}\n```\n\nExamples:\n- `2026W03T14` = Year 2026, Week 3, Hour 14 (2 PM)\n- `2026W52T00` = Year 2026, Week 52, Hour 0 (midnight)\n\n---\n\n## Context Algorithms\n\n### Production Contexts\n\n#### 15MIN (15-Minute City)\n\nThe 15-Minute City context measures accessibility to essential services within a 15-minute walk or bike ride, based on the urban planning concept proposed by Carlos Moreno.\n\n| Metric | Weight | Description |\n|--------|--------|-------------|\n| Grocery Access | 0.25 | Distance to grocery stores |\n| Healthcare Access | 0.20 | Distance to healthcare facilities |\n| Education Access | 0.20 | Distance to schools |\n| Recreation Access | 0.15 | Distance to parks and recreation |\n| Services Access | 0.20 | Distance to essential services |\n\n**Scoring Formula**:\n\n$$S_{15MIN} = \\sum_{i=1}^{5} w_i \\cdot f(d_i)$$\n\nwhere $w_i$ is the weight for category $i$ and $f(d_i)$ is the distance decay function:\n\n$$f(d) = \\max(0, 1 - \\frac{d}{d_{max}})$$\n\n#### TRANSIT (Transit Accessibility)\n\nThe TRANSIT context measures public transportation accessibility based on GTFS data.\n\n| Metric | Weight | Description |\n|--------|--------|-------------|\n| Stop Density | 0.30 | Transit stops per km² |\n| Route Frequency | 0.30 | Average service frequency |\n| Coverage Area | 0.20 | Walkable coverage |\n| Intermodal | 0.20 | Multi-modal connections |\n\n#### WALK (Walkability)\n\nThe WALK context measures pedestrian infrastructure quality.\n\n| Metric | Weight | Description |\n|--------|--------|-------------|\n| Sidewalk Coverage | 0.30 | Percentage of streets with sidewalks |\n| Intersection Density | 0.25 | Street connectivity |\n| Pedestrian Amenities | 0.25 | Benches, crossings, etc. |\n| Traffic Safety | 0.20 | Speed limits, traffic calming |\n\n#### NONE (No Context)\n\nThe NONE context is used when no urban context scoring is applied. The UCID contains only location information with default grade F and score 0.00.\n\n### Planned Contexts\n\n| Context | Category | Status | Target Version |\n|---------|----------|--------|----------------|\n| CLIMATE | Environment | Planned | v1.2.0 |\n| EQUITY | Social | Planned | v1.3.0 |\n| VITALITY | Economic | Planned | v1.4.0 |\n| SAFETY | Safety | Planned | v1.5.0 |\n\n---\n\n## Grading System\n\n### Grade Definitions\n\n| Grade | Range | Label | Color | Description |\n|-------|-------|-------|-------|-------------|\n| A | 0.80-1.00 | Excellent | #0dab76 | Exceptional performance |\n| B | 0.60-0.80 | Good | #139a43 | Above average |\n| C | 0.40-0.60 | Moderate | #f59e0b | Satisfactory |\n| D | 0.20-0.40 | Limited | #ef4444 | Below average |\n| F | 0.00-0.20 | Poor | #dc2626 | Failing |\n\n### Grade Distribution (Academic Dataset)\n\nBased on the 1,000,000 record academic dataset:\n\n| Grade | Count | Percentage |\n|-------|-------|------------|\n| A | 120,474 | 12.0% |\n| B | 280,841 | 28.1% |\n| C | 379,008 | 37.9% |\n| D | 149,774 | 15.0% |\n| F | 69,903 | 7.0% |\n\n### Confidence Levels\n\n| Level | Range | Description |\n|-------|-------|-------------|\n| High | 0.85-1.00 | Comprehensive data |\n| Medium | 0.60-0.85 | Partial data |\n| Low | 0.00-0.60 | Limited data |\n\n---\n\n## City Registry\n\n### Registry Statistics\n\n| Metric | Value |\n|--------|-------|\n| Total Cities | 403 |\n| Countries | 22 |\n| Total Population | 240,287,432 |\n| Average Population | 596,246 |\n| Largest City | 15,519,267 |\n| Smallest City | 1,659 |\n\n### Countries Covered\n\n| Code | Country | Cities |\n|------|---------|--------|\n| AT | Austria | 5 |\n| AU | Australia | 21 |\n| AZ | Azerbaijan | 6 |\n| BE | Belgium | 5 |\n| CH | Switzerland | 5 |\n| DE | Germany | 50 |\n| DK | Denmark | 5 |\n| EE | Estonia | 4 |\n| FI | Finland | 5 |\n| FR | France | 20 |\n| GB | United Kingdom | 15 |\n| IS | Iceland | 3 |\n| JP | Japan | 10 |\n| LI | Liechtenstein | 1 |\n| LT | Lithuania | 4 |\n| LU | Luxembourg | 4 |\n| LV | Latvia | 4 |\n| NL | Netherlands | 12 |\n| NO | Norway | 5 |\n| SE | Sweden | 8 |\n| TR | Turkey | 81 |\n| US | United States | 20 |\n\n### Top 10 Cities by Dataset Records\n\n| City | Code | Country | Records | Population |\n|------|------|---------|---------|------------|\n| Istanbul | IST | TR | 64,586 | 15,519,267 |\n| London | LON | GB | 37,380 | 8,982,000 |\n| New York | NEW | US | 36,036 | 8,336,817 |\n| Ankara | ANK | TR | 23,568 | 5,663,322 |\n| Sydney | SYD | AU | 22,107 | 5,312,163 |\n| Melbourne | MEL | AU | 21,133 | 5,078,193 |\n| Izmir | IZM | TR | 19,687 | 4,425,789 |\n| Berlin | BER | DE | 18,991 | 3,669,495 |\n| Los Angeles | LOS | US | 16,561 | 3,898,747 |\n| San Francisco | SAN | US | 16,542 | 873,965 |\n\n---\n\n## API Reference\n\n### Core Functions\n\n#### create_ucid\n\n```python\ndef create_ucid(\n    city: str,\n    lat: float,\n    lon: float,\n    timestamp: str | None = None,\n    context: str = \"NONE\",\n    h3_res: int = 9,\n) -\u003e UCID:\n    \"\"\"\n    Create a UCID from coordinates and optional context.\n    \n    Args:\n        city: 3-letter city code from registry\n        lat: Latitude in decimal degrees (-90 to 90)\n        lon: Longitude in decimal degrees (-180 to 180)\n        timestamp: ISO week timestamp (default: current)\n        context: Context algorithm ID (default: NONE)\n        h3_res: H3 resolution 7-11 (default: 9)\n    \n    Returns:\n        UCID object with all components\n    \n    Raises:\n        UCIDValidationError: If inputs are invalid\n    \"\"\"\n```\n\n#### parse_ucid\n\n```python\ndef parse_ucid(ucid_string: str) -\u003e UCID:\n    \"\"\"\n    Parse a UCID string into components.\n    \n    Args:\n        ucid_string: Complete UCID string\n    \n    Returns:\n        UCID object with parsed components\n    \n    Raises:\n        UCIDParseError: If string format is invalid\n    \"\"\"\n```\n\n#### validate_ucid\n\n```python\ndef validate_ucid(ucid_string: str) -\u003e bool:\n    \"\"\"\n    Validate a UCID string format and components.\n    \n    Args:\n        ucid_string: UCID string to validate\n    \n    Returns:\n        True if valid\n    \n    Raises:\n        UCIDValidationError: If validation fails\n    \"\"\"\n```\n\n#### list_cities\n\n```python\ndef list_cities() -\u003e list[City]:\n    \"\"\"\n    List all cities in the registry.\n    \n    Returns:\n        List of City objects with metadata\n    \"\"\"\n```\n\n### UCID Object\n\n```python\n@dataclass\nclass UCID:\n    \"\"\"Represents a parsed or created UCID.\"\"\"\n    \n    city: str           # City code\n    lat: float          # Latitude\n    lon: float          # Longitude\n    h3_res: int         # H3 resolution\n    h3_index: str       # H3 cell index\n    timestamp: str      # ISO week timestamp\n    context: str        # Context algorithm ID\n    grade: str          # Letter grade (A-F)\n    score: float        # Numeric score (0-1)\n    confidence: float   # Confidence level\n    \n    def __str__(self) -\u003e str:\n        \"\"\"Return UCID string representation.\"\"\"\n    \n    def to_dict(self) -\u003e dict:\n        \"\"\"Convert to dictionary.\"\"\"\n    \n    def to_geojson(self) -\u003e dict:\n        \"\"\"Convert to GeoJSON feature.\"\"\"\n```\n\n### City Object\n\n```python\n@dataclass\nclass City:\n    \"\"\"Represents a city in the registry.\"\"\"\n    \n    code: str           # 3-letter code\n    name: str           # City name\n    country: str        # Country code\n    timezone: str       # IANA timezone\n    population: int     # Population\n    lat: float          # Center latitude\n    lon: float          # Center longitude\n```\n\n---\n\n## Architecture\n\n### System Architecture\n\n```mermaid\ngraph TB\n    subgraph \"Input Layer\"\n        API[REST API]\n        CLI[CLI]\n        PY[Python API]\n    end\n\n    subgraph \"Core Layer\"\n        Parser[Parser]\n        Validator[Validator]\n        Creator[Creator]\n    end\n\n    subgraph \"Context Layer\"\n        CTX15[15MIN Context]\n        CTXTR[TRANSIT Context]\n        CTXWK[WALK Context]\n    end\n\n    subgraph \"Spatial Layer\"\n        H3[H3 Indexer]\n        GEO[Geometry Engine]\n    end\n\n    subgraph \"Data Layer\"\n        REG[City Registry]\n        OSM[OSM Data]\n        GTFS[GTFS Data]\n    end\n\n    API --\u003e Parser\n    CLI --\u003e Parser\n    PY --\u003e Parser\n    \n    Parser --\u003e Validator\n    Validator --\u003e Creator\n    \n    Creator --\u003e CTX15\n    Creator --\u003e CTXTR\n    Creator --\u003e CTXWK\n    \n    CTX15 --\u003e H3\n    CTXTR --\u003e H3\n    CTXWK --\u003e H3\n    \n    H3 --\u003e GEO\n    \n    CTX15 --\u003e OSM\n    CTXTR --\u003e GTFS\n    CTXWK --\u003e OSM\n    \n    Parser --\u003e REG\n```\n\n### Module Structure\n\n```\nsrc/ucid/\n├── __init__.py          # Public API exports\n├── core/                # Core functionality\n│   ├── parser.py        # UCID parsing\n│   ├── validator.py     # Validation logic\n│   ├── creator.py       # UCID creation\n│   ├── models.py        # Data models\n│   └── errors.py        # Exception classes\n├── contexts/            # Context algorithms\n│   ├── base.py          # Base context class\n│   ├── fifteen_min.py   # 15MIN context\n│   ├── transit.py       # TRANSIT context\n│   └── walk.py          # WALK context\n├── spatial/             # Spatial operations\n│   ├── h3_utils.py      # H3 utilities\n│   └── geometry.py      # Geometry operations\n├── data/                # Data access\n│   ├── registry.py      # City registry\n│   └── sources.py       # External data sources\n├── api/                 # REST API\n│   ├── app.py           # FastAPI application\n│   └── routes.py        # API routes\n└── cli/                 # Command-line interface\n    └── main.py          # CLI entry point\n```\n\n---\n\n## Performance Benchmarks\n\n### Benchmark Results\n\nPerformance measurements from the UCID benchmark suite:\n\n| Operation | Target | Measured | Status |\n|-----------|--------|----------|--------|\n| CREATE | 10,000 ops/sec | 127,000 ops/sec | PASS |\n| PARSE | 10,000 ops/sec | 61,000 ops/sec | PASS |\n| VALIDATE | 50,000 ops/sec | 17,000 ops/sec | Note |\n\n### Latency Distribution\n\n| Percentile | CREATE | PARSE | VALIDATE |\n|------------|--------|-------|----------|\n| P50 | 7.5 us | 15.5 us | 55 us |\n| P95 | 9.0 us | 20.0 us | 70 us |\n| P99 | 12.0 us | 28.0 us | 90 us |\n\n### Memory Usage\n\n| Operation | Memory per UCID |\n|-----------|-----------------|\n| CREATE | 256 bytes |\n| PARSE | 512 bytes |\n| Batch (1M) | 500 MB |\n\n### Optimization Tips\n\n1. Use batch processing for multiple UCIDs\n2. Enable caching for context scoring\n3. Use appropriate H3 resolution\n4. Pre-filter cities before processing\n\n---\n\n## Academic Dataset\n\n### Dataset Overview\n\nThe UCID Academic Dataset provides 1,000,000 sample records for research and development:\n\n| Metric | Value |\n|--------|-------|\n| Total Records | 1,000,000 |\n| Cities | 403 |\n| Countries | 22 |\n| File Size (JSONL) | ~150 MB |\n| File Size (Parquet) | ~50 MB |\n\n### Context Distribution\n\n| Context | Records | Percentage |\n|---------|---------|------------|\n| 15MIN | 350,288 | 35.0% |\n| TRANSIT | 300,431 | 30.0% |\n| WALK | 249,491 | 24.9% |\n| NONE | 99,790 | 10.0% |\n\n### Grade Distribution\n\n| Grade | Records | Percentage |\n|-------|---------|------------|\n| A | 120,474 | 12.0% |\n| B | 280,841 | 28.1% |\n| C | 379,008 | 37.9% |\n| D | 149,774 | 15.0% |\n| F | 69,903 | 7.0% |\n\n### Download\n\n```bash\n# Download from Zenodo\nwget https://zenodo.org/records/18246412/files/ucid_academic_1m.parquet\n\n# Or use the library\nfrom ucid.datasets import download_academic_dataset\ndownload_academic_dataset()\n```\n\n---\n\n## Security\n\n### Security Practices\n\n| Practice | Implementation |\n|----------|----------------|\n| Input Validation | Pydantic models |\n| Type Safety | Full mypy compliance |\n| Dependency Pinning | Locked versions |\n| Code Review | Required for all changes |\n| Static Analysis | Ruff, Bandit in CI |\n\n### Vulnerability Reporting\n\nReport security vulnerabilities to: security@ucid.org\n\nSee [SECURITY.md](SECURITY.md) for full security policy.\n\n---\n\n## Testing\n\n### Test Statistics\n\n| Metric | Value |\n|--------|-------|\n| Test Files | 27 |\n| Test Cases | 500+ |\n| Line Coverage | 85%+ |\n| Branch Coverage | 78%+ |\n\n### Running Tests\n\n```bash\n# All tests\npytest\n\n# With coverage\npytest --cov=ucid --cov-report=html\n\n# Performance tests\npytest -m performance\n```\n\nSee [TESTING.md](TESTING.md) for full testing guide.\n\n---\n\n## Deployment\n\n### Docker\n\n```bash\ndocker run -p 8000:8000 ghcr.io/ucid-foundation/ucid:latest\n```\n\n### Docker Compose\n\n```bash\ndocker-compose up\n```\n\nSee [DEPLOYMENT.md](DEPLOYMENT.md) for full deployment guide.\n\n---\n\n## Contributing\n\nWe welcome contributions. Please see:\n\n- [CONTRIBUTING.md](CONTRIBUTING.md) - Contribution guidelines\n- [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) - Community standards\n- [GOVERNANCE.md](GOVERNANCE.md) - Project governance\n\n---\n\n## Citation\n\nIf you use UCID in your research, please cite:\n\n```bibtex\n@software{ucid2026,\n  author = {Laitinen Imanov, Olaf Yunus},\n  title = {{UCID}: Urban Context Identifier},\n  year = {2026},\n  version = {1.0.5},\n  doi = {10.5281/zenodo.18244258},\n  url = {https://github.com/ucid-foundation/ucid}\n}\n```\n\nSee [CITATION.cff](CITATION.cff) for machine-readable citation.\n\n---\n\n## License\n\nUCID is licensed under the European Union Public License 1.2 (EUPL-1.2).\n\nSee [LICENSE](LICENSE) for the full license text.\n\n---\n\n## References\n\n### Academic References\n\n1. Moreno, C. et al. (2021). Introducing the \"15-Minute City\": Sustainability, Resilience and Place Identity in Future Post-Pandemic Cities. Smart Cities, 4(1), 93-111.\n\n2. Sahr, K., White, D., \u0026 Kimerling, A. J. (2003). Geodesic discrete global grid systems. Cartography and Geographic Information Science, 30(2), 121-134.\n\n### Technical References\n\n- [H3 Documentation](https://h3geo.org/)\n- [PostGIS](https://postgis.net/)\n- [FastAPI](https://fastapi.tiangolo.com/)\n- [Pydantic](https://docs.pydantic.dev/)\n- [OpenStreetMap](https://www.openstreetmap.org/)\n- [GTFS Specification](https://gtfs.org/)\n\n---\n\n## Support\n\n- [Documentation](https://docs.ucid.org)\n- [GitHub Issues](https://github.com/ucid-foundation/ucid/issues)\n- [GitHub Discussions](https://github.com/ucid-foundation/ucid/discussions)\n- [Discord](https://discord.gg/ucid)\n- Email: support@ucid.org\n\nSee [SUPPORT.md](SUPPORT.md) for full support guide.\n\n---\n\n## Troubleshooting\n\nSee [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for common issues and solutions.\n\n---\n\n## Roadmap\n\nSee [ROADMAP.md](ROADMAP.md) for planned features and releases.\n\n---\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for version history.\n\n---\n\n## Advanced Usage\n\n### Custom Context Development\n\nCreate custom context algorithms by extending the base class:\n\n```python\nfrom ucid.contexts.base import BaseContext, ContextResult\n\nclass CustomContext(BaseContext):\n    \"\"\"Custom urban context algorithm.\"\"\"\n    \n    context_id = \"CUSTOM\"\n    name = \"Custom Context\"\n    version = \"1.0.0\"\n    \n    def compute(\n        self,\n        lat: float,\n        lon: float,\n        timestamp: str | None = None,\n    ) -\u003e ContextResult:\n        \"\"\"Compute custom context score.\"\"\"\n        # Your scoring logic here\n        raw_score = self._calculate_score(lat, lon)\n        normalized = self._normalize(raw_score)\n        grade = self._to_grade(normalized)\n        \n        return ContextResult(\n            score=normalized,\n            grade=grade,\n            confidence=0.85,\n            metrics={\n                \"custom_metric_1\": 0.75,\n                \"custom_metric_2\": 0.82,\n            },\n        )\n    \n    def _calculate_score(self, lat: float, lon: float) -\u003e float:\n        \"\"\"Calculate raw score based on location.\"\"\"\n        # Implementation\n        return 0.75\n```\n\n### Registering Custom Contexts\n\n```python\nfrom ucid.contexts import register_context, get_context\n\n# Register your custom context\nregister_context(CustomContext)\n\n# Use it in UCID creation\nucid = create_ucid(\n    city=\"IST\",\n    lat=41.015,\n    lon=28.979,\n    context=\"CUSTOM\",\n)\n```\n\n### Custom City Registration\n\n```python\nfrom ucid.data.registry import CityRegistry, City\n\n# Get registry instance\nregistry = CityRegistry.get_instance()\n\n# Add custom city\ncustom_city = City(\n    code=\"XYZ\",\n    name=\"Custom City\",\n    country=\"XX\",\n    timezone=\"Europe/London\",\n    population=100000,\n    lat=51.5,\n    lon=-0.1,\n)\nregistry.add_city(custom_city)\n\n# Verify registration\ncity = registry.get_city(\"XYZ\")\nprint(f\"Registered: {city.name}\")\n```\n\n### Temporal Operations\n\n#### Working with Timestamps\n\n```python\nfrom ucid.core.temporal import (\n    current_iso_week,\n    parse_timestamp,\n    timestamp_to_datetime,\n    datetime_to_timestamp,\n)\n\n# Get current ISO week timestamp\ncurrent = current_iso_week()\nprint(f\"Current: {current}\")  # e.g., 2026W03T14\n\n# Parse timestamp components\nparsed = parse_timestamp(\"2026W03T14\")\nprint(f\"Year: {parsed.year}\")\nprint(f\"Week: {parsed.week}\")\nprint(f\"Hour: {parsed.hour}\")\n\n# Convert to datetime\ndt = timestamp_to_datetime(\"2026W03T14\")\nprint(f\"DateTime: {dt}\")\n\n# Convert from datetime\nfrom datetime import datetime\nts = datetime_to_timestamp(datetime.now())\nprint(f\"Timestamp: {ts}\")\n```\n\n#### Time Range Queries\n\n```python\nfrom ucid.core.temporal import generate_time_range\n\n# Generate timestamps for a week\ntimestamps = generate_time_range(\n    start=\"2026W03T00\",\n    end=\"2026W03T23\",\n    step_hours=4,\n)\n\nfor ts in timestamps:\n    print(ts)\n# 2026W03T00\n# 2026W03T04\n# 2026W03T08\n# 2026W03T12\n# 2026W03T16\n# 2026W03T20\n```\n\n### Spatial Operations\n\n#### H3 Operations\n\n```python\nfrom ucid.spatial.h3_utils import (\n    coord_to_h3,\n    h3_to_coord,\n    h3_to_boundary,\n    h3_neighbors,\n    h3_resolution,\n)\n\n# Convert coordinates to H3\nh3_index = coord_to_h3(41.015, 28.979, resolution=9)\nprint(f\"H3 Index: {h3_index}\")\n\n# Get cell center\ncenter = h3_to_coord(h3_index)\nprint(f\"Center: {center}\")\n\n# Get cell boundary (as polygon)\nboundary = h3_to_boundary(h3_index)\nprint(f\"Vertices: {len(boundary)}\")\n\n# Get neighboring cells\nneighbors = h3_neighbors(h3_index)\nprint(f\"Neighbors: {len(neighbors)}\")\n\n# Get resolution info\nres = h3_resolution(h3_index)\nprint(f\"Resolution: {res}\")\n```\n\n#### Geometry Operations\n\n```python\nfrom ucid.spatial.geometry import (\n    point_in_city,\n    distance_km,\n    bearing,\n    destination_point,\n)\n\n# Check if point is within city boundary\nis_in = point_in_city(41.015, 28.979, \"IST\")\nprint(f\"In Istanbul: {is_in}\")\n\n# Calculate distance between points\ndist = distance_km(41.015, 28.979, 52.520, 13.405)\nprint(f\"Distance: {dist:.2f} km\")\n\n# Calculate bearing\nbear = bearing(41.015, 28.979, 52.520, 13.405)\nprint(f\"Bearing: {bear:.2f} degrees\")\n\n# Calculate destination point\ndest = destination_point(41.015, 28.979, distance_km=100, bearing=45)\nprint(f\"Destination: {dest}\")\n```\n\n### Batch Processing\n\n#### Large-Scale Processing\n\n```python\nfrom ucid import create_ucid_batch\nfrom ucid.core.batch import BatchProcessor, BatchConfig\n\n# Configure batch processor\nconfig = BatchConfig(\n    batch_size=10000,\n    num_workers=4,\n    show_progress=True,\n    cache_enabled=True,\n)\n\nprocessor = BatchProcessor(config)\n\n# Process large dataset\nlocations = [\n    {\"city\": \"IST\", \"lat\": 41.0 + i * 0.001, \"lon\": 28.9 + i * 0.001}\n    for i in range(100000)\n]\n\nresults = processor.process(locations, context=\"15MIN\")\nprint(f\"Processed: {len(results)} UCIDs\")\n```\n\n#### Async Batch Processing\n\n```python\nimport asyncio\nfrom ucid.core.batch import AsyncBatchProcessor\n\nasync def process_async():\n    processor = AsyncBatchProcessor(num_workers=8)\n    \n    locations = [\n        {\"city\": \"IST\", \"lat\": 41.0 + i * 0.001, \"lon\": 28.9}\n        for i in range(50000)\n    ]\n    \n    results = await processor.process_async(locations)\n    return results\n\n# Run async processing\nresults = asyncio.run(process_async())\n```\n\n### Data Export\n\n#### Export to Various Formats\n\n```python\nfrom ucid.io import (\n    export_to_json,\n    export_to_geojson,\n    export_to_parquet,\n    export_to_csv,\n    export_to_geopackage,\n)\n\n# Create sample UCIDs\nucids = [\n    create_ucid(city=\"IST\", lat=41.015, lon=28.979),\n    create_ucid(city=\"BER\", lat=52.520, lon=13.405),\n    create_ucid(city=\"LON\", lat=51.507, lon=-0.128),\n]\n\n# Export to JSON\nexport_to_json(ucids, \"output.json\")\n\n# Export to GeoJSON\nexport_to_geojson(ucids, \"output.geojson\")\n\n# Export to Parquet\nexport_to_parquet(ucids, \"output.parquet\")\n\n# Export to CSV\nexport_to_csv(ucids, \"output.csv\")\n\n# Export to GeoPackage\nexport_to_geopackage(ucids, \"output.gpkg\")\n```\n\n#### Import from Various Formats\n\n```python\nfrom ucid.io import (\n    import_from_json,\n    import_from_geojson,\n    import_from_parquet,\n    import_from_csv,\n)\n\n# Import from JSON\nucids = import_from_json(\"input.json\")\n\n# Import from GeoJSON\nucids = import_from_geojson(\"input.geojson\")\n\n# Import from Parquet\nucids = import_from_parquet(\"input.parquet\")\n\n# Import from CSV\nucids = import_from_csv(\"input.csv\")\n```\n\n### Database Integration\n\n#### PostGIS Integration\n\n```python\nfrom ucid.db import PostGISConnection\n\n# Connect to PostGIS\nconn = PostGISConnection(\n    host=\"localhost\",\n    port=5432,\n    database=\"ucid_db\",\n    user=\"ucid_user\",\n    password=\"password\",\n)\n\n# Create UCID table\nconn.create_ucid_table(\"ucids\")\n\n# Insert UCIDs\nucids = [create_ucid(city=\"IST\", lat=41.015, lon=28.979)]\nconn.insert_ucids(\"ucids\", ucids)\n\n# Query UCIDs\nresults = conn.query_ucids(\n    table=\"ucids\",\n    city=\"IST\",\n    context=\"15MIN\",\n    min_grade=\"B\",\n)\n\n# Spatial query\nresults = conn.query_within_radius(\n    table=\"ucids\",\n    lat=41.015,\n    lon=28.979,\n    radius_km=5.0,\n)\n```\n\n#### SQLite Integration\n\n```python\nfrom ucid.db import SQLiteConnection\n\n# Connect to SQLite\nconn = SQLiteConnection(\"ucid.db\")\n\n# Create table and insert\nconn.create_ucid_table()\nconn.insert_ucids(ucids)\n\n# Query\nresults = conn.query(city=\"IST\")\n```\n\n---\n\n## CLI Reference\n\n### Overview\n\nThe UCID CLI provides command-line access to all library functionality:\n\n```bash\nucid --help\n```\n\n### Commands\n\n#### create\n\nCreate a UCID from coordinates:\n\n```bash\nucid create --city IST --lat 41.015 --lon 28.979 --context 15MIN\n```\n\nOptions:\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| --city | string | required | City code |\n| --lat | float | required | Latitude |\n| --lon | float | required | Longitude |\n| --context | string | NONE | Context algorithm |\n| --timestamp | string | current | ISO week timestamp |\n| --resolution | int | 9 | H3 resolution |\n| --output | string | stdout | Output file |\n| --format | string | text | Output format (text, json) |\n\n#### parse\n\nParse a UCID string:\n\n```bash\nucid parse \"UCID-V1:IST:+41.015:+28.979:9:891f2ed6df7ffff:2026W03T14:15MIN:B:0.72\"\n```\n\nOptions:\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| --format | string | text | Output format |\n| --verbose | flag | false | Show all fields |\n\n#### validate\n\nValidate a UCID string:\n\n```bash\nucid validate \"UCID-V1:IST:+41.015:+28.979:...\"\n```\n\n#### cities\n\nList available cities:\n\n```bash\nucid cities --country DE --format json\n```\n\nOptions:\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| --country | string | all | Filter by country |\n| --search | string | - | Search by name |\n| --format | string | table | Output format |\n| --limit | int | 100 | Limit results |\n\n#### contexts\n\nList available contexts:\n\n```bash\nucid contexts --status production\n```\n\n#### batch\n\nProcess batch of coordinates:\n\n```bash\nucid batch --input locations.csv --output ucids.json --context TRANSIT\n```\n\nOptions:\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| --input | string | required | Input file |\n| --output | string | required | Output file |\n| --context | string | NONE | Context algorithm |\n| --format | string | json | Output format |\n| --workers | int | 4 | Number of workers |\n\n#### benchmark\n\nRun performance benchmarks:\n\n```bash\nucid benchmark --iterations 100000\n```\n\n#### serve\n\nStart REST API server:\n\n```bash\nucid serve --host 0.0.0.0 --port 8000\n```\n\n---\n\n## Error Handling\n\n### Exception Hierarchy\n\n```\nUCIDError (base)\n├── UCIDParseError\n│   ├── InvalidFormatError\n│   ├── InvalidVersionError\n│   └── MissingComponentError\n├── UCIDValidationError\n│   ├── InvalidCityError\n│   ├── InvalidCoordinateError\n│   ├── InvalidTimestampError\n│   ├── InvalidContextError\n│   └── InvalidH3Error\n├── UCIDContextError\n│   ├── ContextNotFoundError\n│   ├── ContextComputeError\n│   └── DataSourceError\n└── UCIDIOError\n    ├── FileNotFoundError\n    ├── FormatError\n    └── DatabaseError\n```\n\n### Error Handling Examples\n\n```python\nfrom ucid import create_ucid, parse_ucid\nfrom ucid.core.errors import (\n    UCIDError,\n    UCIDParseError,\n    UCIDValidationError,\n    InvalidCityError,\n    InvalidCoordinateError,\n)\n\n# Handling parse errors\ntry:\n    ucid = parse_ucid(\"invalid string\")\nexcept UCIDParseError as e:\n    print(f\"Parse error: {e}\")\n    print(f\"Position: {e.position}\")\n    print(f\"Expected: {e.expected}\")\n\n# Handling validation errors\ntry:\n    ucid = create_ucid(city=\"XXX\", lat=41.015, lon=28.979)\nexcept InvalidCityError as e:\n    print(f\"Invalid city: {e.city}\")\n    print(f\"Valid cities: {e.valid_cities[:5]}...\")\n\n# Handling coordinate errors\ntry:\n    ucid = create_ucid(city=\"IST\", lat=91.0, lon=28.979)\nexcept InvalidCoordinateError as e:\n    print(f\"Invalid coordinate: {e}\")\n    print(f\"Value: {e.value}\")\n    print(f\"Valid range: {e.min_value} to {e.max_value}\")\n\n# Generic error handling\ntry:\n    ucid = create_ucid(city=\"IST\", lat=41.015, lon=28.979)\nexcept UCIDError as e:\n    print(f\"UCID error: {e}\")\n    print(f\"Error code: {e.code}\")\n```\n\n### Error Codes\n\n| Code | Error | Description |\n|------|-------|-------------|\n| E001 | InvalidFormatError | UCID string format invalid |\n| E002 | InvalidVersionError | UCID version not supported |\n| E003 | MissingComponentError | Required component missing |\n| E010 | InvalidCityError | City code not in registry |\n| E011 | InvalidCoordinateError | Coordinate out of range |\n| E012 | InvalidTimestampError | Timestamp format invalid |\n| E013 | InvalidContextError | Context not found |\n| E014 | InvalidH3Error | H3 index invalid |\n| E020 | ContextNotFoundError | Context algorithm not registered |\n| E021 | ContextComputeError | Context computation failed |\n| E022 | DataSourceError | Data source unavailable |\n| E030 | FileNotFoundError | File not found |\n| E031 | FormatError | File format invalid |\n| E032 | DatabaseError | Database operation failed |\n\n---\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| UCID_LOG_LEVEL | INFO | Logging level |\n| UCID_CACHE_DIR | ~/.ucid/cache | Cache directory |\n| UCID_CACHE_TTL | 3600 | Cache TTL in seconds |\n| UCID_DATA_DIR | ~/.ucid/data | Data directory |\n| UCID_API_HOST | 0.0.0.0 | API host |\n| UCID_API_PORT | 8000 | API port |\n| UCID_DB_HOST | localhost | Database host |\n| UCID_DB_PORT | 5432 | Database port |\n| UCID_DB_NAME | ucid | Database name |\n| UCID_DB_USER | ucid | Database user |\n| UCID_DB_PASSWORD | - | Database password |\n| UCID_WORKERS | 4 | Number of workers |\n| UCID_BATCH_SIZE | 10000 | Batch size |\n\n### Configuration File\n\nCreate `~/.ucid/config.yaml`:\n\n```yaml\n# UCID Configuration\n\nlogging:\n  level: INFO\n  format: \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\n  file: ~/.ucid/logs/ucid.log\n\ncache:\n  enabled: true\n  directory: ~/.ucid/cache\n  ttl_seconds: 3600\n  max_size_mb: 1000\n\ndata:\n  directory: ~/.ucid/data\n  cities_file: cities.json\n  contexts_file: contexts.json\n\napi:\n  host: 0.0.0.0\n  port: 8000\n  reload: false\n  workers: 4\n  timeout: 30\n\ndatabase:\n  host: localhost\n  port: 5432\n  name: ucid\n  user: ucid\n  pool_size: 10\n\nbatch:\n  size: 10000\n  workers: 4\n  show_progress: true\n\ncontexts:\n  default: NONE\n  cache_scores: true\n  timeout_seconds: 30\n```\n\n### Loading Configuration\n\n```python\nfrom ucid.config import UCIDConfig, load_config\n\n# Load from default location\nconfig = load_config()\n\n# Load from custom path\nconfig = load_config(\"/path/to/config.yaml\")\n\n# Access configuration\nprint(f\"Log level: {config.logging.level}\")\nprint(f\"API port: {config.api.port}\")\nprint(f\"Cache enabled: {config.cache.enabled}\")\n```\n\n---\n\n## Logging\n\n### Logging Configuration\n\n```python\nimport logging\nfrom ucid.logging import setup_logging, get_logger\n\n# Setup logging\nsetup_logging(\n    level=logging.DEBUG,\n    format=\"%(asctime)s - %(name)s - %(levelname)s - %(message)s\",\n    file=\"ucid.log\",\n)\n\n# Get logger\nlogger = get_logger(__name__)\nlogger.info(\"UCID processing started\")\n```\n\n### Log Levels\n\n| Level | Description |\n|-------|-------------|\n| DEBUG | Detailed debugging information |\n| INFO | General operational information |\n| WARNING | Warning messages |\n| ERROR | Error messages |\n| CRITICAL | Critical errors |\n\n---\n\n## Monitoring\n\n### Metrics\n\nUCID exposes Prometheus-compatible metrics:\n\n```python\nfrom ucid.metrics import MetricsCollector\n\ncollector = MetricsCollector()\n\n# Create UCID and record metrics\nwith collector.timer(\"create_ucid\"):\n    ucid = create_ucid(city=\"IST\", lat=41.015, lon=28.979)\n\n# Get metrics\nmetrics = collector.get_metrics()\nprint(metrics)\n```\n\n### Available Metrics\n\n| Metric | Type | Description |\n|--------|------|-------------|\n| ucid_create_total | Counter | Total UCIDs created |\n| ucid_parse_total | Counter | Total UCIDs parsed |\n| ucid_validate_total | Counter | Total validations |\n| ucid_create_duration_seconds | Histogram | Creation duration |\n| ucid_parse_duration_seconds | Histogram | Parse duration |\n| ucid_context_score_duration_seconds | Histogram | Context scoring duration |\n| ucid_batch_size | Summary | Batch processing sizes |\n| ucid_cache_hits | Counter | Cache hits |\n| ucid_cache_misses | Counter | Cache misses |\n| ucid_errors_total | Counter | Total errors |\n\n### Health Checks\n\n```python\nfrom ucid.health import HealthChecker\n\nchecker = HealthChecker()\n\n# Check all components\nhealth = checker.check_all()\nprint(f\"Overall: {health.status}\")\nprint(f\"Registry: {health.registry}\")\nprint(f\"Contexts: {health.contexts}\")\nprint(f\"Database: {health.database}\")\n```\n\n---\n\n## Caching\n\n### Cache Configuration\n\n```python\nfrom ucid.cache import CacheConfig, UCIDCache\n\nconfig = CacheConfig(\n    enabled=True,\n    backend=\"memory\",  # or \"redis\", \"disk\"\n    ttl_seconds=3600,\n    max_size_mb=1000,\n)\n\ncache = UCIDCache(config)\n```\n\n### Cache Operations\n\n```python\n# Cache a UCID\ncache.set(ucid.h3_index, ucid)\n\n# Retrieve from cache\ncached = cache.get(h3_index)\n\n# Check if cached\nexists = cache.exists(h3_index)\n\n# Clear cache\ncache.clear()\n\n# Get cache stats\nstats = cache.stats()\nprint(f\"Hits: {stats.hits}\")\nprint(f\"Misses: {stats.misses}\")\nprint(f\"Size: {stats.size_mb} MB\")\n```\n\n### Redis Cache\n\n```python\nfrom ucid.cache import RedisCache\n\ncache = RedisCache(\n    host=\"localhost\",\n    port=6379,\n    db=0,\n    password=None,\n    ttl_seconds=3600,\n)\n```\n\n---\n\n## Internationalization\n\n### Supported Languages\n\n| Code | Language | Coverage |\n|------|----------|----------|\n| en | English | 100% |\n| de | German | 80% |\n| fr | French | 80% |\n| es | Spanish | 70% |\n| tr | Turkish | 100% |\n\n### Using Translations\n\n```python\nfrom ucid.i18n import get_translator, set_language\n\n# Set language\nset_language(\"de\")\n\n# Get translator\nt = get_translator()\n\n# Translate error messages\nprint(t(\"error.invalid_city\"))  # \"Ungültiger Stadtcode\"\nprint(t(\"error.invalid_coordinate\"))  # \"Ungültige Koordinate\"\n```\n\n---\n\n## Plugin System\n\n### Creating Plugins\n\n```python\nfrom ucid.plugins import Plugin, PluginManager\n\nclass MyPlugin(Plugin):\n    \"\"\"Custom UCID plugin.\"\"\"\n    \n    name = \"my_plugin\"\n    version = \"1.0.0\"\n    \n    def initialize(self):\n        \"\"\"Initialize plugin.\"\"\"\n        print(\"Plugin initialized\")\n    \n    def on_ucid_created(self, ucid):\n        \"\"\"Hook called after UCID creation.\"\"\"\n        print(f\"UCID created: {ucid}\")\n    \n    def cleanup(self):\n        \"\"\"Cleanup plugin resources.\"\"\"\n        print(\"Plugin cleaned up\")\n```\n\n### Registering Plugins\n\n```python\nfrom ucid.plugins import PluginManager\n\nmanager = PluginManager()\nmanager.register(MyPlugin())\n\n# List plugins\nfor plugin in manager.list_plugins():\n    print(f\"{plugin.name} v{plugin.version}\")\n```\n\n---\n\n## Version History\n\n### Version 1.0.5 (2026-01-16)\n\n- Updated city registry to 403 cities\n- Fixed context scoring algorithms\n- Performance improvements\n- Documentation updates\n\n### Version 1.0.0 (2025-12-01)\n\n- Initial stable release\n- 350 cities supported\n- 3 production contexts (15MIN, TRANSIT, WALK)\n- Full REST API\n- CLI interface\n\nSee [CHANGELOG.md](CHANGELOG.md) for complete history.\n\n---\n\n## Appendix A: City Codes\n\n### Germany (DE) - 50 Cities\n\n| Code | City | Population |\n|------|------|------------|\n| BER | Berlin | 3,669,495 |\n| HAM | Hamburg | 1,906,411 |\n| MUN | Munich | 1,487,708 |\n| KÖL | Köln | 1,073,096 |\n| FRA | Frankfurt | 763,380 |\n| STU | Stuttgart | 626,275 |\n| DÜS | Düsseldorf | 621,877 |\n| ESS | Essen | 579,432 |\n| DOR | Dortmund | 588,250 |\n| DRE | Dresden | 561,922 |\n\n### Turkey (TR) - 81 Cities\n\n| Code | City | Population |\n|------|------|------------|\n| IST | Istanbul | 15,519,267 |\n| ANK | Ankara | 5,663,322 |\n| IZM | Izmir | 4,425,789 |\n| BUR | Bursa | 3,101,833 |\n| ADA | Adana | 2,258,718 |\n| ANT | Antalya | 2,548,308 |\n| GAZ | Gaziantep | 2,130,432 |\n| KON | Konya | 2,277,017 |\n| MER | Mersin | 1,868,757 |\n| SAM | Samsun | 1,356,079 |\n\n### United States (US) - 20 Cities\n\n| Code | City | Population |\n|------|------|------------|\n| NEW | New York | 8,336,817 |\n| LOS | Los Angeles | 3,898,747 |\n| CHI | Chicago | 2,746,388 |\n| HOU | Houston | 2,304,580 |\n| PHO | Phoenix | 1,608,139 |\n| PHI | Philadelphia | 1,584,064 |\n| SAN | San Francisco | 873,965 |\n| DEN | Denver | 715,522 |\n| MIN | Minneapolis | 429,954 |\n| ORL | Orlando | 307,573 |\n\n---\n\n## Appendix B: Context Metrics\n\n### 15MIN Context Metrics\n\n| Metric | Weight | Description | Data Source |\n|--------|--------|-------------|-------------|\n| grocery_access | 0.25 | Nearest grocery store | OSM |\n| healthcare_access | 0.20 | Nearest healthcare | OSM |\n| education_access | 0.20 | Nearest school | OSM |\n| recreation_access | 0.15 | Nearest park | OSM |\n| services_access | 0.20 | Nearest services | OSM |\n\n### TRANSIT Context Metrics\n\n| Metric | Weight | Description | Data Source |\n|--------|--------|-------------|-------------|\n| stop_density | 0.30 | Stops per km² | GTFS |\n| route_frequency | 0.30 | Departures/hour | GTFS |\n| coverage_area | 0.20 | Walking coverage | GTFS |\n| intermodal | 0.20 | Multi-modal | GTFS |\n\n### WALK Context Metrics\n\n| Metric | Weight | Description | Data Source |\n|--------|--------|-------------|-------------|\n| sidewalk_coverage | 0.30 | Sidewalk % | OSM |\n| intersection_density | 0.25 | Intersections/km² | OSM |\n| pedestrian_amenities | 0.25 | Amenity count | OSM |\n| traffic_safety | 0.20 | Speed limits | OSM |\n\n---\n\n## Appendix C: H3 Technical Reference\n\n### Resolution Properties\n\n| Res | Avg Hex Area | Avg Edge Length | Num Cells |\n|-----|--------------|-----------------|-----------|\n| 0 | 4,357,449 km² | 1,281 km | 122 |\n| 1 | 609,788 km² | 483 km | 842 |\n| 2 | 86,802 km² | 182 km | 5,882 |\n| 3 | 12,393 km² | 69 km | 41,162 |\n| 4 | 1,770 km² | 26 km | 288,122 |\n| 5 | 253 km² | 9.9 km | 2,016,842 |\n| 6 | 36 km² | 3.7 km | 14,117,882 |\n| 7 | 5.2 km² | 1.4 km | 98,825,162 |\n| 8 | 0.74 km² | 0.53 km | 691,776,122 |\n| 9 | 0.11 km² | 0.20 km | 4,842,432,842 |\n| 10 | 0.015 km² | 0.075 km | 33,897,029,882 |\n| 11 | 0.002 km² | 0.028 km | 237,279,209,162 |\n| 12 | 0.0003 km² | 0.011 km | 1,660,954,464,122 |\n| 13 | 0.00004 km² | 0.004 km | 11,626,681,248,842 |\n| 14 | 0.000006 km² | 0.002 km | 81,386,768,741,882 |\n| 15 | 0.0000009 km² | 0.0006 km | 569,707,381,193,162 |\n\n### Cell Properties at Resolution 9 (Default)\n\n| Property | Value |\n|----------|-------|\n| Average Area | 0.1053 km² |\n| Average Edge Length | 174.375 m |\n| Number of Cells | 4.84 trillion |\n| Pentagons | 12 |\n\n---\n\n## Appendix D: Glossary\n\n| Term | Definition |\n|------|------------|\n| **UCID** | Urban Context Identifier - standardized urban location key |\n| **H3** | Hierarchical hexagonal spatial index by Uber |\n| **Context** | Urban quality scoring algorithm |\n| **Grade** | Letter grade (A-F) based on context score |\n| **15-Minute City** | Urban concept for walkable neighborhoods |\n| **GTFS** | General Transit Feed Specification |\n| **OSM** | OpenStreetMap |\n| **ISO Week** | Week numbering per ISO 8601 |\n| **Hexagon** | H3 spatial unit cell |\n| **Resolution** | H3 hierarchy level (0-15) |\n\n---\n\n## Appendix E: Frequently Asked Questions\n\n### General\n\n**Q: What is UCID?**\n\nA: UCID (Urban Context Identifier) is a standardized identifier system for urban context analysis, providing a universal key for joining disparate urban datasets.\n\n**Q: What Python versions are supported?**\n\nA: Python 3.11, 3.12, and 3.13.\n\n**Q: Is UCID production-ready?**\n\nA: Yes, version 1.0.x is production-ready with full test coverage.\n\n### Technical\n\n**Q: How many cities are supported?**\n\nA: 403 cities across 22 countries, covering 240+ million population.\n\n**Q: What is the default H3 resolution?**\n\nA: Resolution 9, with cell area of approximately 0.11 km².\n\n**Q: How is the grade calculated?**\n\nA: Grades are assigned based on normalized context scores: A (0.80-1.00), B (0.60-0.80), C (0.40-0.60), D (0.20-0.40), F (0.00-0.20).\n\n### Performance\n\n**Q: What is the creation throughput?**\n\nA: Approximately 127,000 UCIDs per second on modern hardware.\n\n**Q: Can UCID handle millions of records?**\n\nA: Yes, with batch processing optimized for large-scale operations.\n\n---\n\nCopyright 2026 UCID Foundation. All rights reserved.\nLicensed under EUPL-1.2.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fucid-foundation%2Fucid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fucid-foundation%2Fucid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fucid-foundation%2Fucid/lists"}