citygrid 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ .venv/
2
+ dist/
3
+ build/
4
+ *.egg-info/
5
+ __pycache__/
6
+ *.pyc
7
+ .pytest_cache/
citygrid-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Joe Tan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: citygrid
3
+ Version: 0.1.0
4
+ Summary: Zone classification, road generation, pathfinding, and urban analytics for a grid of buildings
5
+ Project-URL: Homepage, https://github.com/Joetankm/citygrid
6
+ Project-URL: Repository, https://github.com/Joetankm/citygrid
7
+ Project-URL: Issues, https://github.com/Joetankm/citygrid/issues
8
+ Author-email: Joe Tan <jtkmjoe@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: city-simulation,game-dev,gis,grid,pathfinding,urban-planning,walkability,zoning
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Topic :: Scientific/Engineering :: GIS
18
+ Classifier: Topic :: Software Development :: Libraries
19
+ Requires-Python: >=3.9
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest>=7.0; extra == 'dev'
22
+ Description-Content-Type: text/markdown
23
+
24
+ # citygrid
25
+
26
+ Zone classification, road generation, pathfinding, and urban analytics for
27
+ a grid of axis-aligned rectangular buildings.
28
+
29
+ Originally built for a physical LEGO-brick smart-city simulator, extracted
30
+ into a standalone library because the underlying logic — "given a bunch of
31
+ rectangles on a grid, classify zones, connect them with roads, and score
32
+ the layout" — is generic enough to be useful for city-builder games, urban
33
+ planning teaching tools, and GIS prototyping.
34
+
35
+ Zero required dependencies — pure Python, `math`/`heapq`/`dataclasses` only.
36
+
37
+ ## Install
38
+
39
+ ```bash
40
+ pip install citygrid
41
+ ```
42
+
43
+ ## What it does
44
+
45
+ **Zoning** (`compute_zones`) — connected-component BFS groups nearby
46
+ buildings into blocks, then classifies each block as Residential,
47
+ Commercial, Industrial, or Mixed based on height/footprint mix; empty
48
+ areas become Green space.
49
+
50
+ **Roads** (`generate_roads`) — two-phase A* generates a closed-circuit
51
+ road network along zone-block faces, connecting every block without
52
+ cutting through building footprints.
53
+
54
+ **Pathfinding** (`pathfind`) — shortest walkable route between two
55
+ buildings by ID, with real-world distance in meters.
56
+
57
+ **Analytics** (`compute_all` and friends) — population & per-capita
58
+ resource use, walkability score (Dijkstra distance-to-amenity), zone
59
+ balance flags (unemployment risk, ghost town, dormitory suburb, etc.),
60
+ crucial-service coverage (hospitals/schools/fire/police), an SDG
61
+ green-space score, a carbon-neutrality timeline, and rooftop solar
62
+ potential.
63
+
64
+ ## Usage
65
+
66
+ ```python
67
+ from citygrid import compute_zones, generate_roads, compute_all, GridConfig
68
+
69
+ # buildings: list of {id, grid_x, grid_y, width_studs, depth_studs,
70
+ # height_bricks, building_type (optional)}
71
+ buildings = [
72
+ {"id": 1, "grid_x": 0, "grid_y": 0, "width_studs": 2, "depth_studs": 2, "height_bricks": 6},
73
+ {"id": 2, "grid_x": 3, "grid_y": 0, "width_studs": 2, "depth_studs": 2, "height_bricks": 6},
74
+ {"id": 3, "grid_x": 0, "grid_y": 3, "width_studs": 2, "depth_studs": 2, "height_bricks": 1},
75
+ ]
76
+
77
+ zones = compute_zones(buildings)
78
+ roads = generate_roads(buildings)
79
+ stats = compute_all(buildings, zones)
80
+
81
+ print(stats["population"]) # {'total_pop': ..., 'density': ..., 'energy': ..., ...}
82
+ print(stats["walkability"]) # {'score': ..., 'avg_dist': ..., 'unreachable': ...}
83
+ ```
84
+
85
+ ### Custom grid size / thresholds
86
+
87
+ Every constant — grid dimensions, per-capita resource use, zone-balance
88
+ thresholds, walkability distance cap, and more — lives in one overridable
89
+ `GridConfig`:
90
+
91
+ ```python
92
+ from citygrid import GridConfig, compute_all
93
+
94
+ config = GridConfig(
95
+ grid_width=32, grid_height=32, # smaller board
96
+ stud_meters=5.0, # different real-world scale
97
+ walk_max_meters=800, # stricter walkability target
98
+ )
99
+ stats = compute_all(buildings, zones, config)
100
+ ```
101
+
102
+ If you don't pass a `config`, every function uses `GridConfig()`'s
103
+ defaults (a 64x64 grid at 10 real-world meters per cell — the values this
104
+ library was originally tuned against).
105
+
106
+ ## Development
107
+
108
+ ```bash
109
+ pip install -e ".[dev]"
110
+ pytest
111
+ ```
112
+
113
+ ## License
114
+
115
+ MIT
@@ -0,0 +1,92 @@
1
+ # citygrid
2
+
3
+ Zone classification, road generation, pathfinding, and urban analytics for
4
+ a grid of axis-aligned rectangular buildings.
5
+
6
+ Originally built for a physical LEGO-brick smart-city simulator, extracted
7
+ into a standalone library because the underlying logic — "given a bunch of
8
+ rectangles on a grid, classify zones, connect them with roads, and score
9
+ the layout" — is generic enough to be useful for city-builder games, urban
10
+ planning teaching tools, and GIS prototyping.
11
+
12
+ Zero required dependencies — pure Python, `math`/`heapq`/`dataclasses` only.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ pip install citygrid
18
+ ```
19
+
20
+ ## What it does
21
+
22
+ **Zoning** (`compute_zones`) — connected-component BFS groups nearby
23
+ buildings into blocks, then classifies each block as Residential,
24
+ Commercial, Industrial, or Mixed based on height/footprint mix; empty
25
+ areas become Green space.
26
+
27
+ **Roads** (`generate_roads`) — two-phase A* generates a closed-circuit
28
+ road network along zone-block faces, connecting every block without
29
+ cutting through building footprints.
30
+
31
+ **Pathfinding** (`pathfind`) — shortest walkable route between two
32
+ buildings by ID, with real-world distance in meters.
33
+
34
+ **Analytics** (`compute_all` and friends) — population & per-capita
35
+ resource use, walkability score (Dijkstra distance-to-amenity), zone
36
+ balance flags (unemployment risk, ghost town, dormitory suburb, etc.),
37
+ crucial-service coverage (hospitals/schools/fire/police), an SDG
38
+ green-space score, a carbon-neutrality timeline, and rooftop solar
39
+ potential.
40
+
41
+ ## Usage
42
+
43
+ ```python
44
+ from citygrid import compute_zones, generate_roads, compute_all, GridConfig
45
+
46
+ # buildings: list of {id, grid_x, grid_y, width_studs, depth_studs,
47
+ # height_bricks, building_type (optional)}
48
+ buildings = [
49
+ {"id": 1, "grid_x": 0, "grid_y": 0, "width_studs": 2, "depth_studs": 2, "height_bricks": 6},
50
+ {"id": 2, "grid_x": 3, "grid_y": 0, "width_studs": 2, "depth_studs": 2, "height_bricks": 6},
51
+ {"id": 3, "grid_x": 0, "grid_y": 3, "width_studs": 2, "depth_studs": 2, "height_bricks": 1},
52
+ ]
53
+
54
+ zones = compute_zones(buildings)
55
+ roads = generate_roads(buildings)
56
+ stats = compute_all(buildings, zones)
57
+
58
+ print(stats["population"]) # {'total_pop': ..., 'density': ..., 'energy': ..., ...}
59
+ print(stats["walkability"]) # {'score': ..., 'avg_dist': ..., 'unreachable': ...}
60
+ ```
61
+
62
+ ### Custom grid size / thresholds
63
+
64
+ Every constant — grid dimensions, per-capita resource use, zone-balance
65
+ thresholds, walkability distance cap, and more — lives in one overridable
66
+ `GridConfig`:
67
+
68
+ ```python
69
+ from citygrid import GridConfig, compute_all
70
+
71
+ config = GridConfig(
72
+ grid_width=32, grid_height=32, # smaller board
73
+ stud_meters=5.0, # different real-world scale
74
+ walk_max_meters=800, # stricter walkability target
75
+ )
76
+ stats = compute_all(buildings, zones, config)
77
+ ```
78
+
79
+ If you don't pass a `config`, every function uses `GridConfig()`'s
80
+ defaults (a 64x64 grid at 10 real-world meters per cell — the values this
81
+ library was originally tuned against).
82
+
83
+ ## Development
84
+
85
+ ```bash
86
+ pip install -e ".[dev]"
87
+ pytest
88
+ ```
89
+
90
+ ## License
91
+
92
+ MIT
@@ -0,0 +1,34 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "citygrid"
7
+ version = "0.1.0"
8
+ description = "Zone classification, road generation, pathfinding, and urban analytics for a grid of buildings"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.9"
12
+ authors = [{ name = "Joe Tan", email = "jtkmjoe@gmail.com" }]
13
+ keywords = ["urban-planning", "city-simulation", "zoning", "pathfinding", "walkability", "grid", "game-dev", "gis"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3 :: Only",
20
+ "Topic :: Scientific/Engineering :: GIS",
21
+ "Topic :: Software Development :: Libraries",
22
+ ]
23
+ dependencies = []
24
+
25
+ [project.optional-dependencies]
26
+ dev = ["pytest>=7.0"]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/Joetankm/citygrid"
30
+ Repository = "https://github.com/Joetankm/citygrid"
31
+ Issues = "https://github.com/Joetankm/citygrid/issues"
32
+
33
+ [tool.hatch.build.targets.wheel]
34
+ packages = ["src/citygrid"]
@@ -0,0 +1,24 @@
1
+ from .config import GridConfig
2
+ from .zones import compute_zones, generate_roads, pathfind
3
+ from .analytics import (
4
+ compute_population_stats,
5
+ compute_walkability,
6
+ compute_zone_balance,
7
+ zone_balance_score,
8
+ compute_crucial_metrics,
9
+ compute_sdg_score,
10
+ compute_carbon_timeline,
11
+ compute_solar_potential,
12
+ compute_all,
13
+ CRUCIAL_TYPES,
14
+ )
15
+
16
+ __all__ = [
17
+ "GridConfig",
18
+ "compute_zones", "generate_roads", "pathfind",
19
+ "compute_population_stats", "compute_walkability", "compute_zone_balance",
20
+ "zone_balance_score", "compute_crucial_metrics", "compute_sdg_score",
21
+ "compute_carbon_timeline", "compute_solar_potential", "compute_all",
22
+ "CRUCIAL_TYPES",
23
+ ]
24
+ __version__ = "0.1.0"