Cumulative cost mapping

How accessible is the hospital?

The amount of effort it takes to access a hospital depends for a large part in the distance to the hospital and the accessibility of the road network. Some roads are easy to travel whereas traveling over other roads is much more complicated.  We can use the cumulative cost function to compute a cost map where every pixel contains the total cost of the lowest cost path to the nearest source location. In the example below we assign different weights to the road network and calculate the cost path to the nearest hospital. The data was obtained from Open Street Map. You can copy the code below into the Google Earth Engine code editor or use this link

// import country boundaries
var countries = ee.FeatureCollection("USDOS/LSIB_SIMPLE/2017");
var cambodia = countries.filter(ee.Filter.eq("country_na","Cambodia"));

//import road feature
var roads = ee.FeatureCollection('projects/servir-mekong/osm/cambodia/gis_osm_roads');
// import osm health center data
var osmhealthCenter = ee.FeatureCollection("projects/servir-mekong/osm/cambodia/hotosm_khm_health_facilities").filterBounds(cambodia);

// print the road categories
print("road categories:", roads.aggregate_histogram("fclass"));

// create lists to categorize the road networks
var primary = ["primary","primary_link"];
var secondary = ["secondary","secondary_link"];
var tertiary = ["tertiary","tertiary_link"];
var other = ee.List(roads.aggregate_histogram("fclass").keys()).removeAll(primary).removeAll(secondary).removeAll(tertiary);

// filter for primary, secondary and tertiary roads
var primaryRoads = roads.filter(ee.Filter.inList("fclass",primary));
var secondaryRoads = roads.filter(ee.Filter.inList("fclass",secondary));
var tertiaryRoads = roads.filter(ee.Filter.inList("fclass",tertiary));
var otherRoads = roads.filter(ee.Filter.inList("fclass",other));

// assign weight to road netwok
var weightPrimary = 0.5;
var weightSecondary = 1;
var weightTertiary = 1.5;
var weightOther = 2;
var weightNonRoads = 10;

// create rasters for the road network
var primaryRaster = ee.Image().toByte().paint(primaryRoads, weightPrimary).unmask(0);
var secondaryRaster = ee.Image().toByte().paint(secondaryRoads, weightSecondary).unmask(0);
var tertiaryRaster = ee.Image().toByte().paint(tertiaryRoads, weightTertiary).unmask(0);
var otherRaster = ee.Image().toByte().paint(otherRoads, weightOther).unmask(0);

//create friction layer 
var roadFriction = primaryRaster.add(secondaryRaster).add(tertiaryRaster).add(otherRaster);
roadFriction = roadFriction.where(roadFriction.eq(0),weightNonRoads);

//convert points to raster
var pointsRaster = ee.Image().toByte().paint(osmhealthCenter, 1);

//calculate cumulative cost 
var cumulativeCost = roadFriction.cumulativeCost({
    source: pointsRaster,
    maxDistance: 100000,

// add data to map
Map.addLayer(primaryRoads.draw("red"),{},"primary roads",false);
Map.addLayer(secondaryRoads.draw("green"),{},"secondary roads",false);
Map.addLayer(tertiaryRoads.draw("blue"),{},"tertiary roads",false);
Map.addLayer(otherRoads.draw("black"),{},"other roads",false);
Map.addLayer(osmhealthCenter,{},"osm health facilities",false);
Map.addLayer(roadFriction,{min:0,max:5},"road friction",false);
Map.addLayer(cumulativeCost.clip(cambodia), {min: 0, max: 1e5, palette: ['darkgreen', 'green', 'yellow', 'orange',"red","darkred","purple","white"]}, 'accessibility', true);

Leave a Reply