A how-to guide on displaying geospatial data with Postman
In this blog post, we'll explore how to use Postman's Visualizer to display geographic data on a map using Leaflet. We'll transform Naurt GeoJSON responses into interactive maps directly within Postman, providing a powerful way to visualize data. Follow along as we walk through each step of this process.
What You'll Need
The Postman Visualizer provides a programmable way to visually represent your request responses. Visualization code added to the Tests/Scripts for a request will render in the Visualize tab for the response body, alongside the Pretty, Raw, and Preview options. The official guide has a lot of examples, but one for plotting a Geojson is still not there.
Ensure that your API returns a JSON response with GeoJSON data. Here, we are using Naurt*-A Geocoder for Last Mile Delivery* in this example.
Try Naurt, If you haven’t already, sign up at Naurt’s dashboard for a free key. The free key comes loaded with thousands of API requests per month, so there’s no cost to try it out. We don’t require a credit card for sign up either!
API details are available at our official documentation and for easy access, use our postman collection. Here's a sample response structure:
1{
2 "best_match": Optional<DESTINATION RESPONSE FORMAT>,
3 "additional_matches": Optional<List<DESTINATION RESPONSE FORMAT>>,
4 "version": Optional<String>
5}
You will only have an additional_matches
field if you set additional_matches
to true in the request.
The DESTINATION RESPONSE FORMAT
is
1{
2 "id": String,
3 "address": String,
4 "geojson": GeoJSON,
5 "distance": Optional<float>
6}
Postman’s Visualizer allows you to render custom visualizations based on your API responses. Here's how to integrate Leaflet with Postman Visualizer:
1// Extract the JSON response
2const responseData = pm.response.json();
3
4// Check if the response contains the expected data structure
5if (responseData && responseData.best_match && responseData.best_match.geojson) {
6 const geojsonData = responseData.best_match.geojson;
7
8pm.visualizer.set(`
9<!DOCTYPE html>
10<html>
11<head>
12 <title>Naurt Geocoder</title>
13 <meta charset="utf-8" />
14 <meta name="viewport" content="width=device-width, initial-scale=1.0">
15 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
16 <style>
17 #map {
18 height: 100vh;
19 margin: 0;
20 padding: 0;
21 border: none;
22 }
23 </style>
24</head>
25<body>
26 <div id="map"></div>
27 <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
28 <script>
29 function getColor(type) {
30 switch (type) {
31 case 'naurt_door': return '#FF0000';
32 case 'naurt_building': return '#9d79f2';
33 case 'naurt_parking': return '#00FF00';
34 default: return '#000000';
35 }
36 }
37
38 function style(feature) {
39 return {
40 fillColor: getColor(feature.properties.naurt_type),
41 weight: 2,
42 opacity: 1,
43 color: 'white',
44 dashArray: '5',
45 fillOpacity: 0.4
46 };
47 }
48
49 function onEachFeatureCurry(address) {
50 return function onEachFeature(feature, layer) {
51 if (feature.properties) {
52 var popupContent = 'Type: ' + feature.properties.naurt_type;
53 if (feature.properties.naurt_type === 'naurt_building') {
54 popupContent += '<br>Address: ' + address;
55 }
56 layer.bindPopup(popupContent).openPopup();
57 }
58 };
59 }
60
61 var map = L.map('map').setView([0, 0], 14); // Adjust zoom level for faster initial load
62 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
63 maxZoom: 19,
64 attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
65 }).addTo(map);
66
67 var response = ${JSON.stringify(responseData)};
68
69 L.geoJSON(response.best_match.geojson, {
70 style: style,
71 onEachFeature: onEachFeatureCurry(response.best_match.address)
72 }).addTo(map);
73
74 if ("additional_matches" in response) {
75 for (const additionalMatch of response.additional_matches) {
76 L.geoJSON(additionalMatch.geojson, {
77 style: style,
78 onEachFeature: onEachFeatureCurry(additionalMatch.address)
79 }).addTo(map);
80 }
81 }
82
83 var bounds = L.geoJSON(response.best_match.geojson).getBounds();
84 map.fitBounds(bounds);
85 </script>
86</body>
87</html>
88`);
89} else {
90 pm.visualizer.set(`<p>GeoJSON data not available in the response.</p>`);
91}
92
This gives you the required visualization:
You can play around using our postman collection, where different examples and scenarios are listed and the visualization is enabled by default. The geojson visualizer folder has some samples that can be tried out readily, which uses the postman echo API with Naurt response.
The visualization script is added at the top level, thereby available to all the requests in the collection. Try them and see the results, both JSON and plot wise.
<div id="map"></div>
This div
serves as the container where the map will be displayed. The map is initialized within this element.
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
The external Leaflet CSS and JavaScript libraries are included to provide the map functionality.
var map = L.map('map').setView([0, 0], 14);
Initializes the map within the map
div, setting the default view to coordinates [0, 0]
with a zoom level of 14
.
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap contributors'
}).addTo(map);
Adds a tile layer from OpenStreetMap, which acts as the base map that displays geographical features.
const responseData = pm.response.json();
Retrieves the JSON response data from Postman to be used in the visualization.
var response = ${JSON.stringify(responseData)};
L.geoJSON(response.best_match.geojson, {
style: style,
onEachFeature: onEachFeatureCurry(response.best_match.address)
}).addTo(map);
Renders the best_match
GeoJSON data onto the map, applying specific styles and popups for each feature.
if ("additional_matches" in response) {
for (const additionalMatch of response.additional_matches) {
L.geoJSON(additionalMatch.geojson, {
style: style,
onEachFeature: onEachFeatureCurry(additionalMatch.address)
}).addTo(map);
}
}
Loops through any additional_matches
in the response and renders them on the map similarly to best_match
.
map.fitBounds(L.geoJSON(response["best_match"]["geojson"]).getBounds());
Adjusts the map's view to fit the bounds of the best_match
GeoJSON data, ensuring all features are visible.
By leveraging Postman’s Visualizer and Leaflet, you can transform API responses into interactive maps for better data insights and analysis. This approach enhances your API testing and visualization workflows, making complex geographic data more accessible and understandable.
Feel free to adapt and expand upon this template based on your specific needs and data structures!
You can view the whole code and many more examples on Naurt’s GitHub.