FEB
10
2008
|
Marble's Secrets Part II - Walking In The Shoes Of Slartibartfast ...In Part I we have seen how easy it is to create your own maps for Marble. We've also seen how this works down to the zoom level of aerial photos or OpenStreetMap. Part II will show how Marble manages to provide the biggest bang for the byte when it comes to providing map data. It outlines how we managed to get the default map squeezed into the 10MB package that the Marble-Qt version gets shipped with. We basically show ... Why Marble is the perfect choice for Asus EeePC, OLPC & Co and some Embedded Devices ... ;-) If you followed our last part closely and did a bit hands-on work then you maybe have stumbled across the contents of ~/.marble/data/maps/earth/srtm . This one contains part of the data for the default topographic view which is pretty colorful to mimic the appearance of a typical school atlas. Although the Marble application focuses on the educational aspect that's only one reason why we default to the topographic map: If you look at the actual tiles of the "Atlas" map then you will realize that they are all provided as grayscale bitmaps! If you actually replace "false" by "true" in line 10 of the srtm.dgml-textfile (which is likely placed in /usr/share/apps/marble/data/maps/earth/srtm/srtm.dgml if you're on a Linux/UNIX system) then your line should look like this:
Restart Marble and choose the "Atlas" map, zoom out a bit and you can see the grayscale data in "raw mode" in its full dull beauty. Actually you'll find out that it has a blue tint as Marble just applies the grayscale data to the blue color channel. So apparently Marble takes the grayscale data, and somehow applies colors to it! This is pretty smart: All tiles get stored as JPG's. But grayscale images use up a lot less space on the hard disc drive than color images. Color images just need four bytes (RGBA) per pixel while grayscale only needs a single byte per pixel! And you can even compress grayscale tiles a lot more than color tiles: Usually people feel offended by highly compressed JPGs due to the violet-pinky artefact-shades that result from an overly compressed JPG-file. With grayscale images this artefact is gone and it's much harder to tell a highly compressed image from an uncompressed one! That's the reason why Marble can store a lot more map data (about 4 times as much) in Atlas View than it would be possible in Satellite View! The grayscale shades actually represent heights. In fact those grayscale shades are based on data that was acquired during the Shuttle Radar Topography Mission" ("SRTM") back in February of 2000: A radar system that flew onboard the Space Shuttle Endeavour during STS-99 mission obtained digital elevation models on a near-global scale from 56 °S to 60 °N. While Marble only ships part of the data the whole SRTM provides the most complete high-resolution digital topographic database of Earth to date! That's why the GIS community loves the SRTM data so much. Now if we would just map those grayscale values to color values and if we would colorize our map that way then we would get a beautiful and clean map. We'd just choose a green-yellow-brown palette for all grayscale-values which represent heights above sea level. And we'd choose a blueish palette for everything below sea level - but wait: There are some large areas, e.g. in northern africa, which are actually below sealevel and which are not filled with water! So we need some data for a coast line which enables us to choose the correct palette for the land and for the sea. Marble right now ships with such data which was very popular back in the 90ies: The "Micro World Database II" - which is based on some work by the Central Intelligence Agency, "CIA" back in the 80ies and has been updated a bit since then. The nice thing about it is that it provides a lot of vector data on as little as about 2 Megabytes: Coastlines, islands, boundaries, lakes and rivers (and we added some more). And yes, MWDBII and SRTM are available under the public domain. So if we use that to colorize our map we get what we have in the screenshot above. Watch the close-up screenshot on the right to see the vector coastline and the texture data pixels nicely blending together! Given that SRTM provides elevation data we could add some highlights and shadows, right? Indeed Marble reuses the very same grayscale data to apply cheap bumpmapping in a way that preserves the vivid colors. Marble does this at runtime for each single frame: so no matter how you rotate the earth, the shadows will always fall to the right. We also reuse the very same colorization trick for the permanent ice on the earth as you can see in the same screenshot. On top of this texture layer we add all those lovely vector lines that represent countries, rivers, lakes, etc. . Then we have our world cities and places which get imported from a set of Google Earth KML files that Marble is using. As a finishing touch the coordinate grid, the compass and the scalebar get added. Right now the whole rendering of the map is done in software (without using SIMD or assembler). This means that Marble will provide a pixel-perfect cross-plattform rendering at acceptable speed on every single computer that has got Qt4 installed. Additionally we are working towards having an optional OpenGL view-plugin for speed-intoxicated Gear^WMarbleheads in the future. I Am Legend As a user you can play around with these different layers by clicking the "Legend" tab on the left. Just check or uncheck the checkboxes. In the legend there's also a list that explains the color codes of the elevation data. As a die-hard armchair-GISmaniac you can even change the colors for the vector line features easily using your favorite text editor: Have a look at the Plain Map's plain.dgml - there are some new tags in there which are pretty self-explaining. Marble Junior Jobs It's time again for Marble Junior Jobs. If you've ever tried to become a famous rockstar coder then this is your chance to become a real Marblehead: First you need to spend 10 minutes to get Marble from the sources and to compile it. You need to check out Marble "trunk". Once this is done the Marble World is waiting for you:
For help or questions you can join us on IRC ( irc.kde.org, #kde-edu ) or send a mail to our mailing list.
|
![]() |
Comments
Great post
Let me say this post (and the first one too) totally rocks !
I'm not that much interested in such apps usually, but this post is very interesting. Your junior jobs offers looks appealing, i hope that you'll get new contributors soon, and that other devs will try to propose junior jobs (and generally get peoples interested in their apps) as well as you did.
What about putting (if not already done) those great texts on techbase ?
>Let me say this post (and
>Let me say this post (and the first one too) totally rocks !
I completely agree. Such posts get people as myself just so much more interested in the app...
I nearly began hacking at the two junior jobs from part I yesterday, heck I am tempted again today, but with two little kids at home (actually babies) and tomorrow being my first day at a new job it is just a no-no. Maybe in a couple of weeks.
Anyway it would be awesome if more KDE maintainers followed Torsten's example and wrote some articles about the technologies in their applications with a couple of junior jobs to top it all.
My (non existent) hat goes off to Torsten.
Re: >Let me say this post (and
Thanks for your kind words! The articles are definetely going to end up on techbase. Maybe we could make this a junior job even ;-)
Best Wishes,
Torsten
easy jr. job
I don't have KDE 4 installed and I have some other things I need to tend to tonight, but I offer some explanation of what I've done below.
I will detail a conversion scheme that I (A complete C++ novice) came
up with for something I'm working on. If this approach is something
that might be of use, maybe I could help.
I have a Unit class that has a static map<UnitEnumeration,
Fraction> (I also have a Fraction class but it's immaterial.
It then stores conversion ratios like so:
template<>
void Unit::populateConversionTable() {
if (m_conversion_map.empty()) { /* ratio to cups */
m_conversion_map[TEASPOON] = Fraction(1,48);
m_conversion_map[TABLESPOON] = Fraction(1,16);
m_conversion_map[FL_OUNCE] = Fraction(1,8);
m_conversion_map[GILL] = Fraction(1,2);
m_conversion_map[CUP] = Fraction(1);
m_conversion_map[PINT] = Fraction(2);
m_conversion_map[QUART] = Fraction(4);
m_conversion_map[GALLON] = Fraction(16);
m_conversion_map[MILLILITER] = Fraction(0.00422675282);
m_conversion_map[CENTILITER] = Fraction(0.0422675282);
m_conversion_map[DECILITER] = Fraction(0.422675282);
m_conversion_map[LITER] = Fraction(4.22675282);
m_conversion_map[DEKALITER] = Fraction(42.2675282);
}
}
This has a method to return the conversion ratio:
return m_conversion_map[m_type] / m_conversion_map[convertTo];
There is then a Quantity class that contains a quantitative measure of
volume or weight and another attribute which is what unit it is stored
in. To convert you do the following:
Quantity returnAsType(const T unitType) const { return Quantity(m_unit.getConversionRatio(unitType) * this->m_quantity, unitType); }
In your case you could decide to record everything in a unified form
of measurement (say kilometers) instead of preserving the unit, and
some overloading of mathematical operations makes sense. It is
probably also worth using a bigint library so you don't get into
trouble trying to convert the circumference of the earth into inches.
Re: easy jr. job
Yes, this looks about like it's the right direction. Just make sure that you don't overengineer things. After all we don't plan to have dozens of different units supported but just the most popular ones.
One of our motto's is the famous "It should be as simple as possible but not more simple than that."
Additionally I guess I should point out that Qt offers a few types itself: http://doc.trolltech.com/4.3/qtglobal.html
Apart from that we still need an actual patch for Marble of course ;-) Good Luck!