Tell me more ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Given the following world images:

day   = Import["http://eoimages.gsfc.nasa.gov/images/imagerecords/55000/55167/earth_lights_lrg.jpg"]
night = Import["http://eoimages.gsfc.nasa.gov/images/imagerecords/57000/57752/land_shallow_topo_2048.tif"]

enter image description here

how would you use Mathematica to create an accurate “day and night map” (examples here and there) of the Earth for a given date and time?

share|improve this question

2 Answers

up vote 20 down vote accepted

Let me first name your maps correctly (you switched night and day maps):

night= Import["http://eoimages.gsfc.nasa.gov/images/imagerecords/55000/55167/earth_lights_lrg.jpg"];
day= Import["http://eoimages.gsfc.nasa.gov/images/imagerecords/57000/57752/land_shallow_topo_2048.tif"];

The images have different sizes:

ImageDimensions[day]

(*
==> {2048, 1024}
*)

ImageDimensions[night]

(*
==> {2400, 1200}
*)

so, I rescale the night image. Artefacts (if any) will probably be less visible there.

night = ImageResize[night, ImageDimensions[day]];

Now, for the calculation of the mask we don't need to use external sources. AstronomicalData will do:

mask =
 Rasterize[
  RegionPlot[
   AstronomicalData["Sun", {"Altitude", {2012, 6, 21}, {lat, long}}] <
     0, {long, -180, 180}, {lat, -90, 90}, Frame -> None, 
   PlotRange -> Full, PlotStyle -> Black, PlotRangePadding -> 0, 
   AspectRatio -> (#2/#1 & @@ ImageDimensions[day])],
  ImageSize -> ImageDimensions[day]
  ]

Mathematica graphics

Then, stealing the ImageCompose idea from Yu-Sung:

pl=ImageCompose[night, SetAlphaChannel[day, mask]]

Mathematica graphics

Borrowing and adapting some code from the Texture doc page:

Show[
 Graphics3D[{White, Tube[{{0, 0, -1.4}, {0, 0, 1.4}}, .04]}],
 SphericalPlot3D[1 , {u, 0, Pi}, {v, 0, 2 Pi}, Mesh -> None, 
  TextureCoordinateFunction -> ({#5, 1 - #4} &), 
  PlotStyle -> Texture[Show[pl, ImageSize -> 1000]], 
  Lighting -> "Neutral", Axes -> False, RotationAction -> "Clip"], 
 Lighting -> "Neutral", Boxed -> False, 
 Method -> {"ShrinkWrap" -> True}
]

Mathematica graphics

share|improve this answer
1  
For day/night Earth textures with matching dimensions, this is one place to get them; you then no longer need to resize. – J. M. Oct 3 '12 at 16:12
Actually the last plot does not work for me: I get !i.stack.imgur.com/peG10.png – chris Dec 15 '12 at 14:54
@chris Do all the examples on the Texture doc page work for you? – Sjoerd C. de Vries Dec 26 '12 at 9:18
@SjoerdC.deVries in fact they do. – chris Dec 26 '12 at 9:27
@chris the final plot is not much different from what's in there. Could you try without Show and the Tube? For now, I suppose this is an issue of your graphics card. – Sjoerd C. de Vries Dec 26 '12 at 9:34
show 5 more comments

Yes, the basic idea is here: Demonstration: Day and Night World Clock

Now, to use the images, create an alpha channel using the computed the day-night curve--called "terminator" curve (rasterize it in grayscale), and compose two images using ImageCompose with the generated alpha channels (SetAlphaChannel to the second image).

Try the following code:

a = Image[ConstantArray[{255, 0, 0}, {200, 300}]];
b = Image[ConstantArray[{0, 255, 0}, {200, 300}]];

(* This is just a made-up mask. Don't mind Plot[] part *)
mask = Rasterize[
  Plot[Sin[x], {x, -Pi/2, 3 Pi/2}, PlotRangePadding->0,
    Filling->-1, FillingStyle->Black, Frame->False, 
    Axes->False, ImageSize->{300, 200}, AspectRatio->2/3],
  "Image", ColorSpace->"GrayScale"];

ImageCompose[a, SetAlphaChannel[b, mask]]

You should get an image with green and red mixed as below. Now you can replace a and b with your day and night textures.

mask

I have to tell you that although the code there computes pretty close approximation of the actual terminator curve, it is not exact. To compute it accurately (or based on actual data), see: NOAA: Day Night Terminator

The following code and output is for the actual images (again the mask is fake):

day = ImageResize[day, {2048, 1024}]; (* Match the dimensions *)

mask = Rasterize[
   Plot[Sin[x], {x, -Pi/2, 3 Pi/2}, PlotRangePadding -> 0, 
    Filling -> -1, FillingStyle -> Black, Frame -> False, 
    Axes -> False, ImageSize -> {2048, 1024}, 
    AspectRatio -> 1024/2048], "Image", ColorSpace -> "GrayScale"];

ImageCompose[night, SetAlphaChannel[day, mask]]

output

share|improve this answer
2  
welcome to the time killer ;-) – ruebenko Mar 22 '12 at 11:14
@ruebenko: you are scaring me :) – Yu-Sung Chang Mar 22 '12 at 12:51
It is very easy to lose days here answering questions, editing text, cavorting with the others in the chat room, etc. But, welcome to the club. – rcollyer Mar 22 '12 at 15:20
Great many thanks for the editing, which adds a composition example I was actually getting nowhere with on my own :) – F'x Mar 28 '12 at 8:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.