ワンクリックで
zoning-envelope
Generate interactive 3D zoning envelope viewers from zoning analysis reports. Requires a zoning analysis report as input.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Generate interactive 3D zoning envelope viewers from zoning analysis reports. Requires a zoning analysis report as input.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Look up ACRIS property transaction records for any NYC property — deeds, mortgages, satisfactions, liens, and ownership history. Use when the user asks who owns a building, when it last sold or for how much, or whether there are mortgages or liens against it. NYC only; for permits or violations use the DOB skills.
Look up Board of Standards and Appeals (BSA) variances and special permits for any NYC property. Use when checking whether a lot carries zoning relief — variances, special permits, appeals — that modifies its as-of-right envelope. NYC only; for base zoning controls use /zoning-analysis-nyc.
Look up DOB permit and job filing history for any NYC building — new-building, alteration, and demolition filings with status and dates. Use when the user asks what work was filed or permitted at an address, or to gauge renovation history during due diligence. NYC only; for open violations use /nyc-dob-violations.
Look up open and resolved DOB and ECB violations for any NYC building, with class, status, and penalty detail. Use when the user asks whether a building has violations, stop-work orders, or outstanding ECB penalties. NYC only; for housing-code violations use /nyc-hpd.
Look up HPD violations, complaints, and building registration for residential buildings.
Check if a NYC building is landmarked or in a historic district using LPC data.
| name | zoning-envelope |
| description | Generate interactive 3D zoning envelope viewers from zoning analysis reports. Requires a zoning analysis report as input. |
| allowed-tools | ["Read","Write","Bash","Glob","Grep","AskUserQuestion"] |
Generate an interactive 3D axonometric zoning envelope viewer as a self-contained HTML file. Uses Three.js with OrbitControls — opens in any browser, no dependencies.
Requires a zoning analysis report generated by /zoning-analysis-nyc. This skill is a renderer — it does not perform zoning calculations.
If PROJECT.md exists in the working directory, read it before fetching — lot geometry and bulk controls may already be on file from /zoning-analysis-nyc. After completing, append a one-line envelope summary and the viewer file path to its Zoning section. Update values in place (the dossier holds current state, not history), every entry with a source and date. No PROJECT.md? Skip silently — or mention /project-dossier init if the user is clearly starting a project.
/zoning-envelope path/to/zoning-analysis.md
/zoning-envelope 250 hudson
/zoning-envelope
.md path is providedRead the file directly.
Search for matching zoning analysis reports in the current working directory.
Use Glob + Grep to find reports matching the search term. If multiple matches, show the options and ask the user to pick one.
Search for the most recently modified zoning-analysis-*.md file in the current working directory. If found, confirm with the user. If not found, tell the user:
No zoning analysis report found. Run
/zoning-analysis-nycfirst, then come back with/zoning-envelope.
If the report exists but lacks the ## Envelope Data JSON block (older report format), tell the user:
This report was generated before the Envelope Data format was added. Re-run the zoning analysis to get an updated report, or I can attempt to parse the tables (results may be approximate).
Read the ## Envelope Data JSON block from the report — a fenced code block containing:
{
"lot_poly": [[x, y], ...],
"unit": "ft",
"setbacks": { "front": 6, "rear": 3, "lateral1": 3, "lateral2": 2 },
"volumes": [
{ "type": "base", "inset": 20, "h_bottom": 0, "h_top": 85, "label": "base" },
{ "type": "tower", "inset": 10, "h_bottom": 85, "h_top": 290, "label": "tower" }
],
"height_cap": 290,
"info": { "title": "...", "zone": "...", "id": "...", "area": "..." },
"stats": { "key": "value", ... },
"scenarios": null
}
From the parsed JSON, build the internal model:
LOT_POLY — the lot boundary polygon in local unitsUNIT — "ft"VOLUMES — array of volumes to extrude, each with inset distance, height range, labelHEIGHT_CAP — max height for the amber cap planeINFO — title, zone, id, area for the overlay panelsSTATS — key/value pairs for the parameters panelSCENARIOS — if present, multi-scenario toggle dataCompute inset polygons using the insetPolygon(poly, distance) function. For multi-volume envelopes (base + tower), compute the tower inset from the base inset (cumulative), not from the lot polygon — so the tower is always smaller than the base.
Compute volumes by extruding inset polygons between height intervals.
Build a self-contained HTML file following the design system below.
| Element | Color | Opacity |
|---|---|---|
| Background | #f5f3ef | 1.0 |
| Ground (lot) | #dcd7cd | 0.5 |
| Lot boundary | #2c2c2c | 1.0 |
| Setback zones | #c85a50 | 0.2 |
| Base volume faces | #6ba0c5 | 0.08–0.10 |
| Base volume edges | #6ba0c5 | 0.30–0.35 |
| Tower/upper volume | #6ba0c5 | 0.05 |
| Height cap / sky plane | #e8a849 | 0.10–0.15 |
| Labels | #333333 | 1.0 (canvas sprites) |
| Grid | #d0ccc4 | 0.15 |
Typography: Helvetica Neue, 11px for overlay panels, canvas sprites for 3D labels.
Layout:
All materials: transparent: true, depthWrite: false, side: DoubleSide.
<script type="importmap">
{ "imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"
} }
</script>
Include these in every generated HTML:
signedArea(poly) — Returns signed area. Positive = CCW winding.
insetPolygon(poly, d) — Shrinks polygon inward by distance d along edge-normal bisectors. Each vertex moves along the bisector of its two adjacent edge normals, with distance adjusted for the bisector angle. CRITICAL: The normal direction depends on polygon winding, which varies by data source (WGS84 vs EPSG:3857 produce opposite windings). The function MUST self-correct: after computing the inset, compare abs(signedArea(result)) against abs(signedArea(poly)). If the result is LARGER, negate the offset direction and recompute. This makes the function robust regardless of input winding.
triangulate(poly) — Ear-clipping triangulation for arbitrary simple polygons. Returns index array for BufferGeometry.setIndex().
extrudePolygon(poly, hBottom, hTop, color, opacity) — Returns a THREE.Group containing:
BufferGeometry with triangulated top/bottom faces + side quadsgroundPolygon(poly, color, opacity, yOffset) — Triangulated flat polygon at a given Y height.
centroid(poly) — Returns [cx, cz] for camera targeting and label placement.
createTextSprite(text, options) — Creates a THREE.Sprite with canvas-rendered text. Options: fontSize, color, bgColor.
renderer = WebGLRenderer({ antialias: true })
renderer.setClearColor(0xf5f3ef, 1)
camera = PerspectiveCamera(35, aspect, 1, maxDim * 10)
camera.position = centroid + [maxDim * 1.5, maxDim * 1.0, maxDim * 1.5]
controls = OrbitControls with damping
AmbientLight(0xffffff, 0.75)
DirectionalLight(0xffffff, 0.35) from upper-right
Scale camera distance to the lot's maximum dimension so it works for both small townhouse lots (~25 ft) and large assembled sites (170 ft+).
For each generated file:
signedAreagroundPolygon(lotPoly, ...) + outline + vertex markers (small spheres)createTextSprite at the edge midpoint, offset outwardextrudePolygon(...)groundPolygon(topPoly, amber, ...) at max heightTHREE.GridHelper scaled to lot size, subtle opacityIf SCENARIOS is populated (multi-lot analysis with apareadas, unified, etc.):
THREE.Group per scenario#scenario-bar div (top-left, below title)showScenario(key) function:
.active class (dark background)| File | Pattern |
|---|---|
./zoning-envelope-250-hudson-st.html | NYC exact polygon, contextual base+tower |
Use this as the code baseline.
Save the HTML next to the source report with zoning-envelope- prefix and the same slug:
zoning-analysis-250-hudson-st.md → zoning-envelope-250-hudson-st.htmlOpen the file in the browser after saving.
unit field in the Envelope Data block determines all labels and scaling.PerspectiveCamera(35) with OrbitControls.scenarios, generate toggle buttons. Use simplified rectangles if individual lot polygons are not available in the report.