CountyCollective Reference
Reference Overview
Explains what was copied from WordPress and what County Collective needs from it.
# CountyCollective Reference — WordPress Plugin Generation Code
**Date copied:** 2026-06-08
**Source plugin version:** 0.3.6
---
## What this folder is
These files are **not active WordPress code**. They are reference material copied
from the `county-gop-core` plugin before the map-generation subsystems were removed.
They exist here so the CountyCollective project can use them as:
- Implementation reference for the generation algorithms being rebuilt outside WordPress
- Specification for what the generated GeoJSON files must look like for consumption
- Reference for data formats (option keys, file paths, manifest structure) that
WordPress still reads after generation
**Do not include these files in any WordPress require/include chain.**
WordPress no longer loads any file from this directory.
---
## Why generation moved out of WordPress
Map generation (Beacon GIS fetch, ArcGIS FeatureServer import, WKT → GeoJSON
coordinate conversion, composite map building) is moving to a new project called
**CountyCollective**. Kinsta (the WordPress host) should not run Python, make live
Beacon requests, or maintain ArcGIS polling crons. WordPress now consumes finished
GeoJSON files only, uploaded directly via the District Map Imports admin page.
---
## Files in this reference
### `wordpress-plugin/includes/gis/class-cgop-gis-boundary-import.php`
**Original path:** `plugins/county-gop-core/includes/gis/class-cgop-gis-boundary-import.php`
**Lines:** 3,032
What it did:
- Registered and managed **Beacon GIS layer** definitions (layer ID, output dir,
field templates)
- Fetched raw WKT geometry from Beacon's `GetVectorLayer` API endpoint using
QPS auth, Cookie header, and User-Agent spoofing
- Spawned a Python subprocess (`convert_beacon_wkt_to_geojson.py`) to convert
EPSG:2965 WKT → EPSG:4326 GeoJSON
- Wrote one `.geojson` file per feature into `wp-content/uploads/county-gop-maps/`
- Built and registered **composite maps** (merge multiple generated files into one)
- Registered **direct GeoJSON upload** handler (this portion is kept and carried
forward in the new lean `class-cgop-map-file-import.php`)
- Generated `manifest.json` index of all known files
- Registered the admin submenu page "GIS Boundary Import" under `CGOP_SETUP_MENU_SLUG`
- All generation admin-post handlers: `CGOP_gis_regenerate`, `CGOP_gis_add_custom_layer`,
`CGOP_gis_delete_custom_layer`, `CGOP_gis_delete_generated_file`,
`CGOP_gis_create_composite`, `CGOP_gis_rebuild_composite`, `CGOP_gis_delete_composite`
What CountyCollective needs from this:
- Beacon API request format (`CGOP_gis_fetch_beacon_layer`) — endpoint, QPS param,
JSON body shape, Cookie/User-Agent handling, `d[]` response envelope
- WKT geometry field name: `WktGeometry` key in each Beacon record
- Coordinate system: input EPSG:2965 (Indiana State Plane), output EPSG:4326 (WGS84)
- Output file structure: one FeatureCollection per district, with `position_id`,
`source_layer_id`, `source_layer_name`, `label`, `name`, `position_type`, `level`
in the feature properties
- Composite algorithm: `CGOP_gis_build_composite_geojson` — plain feature merge,
no dissolve, adds `composite_id` / `composite_label` / `composite_source_file`
properties
- Manifest format: `CGOP_gis_write_manifest` — JSON with `generated_at`, `source`,
`source_crs`, `target_crs`, `layers[]`, `direct[]`, `composites[]`
WordPress option keys still read by the active plugin after generation:
- `CGOP_gis_direct_geojson_imports` — direct-upload records (consumed by kept code)
- `CGOP_gis_composite_maps` — composite map records (may remain until composites are
re-evaluated for CountyCollective)
- `CGOP_GIS_IMPORT_STATUS_OPTION` (`CGOP_gis_boundary_import_status`) — Beacon layer
status; **no longer updated** by active plugin; old data remains readable
---
### `wordpress-plugin/includes/gis/class-cgop-arcgis-boundary-import.php`
**Original path:** `plugins/county-gop-core/includes/gis/class-cgop-arcgis-boundary-import.php`
**Lines:** 1,714
What it did:
- Managed **ArcGIS Portal / FeatureServer** sources (item IDs, portal base URLs,
service URL discovery)
- Fetched layer lists and feature geometry from ArcGIS REST API
- Converted ArcGIS JSON geometry (`rings`/`paths`) to GeoJSON natively (no Python)
- Wrote ArcGIS-imported GeoJSON files to `county-gop-maps/{slug}/generated/arcgis/`
- Ran a **daily WP-Cron** (`CGOP_daily_arcgis_boundary_check`) to detect upstream
source changes
- Showed admin notices when ArcGIS sources changed
- Auto-assigned imported maps to matching Position Keys by label
WordPress option keys used:
- `CGOP_arcgis_boundary_sources` — ArcGIS source definitions
- `CGOP_arcgis_generated_maps` — ArcGIS-generated map metadata
Both options remain in DB as inert data; cron was unscheduled when plugin was
deactivated/reactivated after this code was removed.
What CountyCollective needs from this:
- ArcGIS REST query format: `CGOP_arcgis_fetch_layer_geojson` — tries native GeoJSON
(`f=geojson`), falls back to ArcGIS JSON + `CGOP_arcgis_convert_esri_to_geojson`
- Template system: `CGOP_arcgis_render_template` — `{FIELD}` / `{FIELD_slug}` tokens
for filename and label generation
- Source hash: `CGOP_arcgis_build_source_hash` — detects upstream changes via item
modified timestamp, url, size, layer names
---
### `wordpress-plugin/tools/gis/convert_beacon_wkt_to_geojson.py`
**Original path:** `plugins/county-gop-core/tools/gis/convert_beacon_wkt_to_geojson.py`
**Lines:** 46
What it did:
- Reads `{"wkt": "MULTIPOLYGON (...)"}` on stdin
- Converts EPSG:2965 → EPSG:4326 using `pyproj` + `shapely`
- Outputs `{"ok": true, "geometry": {...}}` on stdout
Dependencies: `pyproj`, `shapely`
CountyCollective should implement this natively rather than shelling to Python.
The coordinate transformation is: `Transformer.from_crs("EPSG:2965", "EPSG:4326", always_xy=True)`.
---
### `wordpress-plugin/includes/csv-tools/class-cgop-csv-tools.php`
**Original path:** `plugins/county-gop-core/includes/csv-tools/class-cgop-csv-tools.php`
**Lines:** 3,042+
This file is **still active** in WordPress — it was not deleted. Only the
Beacon-layer stat display in `CGOP_csv_tools_get_counts()` was removed (lines
138–149 in the original). The rest of the CSV Tools (Position Keys export/import,
Representatives export/import, wipe tools) are unchanged.
This reference copy shows the original state including those stat lines in case
CountyCollective needs the stat-gathering logic.
---
## Output file format WordPress expects
After CountyCollective generates a GeoJSON file, you upload it via the WordPress
admin: **GOP Setup → District Map Imports → Import GeoJSON Map**.
WordPress stores uploaded files at:
```
wp-content/uploads/county-gop-maps/{county_slug}/generated/imported/{slug}.geojson
```
The file must be a valid GeoJSON `FeatureCollection`, `Feature`, `Polygon`, or
`MultiPolygon`. There is no required property schema — WordPress reads the file
as an opaque map boundary and assigns it to Position Keys via the admin UI.
Once imported, the map appears in Position Keys dropdowns under **Uploaded GeoJSON**.
Existing files already generated by the old Beacon/ArcGIS workflow remain readable
as long as the files exist on disk and their records are in the option tables.
---
## Migration note for existing generated files
Files already on disk at `wp-content/uploads/county-gop-maps/*/generated/` were
written by the old generation code and remain intact. WordPress will continue to
serve them as static files. Position Key assignments that pointed to them remain
valid. No action is needed unless you want to re-generate them via CountyCollective
and re-import.
To re-import an existing file, either:
1. Upload it again via District Map Imports → Import GeoJSON Map (creates a new
import record pointing to the new copy), or
2. Leave the old file and its existing Position Key assignment in place.