BoundaryAI
API service to retrieve digital field boundaries for a given area with the Ag-Analytics BoundaryAI technology. These are derived from the last publicly made 2008 Common Land Unit (CLU) boundaries distribution by the USDA.
a) Post Request Field Boundary
Please note, this API has been deprecated. Please use the new version.
It is not uncommon for more than one crop to be grown on a CLU. These CLU boundaries are derived from the last publicly available distribution from 2008. A single CLU is approximately interpreted as a “field”. A Common Land Unit (CLU) is the smallest unit of land that has a permanent, contiguous boundary, a common land cover and land management, a common owner and a common producer in agricultural land associated with USDA farm programs.
The Ag-Analytics Field Boundary API provides a service which a user can pass an extent (bounding box) and retrieve field boundaries in geojson. To our knowledge, this is the only CLU field boundary data service in the market. It is a frequently requested dataset and useful for researchers who seek pre-made field boundaries in order to conduct representative analyses, as well as other apps that wish to serve ‘starter’ field boundaries.
CLU Boundaries in Ag-Analytics FarmScope.
Click the Jupyter Notebook Static Sample to view a static rendition of this APIs Jupyter Notebook.
Click the Jupyter Notebook Github Repo to access the Jupyter Notebook .ipynb files and
instructions needed in order to run this APIs Jupyter Notebook.
Request Parameters
Parameter | Information |
---|---|
geometryType | The type of geometry specified by the geometry parameter. The geometry type can be an envelope, a point, a line, or a polygon. The default geometry type is an envelope. Values: esriGeometryPoint | esriGeometryMultipoint | esriGeometryPolyline | esriGeometryPolygon | esriGeometryEnvelope |
inSR | The spatial reference of the input geometry. The spatial reference can be specified as either a well-known ID or as a spatial reference JSON object. If the inSR is not specified, the geometry is assumed to be in the spatial reference of the map. |
distance | The buffer distance for the input geometries. The distance unit is specified by units. For example, if the distance is 100, the query geometry is a point, units is set to meters, and all points within 100 meters of the point are returned. The geodesic buffer is created based on the datum of the output spatial reference if it exists. If there is no output spatial reference, the input geometry spatial reference is used. Otherwise, the native layer spatial reference is used to generate the geometry buffer used in the query. This parameter only applies if supportsQueryWithDistance is true. |
spatialRel | This parameter applies for hosted feature services running on a spatiotemporal datastore if sqlParserVersion contains ES. Point layers require either an envelope or polygon input geometry and supports the following values: Values: esriSpatialRelIntersects | esriSpatialRelEnvelopeIntersects | esriSpatialRelIndexIntersects | esriSpatialRelWithin Polygon or polyline layers support the following values: Values: esriSpatialRelIntersects | esriSpatialRelContains | esriSpatialRelEnvelopeIntersects | esriSpatialRelIndexIntersects | esriSpatialRelWithin |
units | The unit for calculating the buffer distance. If unit is not specified, the default will be esriSRUnit_Foot when querying feature services in ArcGIS Enterprise, and esriSRUnit_Meter when querying feature services in ArcGIS Online This parameter only applies if supportsQueryWithDistance is true. Values: esriSRUnit_Meter | esriSRUnit_StatuteMile | esriSRUnit_Foot | esriSRUnit_Kilometer | esriSRUnit_NauticalMile | esriSRUnit_USNauticalMile |
relationParam | The spatial relate function that can be applied while performing the query operation. An example for this spatial relate function is "FFFTTT***". For more information on this spatial relate function, see the documentation for the spatial relate function. |
outFields | The list of fields to be included in the returned result set. This list is a comma delimited list of field names. You can also specify the wildcard "*" as the value of this parameter. In this case, the query results include all the field values. Example //Standard usage outFields=AREANAME,ST,POP2000 //Widlcard usage outFields=* |
returnGeometry | If true, the result includes the geometry associated with each feature returned. The default is true. Values: true | false |
maxAllowableOffset | The maximum allowable offset, only applicable for layers that are not editable. |
geometryPrecision | This option can be used to specify the number of decimal places in the response geometries returned by the Query operation. This applies to X and Y values only (not m or z-values). Example geometryPrecision=3 |
outSR | The spatial reference of the returned geometry. The spatial reference can be specified as either a well-known ID or as a spatial reference JSON object. If outSR is not specified, the geometry is returned in the spatial reference of the map. |
gdbVersion | The geodatabase version to query. This parameter applies only if the isDataVersioned property of the layer is true. If this is not specified, the query will apply to the published map’s version. Syntax: gdbVersion=<version> Example: gdbVersion=SDE.DEFAULT |
returnDistinctValues | If true, it returns distinct values based on the fields specified in outFields. This parameter applies only if the supportsAdvancedQueries property of the layer is true. This parameter can be used with returnCountOnly to return the count of distinct values of subfields. Note: Make sure to set returnGeometry to false when returnDistinctValues is true. Otherwise, reliable results will not be returned. Values: true | false |
returnIdsOnly | If true, the response only includes an array of object IDs. Otherwise, the response is a feature set. The default is false. When objectIds are specified, setting this parameter to true is invalid. While there is a limit to the number of features included in the feature set response, there is no limit to the number of object IDs returned in the ID array response. Clients can exploit this to get all the query conforming object IDs by specifying returnIdsOnly=true and subsequently requesting feature sets for subsets of object IDs. Values: true | false |
returnCountOnly | If true, the response only includes the count (number of features/records) that would be returned by a query. Otherwise, the response is a feature set. The default is false. This option supersedes the returnIdsOnly parameter. If returnCountOnly = true, the response will return both the count and the extent. This parameter can be used with returnDistinctValues to return the count of distinct values of subfields. Values: true | false |
returnExtentOnly | This option was added at 10.3. If true, the response only includes the extent of the features that would be returned by the query. If returnCountOnly=true, the response will return both the count and the extent. The default is false. This parameter applies only if the supportsReturningQueryExtent property of the layer is true. Note: At 10.3, this option is only available for hosted feature services. At 10.3.1, this option is available for hosted and non-hosted feature services. Values: true | false |
orderByFields | One or more field names on which the features/records need to be ordered. Use ASC or DESC for ascending or descending, respectively, following every field to control the ordering. orderByFields defaults to ASC (ascending order) if <ORDER> is unspecified. orderByFields is supported on only those layers/tables that indicate supportsAdvancedQueries is true. Note: If supportsOrderByOnlyOnLayerFields is true, only fields from the layer's fields array can be used with the orderByFields parameter. For example, the outStatisticfieldName from outStatistics can't be used if supportsOrderByOnlyOnLayerFields is true. Syntax orderByFields=field1 <ORDER>, field2 <ORDER>, field3 <ORDER> Example orderByFields=STATE_NAME ASC, RACE DESC, GENDER |
groupByFieldsForStatistics | One or more field names on which the values need to be grouped for calculating the statistics. groupByFieldsForStatistics is valid only when the outStatistics parameter is used. Syntax groupByFieldsForStatistics=field1, field2 Example groupByFieldsForStatistics=STATE_NAME, GENDER |
outStatistics | The definitions for one or more field-based statistics to be calculated. This parameter is supported only on layers/tables that indicate supportsStatistics is true. When using outStatistics, the only other parameters that can be used are groupByFieldsForStatistics, orderByFields, time, and where. |
returnZ | If true, Z values will be included in the results if the features have Z values. Otherwise Z values are not returned. The default is false. |
returnM | If true, M values will be included in the results if the features have M values. Otherwise M values are not returned. The default is false. |
multipatchOption | Parameter to support querying feature services whose data source is a multipatch featureclass. |
resultOffset | This option can be used for fetching query results by skipping the specified number of records and starting from the next record (that is, resultOffset + 1th). The default is 0. This parameter only applies if supportsPagination is true. You can use this option to fetch records that are beyond maxRecordCount. |
resultRecordCount | This option can be used for fetching query results up to the resultRecordCount specified. When resultOffset is specified but this parameter is not, the map service defaults it to maxRecordCount. The maximum value for this parameter is the value of the layer's maxRecordCount property. The minimum value entered for this parameter cannot be below 1. This parameter only applies if supportsPagination is true. |
f | The response format. The default response format is html. The supportsQueryFormats layer property describes what formats are supported. Note that the default response format, html, is always supported. Example: "supportedQueryFormats": "JSON,geoJSON,PBF" The output format geoJSON is not supported if returnM is true. Starting at 10.8, geojson will return results that match the RFC7946 specification if no outSR is specified, or if outSR is set to 4326. Setting a different outSR value will return projected results. However, these will not match the RFC7946 specification. Values: html | json | geojson | pbf |
Response Parameters
Parameter | Data Type | Required? |
---|---|---|
objectIdFieldName |
String |
Gets the name of the object ID field. |
globalIdFieldName |
String |
Gets or sets the global ID field name. |
geometryType |
String |
The esriGeometryType Constant |
spatialReference |
List | Defines the spatial reference of a map, layer, or task parameters. |
fields |
List | Each field stores a specific type of data, such as a number, date, or piece of text. |
features |
List | Features are used to associate tabular data with geographic information. Features have two important top-level properties: geometry - A point, polyline, polygon or extent object. attributes - An object of key/value pairs in JSON format to associate with the geometry. |
Boundary Count By State
State |
State FIPS |
Total Acres |
Boundary Count |
---|---|---|---|
Arizona |
4 |
528,832 |
33,917 |
Arkansas |
5 |
6,080,673 |
254,254 |
California |
6 |
13,396,334 |
212,539 |
Colorado |
8 |
19,579,683 |
211,719 |
Connecticut |
9 |
531,976 |
59,321 |
Delaware |
10 |
533,347 |
39,968 |
Georgia |
13 |
8,705,326 |
751,898 |
Hawaii |
15 |
1,611,910 |
10,512 |
Idaho |
16 |
10,732,363 |
383,671 |
Illinois |
17 |
25,372,970 |
1,482,605 |
Indiana |
18 |
14,093,068 |
753,056 |
Iowa |
19 |
26,580,471 |
1,380,415 |
Kansas |
20 |
43,326,372 |
1,142,617 |
Kentucky |
21 |
10,264,908 |
957,171 |
Louisiana |
22 |
7,248,373 |
222,710 |
Maine |
23 |
2,373,594 |
127,727 |
Maryland |
24 |
2,849,453 |
203,967 |
Massachusetts |
25 |
547,786 |
45,412 |
Michigan |
26 |
4,006,083 |
195,718 |
Minnesota |
27 |
22,442,920 |
875,986 |
Mississippi |
28 |
1,649,422 |
95,411 |
Missouri |
29 |
29,821,742 |
1,899,246 |
Montana |
30 |
50,721,906 |
658,292 |
Nebraska |
31 |
36,676,731 |
645,104 |
Nevada |
32 |
1,672,609 |
23,266 |
New Hampshire |
33 |
894,481 |
33,972 |
New Jersey |
34 |
952,435 |
77,706 |
New York |
36 |
9,490,409 |
549,223 |
North Carolina |
37 |
13,146,229 |
1,194,191 |
North Dakota |
38 |
32,140,089 |
872,467 |
Ohio |
39 |
14,995,390 |
983,316 |
Oklahoma |
40 |
29,320,352 |
733,846 |
Oregon |
41 |
13,212,207 |
199,824 |
Pennsylvania |
42 |
7,445,215 |
470,518 |
Rhode Island |
44 |
72,680 |
7,486 |
South Carolina |
45 |
2,897,836 |
182,273 |
South Dakota |
46 |
36,605,108 |
624,934 |
Tennessee |
47 |
14,462,059 |
1,165,303 |
Texas |
48 |
123,069,000 |
1,326,269 |
Utah |
49 |
4,941,516 |
87,729 |
Vermont |
50 |
1,544,910 |
131,722 |
Virginia |
51 |
14,283,368 |
821,230 |
Washington |
53 |
6,000,411 |
183,964 |
West Virginia |
54 |
2,843,839 |
171,781 |
Wisconsin |
55 |
15,227,478 |
959,647 |
Wyoming |
56 |
18,996,788 |
82,021 |
Total |
|
703,890,650 |
23,525,924 |
Call API
Request
Request URL
Request headers
-
(optional)string
-
string
Request body
where=1=1&objectIds=&time=&geometry={"xmin":-89.97802734375,"ymin":39.07890809706475,"xmax":-89.9560546875,"ymax":39.095962936305476,"spatialReference":{"wkid":4326}}&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&distance=&units=esriSRUnit_Foot&relationParam=&outFields=*&returnGeometry=true&maxAllowableOffset=&geometryPrecision=6&outSR=4326&gdbVersion=&returnDistinctValues=false&returnIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&returnZ=false&returnM=false&multipatchOption=&resultOffset=&resultRecordCount=&f=pjson
Code samples
@ECHO OFF
curl -v -X POST "https://ag-analytics.azure-api.net/CommonLandUnitBoundary/post"
-H "Content-Type: application/x-www-form-urlencoded"
-H "Ocp-Apim-Subscription-Key: {subscription key}"
--data-ascii "{body}"
using System;
using System.Net.Http.Headers;
using System.Text;
using System.Net.Http;
using System.Web;
namespace CSHttpClientSample
{
static class Program
{
static void Main()
{
MakeRequest();
Console.WriteLine("Hit ENTER to exit...");
Console.ReadLine();
}
static async void MakeRequest()
{
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");
var uri = "https://ag-analytics.azure-api.net/CommonLandUnitBoundary/post?" + queryString;
HttpResponseMessage response;
// Request body
byte[] byteData = Encoding.UTF8.GetBytes("{body}");
using (var content = new ByteArrayContent(byteData))
{
content.Headers.ContentType = new MediaTypeHeaderValue("< your content type, i.e. application/json >");
response = await client.PostAsync(uri, content);
}
}
}
}
// // This sample uses the Apache HTTP client from HTTP Components (http://hc.apache.org/httpcomponents-client-ga/)
import java.net.URI;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class JavaSample
{
public static void main(String[] args)
{
HttpClient httpclient = HttpClients.createDefault();
try
{
URIBuilder builder = new URIBuilder("https://ag-analytics.azure-api.net/CommonLandUnitBoundary/post");
URI uri = builder.build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "application/x-www-form-urlencoded");
request.setHeader("Ocp-Apim-Subscription-Key", "{subscription key}");
// Request body
StringEntity reqEntity = new StringEntity("{body}");
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
System.out.println(EntityUtils.toString(entity));
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
<!DOCTYPE html>
<html>
<head>
<title>JSSample</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(function() {
var params = {
// Request parameters
};
$.ajax({
url: "https://ag-analytics.azure-api.net/CommonLandUnitBoundary/post?" + $.param(params),
beforeSend: function(xhrObj){
// Request headers
xhrObj.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key","{subscription key}");
},
type: "POST",
// Request body
data: "{body}",
})
.done(function(data) {
alert("success");
})
.fail(function() {
alert("error");
});
});
</script>
</body>
</html>
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString* path = @"https://ag-analytics.azure-api.net/CommonLandUnitBoundary/post";
NSArray* array = @[
// Request parameters
@"entities=true",
];
NSString* string = [array componentsJoinedByString:@"&"];
path = [path stringByAppendingFormat:@"?%@", string];
NSLog(@"%@", path);
NSMutableURLRequest* _request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:path]];
[_request setHTTPMethod:@"POST"];
// Request headers
[_request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[_request setValue:@"{subscription key}" forHTTPHeaderField:@"Ocp-Apim-Subscription-Key"];
// Request body
[_request setHTTPBody:[@"{body}" dataUsingEncoding:NSUTF8StringEncoding]];
NSURLResponse *response = nil;
NSError *error = nil;
NSData* _connectionData = [NSURLConnection sendSynchronousRequest:_request returningResponse:&response error:&error];
if (nil != error)
{
NSLog(@"Error: %@", error);
}
else
{
NSError* error = nil;
NSMutableDictionary* json = nil;
NSString* dataString = [[NSString alloc] initWithData:_connectionData encoding:NSUTF8StringEncoding];
NSLog(@"%@", dataString);
if (nil != _connectionData)
{
json = [NSJSONSerialization JSONObjectWithData:_connectionData options:NSJSONReadingMutableContainers error:&error];
}
if (error || !json)
{
NSLog(@"Could not parse loaded json with error:%@", error);
}
NSLog(@"%@", json);
_connectionData = nil;
}
[pool drain];
return 0;
}
<?php
// This sample uses the Apache HTTP client from HTTP Components (http://hc.apache.org/httpcomponents-client-ga/)
require_once 'HTTP/Request2.php';
$request = new Http_Request2('https://ag-analytics.azure-api.net/CommonLandUnitBoundary/post');
$url = $request->getUrl();
$headers = array(
// Request headers
'Content-Type' => 'application/x-www-form-urlencoded',
'Ocp-Apim-Subscription-Key' => '{subscription key}',
);
$request->setHeader($headers);
$parameters = array(
// Request parameters
);
$url->setQueryVariables($parameters);
$request->setMethod(HTTP_Request2::METHOD_POST);
// Request body
$request->setBody("{body}");
try
{
$response = $request->send();
echo $response->getBody();
}
catch (HttpException $ex)
{
echo $ex;
}
?>
########### Python 2.7 #############
import httplib, urllib, base64
headers = {
# Request headers
'Content-Type': 'application/x-www-form-urlencoded',
'Ocp-Apim-Subscription-Key': '{subscription key}',
}
params = urllib.urlencode({
})
try:
conn = httplib.HTTPSConnection('ag-analytics.azure-api.net')
conn.request("POST", "/CommonLandUnitBoundary/post?%s" % params, "{body}", headers)
response = conn.getresponse()
data = response.read()
print(data)
conn.close()
except Exception as e:
print("[Errno {0}] {1}".format(e.errno, e.strerror))
####################################
########### Python 3.2 #############
import http.client, urllib.request, urllib.parse, urllib.error, base64
headers = {
# Request headers
'Content-Type': 'application/x-www-form-urlencoded',
'Ocp-Apim-Subscription-Key': '{subscription key}',
}
params = urllib.parse.urlencode({
})
try:
conn = http.client.HTTPSConnection('ag-analytics.azure-api.net')
conn.request("POST", "/CommonLandUnitBoundary/post?%s" % params, "{body}", headers)
response = conn.getresponse()
data = response.read()
print(data)
conn.close()
except Exception as e:
print("[Errno {0}] {1}".format(e.errno, e.strerror))
####################################
require 'net/http'
uri = URI('https://ag-analytics.azure-api.net/CommonLandUnitBoundary/post')
request = Net::HTTP::Post.new(uri.request_uri)
# Request headers
request['Content-Type'] = 'application/x-www-form-urlencoded'
# Request headers
request['Ocp-Apim-Subscription-Key'] = '{subscription key}'
# Request body
request.body = "{body}"
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
http.request(request)
end
puts response.body