More features and plants added

This commit is contained in:
2026-06-26 16:16:29 -05:00
parent c5725a0259
commit fe68874b92
3 changed files with 85 additions and 28 deletions
+42 -11
View File
@@ -48,26 +48,57 @@ const flowerBeds = [
]; ];
const daylilies = [ const daylilies = [
new Daylily("You Had Me At Merlot", { new Daylily("Joan Derifield", {
daylilyDatabaseId: "194128", gardenOrgId: "4765",
daylilyDatabaseUrl: "https://daylilydatabase.org/detail.php?id=194128", }).add(geo.offset(lotCorner), geo.east(geo.ft(112)), geo.south(geo.ft(12))),
new Daylily("Predatory Flamingo", {
gardenOrgId: "61201",
}).add(geo.offset(lotCorner), geo.east(geo.ft(112)), geo.south(geo.ft(14))),
new Daylily("You Had Me at Hello", {
gardenOrgId: "235117",
}).add(geo.offset(lotCorner), geo.east(geo.ft(28)), geo.south(geo.ft(45))), }).add(geo.offset(lotCorner), geo.east(geo.ft(28)), geo.south(geo.ft(45))),
new Daylily("Mapping North Dakota", { new Daylily("Mapping North Dakota", {
daylilyDatabaseId: "158640", gardenOrgId: "56003",
daylilyDatabaseUrl: "https://daylilydatabase.org/detail.php?id=158640",
}).add(geo.offset(lotCorner), geo.east(geo.ft(28)), geo.south(geo.ft(47))), }).add(geo.offset(lotCorner), geo.east(geo.ft(28)), geo.south(geo.ft(47))),
new Daylily("Daylily", { new Daylily("Daylily").add(geo.offset(lotCorner), geo.east(geo.ft(31)), geo.south(geo.ft(47))),
daylilyDatabaseId: "",
daylilyDatabaseUrl: "",
}).add(geo.offset(lotCorner), geo.east(geo.ft(31)), geo.south(geo.ft(47))),
]; ];
const trees = [ const trees = [
new Tree("Japanese Empress Elm", { new Tree("Northern Empress Japanese Elm", {
species: "Japanese Empress Elm", species: "Northern Empress Japanese Elm",
canopyDiameterMeters: 6, canopyDiameterMeters: 6,
heightMeters: 7, heightMeters: 7,
}).add(geo.offset(lotCorner), geo.east(geo.ft(9)), geo.south(geo.ft(16))), }).add(geo.offset(lotCorner), geo.east(geo.ft(9)), geo.south(geo.ft(16))),
new Tree("Hot Wings Maple", {
species: "Hot Wings Maple",
canopyDiameterMeters: 5,
heightMeters: 5,
gardenOrgId: "536120",
}).add(geo.offset(lotCorner), geo.east(geo.ft(60)), geo.south(geo.ft(40))),
new Tree("Prairie Expedition American Elm", {
species: "Prairie Expedition American Elm",
canopyDiameterMeters: 5,
heightMeters: 5,
gardenOrgId: "736267",
}).add(geo.offset(lotCorner), geo.east(geo.ft(95)), geo.south(geo.ft(15))),
new Tree("Dwarf Korean Lilac", {
species: "Dwarf Korean Lilac",
canopyDiameterMeters: 1.75,
heightMeters: 2.5,
gardenOrgId: "79137",
}).add(geo.offset(lotCorner), geo.east(geo.ft(3)), geo.south(geo.ft(3))),
new Tree("Dwarf Korean Lilac", {
species: "Dwarf Korean Lilac",
canopyDiameterMeters: 1.75,
heightMeters: 2.5,
gardenOrgId: "79137",
}).add(geo.offset(lotCorner), geo.east(geo.ft(3)), geo.south(geo.ft(20))),
new Tree("Dwarf Korean Lilac", {
species: "Dwarf Korean Lilac",
canopyDiameterMeters: 1.75,
heightMeters: 2.5,
gardenOrgId: "79137",
}).add(geo.offset(lotCorner), geo.east(geo.ft(3)), geo.south(geo.ft(37))),
new Tree("Boulevard Linden", { new Tree("Boulevard Linden", {
species: "Boulevard Linden", species: "Boulevard Linden",
canopyDiameterMeters: 3, canopyDiameterMeters: 3,
+37 -13
View File
@@ -127,9 +127,19 @@ export const featureTypes = {
genus: "string", genus: "string",
species: "string", species: "string",
cultivar: "string", cultivar: "string",
gardenOrgId: "string",
plantedDate: "date", plantedDate: "date",
note: "string", note: "string",
}, },
externalLinks: [
{
label: "Garden.org",
url: (details) =>
details.gardenOrgId
? `https://garden.org/plants/view/${encodeURIComponent(details.gardenOrgId)}/`
: null,
},
],
style: { style: {
color: "#3d7140", color: "#3d7140",
weight: 2, weight: 2,
@@ -170,17 +180,9 @@ export const featureTypes = {
cultivar: "string", cultivar: "string",
bloomColor: "string", bloomColor: "string",
bloomSeason: "string", bloomSeason: "string",
daylilyDatabaseId: "string",
daylilyDatabaseUrl: "url",
plantedDate: "date", plantedDate: "date",
note: "string", note: "string",
}, },
externalLinks: [
{
label: "Daylily database",
url: (details) => details.daylilyDatabaseUrl ?? null,
},
],
style: { style: {
color: "#9f5e1d", color: "#9f5e1d",
weight: 2, weight: 2,
@@ -267,8 +269,8 @@ export function listFeatureTypeSchemas() {
label: definition.label, label: definition.label,
parentKind: definition.parentKind ?? null, parentKind: definition.parentKind ?? null,
geometryType: definition.geometryType, geometryType: definition.geometryType,
detailFields: { ...definition.detailFields }, detailFields: getInheritedDetailFields(kind),
externalLinks: (definition.externalLinks ?? []).map((link) => ({ externalLinks: getInheritedExternalLinks(kind).map((link) => ({
label: link.label, label: link.label,
})), })),
})); }));
@@ -280,12 +282,34 @@ export function resolveFeatureStyle(kind, details = {}) {
} }
export function resolveFeatureLinks(kind, details = {}) { export function resolveFeatureLinks(kind, details = {}) {
const { externalLinks = [] } = getFeatureType(kind); return getInheritedExternalLinks(kind)
return externalLinks
.map((link) => ({ .map((link) => ({
label: link.label, label: link.label,
url: link.url(details), url: link.url(details),
})) }))
.filter((link) => link.url); .filter((link) => link.url);
} }
function getFeatureTypeLineage(kind) {
const lineage = [];
let currentKind = kind;
while (currentKind) {
const definition = getFeatureType(currentKind);
lineage.unshift(definition);
currentKind = definition.parentKind;
}
return lineage;
}
function getInheritedDetailFields(kind) {
return Object.assign(
{},
...getFeatureTypeLineage(kind).map((definition) => definition.detailFields ?? {}),
);
}
function getInheritedExternalLinks(kind) {
return getFeatureTypeLineage(kind).flatMap((definition) => definition.externalLinks ?? []);
}
+6 -4
View File
@@ -188,7 +188,7 @@ function extendBounds(bounds, coordinates) {
function buildPopupContent(properties) { function buildPopupContent(properties) {
const { kind, label, name, startDate, endDate, details, parentId, groupIds } = properties; const { kind, label, name, startDate, endDate, details, parentId, groupIds } = properties;
const entries = Object.entries(details ?? {}).filter( const entries = Object.entries(details ?? {}).filter(
([key, value]) => value !== null && value !== undefined && !key.endsWith("Url"), ([key, value]) => value !== null && value !== undefined && shouldShowDetailField(key),
); );
const lifecycleEntries = []; const lifecycleEntries = [];
const relationshipEntries = []; const relationshipEntries = [];
@@ -221,12 +221,16 @@ function buildPopupContent(properties) {
.map(([key, value]) => `<div><span>${escapeHtml(formatDetailLabel(key))}:</span> ${escapeHtml(formatDetailValue(key, value))}</div>`) .map(([key, value]) => `<div><span>${escapeHtml(formatDetailLabel(key))}:</span> ${escapeHtml(formatDetailValue(key, value))}</div>`)
.join(""); .join("");
const linkRows = linkEntries const linkRows = linkEntries
.map((link) => `<div><span>${escapeHtml(link.label)}:</span> <a href="${escapeHtml(link.url)}" target="_blank" rel="noreferrer">${escapeHtml(link.url)}</a></div>`) .map((link) => `<div><a href="${escapeHtml(link.url)}" target="_blank" rel="noreferrer">Info</a></div>`)
.join(""); .join("");
return `${title}${subtitle}<div>${detailRows}${linkRows}</div>`; return `${title}${subtitle}<div>${detailRows}${linkRows}</div>`;
} }
function shouldShowDetailField(key) {
return !key.endsWith("Url") && key !== "gardenOrgId";
}
function formatDetailLabel(key) { function formatDetailLabel(key) {
const labels = { const labels = {
canopyDiameterMeters: "Canopy diameter", canopyDiameterMeters: "Canopy diameter",
@@ -239,8 +243,6 @@ function formatDetailLabel(key) {
cultivar: "Cultivar", cultivar: "Cultivar",
bloomColor: "Bloom color", bloomColor: "Bloom color",
bloomSeason: "Bloom season", bloomSeason: "Bloom season",
daylilyDatabaseId: "Daylily database ID",
daylilyDatabaseUrl: "Daylily database URL",
species: "Species", species: "Species",
fenceType: "Fence type", fenceType: "Fence type",
axis: "Axis", axis: "Axis",