GPS Visualizer to Upload Data and Visualize GPS Maps for Arduino, ESP32 & other Embedded Devices

Published  January 23, 2025   0
Free IoT-based GPS Tracking Map

We at CircuitDigest have built a lot of IoT Projects, but when working with IoT-based GPS projects, visualizing the GPS data on a Map often requires using a paid service or building a dedicated server. Developing a robust system for capturing, storing, and visualizing GPS data is not always feasible for every individual or early-stage developer. An ideal solution here, would be an API that manages all the visualization tasks, where we only need to send the coordinates, and the API itself stores the data in a database and plots the coordinates as a well-presented GPS Map.

This is where the CircuitDigest Cloud GeoLinker API steps in, offering a free, ready-to-use solution that simplifies GPS data handling. This API is built to work with commonly used embedded development boards like Arduino, ESP32, ESP8266, NodeMCU, Raspberry Pi or any embedded SOC or SOM modules. This API will get geo-coordinates from embedded devices, store them in a database, and plot them on a map with routes and timestamps. In this tutorial, we will learn how to upload GPS data and build a GPS Visualizer map for your GPS tracking projects. 

What is CircuitDigest Cloud?

Circuit Digest Cloud Features

CircuitDigest Cloud is an initiative aimed at empowering engineers, makers, and hobbyists with essential tools for rapid prototyping. In addition to the GeoLinker API, we also offer other useful APIs, such as QR Code Scanning, License Plate Recognition and SMS API, for those interested in expanding their projects. 

How to use GeoLinker to Visualize GPS Maps?

To use this CircuitDigest Cloud GeoLinker API or Any other API by CircuitDigest Cloud, you need an Account in CircuitDigest.Cloud. First let's create an account.

Logging in to the Circuit Digest Cloud

Generating API

Step 1: Visit the Circuit Digest.Cloud Home Page. Click the "Login" button located at the top right corner to be redirected to the login page.

Step 2: If you already have an account, log in using your existing credentials. If not, go to the registration page to create an account by filling in the required details. Once completed, click "Register Now" to sign up.

Step 3: After registering, use your email ID and password to log in on the login page.

Next, Step is to generate the API Key.

Generating API Key

Generating API Key

Step 4: Once logged in, click on "My Account" at the top right corner.

Step 5: You will be directed to a page where you can generate your API Key. Enter the captcha text in the provided box, then click the "Submit" button.

Step 6: If the captcha is correct, you'll see a table displaying your API Key along with its expiration date and usage count. 
Currently, there is a limit of 100 uses per key. Once you reach this limit, you can generate another key, giving you an additional 100 uses. This usage limit is in place to prevent server overload.

API EndPoint

Base URL: https://www.circuitdigest.cloud/geolinker

HTTP Method: POST

Query Parameters:

  • timestamp: The timestamp of the location.  (e.g., "24_01_01 T:24:35")

  • lat: Latitude coordinates (e.g., 11.01080667)

  • long: Longitude coordinates (e.g., 77.01325)

Headers:

  • Authorization: API key for secure access (e.g., "rBVR0iKt0soY")

  • content-Type: application/json

Request Body:

{
   "timestamp": ["timestamp1", "timestamp2", ...],
   "lat": [lat1, lat2, ...],
   "long": [long1, long2, ...]
}

Response

Success Responses: 201- Created

  • Message: New API key added and data inserted

  • Description: The request was successful, a new record for the API key was added to the database with the provided data.

Success Responses: 200- OK

  • Message: Data appended to an existing API key

  • Description: The request was successful, and the data was appended to an existing record associated with the provided API key.

Error Responses: 400- Bad Request

  • Message: Invalid payload, missing keys

  • Description: The client request is missing the required keys (timestamp, lat, or long) in the payload.

Error Responses: 500- Internal Server Error

  • Message: Internal Server Error

  • Description: There was an unexpected error while processing the data, such as a database issue or an exception during execution.

Acceptable Payload Format

{
 "timestamp": ["2025-01-09T12:30:45Z", "2025-01-09T12:31:45Z"], 
 "lat": [12.971598, 12.972341], 
 "long": [77.594566, 77.595123]
}

timestamp:

  • Type: Array of strings.

  • Format: ISO 8601 DateTime format (YYYY-MM-DDTHH:MM:SSZ).

  • Description: A list of timestamps corresponding to the data points.

lat (Latitude):

  • Type: Array of floats.

  • Range: -90.0 to +90.0.

  • Description: A list of latitude values for the locations.

long (Longitude):

  • Type: Array of floats.

  • Range: -180.0 to +180.0.

  • Description: A list of longitude values for the locations.

Example Explanation

  • timestamp: Represents the time when the data point was recorded.

  • lat and long: Represent the latitude and longitude coordinates for the data points.

Validation Rules:

  • All keys (timestamp, lat, long) must be present in the payload.

  • All arrays must be of the same length to maintain a one-to-one relationship between timestamps, latitudes, and longitudes.

GeoLinker - Quickstart code using Python

If you just want to test the API quickly and explore how you can send GPS data to GeoLinker and plot it on a map you can check out this Python code on Google Colab.  In this Python code, make sure you change the authorization header (shown below as "XXXX") with your own API key from the CircuitDigest Cloud Profile page

# Define the headers and data
headers = {
   "Authorization": "XXXXX"  # Replace with your API key
}

The Python code by default has dummy GPS data (shown below) for you to test under the payload variable. You can use the same or provide your own GPS coordinates for testing. If you are changing the payload data, make sure the number of entries in "lat" is the same as the number of entries in "long". 

payload = {
   "timestamp": [
       "24_01_01 T:24:35", "24_01_02 T:24:35", "24_01_03 T:24:35", "24_01_04 T:24:35", "24_01_05 T:24:35", "24_01_06 T:24:35", "24_01_07 T:24:35",
       "24_01_08 T:24:35", "24_01_09 T:24:35", "24_01_10 T:24:35", "24_01_11 T:24:35", "24_01_12 T:24:35", "24_01_13 T:24:35", "24_01_14 T:24:35",
       "24_01_15 T:24:35", "24_01_16 T:24:35", "24_01_17 T:24:35", "24_01_18 T:24:35", "24_01_19 T:24:35", "24_01_20 T:24:35", "24_01_21 T:24:35",
       "24_01_22 T:24:35", "24_01_23 T:24:35", "24_01_24 T:24:35", "24_01_25 T:24:35", "24_01_26 T:24:35", "24_01_27 T:24:35", "24_01_28 T:24:35",
       "24_01_29 T:24:35", "24_01_30 T:24:35", "24_01_31 T:24:35", "24_01_32 T:24:35", "24_01_33 T:24:35", "24_01_34 T:24:35", "24_01_35 T:24:35",
       "24_01_36 T:24:35", "24_01_37 T:24:35", "24_01_38 T:24:35", "24_01_39 T:24:35", "24_01_40 T:24:35", "24_01_41 T:24:35", "24_01_42 T:24:35",
       "24_01_43 T:24:35", "24_01_44 T:24:35", "24_01_45 T:24:35", "24_01_46 T:24:35", "24_01_47 T:24:35", "24_01_48 T:24:35", "24_01_49 T:24:35",
       "24_01_50 T:24:35", "24_01_51 T:24:35", "24_01_52 T:24:35", "24_01_53 T:24:35", "24_01_54 T:24:35", "24_01_55 T:24:35", "24_01_56 T:24:35",
       "24_01_57 T:24:35", "24_01_58 T:24:35", "24_01_59 T:24:35", "24_01_60 T:24:35", "24_01_61 T:24:35", "24_01_62 T:24:35", "24_01_63 T:24:35",
       "24_01_64 T:24:35", "24_01_65 T:24:35", "24_01_66 T:24:35", "24_01_67 T:24:35", "24_01_68 T:24:35", "24_01_69 T:24:35", "24_01_70 T:24:35",
       "24_01_71 T:24:35", "24_01_72 T:24:35"
   ],
   "lat": [
       11.01080667, 11.01088467, 11.010963, 11.01077117, 11.01094217, 11.01091617, 11.010047, 11.00880617, 11.00744267, 11.00716683, 11.00681483,
       11.00671833, 11.00711183, 11.00798117, 11.00793283, 11.00706233, 11.0064835, 11.00596267, 11.00544633, 11.005391, 11.00539567, 11.005282,
       11.00419583, 11.00282633, 11.002293, 11.00230733, 11.0033445, 11.0048425, 11.00565883, 11.0067245, 11.00782567, 11.00867717, 11.00929017,
       11.00913317, 11.00833483, 11.00781217, 11.00720117, 11.00662933, 11.00621167, 11.00516867, 11.00427883, 11.00321783, 11.00131133, 10.99948517,
       10.99774517, 10.997471, 10.99713783, 10.9972695, 10.99727717, 10.99731633, 10.997141, 10.99701317, 10.99706917, 10.99722633, 10.99739583,
       10.99763967, 10.99785783, 10.99804317, 10.99849567, 10.9995235, 11.0008315, 11.00248483, 11.004912, 11.00661833, 11.00704833, 11.00800933,
       11.0089635, 11.01070883, 11.01086517, 11.0109205, 11.0109435, 11.01103283
   ],
   "long": [
       77.01325, 77.0132685, 77.013264, 77.01326483, 77.01316867, 77.01313533, 77.01315133, 77.0134345, 77.01367467, 77.01380633, 77.01410633,
       77.012499, 77.010817, 77.0094135, 77.00850633, 77.00803867, 77.00858533, 77.0093725, 77.0089185, 77.00891083, 77.00892433, 77.008904,
       77.009288, 77.0097245, 77.00950167, 77.0096265, 77.00945533, 77.008958, 77.00846283, 77.007693, 77.00769167, 77.00753533, 77.0060975,
       77.00492067, 77.0029735, 77.0008695, 76.9989075, 76.99735517, 76.99564567, 76.9944295, 76.99340017, 76.9938975, 76.99451333, 76.99508083,
       76.99558933, 76.99569267, 76.99670533, 76.9980445, 76.99932517, 77.001588, 77.00380233, 77.00624183, 77.00751167, 77.00868217, 77.00982017,
       77.011584, 77.01344933, 77.01493317, 77.01576467, 77.01567067, 77.01556833, 77.01535033, 77.01511283, 77.01489667, 77.0141765, 77.01444067,
       77.01447317, 77.01437017, 77.013282, 77.01324467, 77.013234, 77.01321033
   ]
}

Once you are ready hit on the run button and if everything works as expected your GPS data will be sent to the cloud and your get a success message with status code 200 as shown in the below picture. Do note that once your GPS data reaches the cloud it will stay there until you reset the map, any new data you send again will be appended to your existing data, this way you can send your GPS data one by one at the required time intervals when your tracking an actual asset or object and everything will be stored in the cloud for your to visualize on map later. 

How to Use GeoLinker

Once your GPS data is uploaded to the cloud using your API key, you can visualize the map using this page, https://www.circuitdigest.cloud/gps-location-tracking-map just make sure that you have already signed into your account. If you have uploaded the sample payload data your result will look something like this. The purple pin indicates the last known location and each dark blue circle is your GPS points, you can cover on the points to look at the timestamp. You can also notice a table below the that lists all the GPS data you have updated to the cloud. 

GeoLinker GPS Location Tracking  Map

User interface: The geolinker map Page is more straight forward. There are three areas that need to be considered. 

  • The map - where you can see the plotted coordinates, and clicking on each points you can see the timestamp.

  • A Table section below the map - that can be used to see the data that is being sent from your device to the data base.

  • Reset Map Button at middle - can be used to delete all the map data that's been stored in the database, and  once done you will see no map, as there will be no data to plot the map.

No Data Message

If you are not able to use google colab for some reason, you can copy the below python code and use it on any preferred python development environment. 

import requests
# Define the API endpoint
url = "https://www.circuitdigest.cloud/geolinker"  # Replace with your actual server URL

# Define the headers and data
headers = {
   "Authorization": "xxxxxxxxxxxx"  # Replace with your desired API key
}

# Define the payload
payload = {
   "timestamp": [
       "24_01_01 T:24:35", "24_01_02 T:24:35", "24_01_03 T:24:35", "24_01_04 T:24:35", "24_01_05 T:24:35", "24_01_06 T:24:35", "24_01_07 T:24:35",
       "24_01_08 T:24:35", "24_01_09 T:24:35", "24_01_10 T:24:35", "24_01_11 T:24:35", "24_01_12 T:24:35", "24_01_13 T:24:35", "24_01_14 T:24:35",
       "24_01_15 T:24:35", "24_01_16 T:24:35", "24_01_17 T:24:35", "24_01_18 T:24:35", "24_01_19 T:24:35", "24_01_20 T:24:35", "24_01_21 T:24:35",
       "24_01_22 T:24:35", "24_01_23 T:24:35", "24_01_24 T:24:35", "24_01_25 T:24:35", "24_01_26 T:24:35", "24_01_27 T:24:35", "24_01_28 T:24:35",
       "24_01_29 T:24:35", "24_01_30 T:24:35", "24_01_31 T:24:35", "24_01_32 T:24:35", "24_01_33 T:24:35", "24_01_34 T:24:35", "24_01_35 T:24:35",
       "24_01_36 T:24:35", "24_01_37 T:24:35", "24_01_38 T:24:35", "24_01_39 T:24:35", "24_01_40 T:24:35", "24_01_41 T:24:35", "24_01_42 T:24:35",
       "24_01_43 T:24:35", "24_01_44 T:24:35", "24_01_45 T:24:35", "24_01_46 T:24:35", "24_01_47 T:24:35", "24_01_48 T:24:35", "24_01_49 T:24:35",
       "24_01_50 T:24:35", "24_01_51 T:24:35", "24_01_52 T:24:35", "24_01_53 T:24:35", "24_01_54 T:24:35", "24_01_55 T:24:35", "24_01_56 T:24:35",
       "24_01_57 T:24:35", "24_01_58 T:24:35", "24_01_59 T:24:35", "24_01_60 T:24:35", "24_01_61 T:24:35", "24_01_62 T:24:35", "24_01_63 T:24:35",
       "24_01_64 T:24:35", "24_01_65 T:24:35", "24_01_66 T:24:35", "24_01_67 T:24:35", "24_01_68 T:24:35", "24_01_69 T:24:35", "24_01_70 T:24:35",
       "24_01_71 T:24:35", "24_01_72 T:24:35"
   ],
   "lat": [
       11.01080667, 11.01088467, 11.010963, 11.01077117, 11.01094217, 11.01091617, 11.010047, 11.00880617, 11.00744267, 11.00716683, 11.00681483,
       11.00671833, 11.00711183, 11.00798117, 11.00793283, 11.00706233, 11.0064835, 11.00596267, 11.00544633, 11.005391, 11.00539567, 11.005282,
       11.00419583, 11.00282633, 11.002293, 11.00230733, 11.0033445, 11.0048425, 11.00565883, 11.0067245, 11.00782567, 11.00867717, 11.00929017,
       11.00913317, 11.00833483, 11.00781217, 11.00720117, 11.00662933, 11.00621167, 11.00516867, 11.00427883, 11.00321783, 11.00131133, 10.99948517,
       10.99774517, 10.997471, 10.99713783, 10.9972695, 10.99727717, 10.99731633, 10.997141, 10.99701317, 10.99706917, 10.99722633, 10.99739583,
       10.99763967, 10.99785783, 10.99804317, 10.99849567, 10.9995235, 11.0008315, 11.00248483, 11.004912, 11.00661833, 11.00704833, 11.00800933,
       11.0089635, 11.01070883, 11.01086517, 11.0109205, 11.0109435, 11.01103283
   ],
   "long": [
       77.01325, 77.0132685, 77.013264, 77.01326483, 77.01316867, 77.01313533, 77.01315133, 77.0134345, 77.01367467, 77.01380633, 77.01410633,
       77.012499, 77.010817, 77.0094135, 77.00850633, 77.00803867, 77.00858533, 77.0093725, 77.0089185, 77.00891083, 77.00892433, 77.008904,
       77.009288, 77.0097245, 77.00950167, 77.0096265, 77.00945533, 77.008958, 77.00846283, 77.007693, 77.00769167, 77.00753533, 77.0060975,
       77.00492067, 77.0029735, 77.0008695, 76.9989075, 76.99735517, 76.99564567, 76.9944295, 76.99340017, 76.9938975, 76.99451333, 76.99508083,
       76.99558933, 76.99569267, 76.99670533, 76.9980445, 76.99932517, 77.001588, 77.00380233, 77.00624183, 77.00751167, 77.00868217, 77.00982017,
       77.011584, 77.01344933, 77.01493317, 77.01576467, 77.01567067, 77.01556833, 77.01535033, 77.01511283, 77.01489667, 77.0141765, 77.01444067,
       77.01447317, 77.01437017, 77.013282, 77.01324467, 77.013234, 77.01321033
   ]
}


# Make a POST request
try:
   response = requests.post(url, headers=headers, json=payload)

   # Print the response
   print(f"Status Code: {response.status_code}")
   print("Response JSON:")
   print(response.json())
except requests.exceptions.RequestException as e:
   print(f"An error occurred: {e}")

 If you are having any trouble in getting this to work, please reach out to us using the comment section below or via our forums

Code Examples for Arduino, ESP32 & Other Boards

This API has been tested using the NEO-6M and NodeMCU but can be used with any development board capable of handling GPS data and connecting to the internet. We will be adding more projects that use the GeoLinker API, complete with all the circuit connections and code for your reference. Links below will be updated soon. 

  • Python Code for Testing the GeoLinker API

  • Location Tracker Using NodeMCU and GeoLinker API

Create and Share:

We hope this will be useful for quickly testing and deploying your ideas. If you build something using the API, please share it with us, and we will mention your work on this page. Happy building!

Have any question realated to this Article?

Ask Our Community Members