Composition: how to make a day and night world map?
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]
]
Then, stealing the ImageCompose
idea from Yu-Sung:
pl=ImageCompose[night, SetAlphaChannel[day, mask]]
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}
]
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 the 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.
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]]
Since version 10.0, the functions DayHemisphere[]
, NightHemisphere[]
, and DayNightTerminator[]
are now built-in, and can be used with GeoGraphics[]
. These three can either take a specified date, and will otherwise default to Now
. One can now do things like this:
GeoGraphics[{GeoStyling[GrayLevel[0, 2/3]], NightHemisphere[]},
GeoBackground -> GeoStyling["Satellite"], GeoProjection -> "Equirectangular",
GeoRange -> "World"]
which can then be used as a suitable Texture[]
if wanted.