
Introduction
Building footprint data is crucial for urban planning, infrastructure development, disaster management, and rural development projects. Google Earth Engine (GEE) provides direct access to the Open Buildings v3 dataset, a global collection of building polygons derived from high-resolution satellite imagery using deep learning models.
In this article, we will build a simple, interactive tool in GEE to extract building polygons for any user-defined area, filter them by confidence and size, and export the results to Google Drive.
Why Building Footprints Matter
Urban and Rural Planning – Identify settlement growth and infrastructure gaps.
Disaster Risk Reduction – Estimate exposure of households to floods, earthquakes, or cyclones.
Population Mapping – Combine with census or survey data for population density estimation.
Agricultural Villages – Differentiate between cropland and built-up areas to improve land-use studies.
Dataset: Open Buildings v3
Source: GOOGLE/Research/open-buildings/v3/polygons
Coverage: Africa, South Asia, parts of Europe, and expanding globally
Attributes:
geometry: building polygon
confidence: probability score (0–1) indicating model certainty
area_in_meters: building area estimate
Tool Features
The tool developed in GEE includes:
Interactive Drawing – Define any region of interest (ROI) directly on the map.
Custom Filters –
Minimum confidence threshold (e.g., 0.5)
Minimum building size (m²)
Visualization – Building polygons displayed on top of satellite imagery.
Export – Save results to Google Drive as Shapefile for GIS use.
Workflow in Google Earth Engine
Paste the script into the GEE Code Editor and click Run.
Click Start Drawing. Draw a polygon around your ROI. Finish drawing to lock the shape.

Adjust filters: set Min Confidence and Min Area (m²) to your desired thresholds.

Click Extract Buildings. Wait until the status shows a count (e.g., “Found X buildings!”).

Inspect results on the map: ROI shows in red, building polygons in green.
Export: click Export to My Drive. Open the GEE Tasks tab and run the export task. Monitor progress and download the Shapefile from Google Drive when complete.
Full Google Earth Engine Code
You can try the complete working script below. Copy it into your GEE Code Editor
// === Full Code: Building Footprint Finder ===\\
// A simple tool to find and export building footprints from satellite data.
// It’s like a smart search for buildings!
// Configuration settings, feel free to tweak these.
var OPEN_BUILDINGS = ‘GOOGLE/Research/open-buildings/v3/polygons’;
var EXPORT_FOLDER = ‘My_Building_Footprints’;
var MIN_CONFIDENCE = 0.5; // How sure the model has to be that it’s a building.
var MIN_AREA = 6; // Smallest building area to include (in square meters).
// Let’s set up the user interface.
var sidePanel = ui.Panel({
style: {
width: ‘400px’,
padding: ’10px’
}
});
ui.root.insert(0, sidePanel);
// A nice, friendly title.
sidePanel.add(ui.Label(‘Building Footprint Finder’, {
fontSize: ’18px’,
fontWeight: ‘bold’,
margin: ‘0 0 10px 0’
}));
// Quick instructions for a new user.
sidePanel.add(ui.Label(‘Hey there! Just follow these steps:’, {margin: ‘0 0 5px 0’}));
sidePanel.add(ui.Label(‘1. Draw a shape on the map to define your search area.’, {margin: ‘0 0 5px 0’}));
sidePanel.add(ui.Label(‘2. Tweak the filters on the left if you want.’, {margin: ‘0 0 5px 0’}));
sidePanel.add(ui.Label(‘3. Click the “Extract Buildings” button below!’, {margin: ‘0 0 15px 0’}));
// Buttons to control the drawing.
var startDrawButton = ui.Button({
label: ‘Start Drawing’,
onClick: function() {
drawingTools.setShape(‘polygon’);
drawingTools.draw();
statusLabel.setValue(‘Status: Drawing… Get creative with your shape!’);
}
});
var clearAoiButton = ui.Button({
label: ‘Clear Boundary’,
onClick: function() {
// Just remove the drawn polygon layer.
if (drawingTools.layers().length() > 0) {
drawingTools.layers().remove(drawingTools.layers().get(0));
}
statusLabel.setValue(‘Status: Boundary cleared.’);
}
});
var resetButton = ui.Button({
label: ‘Reset All’,
onClick: function() {
// This function cleans up everything and gets you back to the start.
resetAll();
statusLabel.setValue(‘Status: Everything reset.’);
}
});
sidePanel.add(ui.Panel([startDrawButton, clearAoiButton, resetButton], ui.Panel.Layout.flow(‘horizontal’)));
// Let’s add some simple sliders for the filters.
sidePanel.add(ui.Label(‘Filters:’, {fontWeight: ‘bold’, margin: ’10px 0 5px 0′}));
var confSlider = ui.Slider({
min: 0.0,
max: 1.0,
value: MIN_CONFIDENCE,
step: 0.01,
style: {width: ‘300px’}
});
sidePanel.add(ui.Panel([ui.Label(‘Min Confidence:’), confSlider], ui.Panel.Layout.flow(‘horizontal’)));
var areaSlider = ui.Slider({
min: 0,
max: 50,
value: MIN_AREA,
step: 1,
style: {width: ‘300px’}
});
sidePanel.add(ui.Panel([ui.Label(‘Min Area (m²):’), areaSlider], ui.Panel.Layout.flow(‘horizontal’)));
// The main action buttons.
var extractButton = ui.Button({
label: ‘Extract Buildings’,
onClick: findBuildings,
disabled: true,
style: {stretch: ‘horizontal’}
});
sidePanel.add(extractButton);
var exportButton = ui.Button({
label: ‘Export to My Drive’,
onClick: exportToDrive,
disabled: true,
style: {stretch: ‘horizontal’}
});
sidePanel.add(exportButton);
// A little status message to keep you in the loop.
var statusLabel = ui.Label(‘Status: Ready to start. Draw a boundary on the map!’, {margin: ’10px 0 0 0′});
sidePanel.add(statusLabel);
// Initialize the map and drawing tools.
Map.setOptions(‘SATELLITE’);
var drawingTools = Map.drawingTools();
drawingTools.setShown(true);
// Global variables to hold our data.
var drawnArea = null;
var foundBuildings = null;
// This function gets called once the user finishes drawing their shape.
drawingTools.onDraw(function(geometry) {
drawnArea = geometry;
statusLabel.setValue(‘Status: Area drawn! Now click “Extract Buildings”.’);
extractButton.setDisabled(false);
exportButton.setDisabled(true);
});
// A function to reset everything.
function resetAll() {
// Clear the drawn layer.
var layers = drawingTools.layers();
while (layers.length() > 0) {
drawingTools.layers().remove(layers.get(0));
}
// Clear the map layers for the buildings.
Map.layers().reset();
// Reset our variables and button states.
drawnArea = null;
foundBuildings = null;
extractButton.setDisabled(true);
exportButton.setDisabled(true);
}
// Function to actually find the buildings.
function findBuildings() {
if (!drawnArea) {
statusLabel.setValue(‘Status: Oops. You need to draw an area first.’);
return;
}
statusLabel.setValue(‘Status: Searching for buildings…’);
var minConf = confSlider.getValue();
var minArea = areaSlider.getValue();
// Grab the buildings from the dataset and filter them.
var buildings = ee.FeatureCollection(OPEN_BUILDINGS)
.filterBounds(drawnArea)
.filter(ee.Filter.gte(‘confidence’, minConf));
// Clean up the features: clip to the drawn area and calculate the actual area.
var clippedAndFiltered = buildings.map(function(feature) {
var geometry = feature.geometry().intersection(drawnArea, ee.ErrorMargin(1));
var area = geometry.area(1);
return ee.Feature(geometry)
.set(‘area_m2’, area)
.copyProperties(feature, [‘confidence’]);
}).filter(ee.Filter.gte(‘area_m2’, minArea));
// Sort the buildings so they have a nice, logical order.
var sorted = clippedAndFiltered.map(function(feature) {
var centroid = feature.geometry().centroid(1).coordinates();
return feature.set({
‘sort_x’: centroid.get(0),
‘sort_y’: centroid.get(1)
});
}).sort(‘sort_y’).sort(‘sort_x’);
// Give each building a unique ID.
var sequence = ee.List.sequence(1, sorted.size());
var finalFeatures = ee.FeatureCollection(sequence.map(function(i) {
i = ee.Number(i);
var feature = ee.Feature(sorted.toList(sorted.size()).get(i.subtract(1)));
return feature
.set(‘UID’, i)
.select([‘UID’, ‘confidence’, ‘area_m2’]); // Just keep the useful stuff.
}));
// Save the final result and show it on the map.
foundBuildings = finalFeatures;
Map.layers().set(1, ui.Map.Layer(drawnArea, {color: ‘FF0000’}, ‘Your Drawn Area’, true));
Map.layers().set(2, ui.Map.Layer(foundBuildings, {color: ’00FF00′}, ‘Found Buildings’, true));
// Update the status and enable the export button.
exportButton.setDisabled(false);
foundBuildings.size().evaluate(function(count) {
statusLabel.setValue(‘Status: Found ‘ + count + ‘ buildings! Ready to export.’);
});
}
// Function to send the data to your Google Drive.
function exportToDrive() {
if (!foundBuildings) {
statusLabel.setValue(‘Status: Oops. Nothing to export! Find some buildings first.’);
return;
}
// Make a unique filename with a timestamp.
var timestamp = new Date().toISOString().replace(/[:.]/g, ‘-‘).slice(0, -5);
var description = ‘building_footprints_’ + timestamp;
// This is the command that starts the export process.
Export.table.toDrive({
collection: foundBuildings,
description: description,
folder: EXPORT_FOLDER,
fileFormat: ‘SHP’,
selectors: [‘UID’, ‘confidence’, ‘area_m2’]
});
statusLabel.setValue(‘Status: Export started! Check your Google Earth Engine “Tasks” tab for progress.’);
}
Example Output
Below is an example output showing detected buildings (green) over a rural settlement.

Applications:
- Mapping villages for rural electrification projects
- Monitoring urban expansion
- Assessing post-disaster damage in settlements
- Integrating with crop monitoring to separate farmland vs. built-up areas
Conclusion
The Open Buildings dataset in Google Earth Engine provides a ready-to-use global layer of building polygons. With this tool, users can interactively extract footprints for any region, refine results using filters, and export datasets for offline GIS analysis.
This approach is efficient, scalable, and requires no additional external data sources, making it valuable for researchers, planners, and local administrators.
References:
- 1. GitHub Code Site: https://github.com/suyash-bhosale/Building_Extraction_GEE_Code/tree/main
- 2.Google Resource Site: https://developers.google.com/earth-engine/datasets/catalog/GOOGLE_Research_open-buildings_v3_polygons



