Native Win32 + GDI+ field boundary editor for agriculture — draw and measure field polygons, exchange them as ESRI Shapefile and DXF, trace over georeferenced aerial imagery, plan full-coverage drone spray routes, and auto-design sprinkler irrigation with coverage and pipe sizing. Zero third-party dependencies; every file format hand-rolled from the public specs.
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-19 16:05:22 +12:00
docs/images added Readme 2026-08-19 16:05:22 +12:00
FieldCAD added Readme 2026-08-19 16:05:22 +12:00
.gitignore Ignore Claude Code worktrees and machine-local settings 2026-08-19 15:35:18 +12:00
CLAUDE.md added Readme 2026-08-19 16:05:22 +12:00
FieldCAD.sln FieldCAD: initial commit 2026-08-19 14:45:39 +12:00
README.md added Readme 2026-08-19 16:05:22 +12:00

FieldCAD

A native Windows desktop app for mapping agricultural fields — draw and measure field boundaries, exchange them with real GIS and CAD software, trace over georeferenced aerial imagery, plan full-coverage drone spray routes, and auto-design sprinkler irrigation.

Written in C++17 against raw Win32 and GDI+. No third-party libraries — the Shapefile, DXF, world-file and project-file readers and writers are all hand-rolled from the public format specifications, and every pixel of the canvas is drawn by hand.

FieldCAD planning a coverage spray route over two fields


Contents


Draw and measure

Click to place vertices, then close the ring by clicking the first vertex again, double-clicking, or pressing Enter. The status bar reports area in both square metres and acres, plus perimeter, as soon as the field closes. Vertices stay draggable afterwards, and everything is undoable.

Drawing a field boundary vertex by vertex

Snap-to-grid is on by default (G toggles it, + and - change the spacing). If you need exact numbers rather than clicks, press C and type coordinates directly.

Work with many fields

Ctrl+click to add fields to the selection, or drag a marquee across the canvas to grab everything it touches. With more than one selected, the status bar totals their combined area — handy for working out how much you are covering in one pass.

Two fields selected, showing combined area

The right-hand panel lists every field and stays in sync with the canvas selection in both directions. Collapse it with the > strip when you want the full width for drawing.

Drone spray routes

Select the fields to treat, give a start point and a range budget per trip, and FieldCAD plans the flight. It splits the work into as many round trips as the range requires, and says so when a field cannot be reached and returned from within the budget.

Set a spray radius and it plans genuine coverage rather than a sightseeing tour: back-and-forth (boustrophedon) passes one swath wide, inset from the boundary by the spray radius so the sprayed band lands inside the field. Concave fields split into several passes per scanline automatically. The swath is drawn as a translucent band beneath the flight path, so you can see what actually gets wet.

Zooming in on a planned coverage route

Leave the spray radius at 0 and you get the simpler behaviour — a nearest-neighbour tour of field centres, improved by a 2-opt pass.

Pick the start point by typing coordinates, or press Pick Start on Map and click the canvas.

Irrigation auto-design

Select one field, give a sprinkler spacing and radius, and get a full layout: heads placed across the interior, and a minimum-spanning-tree pipe network running from your water source to every one of them.

An irrigation layout with coverage circles and pipe network

  • Coverage is measured, not assumed. The result reports the percentage of the field actually within reach of a sprinkler, and when gaps remain it tells you the spacing that would close them.
  • Square or triangular packing. Hexagonal packing covers the same field with roughly a third fewer heads at equal radius.
  • Pipes are sized, not just routed. Because the network is a tree, the flow in each run is exactly its downstream head count times the per-head flow. From that, FieldCAD reports peak system flow and the mainline diameter needed to stay under a 1.5 m/s velocity cap.

Building

Requires Visual Studio with the Desktop development with C++ workload. x64 only, C++17, /W4, toolset v145. The only dependencies are system libraries (gdiplus, comdlg32, dwmapi, uxtheme) — no vcpkg, no NuGet, no submodules.

Open FieldCAD.sln and press F5, or from a Developer PowerShell:

msbuild FieldCAD.sln /p:Configuration=Release /p:Platform=x64

The executable lands in bin\x64\Release\FieldCAD.exe.

Self-test

There is no separate test project. A hidden console path in the same executable exercises every non-GUI subsystem — geometry, all four file formats, route planning, irrigation placement, pipe routing and hydraulics — without opening a window:

bin\x64\Debug\FieldCAD.exe --selftest

It prints PASS/FAIL for each of 112 checks and exits non-zero if any fail. New non-GUI logic is expected to arrive with cases added to src/SelfTest.cpp.

Controls

Action Input
Add a vertex (starts a field if none is active) Left-click
Close the field being drawn Click the start vertex, double-click, or Enter
Cancel the field being drawn Esc
Select a field Left-click inside it
Add / remove from the selection Ctrl+click
Select everything a drag touches Drag from empty space (Ctrl to add)
Move a vertex Drag it (when exactly one field is selected)
Delete selected field(s) Del
Rename the selected field F2, or double-click it in the list
Type an exact coordinate C
Pick a route start or water source on the canvas Pick ... on Map in either tool dialog, then click
Undo / redo Ctrl+Z / Ctrl+Y
Pan Middle-drag, or hold Space and drag
Zoom to cursor Mouse wheel
Toggle snap-to-grid G
Grow / shrink grid spacing + / -
Reset the view 0

Shortcuts run through a real Win32 accelerator table, so they work no matter which control has keyboard focus.

File formats

Format Notes
Shapefile .shp .shx .dbf .prj Standard ESRI polygon shapefile with ID and NAME attributes; opens in QGIS and ArcGIS. The .prj declares a local planar CRS in metres so GIS tools stop asking.
DXF .dxf ASCII DXF with closed POLYLINE/VERTEX entities; opens in AutoCAD, QCAD and LibreCAD. Import also reads LWPOLYLINE from other CAD software and survives malformed coordinates.
World file .jgw .pgw .wld .tfw Six-line ESRI georeferencing sidecar for background imagery. All six coefficients are applied, so rotated imagery is placed correctly, not just north-up.
Project .fcp Native UTF-8 text format (v2) holding fields, grid, background image placement, spray route and irrigation design. v1 files still load. Saves are atomic, so a failed write cannot destroy the previous version.

Coordinates are a local planar system in metres with no map projection — treat the origin as a survey benchmark on the farm.

Architecture

App is a singleton owning all mutable state; Renderer is stateless and is handed a fresh RenderState each frame. The algorithm modules depend on neither and are tested independently.

File Responsibility
src/main.cpp wWinMain, DPI awareness, --selftest entry point
src/App.h/.cpp Window and message handling, tool state machine, commands, dialogs
src/Geometry.h/.cpp Area, perimeter, centroid, hit-testing, snapping, rect/polygon intersection
src/Camera.h/.cpp World/screen transform, pan, zoom, grid
src/Renderer.h/.cpp Double-buffered GDI+ drawing of every layer plus the HUD
src/Routing.h/.cpp Spray routing: nearest-neighbour + 2-opt, multi-trip, coverage passes
src/Irrigation.h/.cpp Head placement, MST pipe routing, hydraulic sizing, coverage estimation
src/Shapefile.h/.cpp Hand-rolled .shp/.shx/.dbf/.prj
src/Dxf.h/.cpp Hand-rolled ASCII DXF
src/WorldFile.h/.cpp ESRI world-file parsing and image placement
src/ProjectFile.h/.cpp Native .fcp save/load
src/DarkMode.h/.cpp Dark menu bar and popups via undocumented uxtheme ordinals and WM_UAH*
src/SelfTest.h/.cpp The --selftest checks

Known limitations

  • The dark menu bar and popup menus rely on undocumented Windows APIs. They are resolved at runtime and fail soft: a Windows build without them shows the native light menu rather than breaking.
  • Background images are referenced by path, not embedded, so moving or deleting the image leaves a project unable to restore it. The fields still open, with a warning.
  • Irrigation hydraulics are a first-order sizing pass — flow per run and the diameter needed to hold a velocity cap. There is no pressure or friction-loss modelling, no valve or zoning logic, and no scheduling. Pipe runs are straight MST edges, so on a strongly concave field a run can cross outside the boundary.
  • Coverage spray passes are always axis-aligned rather than rotated to a field's longest axis, so a long diagonal field takes more turns than an optimal heading would.
  • Full-coverage spacing advice is the unbounded lattice bound. Heads must sit inside the boundary, so a thin margin along the edge can stay uncovered even at that spacing — triangular packing typically lands a couple of percent short where a square grid reaches 100%. The reported coverage percentage is the figure to trust.