Grower-Farm-Field Application Note

Grower-Farm-Field Application Note

This page documents the Grower, Farm, Field (GFF) or Client (CFF) data application note. It is part of AgGateway's ADAPT Minimum Viable Product (MVP).

The GFF application note documents how to create a transaction to support transfer of lists and data associated with the GFF, whether entered by the MICS operator or selected by the MICS operator from set-up data.

Assumptions

This application note assumes:

There are at least two unrelated applications working with data transmitted in an ADAPT.ApplicationDataModel object.

The data will be shared between the two applications as a serialized version of a data model object.

ADAPT will not be concerned with issues related to linking data in the new ApplicationDataModel being consumed to previous data that has been received and stored. While that is often a critical component of using the data, it is beyond the scope of this application note.

The relationship between grower, farms, fields, crops and the season in which the crop is grown is important to the consuming application.

User Stories

FMIS to FMIS user story

For business reasons, an agreement has been reached between Service Provider A (SP A) and Service Provider B (SP B) to split the customer list of growers. Currently Service Provider A has 300 grower customers and the agreement is to transfer approximately half of these growers to Service Provider B. As part of the agreement, Service Provider B would receive only the Grower-Farm-Field hierarchy and none of the historical data.

Both service providers (A and B) have ADAPT compatible FMIS.

It has been agreed what growers would be transferred from SP A to SP B.

The transfer would not include historical data such as planting and harvest data.

The GFF hierarchy shall include all properties of these entities as well as all unique identifiers.

How to create ADAPT objects (specifically Grower, Farm, Field, and CropZone) and populate their properties.

How to create field and crop zone boundaries.

How the resulting ApplicationDataModel object can be serialized to a file package.

Active Crop Zones

A grower wants to share with a consultant the crops s/he is planning to raise on various fields for the coming year. The grower uses a software application to export the information related to those fields and crop zones into an ADAPT.ApplicationDataModel. The grower copies the exported file to a USB memory stick and sends it to the consultant. The consultant is then able to use a separate application to import the data model and query the information to understand where the various crops are to be produced on the grower's farms and fields.

How serialized data can be loaded by an ADMPlugin object into an ApplicationDataModel.

How the information in the ApplicationData can be filtered by growers, farms, field, crops, or cropping seasons.

How related information can be presented as a flattened view of crops growing on a field within a farm as part of the grower's operation.

FMIS to MICS user story

Following is a Farm Management Information System (FMIS) to Machine Implement Control System (MICS) user story.

A grower has observed variability in a field’s productivity level, and wants to use variable-rate equipped planting equipment to plant corn with different populations across the field. The grower speculates that the rates can be increased in good areas and decreased in the poorer areas, thereby maintaining the same total seed used. The grower's service provider has promoted their ability to use his yield data to create a variable-rate prescription, based on multiple years of data; the grower instructs them to do so.

The service provider uses an FMIS to manage the grower’s data and create the prescription file.

Methods to create a prescription file:

Single year of yield data, classified into zones and rates assigned per zone.

Multiple years of yield data, normalized into zones and rates assigned per zone.

Soil type polygons, and rates assigned per zone.

Other data, such as soil test, EC, or imagery, classified into zones and rates assigned per zone.

Multiple combinations of the above, weighted and rates assigned per zone.

Assumptions:

Service provider has an accurate field boundary and data in their FMIS.

FMIS can export prescription file (shapefile) with a rate column in dbf of output.

MICS can import and read same prescription file with a rate column in dbf.

Code implementation

Users can serialize all types of grower set-up information via the ADM Plugin, including field boundary data. After rendering the data in the ADAPT Application Data Model, use the ADM Plugin to create an optimized serialization of the model. Upon receipt of the output, the consumer then deserializes the data with the ADM Plugin.

// Create the Grower object. The constructor will automatically create the Id property and assign the
// next available ReferenceId integer.
Grower adaptGrower = new Grower();
// Associate your internal, unique identifier to the Grower object by creating a UniqueId object
// and adding it to the Grower object's CompoundIdentifier.
UniqueId ourId = new UniqueId();
ourId.Id = "ce6f7dff-2e4e-4bda-b670-9d4f4dfcda0d";
// Notice the available IdTypeEnum choices. Not everybody uses the same way of identifying things in their
// system. As a result, we must support a number of identification schemes.
ourId.IdType = IdTypeEnum.UUID;
// Almost as important as the identifier is knowing who created it (or where it came from).
ourId.Source = "www.somecompany.com";
ourId.SourceType = IdSourceTypeEnum.URI;
// Each CompoundIdentifier that is used in ADAPT can have multiple unique identifiers associated with it.
// Consider the possibilites here, not only can your identifier for something be peristed but also the
// identifiers that your trading partner assigns to the same object. PLEASE CONSIDER PERSISTING AND RETURNING
// IDENTIFIERS PASSED TO YOU IN THIS FASHION. This has the potential to result in a "frictionless" conversation
// once the initial mapping is done, buy this benefit will only emerge if we all are "good neighbors".
adaptGrower.Id.UniqueIds.Add(ourId);
// You may notice that many of the objects in ADAPT have a minimal number of properties. Don't panic if you
// can't find a place to put all your data. It may be in an associated object or intended to be expressed
// as a ContextItem.
adaptGrower.Name = "Demo Grower";
// Add the Grower object to the Catalog.
export.Catalog.Growers.Add(adaptGrower);
// Create the Farm object. The constructor will automatically create the Id property and assign the
// next available ReferenceId integer.
Farm adaptFarm = new Farm();
ourId = new UniqueId();
ourId.Id = "f4bcb7f7-8d00-403d-891f-1cba80133ea1";
ourId.IdType = IdTypeEnum.UUID;
ourId.Source = "www.somecompany.com";
ourId.SourceType = IdSourceTypeEnum.URI;
adaptFarm.Id.UniqueIds.Add(ourId);
adaptFarm.Description = "Demo Farm";
// Here we link this farm object to the grower. Note that this is the integer (ReferenceId) in the
// Grower's CompountIdentifier object.
adaptFarm.GrowerId = adaptGrower.Id.ReferenceId;
// Add the Farm object to the Catalog.
export.Catalog.Farms.Add(adaptFarm);
// Create the Field object. The constructor will automatically create the Id property and assign the
// next available ReferenceId integer.
Field adaptField = new Field();
ourId = new UniqueId();
ourId.Id = "1e5307bf-bf8f-4735-bc00-a51fa48a3f9e";
ourId.IdType = IdTypeEnum.UUID;
ourId.Source = "www.somecompany.com";
ourId.SourceType = IdSourceTypeEnum.URI;
adaptField.Id.UniqueIds.Add(ourId);
adaptField.Description = "Demo Field";
// Here we link this field object to the farm. Note that this is the integer (ReferenceId) in the
// Farm's CompountIdentifier object.
adaptField.FarmId = adaptFarm.Id.ReferenceId;
// Create the CropZone object. The constructor will automatically create the Id property and assign the
// next available ReferenceId integer.
CropZone adaptCropZone = new CropZone();
ourId = new UniqueId();
ourId.Id = "c29d6d6d-b7ea-4f93-a884-6b08c09ae96c";
ourId.IdType = IdTypeEnum.UUID;
ourId.Source = "www.somecompany.com";
ourId.SourceType = IdSourceTypeEnum.URI;
adaptCropZone.Id.UniqueIds.Add(ourId);
adaptCropZone.Description = "Demo CropZone";
// Here we link this cropzone object to the field. Note that this is the integer (ReferenceId) in the
// Field's CompountIdentifier object.
adaptCropZone.FieldId = adaptField.Id.ReferenceId;
// Here we link this cropzone object to the crop. Note that this is the integer (ReferenceId) in the
// Crop's CompountIdentifier object.
adaptCropZone.CropId = adaptCrop.Id.ReferenceId;
// Here we link this cropzone object to the crop year TimeScope. Note that the TimeScope is used BY VALUE
// instead of BY REFERENCE (like the field and crop above).
adaptCropZone.TimeScopes.Add(cropYear);
// Add the CropZone object to the Catalog.
export.Catalog.CropZones.Add(adaptCropZone);

Use case diagrams

Implementation notes

AgGateway's ADAPT is a model created through a series of compromises, and influenced by the group of volunteers who stepped forward to work on it with dedication over the past couple of years. Throughout the process, we tried not to pick winners. The goal was to support stakeholders (more or less) where they are and not force major refactoring on any one participant's part just to be able to integrate.

As a result, the way ADAPT implements and arranges its Grower, Farm, Field, CropZone, and boundary structures is extremely flexible. Here are some highlights:

Grower, while the theoretical root of the hierarchy, is not actually required by any of the other objects. This was necessary to support its optional nature in representing ISO 11783-10 data.

Farm and Field have collections of TimeScope objects which allow them to be "tagged" as being part of multiple crop years. Stakeholder's systems varied in how they scoped farms and fields in time. Some forced the objects to be redefined (with a new unique identifier) each crop season, others allowed the same object (and unique identifier) to span seasons.

Fields can have multiple FieldBoundary objects associated with them. This allows for a field's boundary to shift over time while still preserving the older versions, as well as supporting special purpose versions of a boundary. The FieldBoundary.SpatialData property is an ADAPT Shape object (which is an abstract class) - what is actually used is one of the child classes of Shape (Polygon, MultiPolygon, etc.). The Field object has a property (ActiveBoundaryId) that allows designation of the "default" FieldBoundary to use.

ADAPT defines CropZones as a spatial area within a field grown to a crop during a specific window of time. This is fundamentally different from the concept of a management zone (that might vary by plant population within the same crop variety, soil type, or fertility amendment requirements). The CropZone (unlike Field) holds its boundary internally. Also unlike Field, a CropZone is only expected to have a single boundary due to its scope in crop and time.