-
Notifications
You must be signed in to change notification settings - Fork 0
Claude/continue work u o5c o #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,345 @@ | ||||||||||||||||||
| # AGENTS-pisd.md — AI Coding Assistant Guide: `pisd_shape` Module | ||||||||||||||||||
|
|
||||||||||||||||||
| **Version:** 1.0.0 | ||||||||||||||||||
| **Module:** `pisd_shape` (Pflugerville ISD Attendance Boundary Shapefile Extractor) | ||||||||||||||||||
| **Environment:** Python 3.12+, uv, ruff, pytest, GitHub Actions CI | ||||||||||||||||||
| **Model:** Claude Sonnet 4.6 (claude-sonnet-4-6) | ||||||||||||||||||
| **Repository:** `Abstract-Data/RyanData-Address-Utils` | ||||||||||||||||||
| **Branch convention:** `claude/<slug>-<id>` (e.g., `claude/continue-work-uO5cO`) | ||||||||||||||||||
|
|
||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Module Purpose | ||||||||||||||||||
|
|
||||||||||||||||||
| `pisd_shape` extracts Pflugerville ISD (PFISD) school attendance boundary layers from an ArcGIS | ||||||||||||||||||
| Experience Builder WebMap and writes them as ESRI Shapefiles for use in GIS tools (QGIS, ArcGIS Pro, etc.). | ||||||||||||||||||
|
|
||||||||||||||||||
| Layers extracted: | ||||||||||||||||||
| - `Elementary_School_Locations` — point geometries, school site locations | ||||||||||||||||||
| - `Elementary_Schools_2025-26` — polygon attendance boundaries | ||||||||||||||||||
| - `Middle_School_Locations` — point geometries | ||||||||||||||||||
| - `Middle_Schools_2025-26` — polygon attendance boundaries | ||||||||||||||||||
| - `High_School_Locations` — point geometries | ||||||||||||||||||
| - `High_Schools_2025-26` — polygon attendance boundaries | ||||||||||||||||||
| - `Pflugerville_ISD_Boundary` — district boundary polygon | ||||||||||||||||||
|
|
||||||||||||||||||
| **Source:** https://experience.arcgis.com/experience/0bc78994af534cd1a703c8959abeac9d | ||||||||||||||||||
| **WebMap JSON:** `https://Pflugervilleisd.maps.arcgis.com/sharing/rest/content/items/bb587c1043a949cca04f1b1904c235e3/data?f=json` | ||||||||||||||||||
|
|
||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Agent Scope | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Reads | ||||||||||||||||||
| - `src/pisd_shape/pfisd_extract_shapefiles.py` — only source file in this module | ||||||||||||||||||
| - `src/pisd_shape/__init__.py` — module docstring | ||||||||||||||||||
| - `src/pisd_shape/export/` — output shapefiles (read-only reference; agent does not parse them) | ||||||||||||||||||
| - `pyproject.toml` — dependency and tool config | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Writes | ||||||||||||||||||
| - `src/pisd_shape/pfisd_extract_shapefiles.py` — geometry helpers, layer extraction, CLI | ||||||||||||||||||
| - `src/pisd_shape/__init__.py` — module-level exports if any are added | ||||||||||||||||||
| - `src/pisd_shape/export/` — shapefile outputs (`.shp`, `.dbf`, `.shx`, `.prj`, `.cpg`) | ||||||||||||||||||
| - `tests/` — new test files for `pisd_shape` (currently no tests exist) | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Executes | ||||||||||||||||||
| ```bash | ||||||||||||||||||
| python src/pisd_shape/pfisd_extract_shapefiles.py # fetch from ArcGIS Online | ||||||||||||||||||
| python src/pisd_shape/pfisd_extract_shapefiles.py --local data.json # load from local JSON | ||||||||||||||||||
| uv run ruff check src/pisd_shape/ # lint | ||||||||||||||||||
| uv run ruff format src/pisd_shape/ # format | ||||||||||||||||||
| uv run mypy src/pisd_shape/ # type check | ||||||||||||||||||
| uv run pytest tests/ -k pisd # run pisd-specific tests | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Off-limits (do not touch without explicit instruction) | ||||||||||||||||||
| - `src/ryandata_address_utils/` — main address parsing package; unrelated to this module | ||||||||||||||||||
| - `tests/test_address_parser.py`, `test_factories.py`, `test_unified_model.py`, etc. | ||||||||||||||||||
| - `.github/workflows/` — CI configuration | ||||||||||||||||||
| - `pyproject.toml` `[project.scripts]` section — no CLI entrypoint for pisd_shape currently | ||||||||||||||||||
|
|
||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| ## File Structure | ||||||||||||||||||
|
|
||||||||||||||||||
| ``` | ||||||||||||||||||
| src/pisd_shape/ | ||||||||||||||||||
| ├── __init__.py # Module docstring only; no public API exports yet | ||||||||||||||||||
| └── pfisd_extract_shapefiles.py # All logic: fetch → parse → reproject → write shapefiles | ||||||||||||||||||
| ├── CONFIG block # WEBMAP_URL, OUTPUT_DIR, transformer (EPSG:3857 → 4326) | ||||||||||||||||||
| ├── Geometry helpers # reproject_ring(), esri_polygon_to_shapely(), esri_point_to_shapely() | ||||||||||||||||||
| ├── Layer extraction # extract_layer() → GeoDataFrame | ||||||||||||||||||
| ├── Filename sanitizer # safe_filename() | ||||||||||||||||||
| └── main() # argparse CLI + orchestration | ||||||||||||||||||
|
|
||||||||||||||||||
| src/pisd_shape/export/ # Committed shapefile outputs (pre-extracted) | ||||||||||||||||||
| ├── Elementary_School_Locations.* | ||||||||||||||||||
| ├── Elementary_Schools_2025-26.* | ||||||||||||||||||
| ├── Middle_School_Locations.* | ||||||||||||||||||
| ├── Middle_Schools_2025-26.* | ||||||||||||||||||
| ├── High_School_Locations.* | ||||||||||||||||||
| ├── High_Schools_2025-26.* | ||||||||||||||||||
| └── Pflugerville_ISD_Boundary.* | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Data Flow | ||||||||||||||||||
|
|
||||||||||||||||||
| ``` | ||||||||||||||||||
| ArcGIS Online WebMap JSON | ||||||||||||||||||
| │ | ||||||||||||||||||
| ▼ requests.get(WEBMAP_URL) [or --local <file>] | ||||||||||||||||||
| webmap["operationalLayers"] | ||||||||||||||||||
| │ | ||||||||||||||||||
| ▼ for each layer | ||||||||||||||||||
| layer["featureCollection"]["layers"] | ||||||||||||||||||
| │ | ||||||||||||||||||
| ▼ extract_layer(sub_layer, title) | ||||||||||||||||||
| featureSet["features"] | ||||||||||||||||||
| │ | ||||||||||||||||||
| ├─ esriGeometryPolygon → esri_polygon_to_shapely() | ||||||||||||||||||
| │ └─ reproject_ring() [EPSG:3857 → EPSG:4326 via pyproj.Transformer] | ||||||||||||||||||
| │ └─ Polygon / MultiPolygon (Shapely, .buffer(0) cleaned) | ||||||||||||||||||
| │ | ||||||||||||||||||
| └─ esriGeometryPoint → esri_point_to_shapely() | ||||||||||||||||||
| └─ transformer.transform(x, y) → Point (Shapely) | ||||||||||||||||||
| │ | ||||||||||||||||||
| ▼ | ||||||||||||||||||
| gpd.GeoDataFrame(rows, crs="EPSG:4326") | ||||||||||||||||||
| │ | ||||||||||||||||||
| ▼ gdf.to_file(path, driver="ESRI Shapefile") | ||||||||||||||||||
| src/pisd_shape/export/<safe_filename>.shp | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Key data facts | ||||||||||||||||||
| - All source geometry is **Web Mercator (EPSG:3857)**; output is always **WGS84 (EPSG:4326)** | ||||||||||||||||||
| - Layers are **inline Feature Collections** — there is no FeatureServer REST endpoint to query | ||||||||||||||||||
| - ESRI polygon rings use winding order for outer/hole distinction; current code treats each ring as an | ||||||||||||||||||
| independent polygon with `buffer(0)` cleanup (acceptable for boundary data) | ||||||||||||||||||
| - Shapefile field names are truncated to **10 characters** (dBASE III limitation) | ||||||||||||||||||
| - Missing or empty geometries are skipped and counted; the module logs warnings, not exceptions | ||||||||||||||||||
|
|
||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| ## CLI Reference | ||||||||||||||||||
|
|
||||||||||||||||||
| ```bash | ||||||||||||||||||
| # Fetch live from ArcGIS Online (requires network access): | ||||||||||||||||||
| python src/pisd_shape/pfisd_extract_shapefiles.py | ||||||||||||||||||
|
|
||||||||||||||||||
| # Use a pre-downloaded local WebMap JSON (for offline/testing): | ||||||||||||||||||
| python src/pisd_shape/pfisd_extract_shapefiles.py --local path/to/webmap.json | ||||||||||||||||||
| python src/pisd_shape/pfisd_extract_shapefiles.py -l path/to/webmap.json | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| There is currently **no `pyproject.toml` script entrypoint** for this module. Run it directly | ||||||||||||||||||
| via `python` or add one under `[project.scripts]` if a CLI entrypoint is needed. | ||||||||||||||||||
|
|
||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Code Style | ||||||||||||||||||
|
|
||||||||||||||||||
| ### General | ||||||||||||||||||
| - **Python version:** 3.12+ (matches `pyproject.toml` `requires-python`) | ||||||||||||||||||
| - **Line length:** 100 characters (matches `[tool.ruff]` config) | ||||||||||||||||||
| - **Formatter/linter:** `ruff format` + `ruff check` with `E, F, I, UP, B, SIM` rules | ||||||||||||||||||
| - **Type checker:** `mypy` — `disallow_untyped_defs = true`, `ignore_missing_imports = true` | ||||||||||||||||||
| - **Function names:** `snake_case` | ||||||||||||||||||
| - **Class names:** `PascalCase` (none currently exist in this module) | ||||||||||||||||||
| - **Type hints:** required on all function signatures | ||||||||||||||||||
|
Comment on lines
+147
to
+150
|
||||||||||||||||||
| - **Type checker:** `mypy` — `disallow_untyped_defs = true`, `ignore_missing_imports = true` | |
| - **Function names:** `snake_case` | |
| - **Class names:** `PascalCase` (none currently exist in this module) | |
| - **Type hints:** required on all function signatures | |
| - **Type checker:** `mypy` — target config `disallow_untyped_defs = true`, `ignore_missing_imports = true` (this module is still being migrated and currently includes some untyped helper functions in `pfisd_extract_shapefiles.py`) | |
| - **Function names:** `snake_case` | |
| - **Class names:** `PascalCase` (none currently exist in this module) | |
| - **Type hints:** required for all new and modified function signatures; legacy untyped functions (e.g., in `pfisd_extract_shapefiles.py`) are permitted temporarily but should be annotated as they are touched |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| UTF-8 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| UTF-8 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| UTF-8 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| UTF-8 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| UTF-8 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| UTF-8 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| UTF-8 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The title line refers to "AGENTS-pisd.md" but the file is named
AGENTS.md. Consider updating the heading to match the actual filename to avoid confusion when referencing this guide.