Ag-Analytics® - Yield Model API

The Ag-Analytics® Yield Forecast API uses Artificial Intelligence algorithms to forecast the yield on a given field, based on geospatial data.

Crop yield is a function of a large set of parameters, many of which are outside the control of the farmer. The forces of nature are unpredictable and can make or break a growing season, while chemical applications can be rendered ineffective by new weeds or pests. The current version of the yield model is relatively simple as compared to the number of factors that actually influence yield, however, it still provides insight and predictive power. Current yield model factors are location, crop season, seeding characteristics, planting date, application characteristics, soil characteristics, past growing history, weather data, and satellite imagery.

In [1]:
import requests
import json
import time
import os
from pandas.io.json import json_normalize
from collections import defaultdict
import pandas as pd
import zipfile, io
from IPython.display import Image

%matplotlib inline
%autosave 0
Autosave disabled

Request parameters details.

Request URL: https://aganalyticsapimanagementservice.azure-api.net/yieldforecast/ Request Type: POST Request Content-Type: application/json

1) MODELNAME (Type of Model, text, required): The type of AI Model e.g. "NN"

2) SHAPE (GeoJson, text, required): The shape of a field in GeoJson format

3) ScalarVariables (Json, text, required): The constants for the given Shape

4) CropSeason (Text, required): Growing season year for prediction. 2013 to 2019. Ex. “2018”

5) PlantingDay1(ScalarVariables, text, required): Date when planting occurred for crop of interest. e.g. PlantingDay1:"05/20/2018" (key, value in ScalarVariables Json)

6) SeedingDensity(ScalarVariables,float,optional): The seeding density applied. Default 0 e.g. SeedingDensity:30000 (key, value in ScalarVariables Json)

7) HarvestDay(ScalarVariables, text, required): Date when harvest is expected. e.g. HarvestDay:“10/20/2018” (key, value in ScalarVariables Json)

In order to get Ocp-Apim-Subscription-Key, please click on this link https://ag-analytics.org/developer/Session/SignInFromPayment

Request Parameters

In [2]:
values = {
"MODELNAME": "NN",
"SHAPE": "{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[-89.199484,40.972729],[-89.199773,40.97258],[-89.200135,40.972415],[-89.20034,40.972318],[-89.200445,40.972177],[-89.200439,40.972001],[-89.200404,40.971815],[-89.200245,40.971599],[-89.20004,40.971397],[-89.199869,40.971233],[-89.199865,40.971097],[-89.199952,40.970952],[-89.200264,40.97078],[-89.200517,40.970664],[-89.200903,40.970471],[-89.201168,40.970345],[-89.201324,40.970277],[-89.201407,40.970174],[-89.201428,40.970042],[-89.20271,40.970005],[-89.202738,40.970421],[-89.202844,40.970431],[-89.202851,40.970648],[-89.203123,40.970666],[-89.203216,40.973626],[-89.20332,40.973635],[-89.203281,40.972154],[-89.203277,40.972049],[-89.203227,40.970607],[-89.204645,40.97055],[-89.204639,40.970427],[-89.205456,40.970446],[-89.205638,40.970467],[-89.206002,40.970527],[-89.206306,40.97059],[-89.206516,40.970642],[-89.206711,40.97061],[-89.20688,40.970542],[-89.207086,40.970492],[-89.207267,40.970414],[-89.207449,40.970364],[-89.207667,40.970286],[-89.207849,40.970255],[-89.208057,40.970251],[-89.208287,40.970328],[-89.208494,40.970369],[-89.208672,40.970421],[-89.208866,40.970506],[-89.208972,40.970511],[-89.209009,40.970595],[-89.20893,40.970671],[-89.208736,40.970787],[-89.208535,40.970909],[-89.208325,40.971052],[-89.207907,40.971306],[-89.207633,40.971478],[-89.207313,40.971574],[-89.207065,40.971645],[-89.206566,40.971699],[-89.206246,40.971784],[-89.205998,40.971878],[-89.205548,40.972042],[-89.205013,40.97232],[-89.20468,40.972494],[-89.204246,40.972725],[-89.203988,40.972931],[-89.203819,40.973168],[-89.203666,40.973428],[-89.203616,40.973685],[-89.203552,40.973966],[-89.203548,40.9743],[-89.203411,40.974615],[-89.203284,40.974906],[-89.202723,40.975587],[-89.20283,40.975719],[-89.203383,40.975106],[-89.203522,40.974847],[-89.203658,40.974521],[-89.203723,40.974241],[-89.20381,40.97376],[-89.203891,40.973546],[-89.20407,40.973197],[-89.204197,40.973016],[-89.204369,40.972868],[-89.204686,40.972672],[-89.205018,40.972499],[-89.205351,40.972314],[-89.205742,40.972139],[-89.206047,40.971999],[-89.206367,40.971904],[-89.206907,40.971771],[-89.207303,40.971719],[-89.207551,40.971658],[-89.207846,40.971535],[-89.207938,40.971481],[-89.208059,40.971448],[-89.208267,40.971295],[-89.208534,40.971115],[-89.209089,40.970762],[-89.209108,40.971493],[-89.209143,40.972829],[-89.209176,40.974108],[-89.209236,40.977186],[-89.20442,40.977285],[-89.199613,40.977383],[-89.199533,40.974593],[-89.199484,40.972729]]]},\"properties\":{\"OBJECTID\":5102679,\"CALCACRES\":145.08999634,\"CALCACRES2\":null},\"id\":5102679}",
"ScalarVariables": {
"CropSeason": "2018",
"PlantingDay1": "05/20/2018",
"SeedingDensity": "30000",
"HarvestDay": "10/20/2018"
}
}

# Basic Header Pattern.
headers={'Content-Type':'application/json'}

# Header for using a subscription key.
# headers={'content-type': "application/json",'Ocp-Apim-Subscription-Key': "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}  

API Function

In [3]:
def yieldmodel(values,headers):
    try:
        url = "https://ag-analytics.azure-api.net/yieldforecast/"
        
        response = requests.post(url, json=values, headers=headers).json()
        
        print(response)

        return response
    
    except Exception as e:
        print(e)
        raise e

Calling API Function and Displaying Result

In [4]:
yield_response=yieldmodel(values,headers)
{'raster_filename': 'result_yieldraster_20191203_225453_703.tif', 'rasterinfo': [{'attributes': {'CellSize': [0.0001, -0.0001], 'CoordinateSystem': 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]]', 'Extent': '-89.209236, 40.969983000000006, -89.19953600000001, 40.977383', 'Legend': [{'Area': '100.0 %', 'Count': 6584, 'CountAllPixels': 6584, 'Max': 858.3340940722671, 'Mean': 858.3340940722671, 'Min': 858.3340940722671, 'color': '#ff0000'}], 'Matrix': [74, 97], 'Max': 858.3340940722671, 'Mean': 858.3340940722669, 'Min': 858.3340940722671, 'OID': 0, 'Percentile5': 858.3340940722671, 'Percentile95': 858.3340940722671, 'Variety': 'NoVariety', 'pngb64': 'data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAGEAAABKCAYAAACrbTpWAAAB1UlEQVR4nO2ZwY6DMAxEJ9X+/y93D1sklE0g0AAz9jyppxbV8TM2JAXCvIH30zHMoERZiDKvpwMwlkCBJRBgCQRYAgGWQIAlEGAJBFgCAZZAgCUQYAkEWAIBlkCAJRBgCQSkllCA8nQMQGIJhehUMa0EFgFAYglMWAIBqSSwDOKaNBKYBnFNGgmsAoAkEljb0EIKCeykkMDcioAEEthbEZBAAvtdACSQoIAlEBBagsI8AIJLUMESCLAEAsJKUJkHQGAJgMY7AhBcggohJTCfHbQIKUGNcBLU7gIgmARFAUAwCYoCgCASlN4JWshLUG1Ba2QlLNWvLgAQlBAp+QUon4/GgiK0nYV6hslIiEDvAeLn7kAysvf0RjcT1B83a0bWQyMh0sBdM7IeGgnRkn+E2yVEazczuFxCnfSMFb+35mkSehWeMekttvIwTYKTvU8vRzSDOQstEYckeKjOoRYxLCHS3g0bwxIs4Do2Jbj93ENTQtQtBICzsMImm5VWEby2vjTzWE7ROt/94bvhGkaK+5ZDnaf2j/YScGUcRzrLvx/OCuxMezvy3zPa5xUSzsTVveBMgKpzZYaMb9Y+fGEvUNXEr/lGwoz1yydwBmclzCpA76IS8Avyn1qVjR08QAAAAABJRU5ErkJggg=='}}]}

Displaying Output Image

In [5]:
# Image legend.
df=defaultdict(list)
for resp in yield_response["rasterinfo"][0]['attributes']['Legend']:
    df['Area %'].append(resp['Area'])
    df['Min'].append(resp['Min'])
    df['Max'].append(resp['Max'])
    df['Mean'].append(resp['Mean'])
    df['Color'].append(resp['color'])

# Create a Data Frame from the dictionary and display.
yield_df=pd.DataFrame.from_dict(df)
yield_df = yield_df.style.applymap(lambda x:"background-color: %s"%x, subset=['Color'])
yield_df
Out[5]:
Area % Min Max Mean Color
0 100.0 % 858.334 858.334 858.334 #ff0000
In [6]:
# Display image of field.
yield_image = yield_response["rasterinfo"][0]['attributes']["pngb64"]
Image(url = yield_image, width = 400, height = 200)
Out[6]:

GET Request

GET request for downloading POST requested file to local machine.

In [9]:
# Specify local path where file will be downloaded.
local_path = r"C:\<Path to download directory>" # E.g., r"C:\Users\John_Doe\Documents\rasters"

# Create GET request payload.
values = {'filename': yield_response['raster_filename']}
In [10]:
def yieldmodel_get(values, local_path):
    try:
        url = 'https://ag-analytics.azure-api.net/yieldforecast/'
    
        download_path = os.path.join(local_path, values['filename'])
     
        response = requests.get(url, params=values)
        open(download_path, 'wb').write(response.content)
        
        print(response.url)

        return response
    
    except Exception as e:
        print(e)
        raise e
In [11]:
yieldmodel_get(values, local_path)
https://ag-analytics.azure-api.net/yieldforecast/?filename=result_yieldraster_20191203_225453_703.tif
Out[11]:
<Response [200]>
In [ ]: