Ag-Analytics® - Farmland Sales API

Ag-Analytics® Farmland Sales API provides users with easy and fast access to filter and find land for sale, complete with the sales and geographic data components to get a detailed description of that land’s value. The data of this service is originally provided by Farmland Finder. In this version of Land Value Service API, each parcel/land has a full description of the entire sale/transaction. Multiple parcel/land record can belong to one transaction. In geographic attribute, each result record gives the detailed description of a certain land/parcel itself, while the attribute in ‘sales’ may carry the information for the transaction/sale other than this parcel/land.

Required libraries

In [81]:
import requests
import json
import pandas as pd
import folium
import mplleaflet
import geojson
import shapely.wkt
import os

Request Parameter Details

Request URL: https://ag-analytics.azure-api.net/farmland-sales/

1). Location Parameters(Required): To make a valid request,at least one location parameters need to be provided.

i. State:  The name of State in string format.Title cased.

ii. County: The name of State in string format. Title cased.This parameter will be valid only if the State parameter is provided

iii.Bounding_box: Area of interest in geoJSON format(See example below).


2). Sale Condition Parameters(optional): Optional parameters to specify response based on sale conditions

i. Status: Sale Condition of the property. Vaild options are: Sold, For Sale, Expired Listing.

ii. StartDate (Required only if Status is Sold):Searching starting date of the property Sale Date. In format 'yyyy-mm-dd'

iii.EndDate (Required only if Status is Sold):Searching end date of the property Sale Date. In format 'yyyy-mm-dd'

Response Description

Listing Information

1).Listing_id: The unique ID for each listing(transaction).

2).Entry_Updated:The date of the sales information has been updated

3).Avg_CSR2: the average The Iowa Corn Suitability Rating(Soil Productivity Index)

4).CRP: If the property joined the Conservation Reserve Program.(‘Yes’ or ‘No’)

5).Total_Acres: the total acres of the entire sale

6).Tillable_Acres: the tillable acres of the sale

7).Percent_Tillable: the percent tillable area

8).CRP_Acres: the CRP acres

9).Sale_Price: the total sale price of the sale record

10).Price_Acre: the price per acre of the sale record

11).Status: one of the following values: "For Sale", "Listing Expired", "Sold"

12).Sale_Condition: one of the following values: "Auction", "Listing"

13).Listing_Agent: the listing agent name

14).Buyer: the buyer name as a string

15).Sale_Date: The sale date string in YYYY-MM-DD format. (When the parcel is still listing, the attribute will be Null

16).Taxes_total: taxes for the sale as a float

17).Assessed_Land: If the land/parcel has been assessed

18).Broker_URL: The URL link to the broker listing webpage as a string

Parcel Information

1).Parcel_ID :The unique sale id for each parcel as a string

2).Parcel: Index of the parcel in one listing(transaction).

3).Shape: The boundary of the parcel/property in Well Known Text type

4).GeoJSON: The boundary of the parcel/property in GeoJSON type

5).Acres: Area of the parcel

6).State: The state where the parcel/property locates in.

7).County:The county where the parcel/property locates in.

8).lat_center: the latitudinal center of the parcel/property as a float value

9).lng_center: the longitudinal center of the parcel/property as a float value

10).range: the range as a string (ex: 26W - always include E or W)

11).sect: the section as string (ex: 17)

12).twnshp: the township as a string (ex: 78N - always include N or S)

13).county_name: the county name as a string (Title cased - for ex: Osceola, Polk, etc.)

14).state_name: the state name as a string (Title cased - for ex: Michigan)

15).STATEFP: the FIPS to state level as a string

16).FIPS: the FIPS to county level as a string

Request Parameter Example

In [134]:
State= "Michigan"
County= "Houghton"
Bounding_box = '{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-88.95973205566405,46.68995749641134],[-88.76678466796875,46.68995749641134],[-88.76678466796875,46.7981792512332],[-88.95973205566405,46.7981792512332],[-88.95973205566405,46.68995749641134]]]}}'

Status = 'Sold'
StartDate = '2019-08-08'
EndDate = '2020-01-01'

#Format the inputs()
values = {
    'State':State,
    'County' : County,
    'Bounding_Box': Bounding_box,
    #'StartDate':StartDate,
    #'EndDate':EndDate,
    #'Status' :Status
}

# Header for using a subscription key.
headers = {'Content-Type': 'application/x-www-form-urlencoded','Ocp-Apim-Subscription-Key': "XXXXXXXXXXXXXX"}

API Function

In [143]:
def LandValueService(values,headers):
    try:
        url = 'https://ag-analytics.azure-api.net/farmland-sales/'
        
        response = requests.post(url, data = values,headers = headers).json()
        print(response.get('status'))
        print(response.get('msg'))
        print(response)
        return response
    
    except Exception as e:
        print(e)
        raise e

Calling API Function and Displaying Response

In [144]:
LandValueResponse = LandValueService(values,headers)
SUCCESS
3 parcel records
{'msg': '3 parcel records', 'records': {'09A7DDA8-2B75-4DAF-BA05-BE5FEE0747A9': {'Assessed_Land': None, 'Avg_CSR2': 21.76897, 'Broker_URL': 'http://www.northernmichiganlandbrokers.com/pages/listings/details.php?mls=1112205', 'Buyer': None, 'CRP': 'No', 'CRP_Acres': None, 'Entry_Updated': 'Fri, 15 Mar 19 00:00:00 GMT', 'Listing_Agent': 'Northern Michigan Land Brokers', 'Listing_id': '09A7DDA8-2B75-4DAF-BA05-BE5FEE0747A9', 'Percent_Tillable': 1.0, 'Price_Acre': 809.0, 'Sale_Condition': 'Listing', 'Sale_Date': None, 'Sale_Price': 129500.0, 'Status': 'For Sale', 'Taxes_total': None, 'Tillable_Acres': 1.3, 'Total_Acres': 160.0, 'parcels': [{'Acres': 160.01292273964387, 'County': 'Houghton', 'FIPS': '26061', 'GeoJSON': {'coordinates': [[[-88.8189026265523, 46.7153441141984], [-88.8241335031313, 46.7153320080954], [-88.8241452523484, 46.7116995060643], [-88.8241569999999, 46.708067], [-88.8188885071246, 46.708091861304], [-88.8136200094686, 46.7081164817389], [-88.808351507078, 46.7081408613044], [-88.8083961838476, 46.7117542397438], [-88.8136458768534, 46.7117362343203], [-88.8188955663688, 46.7117179897604], [-88.8189026265523, 46.7153441141984]]], 'type': 'Polygon'}, 'Parcel': 1, 'Parcel_ID': '5e277282526a87486f9d39f4', 'STATEFP': '26', 'Shape': 'POLYGON((-88.8189026265523 46.7153441141984, -88.8241335031313 46.7153320080954, -88.8241452523484 46.7116995060643, -88.8241569999999 46.708067, -88.8188885071246 46.708091861304, -88.8136200094686 46.7081164817389, -88.808351507078 46.7081408613044, -88.8083961838476 46.7117542397438, -88.8136458768534 46.7117362343203, -88.8188955663688 46.7117179897604, -88.8189026265523 46.7153441141984))', 'State': 'Michigan', 'county_name': 'Houghton', 'lat_center': 46.71082, 'lng_center': -88.81758, 'range': '36W', 'sect': '21', 'state_name': 'Michigan', 'twnshp': '50N'}]}, 'F7B64E2F-B4F2-45CC-98E5-2007C3D3A48D': {'Assessed_Land': None, 'Avg_CSR2': 22.38667, 'Broker_URL': 'http://www.northernmichiganlandbrokers.com/pages/listings/details.php?mls=1116950', 'Buyer': None, 'CRP': 'No', 'CRP_Acres': None, 'Entry_Updated': 'Mon, 14 Oct 19 00:00:00 GMT', 'Listing_Agent': 'Northern Michigan Land Brokers', 'Listing_id': 'F7B64E2F-B4F2-45CC-98E5-2007C3D3A48D', 'Percent_Tillable': 0.0, 'Price_Acre': 812.0, 'Sale_Condition': 'Listing', 'Sale_Date': None, 'Sale_Price': 259000.0, 'Status': 'For Sale', 'Taxes_total': None, 'Tillable_Acres': 0.0, 'Total_Acres': 319.0, 'parcels': [{'Acres': 234.65382977667835, 'County': 'Houghton', 'FIPS': '26061', 'GeoJSON': {'coordinates': [[[-88.9117950719301, 46.7870086560967], [-88.9118881161902, 46.7905846758364], [-88.9170118729634, 46.7906005655726], [-88.9221113985047, 46.7906161549178], [-88.9272951184428, 46.7906317697503], [-88.9324547105098, 46.7906470819293], [-88.9326452315931, 46.7870623358428], [-88.9274216536394, 46.7870492412131], [-88.9221813052567, 46.7870358657119], [-88.9222522051241, 46.7834041522025], [-88.9169813672401, 46.7834185013226], [-88.9117020407763, 46.7834326313904], [-88.9117950719301, 46.7870086560967]]], 'type': 'Polygon'}, 'Parcel': 1, 'Parcel_ID': '5e277282526a87486f9d39e3', 'STATEFP': '26', 'Shape': 'POLYGON((-88.9117950719301 46.7870086560967, -88.9118881161902 46.7905846758364, -88.9170118729634 46.7906005655726, -88.9221113985047 46.7906161549178, -88.9272951184428 46.7906317697503, -88.9324547105098 46.7906470819293, -88.9326452315931 46.7870623358428, -88.9274216536394 46.7870492412131, -88.9221813052567 46.7870358657119, -88.9222522051241 46.7834041522025, -88.9169813672401 46.7834185013226, -88.9117020407763 46.7834326313904, -88.9117950719301 46.7870086560967))', 'State': 'Michigan', 'county_name': 'Houghton', 'lat_center': 46.78761, 'lng_center': -88.92045, 'range': '36W', 'sect': '30', 'state_name': 'Michigan', 'twnshp': '51N'}, {'Acres': 80.8075144784811, 'County': 'Houghton', 'FIPS': '26061', 'GeoJSON': {'coordinates': [[[-88.9221813052567, 46.7870358657119], [-88.9274216536394, 46.7870492412131], [-88.9326452315931, 46.7870623358428], [-88.9328412025953, 46.7833745986661], [-88.9275508958189, 46.7833894849988], [-88.9222522051241, 46.7834041522025], [-88.9221813052567, 46.7870358657119]]], 'type': 'Polygon'}, 'Parcel': 2, 'Parcel_ID': '5e277282526a87486f9d39e4', 'STATEFP': '26', 'Shape': 'POLYGON((-88.9221813052567 46.7870358657119, -88.9274216536394 46.7870492412131, -88.9326452315931 46.7870623358428, -88.9328412025953 46.7833745986661, -88.9275508958189 46.7833894849988, -88.9222522051241 46.7834041522025, -88.9221813052567 46.7870358657119))', 'State': 'Michigan', 'county_name': 'Houghton', 'lat_center': 46.78522, 'lng_center': -88.92749, 'range': '36W', 'sect': '30', 'state_name': 'Michigan', 'twnshp': '51N'}]}}, 'status': 'SUCCESS'}

Format Response

In [145]:
listing_info =[]
records = LandValueResponse.get('records')
for listing in records:
    parcels_info = records.get(listing).get('parcels')
    list_item = records.get(listing)
    list_item.pop('parcels')
    for parcel in parcels_info:
        parcel.update(list_item)
        listing_info.append(parcel)

listing_db = pd.DataFrame(listing_info)

Display Response

In [146]:
#Narrow table
listing_db.set_index('Listing_id').T
#Wide table
# listing_db.set_index('Listing_id')
Out[146]:
Listing_id 09A7DDA8-2B75-4DAF-BA05-BE5FEE0747A9 F7B64E2F-B4F2-45CC-98E5-2007C3D3A48D F7B64E2F-B4F2-45CC-98E5-2007C3D3A48D
Acres 160.013 234.654 80.8075
Assessed_Land None None None
Avg_CSR2 21.769 22.3867 22.3867
Broker_URL http://www.northernmichiganlandbrokers.com/pag... http://www.northernmichiganlandbrokers.com/pag... http://www.northernmichiganlandbrokers.com/pag...
Buyer None None None
CRP No No No
CRP_Acres None None None
County Houghton Houghton Houghton
Entry_Updated Fri, 15 Mar 19 00:00:00 GMT Mon, 14 Oct 19 00:00:00 GMT Mon, 14 Oct 19 00:00:00 GMT
FIPS 26061 26061 26061
GeoJSON {'coordinates': [[[-88.8189026265523, 46.71534... {'coordinates': [[[-88.9117950719301, 46.78700... {'coordinates': [[[-88.9221813052567, 46.78703...
Listing_Agent Northern Michigan Land Brokers Northern Michigan Land Brokers Northern Michigan Land Brokers
Parcel 1 1 2
Parcel_ID 5e277282526a87486f9d39f4 5e277282526a87486f9d39e3 5e277282526a87486f9d39e4
Percent_Tillable 1 0 0
Price_Acre 809 812 812
STATEFP 26 26 26
Sale_Condition Listing Listing Listing
Sale_Date None None None
Sale_Price 129500 259000 259000
Shape POLYGON((-88.8189026265523 46.7153441141984, -... POLYGON((-88.9117950719301 46.7870086560967, -... POLYGON((-88.9221813052567 46.7870358657119, -...
State Michigan Michigan Michigan
Status For Sale For Sale For Sale
Taxes_total None None None
Tillable_Acres 1.3 0 0
Total_Acres 160 319 319
county_name Houghton Houghton Houghton
lat_center 46.7108 46.7876 46.7852
lng_center -88.8176 -88.9205 -88.9275
range 36W 36W 36W
sect 21 30 30
state_name Michigan Michigan Michigan
twnshp 50N 51N 51N

Visualize Parcels on Map

In [147]:
#Display parcels on map
zoom_point=json.loads(Bounding_box)['geometry']['coordinates'][0][0]
m = folium.Map([zoom_point[1],zoom_point[0]],tiles='Cartodb Positron', zoom_start=11,width='70%', height='100%')
for shape in listing_db['GeoJSON']:
    folium.GeoJson(shape).add_to(m)
m
Out[147]:

Download Response

In [83]:
download_path = '<---path on your local directory--->' # ex:r'C:\Users\YourName\Downloads'
listing_db.to_csv(os.path.join(download_path,'FarmLand_Listing.csv'))