
I. Layer Management Class
=========================

Overview:
---------

Currently Marble is already capable of visualizing different kinds of
information based on different rendering classes which paint onto the
map canvas.

These classes:
 - apply texture mapping
 - and apply effects (e.g. colorizing textures, shading) to the
   resulting images.
 - add placemarks,
 - create vectors

There are also classes which create items that display information or
add controls on top of the whole map, called "floating items"
(e.g. compass, scale bar, planned: overview world map, on-map
navigation control ).

However the whole process of rendering using those classes is
hardcoded and not very flexible.

The Layer Management Class ("LMC") is supposed to solve this issue. In
short the new LMC concept aims to:

- Create a QTPLUGIN (type: Lower-Level-API) architecture for the
  rendering process.

- The backend functionality of the current rendering classes should go
  into BACKEND PLUGINS.

- The backend classes should be QT-THREAD-based. (NYI)

- The backend classes should encourage the Model-View concept and make
  use of Qt's INTERVIEW framework.

- It should be possible to instantiate each backend class multiple
  times resulting in multiple layers.

Note that we distinguish between "BACKEND"-classes and the objects
based on the BACKEND-classes called "LAYERS".

Due to different usage and technical requirements layers might either
be:

  a) PROJECTION-BASED LAYERS (i.e. they get applied on top of the
     globe using the respective projection transformations).
	
  b) SCREEN LAYERS (i.e. they don't care about the projection and are
     layers "on top of the screen"

"Execution order" of the different backends should be based on the
following mechanisms:

  a) Each backend should provide "hardcoded" hints which describe
     dependencies (e.g. the texture colorization depends on the result
     of a texturemapping backend ) and allowed ranges for the
     rendering order (e.g. floating items should always be displayed
     on top of the map, a starry background needs to get drawn before
     the globe is painted)

  b) In Marble the structure of each map gets described in the map's
     .dgml file. So the layermanagement class needs to fetch
     information from the .dgml-parser about the different types of
     backends that get used in a map. The .dgml file also needs to
     provide information about the rendering order. 

     ( For more information on this topic have a look at dgml2.txt )


  c) For backend types where there are no hard requirements on the
     rendering order the LMC should decide itself which order to
     take. So if for example a custom backend-plugin doesn't get
     mentioned in the .dgml file the LMC should make a well-educated
     guess at which place inside the layer structure it would be best
     to insert the layer.

According to the concept described so far it should be possible to
paint different layers based on the very same backend directly on top
of each other (e.g. a cloud layer on top of a satellite map layer.
Normally this would result in two different layers.  However for
reasons of performance it needs to be possible to merge the data into
a single layer right from the start ("MergedLayer").

This gets already done for placemarks in current SVN where data from
different files gets merged into a single file. It also gets done
already for clouds on top of the satellite image data. However what's
missing is a more generic approach where a MergedLayerPainter class
operates directly on the tiles based on the information it receives
from the LMC.

Before telling the MergedLayerPainter class which layers need to get
painted on top of the tiles the LMC needs to check whether tiles or
sourceimage data is available for the map. If there is no such data
available the LMC needs to either notify the TileLoader that it needs
to create tiles or the LMC will simply ignore the missing data and
will skip asking the MergedLayerPainter to render the missing data.

- The plugin-backend concept should allow CUSTOM BACKENDS created by
  third party developers.

- Creating new geographical features on the map should happen using a
  Qt-like API (which would include the QPainter API to draw in screen
  coordinates):

  Code snippet:

    bool MarbleTestPlugin::render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer )
    {
    painter->autoMapQuality();
    painter->setPen( Qt::red );

    GeoDataCoordinates flensburg( 9.4, 54.8, 0.0, GeoDataCoordinates::Degree );
    GeoDataCoordinates madrid( -3.7, 40.4, 0.0, GeoDataCoordinates::Degree );

    painter->drawLine( flensburg, madrid );
	
  ( For more information on this topic have a look at paintingmaps.txt )

- It should be possible to use this Qt-style Geo-API either from
  outside the MarbleWidget or from inside the custom backend plugin.

- It should be possible to create custom PROPRIETARY PLUGINS which are
  able to provide PROPRIETARY DATA in a manner that prevents exporting
  the whole data at once.

  Yes, while we strongly believe in free maps and free data we would
  also like to see proprietary apps use our widget - as always patches
  sent to us under a free license are very much appreciated.

- Expiring layer data: The LMC should get notified about expiration
  dates of layer data. If layer data expires the LMC should trigger a
  reload of each chunk of data. Initially it would be enough if we
  supported reloading the whole data set of a single layer. In the
  future reloading single data chunks of a layer would be nice to
  have. (Examples for tile expiration: Real-time cloud layers,
  Improvements for OpenStreetMap data).

- LMC should also work fine with OpenGL-based backend-plugins.

FUTURE low-priority enhancements (for usage in "real" light GIS apps
that might use Marble in the future):

- Make it possible to specify custom changes to the rendering order of
  the layers using the LMC-API.

- Make it possible to create layer groups. This would e.g. enable the
  user to show/hide many "grouped" layers at once.


