Soil Map

Welcome to the State of Art of Soil Mapping.

This service allows you to get in less 24 hours a multi-year digital soil map of any field around the world. You might ask yourself… How this service can produce a digital soil map?

We have build an IT infrastructure that is composed by:

This IT infrastructure allows you to have the soil map of different soil chemical components and allows you to have the temporal variation of:

  1. Organic Carbon
  2. Nitrogen, Potassium, Phosphorus
  3. pH, Carbonates, Electrical Conductivity

How can You interact with it?

We have two different options:

  1. Web Application available here https://agronomofiorentini.shinyapps.io/OrganicFarmingMap/
  2. API, Yes we have an API that you can plug-in inside your application.

How the interaction works?

The steps to make a request are the following:

  1. We need information, the spatial location of the field (geojson), Soil Chemical Nutrient, Land Use, Crop Rotation and which Crop (if it’s needed).
  2. You submit the request and an automatic process start to work.
  3. After less than 24 hour your map is ready.

Yes there is also a fourth step. In fact if you have geo-referenced soil data we can improve the accuracy of our model i.e. Reinforcement Learning right above your field.

Stakeholder

The stakeholders of this system are:

  • Carbon Credit Certifiers, Remote monitoring of the soil organic carbon variation during years.

  • Precision Agriculture, Prescription maps based on crop need and available soil nutrient.

  • Agri-Food Supply Chain, Environmental best practices and metrics at hand

API Documentation

From here the API documentation will be divided:

  • Getting Started Tutorial

  • Available Endpoint

Getting Started Tutorial

We will show you here below the workflow to use properly our API related to the Soil Mapping with four programming languages (Python, R, Node.js, Java)

In order to get a soil map proprieties we have to define:

  1. Area of Interest (geojson)
  2. Land Use
  3. Crop Rotation
  4. Crop1 The crop of the previous year
  5. Crop2 The crop of two years ago
  6. Crop3 The crop of three year ago
  7. The soil chemical component that you want to receive.

Python

List of the available nutrient
# Load the libraries
import requests
from requests.auth import HTTPBasicAuth
import pandas as pd

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapNutrientAvailableNew"

# Set the useremail & Password

USEREMAIL="USEREMAIL"
APIKEY="PASSWORD"

# Set the headers for the request
headers = {
    "Content-Type": "application/json"
}

# Make the POST request

response = requests.get(url, 
                        headers=headers,
                        auth=HTTPBasicAuth(USEREMAIL, APIKEY))

# Convert from response to json

data = response.json()

# Convert from json to pandas

df = pd.DataFrame(data)

# Let's see the first 5 agricultural products

df.head()
List of the land use
# Load the libraries
import requests
from requests.auth import HTTPBasicAuth
import pandas as pd

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropLanduseListNew"

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Set the headers for the request
headers = {
    "Content-Type": "application/json"
}

# Make the POST request

response = requests.get(url, 
                        headers=headers,
                        auth=HTTPBasicAuth(USEREMAIL, APIKEY))

# Convert from response to json

data = response.json()

# Convert from json to pandas

df = pd.DataFrame(data)

# Let's see the first 5 agricultural products

df.head()
List of the available crop rotation
# Load the libraries
import requests
from requests.auth import HTTPBasicAuth
import pandas as pd

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropRotation"

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Set the headers for the request
headers = {
    "Content-Type": "application/json"
}

# Make the POST request

response = requests.get(url, 
                        headers=headers,
                        auth=HTTPBasicAuth(USEREMAIL, APIKEY))

# Convert from response to json

data = response.json()

# Convert from json to pandas

df = pd.DataFrame(data)

# Let's see the first 5 agricultural products

df.head()
List of the available crop available

To get a complete list of the available crop you should pass set the landuse API Parameter.

The landuse API parameter must be setted one of the following:

  1. Woodland
  2. Cropland
  3. Grassland
# Load the libraries
import requests
from requests.auth import HTTPBasicAuth
import pandas as pd

# Define the API Parameter
landuse="Cropland"

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropAvailableNew?landuse="+landuse

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Set the headers for the request
headers = {
    "Content-Type": "application/json"
}

# Make the POST request

response = requests.get(url, 
                        headers=headers,
                        auth=HTTPBasicAuth(USEREMAIL, APIKEY))

# Convert from response to json

data = response.json()

# Convert from json to pandas

df = pd.DataFrame(data)

# Let's see the first 5 agricultural products

df.head()
Making the first POST request

After defined the:

  1. Nutrient that you would like to get
  2. Landuse
  3. Crop Rotation
  4. Crop type

We can make the request for the soil map.

The parameter needed to make the request are:

  1. fieldnumber, The field number. You have to refereed to the field that you can get from the gid column of the UserField endpoint response
  2. action, the action must be setted as none, new, edit. If you want to receive the data based on the polygons saved in the past set none. If you want to add a new field set as new. If you want to change the shape of the polygons set edit.
  3. nutrient, The soil chemical component that you want to get. Must be one of carbonates, organic_carbon, soil_electrical_conductivity, nitrogen, potassium, phosphorus or pH
  4. croprotation, The crop rotation. Must be one of perennial, biennial or triennial
  5. landuse, Tha land use selected. Must be one of Woodland or Cropland or Grassland
  6. crop1, The crop of the previous year
  7. crop2, The crop of the two years ago
  8. crop3, The crop of the three years ago
  9. file_path_to_geojson, The goejson file related to the spatial location of the field (you can find it here county.geojson the county file of the example). Please submit a geojson with WGS 84 Coordinate Reference System.
# Load the libraries

import requests
import fiona
import geopandas as gpd
from requests.auth import HTTPBasicAuth

# Define the API call parameters

fieldnumber="1"
action="new"
nutrient="organic_carbon"
croprotation="biennial"
landuse="Cropland"
crop1="Sunflower"
crop2="Durum_wheat"
crop3="Sunflower"

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapGeojsonNew?fieldnumber="+fieldnumber+"&action="+action+"&nutrient="+nutrient+"&croprotation="+croprotation+"&landuse="+landuse+"&crop1="+crop1+"&crop2="+crop2+"&crop3="+crop3


# Set the useremail & Password

USEREMAIL="email"
APIKEY="password"

# Path to the GeoJSON file

file_path_to_geojson = "county.geojson"

# Read the GeoJSON file contents

with open(file_path_to_geojson, "r") as file:
    geojson_data = file.read()

# Set the headers for the request

headers = {
    "Content-Type": "application/json"
}

# Make the POST request with the GeoJSON data as the request body

response = requests.post(url, 
                         data=geojson_data, 
                         headers=headers,
                         auth=HTTPBasicAuth(USEREMAIL, APIKEY))

b = bytes(response.content)

with fiona.BytesCollection(b) as f:
    crs = f.crs
    gdf = gpd.GeoDataFrame.from_features(f, crs=crs)

#  Visualize the data

gdf.explore("X2022")

R

List of the available nutrient
# import libraries

library(tictoc)
library(httr)
library(gt)
library(tidyverse)

# Define the url of the API

api_url <- paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapNutrientAvailableNew")

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Get the start time to API Call

tic()

# Make the POST request

r <- GET(
  api_url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  )
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
[1] "The API needed:"
toc()
0.41 sec elapsed
# Get the status of the request

httr::status_code(r)
[1] 200
# Print out the list of the Phytofarmaceutical products

cont <- httr::content(r, as = "text", type = "application/json", encoding="UTF-8")
cont<-jsonlite::fromJSON(cont) %>% as.data.frame
cont
                      nutrient
1               organic_carbon
2                     nitrogen
3                    potassium
4                   phosphorus
5                           pH
6 soil_electrical_conductivity
7                   carbonates
List of the land use
library(tictoc)
library(httr)
library(gt)
library(tidyverse)

# Define the url of the API

api_url <- paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropLanduseListNew")

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Get the start time to API Call

tic()

# Make the POST request

r <- GET(
  api_url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  )
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
[1] "The API needed:"
toc()
0.3 sec elapsed
# Get the status of the request

httr::status_code(r)
[1] 200
# Print out the list of the Phytofarmaceutical products

cont <- httr::content(r, as = "text", type = "application/json", encoding="UTF-8")
cont<-jsonlite::fromJSON(cont) %>% as.data.frame
cont
   Land Use
1  Woodland
2  Cropland
3 Grassland
List of the available crop rotation
library(tictoc)
library(httr)
library(gt)
library(tidyverse)

# Define the url of the API

api_url <- paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropRotationNew")

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Get the start time to API Call

tic()

# Make the POST request

r <- GET(
  api_url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  )
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
[1] "The API needed:"
toc()
0.29 sec elapsed
# Get the status of the request

httr::status_code(r)
[1] 200
# Print out the list of the Phytofarmaceutical products

cont <- httr::content(r, as = "text", type = "application/json", encoding="UTF-8")
cont<-jsonlite::fromJSON(cont) %>% as.data.frame
cont
  croprotation
1    perennial
2     biennial
3    triennial
List of the available crop available

To get a complete list of the available crop you should pass set the landuse API Parameter.

The landuse API parameter must be setted one of the following:

  1. Woodland
  2. Cropland
  3. Grassland
library(tictoc)
library(httr)
library(gt)
library(tidyverse)

landuse="Cropland"

# Define the url of the API

api_url <- paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropAvailableNew?landuse=", landuse)

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Get the start time to API Call

tic()

# Make the POST request

r <- GET(
  api_url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  )
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
[1] "The API needed:"
toc()
0.34 sec elapsed
# Get the status of the request

httr::status_code(r)
[1] 200
# Print out the list of the Phytofarmaceutical products

cont <- httr::content(r, as = "text", type = "application/json", encoding="UTF-8")
cont<-jsonlite::fromJSON(cont) %>% as.data.frame
cont
                                        Crop
1                                  Vineyards
2                       Rape_and_turnip_rape
3                                        Rye
4                                     Barley
5                                      Maize
6                        Temporary_grassland
7                                   Potatoes
8                                  Triticale
9                                Durum_wheat
10                              Common_wheat
11                          Other_root_crops
12                                Dry_pulses
13                                Sugar_beet
14                                 Sunflower
15                                      Soya
16             Other_fruit_trees_and_berries
17                              Olive_groves
18                                Pear_fruit
19 Other_Leguminous__and_mixtures_for_fodder
20          Other_fibre_and_oleaginous_crops
21                                      Oats
22                Permanent_industrial_crops
23                                   Lucerne
24                            Mix_of_cereals
25                                   Oranges
26                               Apple_fruit
27                             Other_cereals
28                                   Clovers
29                    Other_fresh_vegetables
30                                    Cotton
31                              Cherry_fruit
32                                Nuts_trees
33                                  Tomatoes
Making the first POST request

After defined the:

  1. Nutrient that you would like to get
  2. Landuse
  3. Crop Rotation
  4. Crop type

We can make the request for the soil map.

The parameter needed to make the request are:

  1. fieldnumber, The field number. You have to refereed to the field that you can get from the gid column of the UserField endpoint response
  2. action, the action must be setted as none, new, edit. If you want to receive the data based on the polygons saved in the past set none. If you want to add a new field set as new. If you want to change the shape of the polygons set edit.
  3. nutrient, The soil chemical component that you want to get. Must be one of carbonates, organic_carbon, soil_electrical_conductivity, nitrogen, potassium, phosphorus or pH
  4. croprotation, The crop rotation. Must be one of perennial, biennial or triennial
  5. landuse, Tha land use selected. Must be one of Woodland or Cropland or Grassland
  6. crop1, The crop of the previous year
  7. crop2, The crop of the two years ago
  8. crop3, The crop of the three years ago
  9. file_path_to_geojson, The goejson file related to the spatial location of the field (you can find it here county.geojson the county file of the example). Please submit a geojson with WGS 84 Coordinate Reference System.
# Load the libraries

library(tictoc)
library(httr)
library(geojsonio)
library(mapview)

# Define the API call parameters

fieldnumber="1"
action="new"
nutrient="organic_carbon"
croprotation="biennial"
landuse="Cropland"
crop1="Sunflower"
crop2="Durum_wheat"
crop3="Sunflower"
  
# Define the url of the API

url = paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapGeojsonNew?fieldnumber=",fieldnumber,"&action=",action,"&nutrient=",
             nutrient,
             "&croprotation=",croprotation,
             "&landuse=", landuse,
             "&crop1=",crop1 ,
             "&crop2=", crop2,
             "&crop3=", crop3)

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Path to the GeoJSON file

file_path_to_geojson = "county.geojson"

# Get the start time to API Call

tic()

# Make the POST request

api_call <- POST(
  url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  ),
  body=httr::upload_file(file_path_to_geojson)
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
toc()

# Print out the status_code of the request
api_call$status_code

# Visualize the prescription map

soilmap <- content(api_call, as = "text", type = "application/geo+json")
soilmap<-geojson_sp(soilmap)
mapview(soilmap, 
        layer.name=paste0("Soil Organic Carbon - ", str_replace(names(soilmap)[1], "X", "")), 
        zcol=names(soilmap)[1])

Node.js

List of the available nutrient
// load libraries

const axios = require('axios');

// Set username e apikey

const username = 'XXXXXXXXXXXXXX';
const password = 'XXXXXXXXXXXXXX';

// set the apiurl

const url='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapNutrientAvailableNew';

const options = {
  method: 'get',
  url: url,
  auth: {
    username: username,
    password: password,
  },
};

axios(options)
  .then(response => {
    console.log('Risposta JSON:', response.data);
  })
  .catch(error => {
    console.error('Errore:', error.message);
  });
List of the land use
// load libraries

const axios = require('axios');

// Set username e apikey

const username = 'XXXXXXXXXXXXXX';
const password = 'XXXXXXXXXXXXXX';

// set the apiurl

const url='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropLanduseListNew';

const options = {
  method: 'get',
  url: url,
  auth: {
    username: username,
    password: password,
  },
};

axios(options)
  .then(response => {
    console.log('Risposta JSON:', response.data);
  })
  .catch(error => {
    console.error('Errore:', error.message);
  });
List of the available crop rotation
// load libraries

const axios = require('axios');

// Set username e apikey

const username = 'XXXXXXXXXXXXXX';
const password = 'XXXXXXXXXXXXXX';

// set the apiurl

const url='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropRotationNew';

const options = {
  method: 'get',
  url: url,
  auth: {
    username: username,
    password: password,
  },
};

axios(options)
  .then(response => {
    console.log('Risposta JSON:', response.data);
  })
  .catch(error => {
    console.error('Errore:', error.message);
  });
List of the available crop available

To get a complete list of the available crop you should pass set the landuse API Parameter.

The landuse API parameter must be setted one of the following:

  1. Woodland
  2. Cropland
  3. Grassland
// load libraries

const axios = require('axios');

// Set username e apikey

const username = 'XXXXXXXXXXXXXX';
const password = 'XXXXXXXXXXXXXX';

// set the apiurl

const apiurl='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropAvailableNew?landuse=';

// set the product_name parameter

const landuse ="Cropland";

// set the apiendpoint

const url = apiurl.concat(landuse)

const options = {
  method: 'get',
  url: url,
  auth: {
    username: username,
    password: password,
  },
};

axios(options)
  .then(response => {
    console.log('Risposta JSON:', response.data);
  })
  .catch(error => {
    console.error('Errore:', error.message);
  });
Making the first POST request

After defined the:

  1. Nutrient that you would like to get
  2. Landuse
  3. Crop Rotation
  4. Crop type

We can make the request for the soil map.

The parameter needed to make the request are:

  1. fieldnumber, The field number. You have to refereed to the field that you can get from the gid column of the UserField endpoint response
  2. action, the action must be setted as none, new, edit. If you want to receive the data based on the polygons saved in the past set none. If you want to add a new field set as new. If you want to change the shape of the polygons set edit.
  3. nutrient, The soil chemical component that you want to get. Must be one of carbonates, organic_carbon, soil_electrical_conductivity, nitrogen, potassium, phosphorus or pH
  4. croprotation, The crop rotation. Must be one of perennial, biennial or triennial
  5. landuse, Tha land use selected. Must be one of Woodland or Cropland or Grassland
  6. crop1, The crop of the previous year
  7. crop2, The crop of the two years ago
  8. crop3, The crop of the three years ago
  9. file_path_to_geojson, The goejson file related to the spatial location of the field (you can find it here county.geojson the county file of the example). Please submit a geojson with WGS 84 Coordinate Reference System.
// Load Libraries

const fs = require('fs');
const axios = require('axios');

// Set the useremail & passowrd

const useremail = 'XXXXXXXXXXXXX';
const apikey = 'XXXXXXXXXXXXX';

// Set the API Parameter

const fieldnumber="1";
const action="new";
const nutrient="organic_carbon";
const croprotation="biennial";
const landuse="Cropland";
const crop1="Sunflower";
const crop2="Durum_wheat";
const crop3="Sunflower";

// Set API Url

const api_url='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapGeojsonNew?fieldnumber=';

// Set endpoint Url

const apiEndpoint = api_url.concat(fieldnumber,"&action=",action,"&nutrient=",nutrient, "&croprotation=",croprotation, "&landuse=", landuse, "&crop1=", crop1, "&crop2=", crop2, "&crop3=", crop3);

// Set path to load the geojson to send as body of POST request to the API

const file_path_to_geojson = './county.geojson';

// Set path to save the geojson prescription map

const outputFilePath = './result.geojson'; 

(async () => {
  try {

    const geojsonContent = await fs.promises.readFile(file_path_to_geojson, 'utf8');
    
    const geojsonObject = JSON.parse(geojsonContent);

    
    const authHeader = `Basic ${Buffer.from(`${useremail}:${apikey}`).toString('base64')}`;

    
    const response = await axios.post(apiEndpoint, geojsonObject, {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': authHeader
      }
    });

    const resultGeoJSON = response.data;
    
    console.log('Answer From the API:', resultGeoJSON);

    await fs.promises.writeFile(outputFilePath, JSON.stringify(resultGeoJSON, null, 2), 'utf8');

  } catch (err) {
    console.error('Error:', err.message);
  }
})();

Java

WORK IN PROGRESS

Available Endpoint

SoilMapNutrientAvailable

This endpoint allow you to get a list of nutrien available in our system.

In order to use it, you must define the following parameter:

  1. USEREMAIL

  2. APIKEY

Python
# Load the libraries
import requests
from requests.auth import HTTPBasicAuth
import pandas as pd

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapNutrientAvailableNew"

# Set the useremail & Password

USEREMAIL="USEREMAIL"
APIKEY="PASSWORD"

# Set the headers for the request
headers = {
    "Content-Type": "application/json"
}

# Make the POST request

response = requests.get(url, 
                        headers=headers,
                        auth=HTTPBasicAuth(USEREMAIL, APIKEY))

# Convert from response to json

data = response.json()

# Convert from json to pandas

df = pd.DataFrame(data)

# Let's see the first 5 agricultural products

df.head()
R
library(tictoc)
library(httr)
library(gt)
library(tidyverse)

# Define the url of the API

api_url <- paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapNutrientAvailableNew")

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Get the start time to API Call

tic()

# Make the POST request

r <- GET(
  api_url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  )
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
[1] "The API needed:"
toc()
0.25 sec elapsed
# Get the status of the request

httr::status_code(r)
[1] 200
# Print out the list of the Phytofarmaceutical products

cont <- httr::content(r, as = "text", type = "application/json", encoding="UTF-8")
cont<-jsonlite::fromJSON(cont) %>% as.data.frame
cont
                      nutrient
1               organic_carbon
2                     nitrogen
3                    potassium
4                   phosphorus
5                           pH
6 soil_electrical_conductivity
7                   carbonates
Node.js
// load libraries

const axios = require('axios');

// Set username e apikey

const username = 'XXXXXXXXXXXXXX';
const password = 'XXXXXXXXXXXXXX';

// set the apiurl

const url='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapNutrientAvailableNew';

const options = {
  method: 'get',
  url: url,
  auth: {
    username: username,
    password: password,
  },
};

axios(options)
  .then(response => {
    console.log('Risposta JSON:', response.data);
  })
  .catch(error => {
    console.error('Errore:', error.message);
  });
Java

Work In Progress

SoilMapCropRotation

This endpoint allow you to get a list of crop rotation available in our system.

In order to use it, you must define the following parameter:

  1. USEREMAIL

  2. APIKEY

Python
# Load the libraries
import requests
from requests.auth import HTTPBasicAuth
import pandas as pd

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropRotationNew"

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Set the headers for the request
headers = {
    "Content-Type": "application/json"
}

# Make the POST request

response = requests.get(url, 
                        headers=headers,
                        auth=HTTPBasicAuth(USEREMAIL, APIKEY))

# Convert from response to json

data = response.json()

# Convert from json to pandas

df = pd.DataFrame(data)

# Let's see the first 5 agricultural products

df.head()
R
library(tictoc)
library(httr)
library(gt)
library(tidyverse)

# Define the url of the API

api_url <- paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropRotationNew")

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Get the start time to API Call

tic()

# Make the POST request

r <- GET(
  api_url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  )
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
[1] "The API needed:"
toc()
0.31 sec elapsed
# Get the status of the request

httr::status_code(r)
[1] 200
# Print out the list of the Phytofarmaceutical products

cont <- httr::content(r, as = "text", type = "application/json", encoding="UTF-8")
cont<-jsonlite::fromJSON(cont) %>% as.data.frame
cont
  croprotation
1    perennial
2     biennial
3    triennial
Node.js
// load libraries

const axios = require('axios');

// Set username e apikey

const username = 'XXXXXXXXXXXXXX';
const password = 'XXXXXXXXXXXXXX';

// set the apiurl

const url='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropRotationNew';

const options = {
  method: 'get',
  url: url,
  auth: {
    username: username,
    password: password,
  },
};

axios(options)
  .then(response => {
    console.log('Risposta JSON:', response.data);
  })
  .catch(error => {
    console.error('Errore:', error.message);
  });
Java

Work In Progress

SoilMapCropLanduseList

This endpoint allow you to get a list of land use available in our system.

In order to use it, you must define the following parameter:

  1. USEREMAIL

  2. APIKEY

Python
# Load the libraries
import requests
from requests.auth import HTTPBasicAuth
import pandas as pd

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropLanduseListNew"

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Set the headers for the request
headers = {
    "Content-Type": "application/json"
}

# Make the POST request

response = requests.get(url, 
                        headers=headers,
                        auth=HTTPBasicAuth(USEREMAIL, APIKEY))

# Convert from response to json

data = response.json()

# Convert from json to pandas

df = pd.DataFrame(data)

# Let's see the first 5 agricultural products

df.head()
R
library(tictoc)
library(httr)
library(gt)
library(tidyverse)

# Define the url of the API

api_url <- paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropLanduseListNew")

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Get the start time to API Call

tic()

# Make the POST request

r <- GET(
  api_url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  )
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
[1] "The API needed:"
toc()
0.32 sec elapsed
# Get the status of the request

httr::status_code(r)
[1] 200
# Print out the list of the Phytofarmaceutical products

cont <- httr::content(r, as = "text", type = "application/json", encoding="UTF-8")
cont<-jsonlite::fromJSON(cont) %>% as.data.frame
cont
   Land Use
1  Woodland
2  Cropland
3 Grassland
Node.js
// load libraries

const axios = require('axios');

// Set username e apikey

const username = 'XXXXXXXXXXXXXX';
const password = 'XXXXXXXXXXXXXX';

// set the apiurl

const url='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropLanduseListNew';

const options = {
  method: 'get',
  url: url,
  auth: {
    username: username,
    password: password,
  },
};

axios(options)
  .then(response => {
    console.log('Risposta JSON:', response.data);
  })
  .catch(error => {
    console.error('Errore:', error.message);
  });
Java

Work In Progress

SoilMapCropAvailable

This endpoint allow you to get a list of land use available in our system.

In order to use it, you must define the following parameter:

  1. USEREMAIL

  2. APIKEY

  3. landuse, The land use selected. Must be one of Woodland or Cropland or Grassland

Python
# Load the libraries
import requests
from requests.auth import HTTPBasicAuth
import pandas as pd

# Define the API Parameter
landuse="Cropland"

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropAvailableNew?landuse="+landuse

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Set the headers for the request
headers = {
    "Content-Type": "application/json"
}

# Make the POST request

response = requests.get(url, 
                        headers=headers,
                        auth=HTTPBasicAuth(USEREMAIL, APIKEY))

# Convert from response to json

data = response.json()

# Convert from json to pandas

df = pd.DataFrame(data)

# Let's see the first 5 agricultural products

df.head()
R
library(tictoc)
library(httr)
library(gt)
library(tidyverse)

landuse="Cropland"

# Define the url of the API

api_url <- paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropAvailableNew?landuse=", landuse)

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Get the start time to API Call

tic()

# Make the POST request

r <- GET(
  api_url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  )
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
[1] "The API needed:"
toc()
0.43 sec elapsed
# Get the status of the request

httr::status_code(r)
[1] 200
# Print out the list of the Phytofarmaceutical products

cont <- httr::content(r, as = "text", type = "application/json", encoding="UTF-8")
cont<-jsonlite::fromJSON(cont) %>% as.data.frame
cont
                                        Crop
1                                  Vineyards
2                       Rape_and_turnip_rape
3                                        Rye
4                                     Barley
5                                      Maize
6                        Temporary_grassland
7                                   Potatoes
8                                  Triticale
9                                Durum_wheat
10                              Common_wheat
11                          Other_root_crops
12                                Dry_pulses
13                                Sugar_beet
14                                 Sunflower
15                                      Soya
16             Other_fruit_trees_and_berries
17                              Olive_groves
18                                Pear_fruit
19 Other_Leguminous__and_mixtures_for_fodder
20          Other_fibre_and_oleaginous_crops
21                                      Oats
22                Permanent_industrial_crops
23                                   Lucerne
24                            Mix_of_cereals
25                                   Oranges
26                               Apple_fruit
27                             Other_cereals
28                                   Clovers
29                    Other_fresh_vegetables
30                                    Cotton
31                              Cherry_fruit
32                                Nuts_trees
33                                  Tomatoes
Node.js
// load libraries

const axios = require('axios');

// Set username e apikey

const username = 'XXXXXXXXXXXXXX';
const password = 'XXXXXXXXXXXXXX';

// set the apiurl

const apiurl='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapCropAvailableNew?landuse=';

// set the product_name parameter

const landuse ="Cropland";

// set the apiendpoint

const url = apiurl.concat(landuse)

const options = {
  method: 'get',
  url: url,
  auth: {
    username: username,
    password: password,
  },
};

axios(options)
  .then(response => {
    console.log('Risposta JSON:', response.data);
  })
  .catch(error => {
    console.error('Errore:', error.message);
  });
Java

Work In Progress

SoilMapUserField

This endpoint allow you to get a geojson of the field registrated for the soil map services for your account.

In order to use it, you must define the following parameter:

  1. USEREMAIL

  2. APIKEY

Python
# Load the libraries

import requests
import fiona
import geopandas as gpd
from requests.auth import HTTPBasicAuth

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapUserFieldNew?"

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Set the headers for the request

headers = {
    "Content-Type": "application/json"
}

# Make the GET request with the GeoJSON data as the request body

response = requests.get(url,
                         headers=headers,
                         auth=HTTPBasicAuth(USEREMAIL, APIKEY))

b = bytes(response.content)

with fiona.BytesCollection(b) as f:
    crs = f.crs
    gdf = gpd.GeoDataFrame.from_features(f, crs=crs)

#  Visualize the data

gdf.explore()
R
# Import libraries

library(tictoc)
library(httr)
library(gt)
library(tidyverse)

# Define the url of the API

api_url <- "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapUserFieldNew?"

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Get the start time to API Call

tic()

# Make the GET request

r <- GET(
  api_url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  )
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
[1] "The API needed:"
toc()
0.67 sec elapsed
# Get the status of the request

httr::status_code(r)
[1] 200
# Visulize the field boundaries

mappa <- httr::content(r, as = "text", type = "application/geo+json")
mappa<-geojsonio::geojson_sp(mappa)
mapview::mapview(mappa)
Node.js
// Load Libraries

const fs = require('fs');
const axios = require('axios');

// Set the useremail & passowrd

const useremail = 'XXXXXXXXXXXXXXXXXXXXXXX';
const apikey = 'XXXXXXXXXXXXXXXXXXXXXXX';

// Set API Url

const apiEndpoint='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapUserFieldNew?';

// Set path to save the geojson prescription map

const outputFilePath = './result.geojson'; 

(async () => {
  try {
    
    const authHeader = `Basic ${Buffer.from(`${useremail}:${apikey}`).toString('base64')}`;
    
    const response = await axios.get(apiEndpoint, {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': authHeader
      }
    });

    const resultGeoJSON = response.data;
    
    console.log('Answer From the API:', resultGeoJSON);

    await fs.promises.writeFile(outputFilePath, JSON.stringify(resultGeoJSON, null, 2), 'utf8');

  } catch (err) {
    console.error('Error:', err.message);
  }
})();
Java

Work In Progress

SoilMapUserFieldArea

This endpoint allow you to get the total amount of hectares related to your account for the soil map services.

In order to use it, you must define the following parameter:

  1. USEREMAIL

  2. APIKEY

Python
# Load the libraries
import requests
from requests.auth import HTTPBasicAuth
import pandas as pd

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapUserFieldAreaNew?"

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Set the headers for the request
headers = {
    "Content-Type": "application/json"
}

# Make the GET request

response = requests.get(url, 
                         headers=headers,
                         auth=HTTPBasicAuth(USEREMAIL, APIKEY))

# Convert from response to json

data = response.json()

# Convert from json to pandas

df = pd.DataFrame(data)

# Let's see the first 5 agricultural products

df.head()
R
library(tictoc)
library(httr)
library(gt)
library(tidyverse)

# Define the url of the API

api_url <- "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapUserFieldAreaNew?"

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Get the start time to API Call

tic()

# Make the GET request

r <- GET(
  api_url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  )
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
[1] "The API needed:"
toc()
0.6 sec elapsed
# Get the status of the request

httr::status_code(r)
[1] 200
# Get info about the hectares

cont <- httr::content(r, as ="text", type = "application/json")

head(jsonlite::fromJSON(cont))
[1] 9.4983
Node.js

const fs = require('fs');
const axios = require('axios');

// Set the useremail & passowrd

const useremail = 'XXXXXXXXXXXXXXXXXXXXXXX';
const apikey = 'XXXXXXXXXXXXXXXXXXXXXXX';

// Set API Url

const apiEndpoint='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapUserFieldAreaNew?';


(async () => {
  try {
    
    const authHeader = `Basic ${Buffer.from(`${useremail}:${apikey}`).toString('base64')}`;
    
    const response = await axios.get(apiEndpoint, {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': authHeader
      }
    });

    const resultGeoJSON = response.data;
    
    console.log('Answer From the API:', resultGeoJSON);

  } catch (err) {
    console.error('Error:', err.message);
  }
})();
Java

Work In Progress

SoilMapTiff

This endpoint allow you to get the soil map of the nutrient requested in tiff file format.

In order to use it, you must define the following parameter:

  1. fieldnumber, The field number. You have to refereed to the field that you can get from the gid column of the UserField endpoint response
  2. action, the action must be setted as none, new, edit. If you want to receive the data based on the polygons saved in the past set none. If you want to add a new field set as new. If you want to change the shape of the polygons set edit.
  3. nutrient, The soil chemical component that you want to get. Must be one of carbonates, organic_carbon, soil_electrical_conductivity, nitrogen, potassium, phosphorus or pH
  4. croprotation, The crop rotation. Must be one of perennial, biennial or triennial
  5. landuse, Tha land use selected. Must be one of Woodland or Cropland or Grassland
  6. crop1, The crop of the previous year
  7. crop2, The crop of the two years ago
  8. crop3, The crop of the three years ago
  9. file_path_to_geojson, The goejson file related to the spatial location of the field (you can find it here county.geojson the county file of the example). Please submit a geojson with WGS 84 Coordinate Reference System.
Python
Load Libraries
import requests
import rasterio
import rasterio.plot
import folium
from rasterio.warp import calculate_default_transform, reproject, Resampling
from requests.auth import HTTPBasicAuth
Setting of the API
# Define the vegetation index that you want

fieldnumber="1"
action="new"
nutrient="organic_carbon"
croprotation="biennial"
landuse="Cropland"
crop1="Sunflower"
crop2="Durum_wheat"
crop3="Sunflower"

# Define the url of the API

api_url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapTiffNew?fieldnumber="+fieldnumber+"&action="+action+"&nutrient="+nutrient+"&croprotation="+croprotation+"&landuse="+landuse+"&crop1="+crop1+"&crop2="+crop2+"&crop3="+crop3

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Set the geojson file to send
geojson_file_path = "county.geojson"
Define python function
def convert_to_wgs84(input_raster_path, output_raster_path):
    # Open the input raster
    with rasterio.open(input_raster_path) as src:
        # Define the target CRS (WGS 84 - EPSG:4326)
        target_crs = 'EPSG:4326'

        # Get the affine transformation and dimensions of the new raster
        transform, width, height = calculate_default_transform(src.crs, target_crs, src.width, src.height, *src.bounds)

        # Create the options for reprojection
        kwargs = src.meta.copy()
        kwargs.update({
            'crs': target_crs,
            'transform': transform,
            'width': width,
            'height': height
        })

        # Reproject the raster to WGS 84
        with rasterio.open(output_raster_path, 'w', **kwargs) as dst:
            for i in range(1, src.count + 1):
                reproject(
                    source=rasterio.band(src, i),
                    destination=rasterio.band(dst, i),
                    src_transform=src.transform,
                    src_crs=src.crs,
                    dst_transform=transform,
                    dst_crs=target_crs,
                    resampling=Resampling.nearest
                )
def post_request_with_geojson(geojson_file_path, api_url):
    # Leggi il file GeoJSON
    with open(geojson_file_path, 'r') as file:
        geojson_data = file.read()

    # Specifica l'header per la POST request
    headers = {'Content-Type': 'application/json'}

    # Effettua la POST request
    response = requests.post(api_url, 
                             data=geojson_data, 
                             headers=headers,
                             auth=HTTPBasicAuth(USEREMAIL, APIKEY))
    
    if response.status_code == 200:
        # Save the response as a temporary raster file
        temp_raster_path = "temp_raster.tif"
        with open(temp_raster_path, 'wb') as temp_raster_file:
            temp_raster_file.write(response.content)

        # Convert the raster to WGS 84 (EPSG:4326)
        wgs84_raster_path = "temp_raster_wgs84.tif"
        convert_to_wgs84(temp_raster_path, wgs84_raster_path)

        # Open the WGS 84 raster using rasterio
        wgs84_raster = rasterio.open(wgs84_raster_path)

        # Read the image as a numpy array
        data = wgs84_raster.read(1)

        # Get the extent of the image
        xmin, ymin, xmax, ymax = wgs84_raster.bounds

        # Create a folium map centered at the center of the extent of the image
        center = [(ymin+ymax)/2, (xmin+xmax)/2]
        m = folium.Map(location=center, zoom_start=16)

        # Add the tif file as a raster layer
        overlay = folium.raster_layers.ImageOverlay(
            image=data,
            bounds=[[ymin, xmin], [ymax, xmax]],
            colormap=lambda x: (0, 0, 0, x/255),
            mercator_project=True)
        
        overlay.add_to(m)

        # Visualize the map
        return m
    else:
        print("Error during the request.")
        return None
# Make the POST request
m = post_request_with_geojson(geojson_file_path, api_url)

# Visualize the results

m
R
library(tictoc)
library(httr)
library(gt)
library(tidyverse)
library(raster)
library(mapview)

# Define the API parameters setting

fieldnumber="1"
action="new"
nutrient="organic_carbon"
croprotation="biennial"
landuse="Cropland"
crop1="Sunflower"
crop2="Durum_wheat"
crop3="Sunflower"

# Define the url of the API

api_url <- paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapTiffNew?fieldnumber=",fieldnumber,"&action=",action,"&nutrient=",nutrient,"&croprotation=",croprotation,"&landuse=",landuse,"&crop1=",crop1,"&crop2=",crop2,"&crop3=",crop3)

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Path to the GeoJSON file

file_path_to_geojson = "county.geojson"

# Get the start time to API Call

tic()

# Make the POST request

r <- POST(
  api_url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  ),
  body=httr::upload_file(file_path_to_geojson)
)

# Print out the seconds needed to get the satellite image

print("The API needed:")
toc()

# Get the status of the request

httr::status_code(r)

# Visulize the vegetation index

bin_raster<-readBin(r$content, what = "raw", n=length(r$content))

writeBin(bin_raster, con = "raster.tif")

raster <- raster::raster("raster.tif")

mapview(raster, layer.name="Soil Organic Map")
Node.js
// load libraries

const axios = require('axios');
const fs = require('fs');

// Set the username & API key
const username = "XXXXXXXXX";
const password = "XXXXXXXXX";

// Set the API parameter
const fieldnumber="1";
const action="new";
const nutrient="organic_carbon";
const croprotation="biennial";
const landuse="Cropland";
const crop1="Sunflower";
const crop2="Durum_wheat";
const crop3="Sunflower";

// Set api endpoint

const apiUrl = 'https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapTiffNew?';

// Set api endpoint that we will use

const apiendpoint=apiUrl.concat("fieldnumber=",fieldnumber,"&action=",action,"&nutrient=",nutrient, "&croprotation=", croprotation, "&landuse=",landuse,"&crop1=",crop1, "&crop2=",crop2, "&crop3=",crop3)

// Set the path to the local GeoJson that you want to use

const geojsonFilePath = './county.geojson';


// Set the path to save the raster that we will recive
const rasterFilePath = './file.tif';

async function makePostRequest() {

  const geojsonFile = fs.readFileSync(geojsonFilePath, 'utf8');

  const authHeader = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');

  try {
    const response = await axios.post(apiendpoint, geojsonFile, {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': authHeader,
      },
      responseType: 'arraybuffer',
    });
    
    fs.writeFileSync(rasterFilePath, response.data);

    console.log('The raster file was locally saved', rasterFilePath);
  } catch (error) {
    console.error('An error occurred:', error.message);
  }
}

makePostRequest();
Java

Work In Progress

SoilMapGeojson

This endpoint allow you to get the soil map of the nutrient requested in geojson file format.

In order to use it, you must define the following parameter:

  1. fieldnumber, The field number. You have to refereed to the field that you can get from the gid column of the UserField endpoint response
  2. action, the action must be setted as none, new, edit. If you want to receive the data based on the polygons saved in the past set none. If you want to add a new field set as new. If you want to change the shape of the polygons set edit.
  3. nutrient, The soil chemical component that you want to get. Must be one of carbonates, organic_carbon, soil_electrical_conductivity, nitrogen, potassium, phosphorus or pH
  4. croprotation, The crop rotation. Must be one of perennial, biennial or triennial
  5. landuse, Tha land use selected. Must be one of Woodland or Cropland or Grassland
  6. crop1, The crop of the previous year
  7. crop2, The crop of the two years ago
  8. crop3, The crop of the three years ago
  9. file_path_to_geojson, The goejson file related to the spatial location of the field (you can find it here county.geojson the county file of the example). Please submit a geojson with WGS 84 Coordinate Reference System.
Python
# Load the libraries

import requests
import fiona
import geopandas as gpd
from requests.auth import HTTPBasicAuth

# Define the API call parameters

fieldnumber="1"
action="new"
nutrient="organic_carbon"
croprotation="biennial"
landuse="Cropland"
crop1="Sunflower"
crop2="Durum_wheat"
crop3="Sunflower"

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapGeojsonNew?fieldnumber="+fieldnumber+"&action="+action+"&nutrient="+nutrient+"&croprotation="+croprotation+"&landuse="+landuse+"&crop1="+crop1+"&crop2="+crop2+"&crop3="+crop3


# Set the useremail & Password

USEREMAIL="email"
APIKEY="password"

# Path to the GeoJSON file

file_path_to_geojson = "county.geojson"

# Read the GeoJSON file contents

with open(file_path_to_geojson, "r") as file:
    geojson_data = file.read()

# Set the headers for the request

headers = {
    "Content-Type": "application/json"
}

# Make the POST request with the GeoJSON data as the request body

response = requests.post(url, 
                         data=geojson_data, 
                         headers=headers,
                         auth=HTTPBasicAuth(USEREMAIL, APIKEY))

b = bytes(response.content)

with fiona.BytesCollection(b) as f:
    crs = f.crs
    gdf = gpd.GeoDataFrame.from_features(f, crs=crs)

#  Visualize the data

gdf.explore("X2022")
R
library(tictoc)
library(httr)
library(geojsonio)
library(mapview)

# Define the API call parameters

fieldnumber="1"
action="new"
nutrient="organic_carbon"
croprotation="biennial"
landuse="Cropland"
crop1="Sunflower"
crop2="Durum_wheat"
crop3="Sunflower"
  
# Define the url of the API

url = paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapGeojsonNew?fieldnumber=", fieldnumber, "&action=",action,"&nutrient=",
             nutrient,
             "&croprotation=",croprotation,
             "&landuse=", landuse,
             "&crop1=",crop1 ,
             "&crop2=", crop2,
             "&crop3=", crop3)

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Path to the GeoJSON file

file_path_to_geojson = "county.geojson"

# Get the start time to API Call

tic()

# Make the POST request

api_call <- POST(
  url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  ),
  body=httr::upload_file(file_path_to_geojson)
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
toc()

# Print out the status_code of the request
api_call$status_code

# Visualize the prescription map

soilmap <- content(api_call, as = "text", type = "application/geo+json")
soilmap<-geojson_sp(soilmap)
mapview(soilmap, 
        layer.name=paste0("Soil Organic Carbon - ", str_replace(names(soilmap)[1], "X", "")), 
        zcol=names(soilmap)[1])
Node.js
// Load Libraries

const fs = require('fs');
const axios = require('axios');

// Set the useremail & passowrd

const useremail = 'XXXXXXXXXXXXX';
const apikey = 'XXXXXXXXXXXXX';

// Set the API Parameter

const fieldnumber="1";
const action="new";
const nutrient="organic_carbon";
const croprotation="biennial";
const landuse="Cropland";
const crop1="Sunflower";
const crop2="Durum_wheat";
const crop3="Sunflower";

// Set API Url

const api_url='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapGeojsonNew?fieldnumber=';

// Set endpoint Url

const apiEndpoint = api_url.concat(fieldnumber,"&action=",action,"&nutrient=",nutrient, "&croprotation=",croprotation, "&landuse=", landuse, "&crop1=", crop1, "&crop2=", crop2, "&crop3=", crop3);

// Set path to load the geojson to send as body of POST request to the API

const file_path_to_geojson = './county.geojson';

// Set path to save the geojson prescription map

const outputFilePath = './result.geojson'; 

(async () => {
  try {

    const geojsonContent = await fs.promises.readFile(file_path_to_geojson, 'utf8');
    
    const geojsonObject = JSON.parse(geojsonContent);

    
    const authHeader = `Basic ${Buffer.from(`${useremail}:${apikey}`).toString('base64')}`;

    
    const response = await axios.post(apiEndpoint, geojsonObject, {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': authHeader
      }
    });

    const resultGeoJSON = response.data;
    
    console.log('Answer From the API:', resultGeoJSON);

    await fs.promises.writeFile(outputFilePath, JSON.stringify(resultGeoJSON, null, 2), 'utf8');

  } catch (err) {
    console.error('Error:', err.message);
  }
})();
Java

Work In Progress

SoilMapHtml

This endpoint allow you to get the soil map of the nutrient requested in a leaflet colored map html file format.

In order to use it, you must define the following parameter:

  1. fieldnumber, The field number. You have to refereed to the field that you can get from the gid column of the UserField endpoint response
  2. action, the action must be setted as none, new, edit. If you want to receive the data based on the polygons saved in the past set none. If you want to add a new field set as new. If you want to change the shape of the polygons set edit.
  3. nutrient, The soil chemical component that you want to get. Must be one of carbonates, organic_carbon, soil_electrical_conductivity, nitrogen, potassium, phosphorus or pH
  4. croprotation, The crop rotation. Must be one of perennial, biennial or triennial
  5. landuse, Tha land use selected. Must be one of Woodland or Cropland or Grassland
  6. crop1, The crop of the previous year
  7. crop2, The crop of the two years ago
  8. crop3, The crop of the three years ago
  9. initialmap The name of the base map you wuould like to display disrt (could be one of CartNormal, CartoDark, EsriWorldImagery, OpenTopoMap)
  10. basemap, Parameter that allows you to determine whether to receive every base map or receive only the base map selected with the initialmap parameter. Must be setted as one for just the selected basemap, or all to get all the base maps.
  11. file_path_to_geojson, The goejson file related to the spatial location of the field (you can find it here county.geojson the county file of the example). Please submit a geojson with WGS 84 Coordinate Reference System.
Python
# Import libraries

import requests
import webbrowser
import json

# Define the API call parameters

fieldnumber="1"
action="new"
nutrient="organic_carbon"
croprotation="biennial"
landuse="Cropland"
crop1="Sunflower"
crop2="Durum_wheat"
crop3="Sunflower"
initialmap="EsriWorldImagery"
basemap="one"

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapHtmlNew?fieldnumber="+fieldnumber+"&action="+action+"&nutrient="+nutrient+"&croprotation="+croprotation+"&landuse="+landuse+"&crop1="+crop1+"&crop2="+crop2+"&crop3="+crop3+ "&initialmap="+ initialmap+"&basemap="+basemap

# Set the path to the geojson
geojson = "county.geojson"

# Set username & password

USERNAME="XXXXXXXXXXXX"
PASSWORD="XXXXXXXXXXXX"

# Set the authentication header
auth_data = {
    "username": USERNAME,
    "password": PASSWORD
}

# Read the content of geojson
with open(geojson, "r") as file:
    geojson_data = json.load(file)

# Make the POST request
response = requests.post(url, json=geojson_data, auth=(auth_data["username"], auth_data["password"]))

# Check the status of the response
if response.status_code == 200:
    # Save the content of the response to an HTML file
    with open("Response.html", "wb") as file:
        file.write(response.content)
    
    # Open the HTML file in your default browser
    webbrowser.open("Response.html")
else:
    print(f"The request was unsuccessful. Status code: {response.status_code}")
R
library(httr)

# Define the API call parameters

fieldnumber="1"
action="new"
nutrient="organic_carbon"
croprotation="biennial"
landuse="Cropland"
crop1="Sunflower"
crop2="Durum_wheat"
crop3="Sunflower"
initialmap="EsriWorldImagery"
basemap="one"
  
# Define the url of the API

url = paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapHtmlNew?fieldnumber=",fieldnumber, "&action=",action,"&nutrient=",
             nutrient,
             "&croprotation=",croprotation,
             "&landuse=", landuse,
             "&crop1=",crop1 ,
             "&crop2=", crop2,
             "&crop3=", crop3,
             "&initialmap=",initialmap,
             "&basemap=",basemap)

# Set the path to geojson

geojson <- "county.geojson"

# Set username and password

USEREMAIL="useremail"
APIKEY="apikey"

# Make the post request

response <- POST(
  url,
  authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  ),
  body=upload_file(geojson)
)

# Get the status code of the response

status_code(response)

# Parse the response content
response_content <- content(response, as = "text")

# Write and show html file
writeLines(response_content,"soil_map_1.html")
Node.js

// load libraries
const express = require('express');
const axios = require('axios');
const fs = require('fs');

const app = express();
const PORT = process.env.PORT || 3000;

// Set the useremail & passowrd

const USERNAME = 'XXXXXXXXXXXXX';
const PASSWORD = 'XXXXXXXXXXXXX';

// Set the API Parameter

const fieldnumber="1";
const action="new";
const nutrient="organic_carbon";
const croprotation="biennial";
const landuse="Cropland";
const crop1="Sunflower";
const crop2="Durum_wheat";
const crop3="Sunflower";
const initialmap="EsriWorldImagery";
const basemap="one";

// Set API Url

const api_url='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapHtmlNew?fieldnumber=';

// Set endpoint Url

const apiEndpoint = api_url.concat(fieldnumber,"&action=",action, "&nutrient=",nutrient, "&croprotation=",croprotation, "&landuse=", landuse, "&crop1=", crop1, "&crop2=", crop2, "&crop3=", crop3, "&initialmap=", initialmap, "&basemap=", basemap);

app.get('/', async (req, res) => {
  try {
    // Read the GeoJSON file
    const geojson = fs.readFileSync("county.geojson", 'utf8');

    // Set up the authentication headers
    const authHeaders = {
      auth: {
        username: USERNAME,
        password: PASSWORD,
      },
    };

    // Perform the authenticated POST request
    const response = await axios.post(apiEndpoint, geojson, authHeaders);

    // Assuming the response data contains the HTML content
    const htmlContent = response.data;

    // Send the HTML content as the response
    res.send(htmlContent);
  } catch (error) {
    console.error('Error:', error);
    res.status(500).send('An error occurred');
  }
});

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});
Java

Work In Progress

SoilMapEcharts

This endpoint allow you to get the soil map of the nutrient requested in echarts html file format.

In order to use it, you must define the following parameter:

  1. fieldnumber, The field number. You have to refereed to the field that you can get from the gid column of the UserField endpoint response
  2. action, the action must be setted as none, new, edit. If you want to receive the data based on the polygons saved in the past set none. If you want to add a new field set as new. If you want to change the shape of the polygons set edit.
  3. nutrient, The soil chemical component that you want to get. Must be one of carbonates, organic_carbon, soil_electrical_conductivity, nitrogen, potassium, phosphorus or pH
  4. croprotation, The crop rotation. Must be one of perennial, biennial or triennial
  5. landuse, Tha land use selected. Must be one of Woodland or Cropland or Grassland
  6. crop1, The crop of the previous year
  7. crop2, The crop of the two years ago
  8. crop3, The crop of the three years ago
  9. file_path_to_geojson, The goejson file related to the spatial location of the field (you can find it here county.geojson the county file of the example). Please submit a geojson with WGS 84 Coordinate Reference System.
Python
# Import libraries

import requests
import webbrowser
import json

# Define the API call parameters

fieldnumber="1"
action="new"
nutrient="organic_carbon"
croprotation="biennial"
landuse="Cropland"
crop1="Sunflower"
crop2="Durum_wheat"
crop3="Sunflower"

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapEchartsNew?fieldnumber="+fieldnumber+"&action="+action+"&nutrient="+nutrient+"&croprotation="+croprotation+"&landuse="+landuse+"&crop1="+crop1+"&crop2="+crop2+"&crop3="+crop3

# Set the path to the geojson
geojson = "county.geojson"

# Set username & password

USERNAME="XXXXXX"
PASSWORD="XXXXXX"

# Set the authentication header
auth_data = {
    "username": USERNAME,
    "password": PASSWORD
}

# Read the content of geojson
with open(geojson, "r") as file:
    geojson_data = json.load(file)

# Make the POST request
response = requests.post(url, json=geojson_data, auth=(auth_data["username"], auth_data["password"]))

# Check the status of the response
if response.status_code == 200:
    # Save the content of the response to an HTML file
    with open("Response.html", "wb") as file:
        file.write(response.content)
    
    # Open the HTML file in your default browser
    webbrowser.open("Response.html")
else:
    print(f"The request was unsuccessful. Status code: {response.status_code}")
R
# Load libraries 
library(httr)

# Define the API call parameters

fieldnumber="1"
action="new"
nutrient="organic_carbon"
croprotation="biennial"
landuse="Cropland"
crop1="Sunflower"
crop2="Durum_wheat"
crop3="Sunflower"
  
# Define the url of the API

url = paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapEchartsNew?fieldnumber=",fieldnumber, "&action=",action, "&nutrient=",
             nutrient,
             "&croprotation=",croprotation,
             "&landuse=", landuse,
             "&crop1=",crop1 ,
             "&crop2=", crop2,
             "&crop3=", crop3)

# Set the path to geojson

geojson <- "county.geojson"

# Set username and password

USERNAME="useremail"
PASSWORD="apikey"

# Make the post request

response <- POST(
  url,
  authenticate(
    user = Sys.getenv(USERNAME),
    password = Sys.getenv(PASSWORD)
  ),
  body=upload_file(geojson)
)

# Get the status code of the response

status_code(response)

# Parse the response content
response_content <- content(response, as = "text")

# Write and show html file
writeLines(response_content,"soil_map_echart.html")
Node.js
// load libraries

const express = require('express');
const axios = require('axios');
const fs = require('fs');

const app = express();
const PORT = process.env.PORT || 3000;

// Set the API Parameter

const fieldnumber="1";
const action="new";
const nutrient="organic_carbon";
const croprotation="biennial";
const landuse="Cropland";
const crop1="Sunflower";
const crop2="Durum_wheat";
const crop3="Sunflower";

// Set API Url

const api_url='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapEchartsNew?fieldnumber=';

// Set endpoint Url

const apiEndpoint = api_url.concat(fieldnumber,"&action=",action, "&nutrient=",nutrient, "&croprotation=",croprotation, "&landuse=", landuse, "&crop1=", crop1, "&crop2=", crop2, "&crop3=", crop3);


// set username and password

const USERNAME = 'XXXXXXXXXXXX';
const PASSWORD = 'XXXXXXXXXXXX';

app.get('/', async (req, res) => {
  try {
    // Read the GeoJSON file
    const geojson = fs.readFileSync("county.geojson", 'utf8');

    // Set up the authentication headers
    const authHeaders = {
      auth: {
        username: USERNAME,
        password: PASSWORD,
      },
    };

    // Perform the authenticated POST request
    const response = await axios.post(apiEndpoint, geojson, authHeaders);

    // Assuming the response data contains the HTML content
    const htmlContent = response.data;

    // Send the HTML content as the response
    res.send(htmlContent);
  } catch (error) {
    console.error('Error:', error);
    res.status(500).send('An error occurred');
  }
});

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});
Java

Work In Progress

SoilMapTemporalVariationJson

This endpoint allow you to get the soil map of the nutrient requested in json file format.

In order to use it, you must define the following parameter:

  1. fieldnumber, The field number. You have to refereed to the field that you can get from the gid column of the UserField endpoint response
  2. action, the action must be setted as none, new, edit. If you want to receive the data based on the polygons saved in the past set none. If you want to add a new field set as new. If you want to change the shape of the polygons set edit.
  3. nutrient, The soil chemical component that you want to get. Must be one of carbonates, organic_carbon, soil_electrical_conductivity, nitrogen, potassium, phosphorus or pH
  4. croprotation, The crop rotation. Must be one of perennial, biennial or triennial
  5. landuse, Tha land use selected. Must be one of Woodland or Cropland or Grassland
  6. crop1, The crop of the previous year
  7. crop2, The crop of the two years ago
  8. crop3, The crop of the three years ago
  9. file_path_to_geojson, The goejson file related to the spatial location of the field (you can find it here county.geojson the county file of the example). Please submit a geojson with WGS 84 Coordinate Reference System.
Python
# Load the libraries

import requests
import json
import pandas as pd
from requests.auth import HTTPBasicAuth

# Define the API parameter

fieldnumber="1"
action="new"
nutrient="organic_carbon"
croprotation="biennial"
landuse="Cropland"
crop1="Sunflower"
crop2="Durum_wheat"
crop3="Sunflower"

# Define the url of the API

url = "https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapTemporalVariationJsonNew?fieldnumber="+fieldnumber+"&action="action+"&nutrient="+nutrient+"&croprotation="+croprotation+"&landuse="+landuse+"&crop1="+crop1+"&crop2="+crop2+"&crop3="+crop3

# Set the useremail & Password

USEREMAIL="XXXXXXXXXXXX"
APIKEY="XXXXXXX"

# Path to the GeoJSON file

file_path_to_geojson = "county.geojson"

# Read the GeoJSON file contents

with open(file_path_to_geojson, "r") as file:
    geojson_data = file.read()

# Set the headers for the request

headers = {
    "Content-Type": "application/json"
}

# Make the POST request with the GeoJSON data as the request body

response = requests.post(url, 
                         data=geojson_data, 
                         headers=headers,
                         auth=HTTPBasicAuth(USEREMAIL, APIKEY))

response_bytes=response.content

response_str = response_bytes.decode('utf-8')

# Parse the JSON string
data = json.loads(response_str)

# Create a DataFrame
df = pd.DataFrame(data)

df.head()
R
# Load the libraries

library(tictoc)
library(httr)
library(geojsonio)
library(mapview)

# Define the API call parameters

fieldnumber="1"
action="new"
nutrient="organic_carbon"
croprotation="biennial"
landuse="Cropland"
crop1="Sunflower"
crop2="Durum_wheat"
crop3="Sunflower"
  
# Define the url of the API

url = paste0("https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapTemporalVariationJsonNew?fieldnumber=",fieldnumber,"&action=",action,"&nutrient=",
             nutrient,
             "&croprotation=",croprotation,
             "&landuse=", landuse,
             "&crop1=",crop1 ,
             "&crop2=", crop2,
             "&crop3=", crop3)

# Set the useremail & Password

USEREMAIL="useremail"
APIKEY="apikey"

# Path to the GeoJSON file

file_path_to_geojson = "county.geojson"

# Get the start time to API Call

tic()

# Make the POST request

api_call <- POST(
  url,
  httr::authenticate(
    user = Sys.getenv(USEREMAIL),
    password = Sys.getenv(APIKEY)
  ),
  body=httr::upload_file(file_path_to_geojson)
)

# Print out the seconds needed to create the prescription map

print("The API needed:")
toc()

# Visualize the prescription map
cont <- httr::content(api_call, as = "text", type = "application/json", encoding="UTF-8")
cont<-jsonlite::fromJSON(cont) %>% as.data.frame
cont
Node.js
// Load Libraries

const fs = require('fs');
const axios = require('axios');


// set the username and apikey
const useremail = 'XXXXXXXXXXXX';
const apikey = 'XXXXXXXXXXXX';

// set the api parameters

const fieldnumber="1";
const action="new";
const nutrient="organic_carbon";
const croprotation="biennial";
const landuse="Cropland";
const crop1="Sunflower";
const crop2="Durum_wheat";
const crop3="Sunflower";

// Set API Url

const api_url='https://www.api.automaticfarmsolutionwebapp.com/AFS/SoilMapTemporalVariationJsonNew?fieldnumber=';

// Set endpoint Url

const apiEndpoint = api_url.concat(fieldnumber, "&action=", action, "&nutrient=",nutrient, "&croprotation=",croprotation, "&landuse=", landuse, "&crop1=", crop1, "&crop2=", crop2, "&crop3=", crop3);

const file_path_to_geojson = './county.geojson';

async function main() {
  try {
    const geojson = JSON.parse(fs.readFileSync(file_path_to_geojson, 'utf8'));
    const authHeader = `Basic ${Buffer.from(`${useremail}:${apikey}`).toString('base64')}`;

    const response = await axios.post(apiEndpoint, geojson, {
      headers: {
        Authorization: authHeader,
        'Content-Type': 'application/json',
      },
    });

    // Print the formatted JSON response to the console
    console.log(JSON.stringify(response.data, null, 2));
  } catch (error) {
    console.error('An error occurred:', error.message);
  }
}

main();
Java

Work In Progress

Easy - Fast - Customizable

Back to top