Spaces:
Sleeping
Sleeping
| 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) | |