I'm using Google Earth Engine (GEE) to calculate the Euclidean distance from sample points to the nearest brightest pixel above the threshold value "avg_rad > 10" in nighttime light data. Some of the point coordinates I use as the base shapefile are as below:
U -14.335572 35.639824
U -13.203245 37.501709
U -15.198814 35.863956
R -13.422739 34.870815
R -13.203394 35.187214
R -15.004614 36.633186
R -14.895029 36.772968
R -14.597268 36.350857
R -14.488451 36.53352
My approach:
- Process VIIRS Data: Compute the median of 2021 data and mask bright pixels (avg_rad > 10).
- Compute Distance: Use fastDistanceTransform(1024).sqrt().
- Find Nearest Bright Pixel: Convert bright pixels to centroids with reduceToVectors(), then match them to sample points.
- Extract Distance: Sample distance_to_bright at sample points.
Am I coding it correctly?
// ==========================
// 1️⃣ Load & Process Nighttime Light Data (VIIRS)
// ==========================
var nightLights = ee.ImageCollection('NOAA/VIIRS/DNB/MONTHLY_V1/VCMSLCFG')
.filterDate('2021-01-01', '2021-12-31') // Use one year of data
.median() // Reduce noise by computing the median composite
.select('avg_rad'); // Select the average radiance band
// ==========================
// 2️⃣ Compute Euclidean Distance to Nearest Bright Pixel (avg_rad > 10)
// ==========================
var brightPixels = nightLights.gt(10); // Mask for bright pixels
// Compute Euclidean distance to the nearest bright pixel
var distToBright = brightPixels.fastDistanceTransform(1024).sqrt()
.rename('distance_to_bright');
// ==========================
// 3️⃣ Define Sample Points
// ==========================
// Load sample points from shapefile
var samplePoints = ee.FeatureCollection("projects/ee-researchgamage/assets/base1");
// ==========================
// 4️⃣ Define Region and Extract Nearest Bright Pixel Coordinates
// ==========================
// Ensure processing is limited to the area where night lights exist
var nightLightsBounds = nightLights.geometry();
var region = nightLightsBounds.intersection(samplePoints.geometry().buffer(50000), ee.ErrorMargin(1));
var brightPixelPoints = brightPixels.selfMask()
.reduceToVectors({
geometryType: 'centroid',
scale: 500,
geometry: region,
geometryInNativeProjection: false,
maxPixels: 1e7, // Set max pixels to 10 million
bestEffort: true // Allow flexible aggregation
});
// Function to find nearest bright pixel for each sample point
var findNearestBrightPixel = function(feature) {
var nearestBright = brightPixelPoints
.filterBounds(feature.geometry()) // Search for nearby bright pixels
.sort('distance_to_bright') // Sort by distance
.first(); // Get closest
// Extract coordinates safely
var brightLonLat = ee.Algorithms.If(
nearestBright,
ee.Feature(nearestBright).geometry().coordinates(),
ee.List([null, null]) // Handle cases with no bright pixel nearby
);
// Set attributes
return feature.set({
'point_lon': feature.geometry().coordinates().get(0),
'point_lat': feature.geometry().coordinates().get(1),
'bright_lon': ee.List(brightLonLat).get(0), // Extract longitude
'bright_lat': ee.List(brightLonLat).get(1) // Extract latitude
});
};
// Apply function to sample points
var enrichedSamplePoints = samplePoints.map(findNearestBrightPixel);
// ==========================
// 5️⃣ Extract Distance for Sample Points
// ==========================
var sampledDistances = distToBright.sampleRegions({
collection: enrichedSamplePoints,
scale: 500, // Adjust based on VIIRS resolution
projection: 'EPSG:4326',
geometries: true
});
// Print extracted distances
print("Sampled Distances:", sampledDistances);
// ==========================
// 6️⃣ Export CSV with Coordinates
// ==========================
Export.table.toDrive({
collection: sampledDistances,
description: 'Point_Distance_to_Bright_Night_Areas_2021', // Naming it as 2020
folder: 'GEE_Exports',
fileNamePrefix: 'point_distance_2021', // Forces the output name to 2020
fileFormat: 'CSV'
});
//======================