Spaces:
Sleeping
Sleeping
| # JSON Integration Schemas | |
| This directory contains sample JSON formats for integrating the Farm Layout Model with your user app. | |
| All formats follow **GeoJSON RFC 7946** standard for maximum compatibility with map libraries (Leaflet, Mapbox, Google Maps, etc.). | |
| ## Files | |
| - `input_example.json` β What your user app sends to the layout engine | |
| - `output_example.json` β What the layout engine returns | |
| ## Input Schema | |
| ### Top-level structure | |
| ```json | |
| { | |
| "type": "FeatureCollection", | |
| "properties": { ... }, // Farm-level metadata | |
| "features": [ ... ] // List of geometric features | |
| } | |
| ``` | |
| ### Top-level properties (farm metadata) | |
| | Field | Type | Required | Description | | |
| |-------|------|----------|-------------| | |
| | `farm_id` | string | Yes | Unique identifier for the farm | | |
| | `farm_name` | string | No | Human-readable name | | |
| | `pump_hp` | float | Yes | Pump horsepower (for flow calculation) | | |
| | `centralized` | boolean | Yes | `true` = centralized manifold, `false` = distributed | | |
| | `headland_buffer_m` | float | No | Inward buffer from field edge (default: 1.0m) | | |
| | `override_lateral_spacing_m` | float\|null | No | Override crop default spacing | | |
| ### Required features | |
| **1. Farm boundary (Polygon)** | |
| ```json | |
| { | |
| "type": "Feature", | |
| "properties": { "type": "farm_boundary" }, | |
| "geometry": { | |
| "type": "Polygon", | |
| "coordinates": [[[lon, lat], ...]] | |
| } | |
| } | |
| ``` | |
| **2. Pump location (Point)** | |
| ```json | |
| { | |
| "type": "Feature", | |
| "properties": { | |
| "type": "pump", | |
| "pump_hp": 5.0 | |
| }, | |
| "geometry": { | |
| "type": "Point", | |
| "coordinates": [lon, lat] | |
| } | |
| } | |
| ``` | |
| **3. Crop zones (one or more Polygons)** | |
| ```json | |
| { | |
| "type": "Feature", | |
| "properties": { | |
| "type": "crop_zone", | |
| "crop": "tomato" | |
| }, | |
| "geometry": { | |
| "type": "Polygon", | |
| "coordinates": [[[lon, lat], ...]] | |
| } | |
| } | |
| ``` | |
| ### Optional features | |
| **Elevation data (Point with properties)** | |
| ```json | |
| { | |
| "type": "Feature", | |
| "properties": { | |
| "type": "elevation", | |
| "min_elevation_m": 920, | |
| "max_elevation_m": 923 | |
| }, | |
| "geometry": { | |
| "type": "Point", | |
| "coordinates": [lon, lat] | |
| } | |
| } | |
| ``` | |
| ### Supported crop types | |
| `tomato`, `pepper`, `lettuce`, `cucumber`, `orchard`, `generic` | |
| ## Output Schema | |
| ### Top-level structure | |
| ```json | |
| { | |
| "type": "FeatureCollection", | |
| "properties": { | |
| "type": "farm_design", | |
| "design_summary": { ... }, | |
| "bom": { ... } | |
| }, | |
| "features": [ ... ] | |
| } | |
| ``` | |
| ### Design Summary (top-level properties) | |
| ```json | |
| { | |
| "farm_area_ha": 0.24, | |
| "total_valves": 3, | |
| "total_drip_tape_m": 480.5, | |
| "total_main_line_m": 45.2, | |
| "total_emitters": 1202, | |
| "pump_hp": 5.0, | |
| "pump_flow_lph": 500, | |
| "manifold_strategy": "distributed" | |
| } | |
| ``` | |
| ### Bill of Materials (top-level properties) | |
| ```json | |
| { | |
| "main_line_16mm_m": 45.2, | |
| "drip_tape_16mm_m": 480.5, | |
| "inline_emitters": 1202, | |
| "total_pipe_m": 525.7, | |
| "valves_count": 3, | |
| "cost_main": 22.60, | |
| "cost_drip_tape": 72.08, | |
| "cost_emitters": 96.16, | |
| "cost_valves": 45.00, | |
| "total_cost_usd": 235.84 | |
| } | |
| ``` | |
| ### Output feature types | |
| | `properties.type` | Geometry | Purpose | | |
| |-------------------|----------|---------| | |
| | `farm_boundary` | Polygon | Echo of input farm boundary | | |
| | `valve` | Point | Valve placement with metadata | | |
| | `valve_zone` | Polygon | Area controlled by each valve | | |
| | `main_line` | LineString | Main irrigation line | | |
| | `lateral` | LineString | Individual drip lateral | | |
| ### Valve metadata | |
| Each valve Feature has these properties: | |
| ```json | |
| { | |
| "type": "valve", | |
| "id": "valve_000", | |
| "strategy": "distributed", // or "centralized" | |
| "reason": "crop_type", // or "capacity_split", "topography_split", "hydraulics_split" | |
| "crop": "tomato", | |
| "flow_capacity_lph": 500, | |
| "estimated_demand_lph": 480 | |
| } | |
| ``` | |
| ### Lateral metadata | |
| Each lateral Feature has: | |
| ```json | |
| { | |
| "type": "lateral", | |
| "index": 0, | |
| "length_m": 30.0, | |
| "valve_id": "valve_000", // Which valve controls this lateral | |
| "spacing_m": 0.5 | |
| } | |
| ``` | |
| ## Rendering on Your Map | |
| All coordinates are in **WGS84 (EPSG:4326)** β lat/lon format compatible with: | |
| - **Leaflet**: `L.geoJSON(data).addTo(map)` | |
| - **Mapbox GL JS**: `map.addSource('design', { type: 'geojson', data })` | |
| - **Google Maps**: `map.data.addGeoJson(data)` | |
| ### Recommended styling | |
| ```javascript | |
| { | |
| "farm_boundary": { color: "green", weight: 3, fillOpacity: 0.1 }, | |
| "valve": { color: "red", radius: 8, fillColor: "red" }, | |
| "valve_zone": { color: "purple", weight: 1, fillOpacity: 0.2 }, | |
| "main_line": { color: "blue", weight: 4 }, | |
| "lateral": { color: "cyan", weight: 1, opacity: 0.6 } | |
| } | |
| ``` | |
| ## Coordinate Order Note | |
| GeoJSON uses **[longitude, latitude]** order (not lat/lon). | |
| Always double-check your user app sends coordinates in this order. | |
| ## Example: Minimal Input | |
| If your user app only has farm boundary + pump + one crop: | |
| ```json | |
| { | |
| "type": "FeatureCollection", | |
| "properties": { | |
| "pump_hp": 5.0, | |
| "centralized": false | |
| }, | |
| "features": [ | |
| { | |
| "type": "Feature", | |
| "properties": { "type": "farm_boundary" }, | |
| "geometry": { | |
| "type": "Polygon", | |
| "coordinates": [[[77.59, 12.97], [77.60, 12.97], [77.60, 12.98], [77.59, 12.98], [77.59, 12.97]]] | |
| } | |
| }, | |
| { | |
| "type": "Feature", | |
| "properties": { "type": "pump", "pump_hp": 5.0 }, | |
| "geometry": { "type": "Point", "coordinates": [77.59, 12.97] } | |
| }, | |
| { | |
| "type": "Feature", | |
| "properties": { "type": "crop_zone", "crop": "tomato" }, | |
| "geometry": { | |
| "type": "Polygon", | |
| "coordinates": [[[77.59, 12.97], [77.60, 12.97], [77.60, 12.98], [77.59, 12.98], [77.59, 12.97]]] | |
| } | |
| } | |
| ] | |
| } | |
| ``` | |
| ## Error Response Format | |
| If the engine fails to generate a design: | |
| ```json | |
| { | |
| "type": "FeatureCollection", | |
| "properties": { | |
| "type": "farm_design_error", | |
| "error": { | |
| "code": "INVALID_POLYGON", | |
| "message": "Farm boundary self-intersects at coordinates [77.59, 12.97]", | |
| "details": { ... } | |
| } | |
| }, | |
| "features": [] | |
| } | |
| ``` | |
| ### Error codes | |
| - `INVALID_POLYGON` β Farm boundary is invalid (self-intersecting, too small, etc.) | |
| - `NO_PUMP_FOUND` β No pump feature in input | |
| - `NO_CROP_ZONES` β No crop zones specified | |
| - `INVALID_PUMP_HP` β pump_hp missing or β€ 0 | |
| - `HEADLAND_TOO_LARGE` β Headland buffer exceeds field dimensions | |
| - `INTERNAL_ERROR` β Unexpected server error | |