I'm trying to calculate the surface area of a building using the Overpass API, OpenStreetMap API, ReactJS. Here's the code:
import { useState, useEffect } from 'react';
import axios from 'axios';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css'; // Import Leaflet CSS
import 'leaflet/dist/leaflet-src.esm'; // Import Leaflet as ES module
import * as turf from '@turf/turf'; // Import turf library
const MapComponent = () => {
const [buildingData, setBuildingData] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
// Make a request to the Overpass API
const response = await axios.get('https://api.openstreetmap.org/api/interpreter');
setBuildingData(response.data);
} catch (error) {
console.error('Error fetching data:', error);
}
};
fetchData();
}, []); // Run once on component mount
const calculateArea = () => {
if (!buildingData || buildingData.features.length === 0) {
return { areaSquareMeters: 0, areaSquareKilometers: 0 };
}
// Assuming buildingData is in a suitable format, adjust accordingly
const osmCoordinates = buildingData.features[0].geometry.coordinates[0];
// Convert OSM coordinates to Leaflet-compatible coordinates
const leafletCoordinates = osmCoordinates.map(([lon, lat]) => [lat, lon]);
// Create a Leaflet map with a simple base layer
const map = L.map('map').setView([59.132659900251944, 9.727169813491393], 12);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}).addTo(map);
// Create a Leaflet polygon
const polygon = new L.Polygon(leafletCoordinates);
// Add the polygon to the map
polygon.addTo(map);
// Convert Leaflet polygon coordinates to GeoJSON format
const geoJsonPolygon = {
type: 'Polygon',
coordinates: [leafletCoordinates],
};
// Calculate the area using the turf library
const areaSquareMeters = turf.area(geoJsonPolygon);
return {
areaSquareMeters
};
};
const area = calculateArea();
return (
<div style={{ width: "100%", height: "100vh", display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column" }}>
<p>Area: {area.areaSquareMeters} square meters</p>
<div id="map" style={{ height: '500px', width: '500px', border: "3.2px solid red" }}></div>
</div>
);
};
export default MapComponent;
I'm expecting a map to show (id="map" container) but it doesn't, and the area outputs 0. I've figured out that the problem lies with the Overpass API Endpoint (https://api.openstreetmap.org/api/interpreter).
Is there a way to fix this?
You Component needs there change two items
API Endpoint: Later, you switched to using https://overpass-api.de/api/interpreter, which is specifically designed for complex and extensive queries on the OpenStreetMap database. And not
GET, should bePOSTcall.Query Format: The query format in Overpass QL was likely enhanced to include more specific parameters, filters, or bounding box coordinates to fetch more targeted data like buildings within a certain radius.
More documentation in here
Overpass QL
Overpass API Wiki
Overpass Turbo
Wrong URL
Correct URL
Body with
textformatDemo component
Save as 'MapComponent.js'
Result
The text "Area: 303102.35 square meters" represents This means that the total area covered by the buildings or features you queried is approximately 303,102.35 square meters. It's a quantitative measure of how much surface area these buildings occupy.
Zoom in for seeing detail polygon
Update Component Two different color building drawing
the calculateAndDisplayArea function checks the building tag of each feature and applies a blue color for "office" buildings and a red color for "industrial" buildings.
Result