> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ploterr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Site

> Site is the land parcel.

It holds the boundary, the class of each lot line and an optional geographic anchor.

## Import

```typescript theme={null}
import { Site, classifyLotLines } from '@opengeometry/floorkit';
```

## Example

```typescript theme={null}
import { Floorkit, Site } from '@opengeometry/floorkit';

export async function createParcel() {
  await new Floorkit().setupOpenGeometry();
  const site = new Site({
    labelName: 'Parcel',
    profile: {
      outerRing: [
        [0, 0],
        [30, 0],
        [30, 20],
        [0, 20],
      ],
    },
    lotLines: ['front', 'side', 'rear', 'side'],
    elevation: 0,
  });
  console.log(site.area, site.perimeter);
  return site;
}
```

## Notes

* Points are `[x, z]` in metres. `elevation` is the world height of the ground.
* `area` is the net area in square metres, with holes subtracted. `perimeter` measures the outer boundary.
* The lot-line list must have one entry for each boundary edge. An edge without a class is a `side` line.
* `trueNorthDeg` is the clockwise angle from project north (−Z) to true north.
* A site in Floorkit is a design aid. It is not a legal survey.
* Start the geometry kernel before you create this object. See [`Floorkit`](/floorkit/api/runtime/floorkit).

**Inheritance:** `extends OPElement implements IPlaceable, PlanVectorExportable`

## Constructor

```typescript theme={null}
constructor(config?: Partial<ISite>);
```

## Properties

<ResponseField name="ogType" type="ElementType" />

<ResponseField name="ogid" type="string" />

<ResponseField name="subElements2D" type="Map<string, OPGeometry>" />

<ResponseField name="subElements3D" type="Map<string, OPGeometry>">
  Always empty — the parcel is a surface. Kept so `dispose()` stays uniform.
</ResponseField>

<ResponseField name="selected" type="boolean" />

<ResponseField name="edit" type="boolean" />

<ResponseField name="locked" type="boolean" />

<ResponseField name="propertySet" type="ISite" />

<ResponseField name="labelName" type="string" />

<ResponseField name="profile" type="PolygonProfile" />

<ResponseField name="lotLines" type="LotLineClass[]">
  Resolved lot-line classes, one per unique outer-ring edge (`side` when unset).
</ResponseField>

<ResponseField name="geoAnchor" type="GeoAnchor | undefined" />

<ResponseField name="trueNorthDeg" type="number" />

<ResponseField name="color" type="number" />

<ResponseField name="elevation" type="number" />

<ResponseField name="area" type="number">
  Read-only. Net parcel area in m² — outer ring minus holes. Computed, read-only.
</ResponseField>

<ResponseField name="perimeter" type="number">
  Read-only. Outer-boundary length in m. Computed, read-only.
</ResponseField>

<ResponseField name="outline" type="boolean" />

## Methods

### editableSchema

```typescript theme={null}
static editableSchema(): OPEditableSchema;
```

Self-describing editable surface; a host inspector renders this generically.

### move

```typescript theme={null}
move(delta: Vec3): void;
```

Translate this element by `delta` (world-space, meters).

### rotate

```typescript theme={null}
rotate(angleDeg: number, axis?: Vec3, anchor?: Vec3): void;
```

Rotate about Y.

### getOPConfig

```typescript theme={null}
getOPConfig(): ISite;
```

### setOPConfig

```typescript theme={null}
setOPConfig(config: Partial<ISite>): void;
```

Merge a partial config and rebuild geometry.

### beginEdit

```typescript theme={null}
beginEdit(): void;
```

Start one live edit; a second `beginEdit` before `endEdit` keeps the first start.

### endEdit

```typescript theme={null}
endEdit(): {
    undo: () => void;
    redo: () => void;
} | undefined;
```

End the live edit; its exact undo and redo, or undefined when no option changed.

### getEditAnchors

```typescript theme={null}
getEditAnchors(): EditAnchor[];
```

Draggable handles, in the element's local frame (y = elevation): - one `xz` `vertex` anchor per outer-ring point (`v:outer:&lt;i&gt;`), and - one `xz` `edge-mid` anchor per edge midpoint (`m:outer:&lt;i&gt;`, edge `i`→`i+1`) — the insert-vertex affordance (Mapbox/nebula midpoint handles).

### applyEditAnchor

```typescript theme={null}
applyEditAnchor(id: string, position: [
    number,
    number,
    number
]): void;
```

Write back a previewed handle drag (anchors are in local frame, y = elevation): - `v:outer:&lt;i&gt;` moves outer-ring point i to the dropped (x, z), and - `m:outer:&lt;i&gt;` inserts a new point on edge i→i+1 at the dropped (x, z); the two edges it makes inherit edge i's lot-line class.

### setOPGeometry

```typescript theme={null}
setOPGeometry(): void;
```

### getExportRoots

```typescript theme={null}
getExportRoots(view: PlanExportView): THREE.Object3D[];
```

The parcel is a plan polygon and nothing else, so only `top` exports.

### toDrawing

```typescript theme={null}
toDrawing(view: PlanExportView): DrawingPrimitive[];
```

The parcel boundary (outer ring + excluded holes) as one region primitive.

### setOPMaterial

```typescript theme={null}
setOPMaterial(): void;
```

### dispose

```typescript theme={null}
dispose(): void;
```

## classifyLotLines

Classify each parcel edge as `front` / `rear` / `side` from the designated street-facing front edge.

```typescript theme={null}
function classifyLotLines(outerRing: PointXZ[], frontEdgeIndex: number): LotLineClass[];
```

## Types

### ISite

```typescript theme={null}
interface ISite extends HasPropertySets {
  ogid?: string;
  labelName: string;
  type: ElementType.SITE;
  profile: PolygonProfile;
  lotLines?: LotLineClass[];
  geoAnchor?: GeoAnchor;
  trueNorthDeg?: number;
  color: number;
  elevation: number;
}
```

### LotLineClass

Zoning class of one parcel edge.

```typescript theme={null}
type LotLineClass = 'front' | 'side' | 'rear' | 'custom';
```

### GeoAnchor

WGS84 fix of the local origin.

```typescript theme={null}
interface GeoAnchor {
  latitude: number;
  longitude: number;
  elevation?: number;
}
```

<ResponseField name="latitude" type="number" required />

<ResponseField name="longitude" type="number" required />

<ResponseField name="elevation" type="number">
  Metres above sea level, if known. Carried through, never used by the projection.
</ResponseField>

## Related

* [`OPElement`](/floorkit/api/architecture/op-element)
* [`DrawingPrimitive`](/floorkit/api/drawings/draw-project-view#drawingprimitive)
* [`EditAnchor`](/floorkit/api/architecture/op-element#editanchor)
* [`ElementType`](/floorkit/api/architecture/op-element#elementtype)
* [`HasPropertySets`](/floorkit/api/architecture/op-element#haspropertysets)
* [`IPlaceable`](/floorkit/api/architecture/op-element#iplaceable)
* [`OPEditableSchema`](/floorkit/api/architecture/op-element#opeditableschema)
* [`OPGeometry`](/floorkit/api/architecture/opening#opgeometry)
* [`PlanExportView`](/floorkit/api/shapes/cylinder-shape#planexportview)
* [`PlanVectorExportable`](/floorkit/api/shapes/cylinder-shape#planvectorexportable)
* [`PointXZ`](/floorkit/api/primitives/polygon-maths#pointxz)
* [`PolygonProfile`](/floorkit/api/primitives/polygon-maths#polygonprofile)
* [`Vec3`](/floorkit/api/architecture/wall#vec3)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.