Add printable yard map and sprinkler zones with estimated coverage
Check and deploy / deploy (push) Successful in 25s

This commit is contained in:
aaron.axvig committed 2026-10-14 21:24:39 -05:00
1 parent c8c26c1706
commit 6fd308aca8
14 files changed
+609 -37

No files matched your search

+70 -4
View File
@@ -1,8 +1,74 @@
import { east, ft, offset, south } from "../lib/geometry.js";
import { Sprinkler } from "../lib/yard-features.js";
import { defineGroup, Sprinkler } from "../lib/yard-features.js";
import { lotCorner } from "./anchors.js";
export const irrigationGroup = defineGroup("group:irrigation", "Sprinklers", {
categoryId: "infrastructure",
});
const zones = [1, 2, 3, 4].map((zone) => defineGroup(
`group:irrigation-zone-${zone}`, `Zone ${zone}`, {
categoryId: "infrastructure", parentGroupId: irrigationGroup.id,
},
));
export const irrigationGroups = [irrigationGroup, ...zones];
// Transcribed from the annotated October 14, 2026 printout using its 10 ft grid.
// Locations are approximate. All reaches and arcs are initial visual estimates.
// Coordinates: feet east/south of lotCorner; negative east is the boulevard.
// Bearings below are clockwise from LOT north; coverage exports true bearings.
function head(zone, number, name, eastFeet, southFeet, headType, reachFeet,
startBearingDegrees, arcDegrees, note) {
return new Sprinkler(`Zone ${zone} · ${number} · ${name}`, {
zone: String(zone), headType, reachFeet,
startBearingDegrees: startBearingDegrees + lotCorner.assumedNorthClockwiseDegrees,
arcDegrees, coverageEstimated: true,
note: note ?? "Position read from annotated printout; reach and arc estimated.",
})
.withId(`sprinkler:zone-${zone}-${number}`)
.inGroup(zones[zone - 1])
.add(offset(lotCorner), east(ft(eastFeet)), south(ft(southFeet)));
}
export const irrigationFeatures = [
new Sprinkler("Front bed sprinkler").add(offset(lotCorner), south(ft(15)), east(ft(10))),
new Sprinkler("Garage side sprinkler").add(offset(lotCorner), south(ft(92)), east(ft(40))),
];
// Zone 1: boulevard north of the entry walk, and north front lawn.
head(1, 1, "Boulevard northwest", -18.5, 0.5, "mist", 10, 90, 90),
head(1, 2, "Boulevard northeast", -5, 0.5, "mist", 10, 180, 90),
head(1, 3, "Boulevard southwest", -18.5, 11.5, "mist", 10, 0, 90),
head(1, 4, "Boulevard southeast", -5, 11.5, "mist", 10, 270, 90),
head(1, 5, "Front lawn northwest", 5.5, 10, "mist", 10, 0, 90),
head(1, 6, "Front walk bend", 19, 10, "mist", 10, 270, 90),
head(1, 7, "Front lawn west", 5.5, 17, "mist", 15, 90, 90),
head(1, 8, "Front porch edge", 22, 17, "mist", 16, 180, 90),
head(1, 9, "Front lawn south", 17.5, 32.5, "mist", 16, 270, 90),
// Zone 2: paired heads down the longer southern boulevard strip.
head(2, 1, "Boulevard northwest", -18.5, 15.5, "mist", 12, 90, 90),
head(2, 2, "Boulevard northeast", -5, 15.5, "mist", 12, 180, 90),
head(2, 3, "Boulevard west upper", -18.5, 28, "mist", 12, 0, 180),
head(2, 4, "Boulevard east upper", -5, 28, "mist", 12, 180, 180),
head(2, 5, "Boulevard west lower", -18.5, 39, "mist", 12, 0, 180),
head(2, 6, "Boulevard east lower", -5, 39, "mist", 12, 180, 180),
head(2, 7, "Boulevard southwest", -18.5, 50.5, "mist", 12, 0, 90),
head(2, 8, "Boulevard southeast", -5, 50.5, "mist", 12, 270, 90),
// Zone 3: south front lawn and the narrow lawn along the house.
head(3, 1, "Front west upper", 5, 28, "rotator", 12, 90, 90),
head(3, 2, "Front west lower", 5.5, 43, "rotator", 12, 0, 90),
head(3, 3, "Porch southwest", 28, 37.5, "rotator", 10, 180, 90),
head(3, 4, "South fence by front bed", 26, 49.5, "rotator", 15, 270, 90),
head(3, 5, "South bed northeast", 42, 38, "rotator", 12, 90, 90),
head(3, 6, "South fence by bed", 44, 49.5, "rotator", 12, 0, 90),
head(3, 7, "House south wall", 57, 31, "rotator", 12, 90, 180),
// Zone 4: rear lawn. The adjacent head marked 2 belongs to zone 2.
head(4, 1, "Rear lawn northwest", 80, 6, "rotator", 15, 90, 90),
head(4, 2, "Rear lawn northeast", 106, 6, "rotator", 15, 180, 90),
head(4, 3, "Rear lawn southwest", 80, 23.5, "rotator", 15, 0, 90),
head(4, 4, "Rear lawn southeast", 105, 25, "rotator", 15, 270, 90),
head(2, 9, "House southeast mist", 82, 34.5, "mist", 12, 90, 90,
"Confirmed zone 2 mist head. Position and coverage estimated.").withId("sprinkler:zone-4-5"),
head(4, 6, "Rear path rotator", 93, 29, "rotator", 15, 90, 90,
"Confirmed zone 4 rotator. Position and coverage estimated."),
head(4, 7, "South fence west", 86, 50, "rotator", 15, 0, 90),
head(4, 8, "South fence by garage", 112, 49.5, "rotator", 15, 270, 90),
];
+31 -2
View File
@@ -1,4 +1,6 @@
import { defineGroup, Driveway, Walkway } from "../lib/yard-features.js";
import { defineGroup, Driveway, Street, Walkway } from "../lib/yard-features.js";
import * as geo from "../lib/geometry.js";
import { lotCorner } from "./anchors.js";
export const pavedSurfacesGroup = defineGroup("group:paved-surfaces", "Paved Surfaces", {
categoryId: "structures",
@@ -52,5 +54,32 @@ const stepPad = new Walkway("Step pad").inGroup(pavedSurfacesGroup).trace([
[-100.89837111222856, 46.82674500346631],
]);
export const pavementFeatures = [frontWalk, driveway, garageWalk, stepPad];
// The front fence runs along the west edge of the 51-foot-deep lot.
// Put the sidewalk outside it, with roughly 15 feet beyond either end.
const frontSidewalk = new Walkway("Front sidewalk")
.inGroup(pavedSurfacesGroup)
.add(geo.offset(lotCorner), geo.north(geo.ft(15)))
.add(geo.offset(lotCorner), geo.north(geo.ft(15)), geo.west(geo.ft(4.5)))
.add(geo.offset(lotCorner), geo.south(geo.ft(51 + 15)), geo.west(geo.ft(4.5)))
.add(geo.offset(lotCorner), geo.south(geo.ft(51 + 15)));
// Near curb is 19 feet outside the fence; the far curb is another 40 feet west.
const frontStreet = new Street("6th Avenue NW")
.inGroup(pavedSurfacesGroup)
.add(geo.offset(lotCorner), geo.north(geo.ft(15)), geo.west(geo.ft(19)))
.add(geo.offset(lotCorner), geo.north(geo.ft(15)), geo.west(geo.ft(19 + 40)))
.add(geo.offset(lotCorner), geo.south(geo.ft(51 + 15)), geo.west(geo.ft(19 + 40)))
.add(geo.offset(lotCorner), geo.south(geo.ft(51 + 15)), geo.west(geo.ft(19)));
// The surveyed front walk meets the fence about 13.15 feet south of lotCorner.
// Center the 3-foot walk there, spanning the boulevard from sidewalk to curb.
const frontWalkCenterSouthFeet = 13.15;
const boulevardWalk = new Walkway("Boulevard walk")
.inGroup(pavedSurfacesGroup)
.add(geo.offset(lotCorner), geo.south(geo.ft(frontWalkCenterSouthFeet - 1.5)), geo.west(geo.ft(4.5)))
.add(geo.offset(lotCorner), geo.south(geo.ft(frontWalkCenterSouthFeet - 1.5)), geo.west(geo.ft(19)))
.add(geo.offset(lotCorner), geo.south(geo.ft(frontWalkCenterSouthFeet + 1.5)), geo.west(geo.ft(19)))
.add(geo.offset(lotCorner), geo.south(geo.ft(frontWalkCenterSouthFeet + 1.5)), geo.west(geo.ft(4.5)));
export const pavementFeatures = [frontWalk, driveway, garageWalk, stepPad, frontSidewalk, frontStreet, boulevardWalk];
export const pavementGroups = [pavedSurfacesGroup];
+64 -25
View File
@@ -3,19 +3,16 @@
"nodes": [
"visibility:category:plants",
"visibility:category:plants>visibility:type:flower",
"visibility:category:plants>visibility:type:flower>visibility:feature:83",
"visibility:category:plants>visibility:type:flower>visibility:feature:84",
"visibility:category:plants>visibility:type:flower>visibility:feature:85",
"visibility:category:plants>visibility:type:flower>visibility:feature:86",
"visibility:category:plants>visibility:type:flower>visibility:feature:87",
"visibility:category:plants>visibility:type:flower>visibility:feature:88",
"visibility:category:plants>visibility:type:flower>visibility:feature:89",
"visibility:category:plants>visibility:type:flower>visibility:feature:90",
"visibility:category:plants>visibility:type:flower>visibility:feature:91",
"visibility:category:plants>visibility:type:flower>visibility:feature:92",
"visibility:category:plants>visibility:type:flower>visibility:feature:93",
"visibility:category:plants>visibility:type:flower>visibility:feature:94",
"visibility:category:plants>visibility:type:flower>visibility:type:daylily",
"visibility:category:plants>visibility:type:flower>visibility:type:daylily>visibility:feature:53",
"visibility:category:plants>visibility:type:flower>visibility:type:daylily>visibility:feature:54",
"visibility:category:plants>visibility:type:flower>visibility:type:daylily>visibility:feature:55",
"visibility:category:plants>visibility:type:flower>visibility:type:daylily>visibility:feature:56",
"visibility:category:plants>visibility:type:flower>visibility:type:daylily>visibility:feature:57",
"visibility:category:plants>visibility:type:flower>visibility:type:daylily>visibility:feature:58",
@@ -43,10 +40,10 @@
"visibility:category:plants>visibility:type:flower>visibility:type:daylily>visibility:feature:80",
"visibility:category:plants>visibility:type:flower>visibility:type:daylily>visibility:feature:81",
"visibility:category:plants>visibility:type:flower>visibility:type:daylily>visibility:feature:82",
"visibility:category:plants>visibility:type:flower>visibility:type:daylily>visibility:feature:83",
"visibility:category:plants>visibility:type:flower>visibility:type:daylily>visibility:feature:84",
"visibility:category:plants>visibility:type:flower>visibility:type:daylily>visibility:feature:85",
"visibility:category:plants>visibility:type:tree",
"visibility:category:plants>visibility:type:tree>visibility:feature:92",
"visibility:category:plants>visibility:type:tree>visibility:feature:93",
"visibility:category:plants>visibility:type:tree>visibility:feature:94",
"visibility:category:plants>visibility:type:tree>visibility:feature:95",
"visibility:category:plants>visibility:type:tree>visibility:feature:96",
"visibility:category:plants>visibility:type:tree>visibility:feature:97",
@@ -56,31 +53,34 @@
"visibility:category:plants>visibility:type:tree>visibility:feature:101",
"visibility:category:plants>visibility:type:tree>visibility:feature:102",
"visibility:category:plants>visibility:type:tree>visibility:feature:103",
"visibility:category:plants>visibility:type:tree>visibility:feature:114",
"visibility:category:plants>visibility:type:tree>visibility:feature:115",
"visibility:category:plants>visibility:type:tree>visibility:feature:116",
"visibility:category:plants>visibility:type:tree>visibility:feature:104",
"visibility:category:plants>visibility:type:tree>visibility:feature:105",
"visibility:category:plants>visibility:type:tree>visibility:feature:106",
"visibility:category:plants>visibility:type:tree>visibility:feature:117",
"visibility:category:plants>visibility:type:tree>visibility:feature:118",
"visibility:category:plants>visibility:type:tree>visibility:feature:119",
"visibility:category:plants>visibility:type:tree>visibility:feature:120",
"visibility:category:plants>visibility:type:bush",
"visibility:category:plants>visibility:type:bush>visibility:feature:109",
"visibility:category:plants>visibility:type:bush>visibility:feature:110",
"visibility:category:plants>visibility:type:bush>visibility:feature:111",
"visibility:category:plants>visibility:type:bush>visibility:feature:112",
"visibility:category:plants>visibility:type:bush>visibility:feature:113",
"visibility:category:plants>visibility:type:bush>visibility:feature:114",
"visibility:category:plants>visibility:type:bush>visibility:feature:115",
"visibility:category:plants>visibility:type:bush>visibility:feature:116",
"visibility:category:plants>visibility:type:bush>visibility:group:juniper-trees",
"visibility:category:plants>visibility:type:bush>visibility:group:juniper-trees>visibility:feature:104",
"visibility:category:plants>visibility:type:bush>visibility:group:juniper-trees>visibility:feature:105",
"visibility:category:plants>visibility:type:bush>visibility:group:juniper-trees>visibility:feature:106",
"visibility:category:plants>visibility:type:bush>visibility:group:juniper-trees>visibility:feature:107",
"visibility:category:plants>visibility:type:bush>visibility:group:juniper-trees>visibility:feature:108",
"visibility:category:plants>visibility:type:bush>visibility:group:juniper-trees>visibility:feature:109",
"visibility:category:plants>visibility:type:bush>visibility:group:juniper-trees>visibility:feature:110",
"visibility:category:plants>visibility:type:bush>visibility:group:juniper-trees>visibility:feature:111",
"visibility:category:structures",
"visibility:category:structures>visibility:type:fence",
"visibility:category:structures>visibility:type:fence>visibility:feature:1",
"visibility:category:structures>visibility:type:flowerBed",
"visibility:category:structures>visibility:type:flowerBed>visibility:feature:48",
"visibility:category:structures>visibility:type:flowerBed>visibility:feature:49",
"visibility:category:structures>visibility:type:flowerBed>visibility:feature:50",
"visibility:category:structures>visibility:type:flowerBed>visibility:feature:51",
"visibility:category:structures>visibility:type:flowerBed>visibility:feature:52",
"visibility:category:structures>visibility:type:flowerBed>visibility:feature:53",
"visibility:category:structures>visibility:type:flowerBed>visibility:feature:54",
"visibility:category:structures>visibility:type:flowerBed>visibility:feature:55",
"visibility:category:structures>visibility:group:buildings",
"visibility:category:structures>visibility:group:buildings>visibility:feature:40",
"visibility:category:structures>visibility:group:buildings>visibility:feature:41",
@@ -93,9 +93,9 @@
"visibility:category:structures>visibility:group:paved-surfaces>visibility:feature:46",
"visibility:category:structures>visibility:group:paved-surfaces>visibility:feature:47",
"visibility:category:infrastructure",
"visibility:category:infrastructure>visibility:type:sprinkler",
"visibility:category:infrastructure>visibility:type:sprinkler>visibility:feature:118",
"visibility:category:infrastructure>visibility:type:sprinkler>visibility:feature:119",
"visibility:category:infrastructure>visibility:group:irrigation",
null,
null,
"visibility:category:reference",
"visibility:category:reference>visibility:type:lotBoundary",
"visibility:category:reference>visibility:type:lotBoundary>visibility:feature:0",
@@ -137,6 +137,45 @@
"visibility:category:reference>visibility:group:yard-grid>visibility:feature:36",
"visibility:category:reference>visibility:group:yard-grid>visibility:feature:37",
"visibility:category:reference>visibility:group:yard-grid>visibility:feature:38",
"visibility:category:reference>visibility:group:yard-grid>visibility:feature:39"
"visibility:category:reference>visibility:group:yard-grid>visibility:feature:39",
"visibility:category:structures>visibility:group:paved-surfaces>visibility:feature:48",
"visibility:category:structures>visibility:group:paved-surfaces>visibility:feature:49",
"visibility:category:structures>visibility:group:paved-surfaces>visibility:feature:50",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-1",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-2",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-3",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-4",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-1>visibility:feature:121",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-1>visibility:feature:122",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-1>visibility:feature:123",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-1>visibility:feature:124",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-1>visibility:feature:125",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-1>visibility:feature:126",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-1>visibility:feature:127",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-1>visibility:feature:128",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-1>visibility:feature:129",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-2>visibility:feature:130",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-2>visibility:feature:131",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-2>visibility:feature:132",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-2>visibility:feature:133",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-2>visibility:feature:134",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-2>visibility:feature:135",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-2>visibility:feature:136",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-2>visibility:feature:137",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-3>visibility:feature:138",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-3>visibility:feature:139",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-3>visibility:feature:140",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-3>visibility:feature:141",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-3>visibility:feature:142",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-3>visibility:feature:143",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-3>visibility:feature:144",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-4>visibility:feature:145",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-4>visibility:feature:146",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-4>visibility:feature:147",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-4>visibility:feature:148",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-2>visibility:feature:149",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-4>visibility:feature:150",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-4>visibility:feature:151",
"visibility:category:infrastructure>visibility:group:irrigation>visibility:group:irrigation-zone-4>visibility:feature:152"
]
}
+2 -1
View File
@@ -2,7 +2,7 @@ import { collectYardData } from "../lib/yard-features.js";
import { boundaryFeatures } from "./boundaries.js";
import { buildingFeatures, buildingGroups } from "./buildings.js";
import { gridFeatures, gridGroups } from "./grid.js";
import { irrigationFeatures } from "./irrigation.js";
import { irrigationFeatures, irrigationGroups } from "./irrigation.js";
import { pavementFeatures, pavementGroups } from "./pavement.js";
import { plantFeatures, plantGroups } from "./plants.js";
@@ -20,5 +20,6 @@ export const yardGeoJSON = collectYardData(
...gridGroups,
...pavementGroups,
...plantGroups,
...irrigationGroups,
],
);