--- title: Farm Drip Irrigation Designer emoji: 💧 colorFrom: green colorTo: blue sdk: gradio sdk_version: 6.14.0 app_file: app.py pinned: false short_description: 'Design drip irrigation layouts with deterministic geometry' --- # Farm Drip Irrigation Designer ## Overview A conversational tool for designing drip irrigation systems for farms. **Phase 1** focuses on the geometry engine: deterministic pipe layout generation using shapely and pyproj. Key features: - Parse farm boundaries (geofences) from text input - Generate drip irrigation layouts (main lines + parallel laterals) - Calculate material requirements and cost estimates - Support for multiple crop types with optimized spacing parameters ## Architecture ### Phase 1: Geometry Engine (Current) **Core modules:** - `drip_engine.py` – Pure geometry functions (no ML) - Geofence parsing and validation - UTM coordinate conversion (via pyproj) - Drip layout generation (main + laterals with clipping) - Bill of materials (BOM) estimation - Human-readable design summaries - `app.py` – Gradio UI for testing - Input: farm boundary (geofence), crop type, design parameters - Output: visualized layout, BOM (JSON), design summary - Example geofences for quick testing - `test_drip_engine.py` – Comprehensive test suite - 26 unit tests covering parsing, geometry, BOM, edge cases - All tests passing ✅ ### Phase 2: LLM Integration (Planned) - `llm_handler.py` – Conversational interface - LLM as drip irrigation specialist - Guides users through design decisions - Calls geometry engine to update designs - Answers domain-specific questions ### Phase 3: Deployment & Polish - Error handling and input validation - HF Spaces deployment with live inference - Documentation and user workflows ## Getting Started ### Install Dependencies ```bash pip install -r requirements.txt ``` ### Run Tests ```bash python3 -m pytest test_drip_engine.py -v ``` Expected: 26/26 tests passing ### Run the UI ```bash python3 app.py ``` Then open `http://localhost:7860` in your browser. ### Example: 1-hectare tomato field 1. Default geofence: `0,0;100,0;100,100;0,100` (100m × 100m = 1 ha) 2. Select crop: "tomato" (0.5m lateral spacing) 3. Headland: 1.0 m 4. Click "Generate Design" **Output:** - Visual layout (green boundary, red main line, blue laterals) - BOM with pipe lengths and costs - Design summary with emitter count and flow rate ## Design Decisions ### Why Geometry, Not ML? Drip design is **deterministic**. Given a field shape, crop type, and spacing preferences, the layout is fully determined. ML would be: - Slower - Harder to debug - Less accurate - Overkill for a well-defined problem The geometry engine is the source of truth. Future ML (e.g., SAM for boundary extraction) would feed *into* this engine, not replace it. ### Why LLM in Phase 2? Users think in **intent** ("I want to grow tomatoes on 3 hectares, budget $500"), not **parameters** ("0.5m lateral spacing, 100m mains"). The LLM: - Translates intent → geometry parameters - Explains design tradeoffs - Answers agronomic questions - Iteratively refines based on feedback ### Coordinate Systems - **Input**: Pixel coords (from map screenshots) or lat/lon (GPS) - **Internal**: UTM (meters) – accurate area/length calculations - **Output**: Geometry objects (shapely) + JSON specs ## Extensibility ### Add a New Crop Edit `drip_engine.py`'s `CROP_DEFAULTS`: ```python CROP_DEFAULTS = { "my_crop": { "lateral_spacing_m": 0.75, "emitter_spacing_m": 0.35, "emitter_discharge_lph": 5 }, # ... } ``` ### Adjust Cost Estimates Edit `PIPE_COSTS` in `drip_engine.py`: ```python PIPE_COSTS = { "main_line_16mm": 0.60, # Update $/meter # ... } ``` ### Support Lat/Lon Input Use `latlon_to_utm()` instead of treating pixel coords as UTM: ```python polygon_latlon = parse_geofence_to_polygon(user_input) polygon_utm = latlon_to_utm(polygon_latlon) # Auto-selects UTM zone design = generate_drip_layout(polygon_utm, ...) ``` ## Testing Test coverage includes: - ✅ Geofence parsing (valid, invalid, edge cases) - ✅ Polygon validation (self-intersecting, too small, etc.) - ✅ Area calculation (hectares from UTM) - ✅ Layout generation (rectangular, irregular, triangular fields) - ✅ Headland buffering - ✅ Crop-specific spacing - ✅ BOM cost breakdown - ✅ Edge cases (tiny fields, long strips, etc.) ## REST API In addition to the Gradio UI, the Space exposes a one-shot REST endpoint that accepts a flat `farm / plots / water_sources` payload — no Gradio `/call/` two-step required. ### Endpoints - `GET /api/v1/health` → `{ "status": "ok", "schema_version": "v1" }` - `POST /api/v1/design` → returns `{ farm_name, design_summary, bom, zone_details, warnings, geojson }` ### Request schema ```json { "farm": { "name": "DakshFarm", "location": { "address": "...", "latitude": 20.5937, "longitude": 78.9629 }, "size": { "value": 2.5, "unit": "acres" }, "crop_name": "Wheat" }, "plots": [ { "plot_id": "plot_1", "name": "Plot 1", "area_sq_m": 12450.0, "centroid": { "latitude": 20.5938, "longitude": 78.9627 }, "boundaries": [ { "latitude": 20.5937, "longitude": 78.9626 }, { "latitude": 20.5939, "longitude": 78.9626 }, { "latitude": 20.5939, "longitude": 78.9628 }, { "latitude": 20.5937, "longitude": 78.9628 } ] } ], "water_sources": [ { "water_source_id": "ws_1", "type": "Motor", "name": "Motor-1", "location": { "latitude": 20.5938, "longitude": 78.9627 }, "plot_id": "plot_1" } ], "pump_hp": 5.0, "headland_buffer_m": 1.0 } ``` ### `curl` example ```bash curl -X POST 'https://uniphy-farm-layout-model.hf.space/api/v1/design' \ -H 'Content-Type: application/json' \ -d @samples/rest_input_example.json ``` ### Notes / current limits - Multiple `water_sources` are accepted, but only the first is used as the pump (returned in `warnings`). - All plots inherit `farm.crop_name` as their crop. Per-plot crop overrides aren't wired up yet. - If plot polygons don't overlap, the engine sees the convex hull of their union as the farm boundary. ## API Reference ### `parse_geofence_to_polygon(geofence_input: str) → Polygon` Parse text like `"0,0;100,0;100,100;0,100"` into a Shapely Polygon. ### `generate_drip_layout(polygon_utm, crop, headland_buffer_m, ...) → Dict` Generate layout. Returns dict with: - `farm_area_ha`: Area in hectares - `main_line`: LineString - `laterals`: List of LineStrings - `total_drip_tape_m`: Total lateral length - `emitter_count`: Estimated emitters - `design_params`: Spacing, discharge, etc. ### `estimate_bom(design, unit="usd") → Dict` Bill of materials with quantities and costs. ### `design_summary(design, bom) → str` Human-readable summary for the user. ## Next Steps 1. **Deploy Phase 1 to HF Spaces** – test with real users 2. **Build Phase 2** – add LLM conversational layer 3. **Integrate boundary extraction** – use SAM or segmentation model for auto-boundary from aerial imagery (optional) 4. **Real-world validation** – test designs with actual irrigation installers ## References - [Shapely geometry library](https://shapely.readthedocs.io/) - [Pyproj coordinate transformations](https://pyproj4.github.io/pyproj/stable/) - [Web Mercator projection](https://en.wikipedia.org/wiki/Web_Mercator_projection) - [Drip irrigation design standards](https://www.fao.org/3/s2022e/s2022e00.htm) ## License MIT (for now – update as needed)