Message Boards Message Boards

How to estimate the area and volume of the dam reservoir from the satellite image?

Posted 1 year ago

Hello all dear, I have the satellite image of Canton dam reservoir and I want to get its volume and area.

The actual specifications of the dam reservoir: volume=0.472km^3 & Surface area=32.01km^2

I did the following command to estimate the area, but the result was not acceptable and the unit is not clear. Please guide me to estimate the area and volume. Thank you

enter image description here

First, I manually obtained the shape below from the Mask Tool command.

enter image description here

imge =(image);

img = Binarize@imge~Erosion~1;
(m = MorphologicalComponents[img]) // Colorize

enter image description here

linecount = 
  3 /. (Binarize@imge // ColorNegate // Thinning // 
     ComponentMeasurements[#, "PerimeterCount"] &);
areacount = 
  2 /. ComponentMeasurements[MorphologicalComponents[img], "Count"];
areacount/linecount^2 // N

out put is : 0.111111

POSTED BY: Erfan Abdi
11 Replies

There is no easy way to do this - especially if the dam is an obscure one, or one that Wolfram doesn't have much data about. Why? Well we'd have to know a lot of entry points - such as, the outflow of the river, the height of the dam, the length of the dam etc. For much larger/well known dams, it is possible for us to get data relatively easily using the Dam Entity.

Here is what it might look like if you want to find the area and volume of dams on a particular (well-known) river.

DamsOn[River_] := 
 EntityClass["Dam", "River" -> SemanticInterpretation[River]] // EntityList
AssortDamsOn[River_] := 
ReverseSortBy[Table[{i, DamData[i, "Volume"]}, {i,DamsOn[River]}], Last]

Alternatively, if you want the volume of all of the tributaries as well

mississippiRiver = 
 EntityClass["River", 
   "Outflow" -> Entity["River", "MississippiRiver::mnr4z"]] // EntityList;

DamsMississippi = 
     FilteredEntityClass["Dam", 
       EntityFunction[
        y, ! MissingQ[y["Position"]] && 
         ContainsAny[y["River"], 
          Append[mississippiRiver, 
           Entity["River", "MississippiRiver::mnr4z"]]]]] // EntityList;

And we can create a beautiful graph of it using

GeoRegionValuePlot[EntityValue[DamsMississippi, "Volume", "EntityAssociation"], 
         AspectRatio -> 1, MissingStyle -> Transparent, 
         GeoBackground -> "Satellite"]

You also might want to look into CNNs for this sort of stuff. There are two excellent blog posts on predicting the scale of a satellite image - https://community.wolfram.com/groups/-/m/t/1732295 and https://community.wolfram.com/web/community/groups/-/m/t/1379645

POSTED BY: Navvye Anand

If I had to do it, I would do this:

GeoGraphics[GeoRange -> {{36.05, 36.17}, {-98.7, -98.52}}, 
 GeoRangePadding -> Scaled[0.1], GeoBackground -> "Satellite"]

then, trace the contour of the dam with the "get coordinates" tool, and then use GeoArea:

damContour = {{36.14216500804076`, -98.66601000992658`},
   {36.15131161335255`, -98.6549477815357`},
   {36.1501032100147`, -98.62214348441108`},
   {36.15000037203102`, -98.60908533742007`},
   {36.13193732747872`, -98.58352140011719`},
   {36.10128112030604`, -98.57004960135653`},
   {36.08009879008038`, -98.6043835918035`},
   {36.1172565230945`, -98.61315564049649`},
   {36.12831708030723`, -98.62663775701455`},
   {36.13202116684048`, -98.64507269213401`},
   {36.13870030579935`, -98.6454368865287`},
   {36.13708633726377`, -98.6568745786338`}};
GeoGraphics[{White, Thick, Line[GeoPosition[damContour]]}, 
 GeoRange -> {{36.05, 36.17}, {-98.7, -98.52}}, 
 GeoRangePadding -> Scaled[0.1], GeoBackground -> "Satellite"]
GeoArea[Polygon[GeoPosition[damContour]]]
POSTED BY: Gianluca Gorni

Your code amounts to this:

linecount = 3 /. {1 -> 587, 2 -> 76}
areacount = 2 /. {1 -> 11150, 2 -> 1, 3 -> 187734}

which does not make much sense to me.

POSTED BY: Gianluca Gorni
Posted 1 year ago

Thank you, I think the area can be found by relating the pixels of the image and the scale, for the volume, the bathymetry image may be useful. But I'm not sure

POSTED BY: Erfan Abdi

Great solution. I wonder if there's any way to recognise the dam automatically without manually using track-coordinates

POSTED BY: Navvye Anand
Posted 1 year ago

Thanks, this is better. Can I get information from Mathematica about bathymetry to find depth and look for volume?

POSTED BY: Erfan Abdi

I have found a solution

gcarc = GeoPath[Table[i, {i, damContour}], "Geodesic"]
gcarcDistance = 
 GeoDistance[Table[i, {i, damContour}], UnitSystem -> "Metric"]
   profile = 
    GeoElevationData[gcarc, Automatic, "GeoPosition", GeoZoomLevel -> 4]
       pts = profile[[1]][[1]]
        depths = #[[3]] & /@ pts
        distances = 
         QuantityMagnitude[
            GeoDistance[{pts[[1]][[1 ;; 2]], #[[1 ;; 2]]}, 
             UnitSystem -> "Metric"]] & /@ pts
                avg = Mean[depths]
            pts = Transpose[{distances, depths}]
            p1 = ListLinePlot[pts]

Modified from https://sites.psu.edu/charlesammon/2017/03/22/manipulating-elevationbathymetry-profiles-with-mathematica/

POSTED BY: Navvye Anand
Posted 1 year ago

Thanks for your efforts Navvye, is it possible to combined with (Gianluca command) and get the volume?

POSTED BY: Erfan Abdi

Just multiply the area with the depth.

The entire code is uploaded as a nb

POSTED BY: Navvye Anand
Posted 1 year ago

Thank you Navvye for share note book, but Volume of reservoir is 0.472km^3

POSTED BY: Erfan Abdi

I realised that! Well at least the area is somewhat accurate. I'll try to improve the depth mechanism in sometime

POSTED BY: Navvye Anand
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract