Many improvements

This commit is contained in:
2026-06-26 15:48:12 -05:00
parent 2a52e0546e
commit c5725a0259
22 changed files with 1392 additions and 97 deletions
+97 -27
View File
@@ -1,13 +1,25 @@
import { collectGeoJSON, offset, pointsFromLngLat } from "./geometry.js";
import { getFeatureType, resolveFeatureStyle } from "./feature-types.js";
import { getFeatureType, listFeatureTypeSchemas } from "./feature-types.js";
export const YARD_SCHEMA_VERSION = 1;
class YardFeature {
constructor(kind, geometryType, name, details = {}) {
const featureType = getFeatureType(kind);
if (featureType.geometryType !== geometryType) {
throw new Error(
`${kind} features must use ${featureType.geometryType} geometry, got ${geometryType}`,
);
}
this.kind = kind;
this.geometryType = geometryType;
this.name = name ?? getFeatureType(kind).label;
this.name = name ?? featureType.label;
this.id = buildFeatureId(kind, this.name);
this.details = { ...details };
const { startDate = null, endDate = null, ...restDetails } = details;
this.startDate = startDate;
this.endDate = endDate;
this.details = { ...restDetails };
this.coordinates = [];
this.parentId = null;
this.groupIds = [];
@@ -36,6 +48,22 @@ class YardFeature {
return this;
}
activeFrom(startDate) {
this.startDate = startDate;
return this;
}
activeUntil(endDate) {
this.endDate = endDate;
return this;
}
withDateRange(startDate, endDate = null) {
this.startDate = startDate;
this.endDate = endDate;
return this;
}
childOf(parent) {
this.parentId = resolveFeatureReference(parent);
return this;
@@ -49,22 +77,23 @@ class YardFeature {
toGeoJSON() {
const label = getFeatureType(this.kind).label;
const style = resolveFeatureStyle(this.kind, this.details);
const properties = {
id: this.id,
kind: this.kind,
label,
name: this.name,
startDate: this.startDate,
endDate: this.endDate,
parentId: this.parentId,
groupIds: this.groupIds,
details: this.details,
};
if (this.geometryType === "Point") {
const [first] = this.coordinates;
return {
type: "Feature",
properties: {
id: this.id,
kind: this.kind,
label,
name: this.name,
parentId: this.parentId,
groupIds: this.groupIds,
details: this.details,
style,
},
properties,
geometry: {
type: "Point",
coordinates: [first.lon, first.lat],
@@ -80,16 +109,7 @@ class YardFeature {
return {
type: "Feature",
properties: {
id: this.id,
kind: this.kind,
label,
name: this.name,
parentId: this.parentId,
groupIds: this.groupIds,
details: this.details,
style,
},
properties,
geometry,
};
}
@@ -194,6 +214,10 @@ function resolveCoordinate(values) {
const [first, ...rest] = values;
if (isOffsetAnchor(first) && rest.every(isMove)) {
if (rest.length === 0) {
return first.origin;
}
return offset(first.origin, ...rest);
}
@@ -212,6 +236,12 @@ export class Fence extends LineFeature {
}
}
export class YardGridLine extends LineFeature {
constructor(name = "Yard Grid", details = {}) {
super("yardGrid", name, details);
}
}
export class House extends PolygonFeature {
constructor(name = "House", details = {}) {
super("house", name, details);
@@ -254,9 +284,43 @@ export class FlowerBed extends PolygonFeature {
}
}
export class Tree extends PointFeature {
export class Plant extends PointFeature {
constructor(name = "Plant", details = {}, kind = "plant") {
super(kind, name, details);
}
}
export class Flower extends Plant {
constructor(name = "Flower", details = {}, kind = "flower") {
super(name, details, kind);
}
}
export class Daylily extends Flower {
constructor(name = "Daylily", details = {}) {
super(name, {
commonName: "Daylily",
genus: "Hemerocallis",
...details,
}, "daylily");
}
}
export class Shrub extends Plant {
constructor(name = "Shrub", details = {}) {
super(name, details, "shrub");
}
}
export class Bush extends Shrub {
constructor(name = "Bush", details = {}) {
super(name, details);
}
}
export class Tree extends Plant {
constructor(name = "Tree", details = {}) {
super("tree", name, details);
super(name, details, "tree");
}
}
@@ -268,6 +332,12 @@ export class Sprinkler extends PointFeature {
export function collectYardData(features, groups = []) {
const collection = collectGeoJSON(features);
collection.schemaVersion = YARD_SCHEMA_VERSION;
collection.lifecycleFields = {
startDate: "date",
endDate: "date",
};
collection.featureTypes = listFeatureTypeSchemas();
collection.groups = groups.map((group) => ({
id: group.id,
label: group.label,
@@ -276,4 +346,4 @@ export function collectYardData(features, groups = []) {
return collection;
}
export { collectGeoJSON };
export { collectGeoJSON };