# 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