Jump to content

Marble/GraphicsViewGeoParser: Difference between revisions

From KDE Community Wiki
*>Mansona
Created page with '== GeoParser and the GeoGraphicsView == The current GeoData XML Parser ( aka. GeoParser ) has been implemented to specifically deal with our current GeoData data structure. If y...'
 
Frinring (talk | contribs)
m Update links
 
(10 intermediate revisions by 4 users not shown)
Line 1: Line 1:
== GeoParser and the GeoGraphicsView ==  
== The Problem ==
The current GeoData XML Parser ( aka. GeoParser ) has been implemented to specifically deal with our current GeoData data structure. If you want to see a more complete documentation of the GeoData library you can see the [[Projects/Marble/LibGeoData|GeoData Library documentation]]. I will only describe the particular problem to the GeoGraphicsView implementation here.  
Data is read from files with the [[Marble/GeoData/GeoDataParsing|GeoDataParser framework]] in order to be displayed.


<!-- move this section to a dedicated "How the XML parser works" section -->
The [[Marble/GeoData|GeoData framework]] is used to manipulate {{class|GeoDataObject|kdeedu|4.x}} classes. GeoData should be accessed in a sensible way because of its "shared data" logic.
=== Parsing GeoData ===
The GeoParser is an implementation of the QXMLStreamReader class in Qt, more information can be found [http://doc.qtsoftware.com/4.5/qtxml.html here]. There are other things built into this implementation that simplify the creation of a parser for new XML format document, namely:
* The Concept of a TagHandler class that deals with only one tag
* A Stack Item class that implements the Structural parts of the XML document
* The collection class where the results of the XML parsing will be placed
* A element dictionary that prevents the need for string comparison everywere


To implement a new XML parser you need to  
Items to be displayed are {{class|GeoGraphicsItems|kdeedu|4.x}}, following the [[Marble/GeoGraphicsViewOverview|GeoGraphicsView]] framework.
#compile an element dictionary of all of the available tags in the namespace
#implement a tag handler for each of these elements
#register that tag handler with the GeoParser


==== Implementing a tag handler ====
The Link between GeoData and GeoGraphicsItems has to permit:
Each tag handler is called when the relevant XML tag is reached by the GeoParser ( which knows what tags to call by its registered tag list ). Each tag can access the stack data structure of the GeoParser as well as the Collection Data Structure of the GeoParser. This allows the tag handler to access items from the stack and allows root elements of the XML to add themselves to the collection data structure.
* To display corresponding items, and get the data updates.
<!-- more information needed when moved to its own page -->
* To edit data through interaction (i.e. clicking on the map, dragging an item, changing the text of a placemark, adding placemarks)


=== Down Casting ===  
== A bit of history and issues ==
The unfortunate thing about the current implementation of the GeoParser is that when any item is added to the Collection Data Structure it is effectively downcast to the collection's type and removes any ability for 3rd party developers to add parsing capability to marble with functionality other than that which marble provides. This is not in line with the design of the QGraphicsItem implementation and something that is a current development effort to fix. What needs to happen is that an extra data model needs to be added to the GeoParser that is more in line with the idea of passing pointers around and that way we can conserve the typing information at run time.
=== GeoData manipulation ===
Previously, GeoData has been accessed through shallow copy from the rendering objects. this posed problems as GeoData uses data sharing internally and updates in GeoData were thus not seen in Items.
 
=== Model-View framework ===
Also, the Model-View framework from Qt has been used many times with various shades of success for that specific matter (see [[Marble/ModelView|Model View status]] for more info).
 
A "Model" in the Model-view framework in Qt is an interface to facilitate access to lists of data from widgets which need not know what data is inside. The interface may sound nice, but the abstraction is a bit too much when the interaction between data and its representation increases. These "Model" are also not data stores in order to avoid the previous issue.
 
== Possible Solutions and discussion ==
 
=== Multiple Inheritance try ===
Multiple inheritance could be possible where GeoGraphicsItems would also be GeoNodes:
* but that raises issues regarding modularity, because both the model and its representation would be in the same object
** Somebody could want to display the GeoData as a list for example.
* we try not to have multiple inheritance at all (please add reasons)
 
=== Time of creation of GeoGraphicsItems ===
To display the GeoDataFeature- and GeoDataGeometry-objects we want to use GeoGraphicsItems on a global GeoGraphicsScene.
This leads to the problem when to create the GeoGraphicsItems for displaying on the scene:
* Creating the items as they were read.
** This will probably be really slow as GeoGraphicsItems shouldn't be created in the thread which parses the file (why not?)
** This will use (lots of) memory as everything has to be ready for painting.
* Using a proxy concept: In another Thread runs a check for the GeoDataFeatures and GeoDataGeometries which entered the scene (because of moving around). This will probably go through a list of say 20000 entries, but, as it runs in a thread it won't stop the user interface from repainting. As the user interface repaints (in main thread), the GeoGraphicsItems for the new GeoData...-objects are created (we know which are needed because of our Proxy-Thread). Our GeoGraphicsScene allows to add items temporary, removing them when they are out of the viewport for some time. Our GeoGraphicsScene would hold about 200 entries, which can be access via a list or a [http://en.wikipedia.org/wiki/Binary_space_partitioning BSP-tree] (depending on which turns out to be more reasonable).
** Using a BSP-tree here, it should be possible to keep many entries in GeoGraphicsScene.
 
=== Display the data ===
We should follow an [http://en.wikipedia.org/wiki/Observer_pattern Observer Pattern] logic for the first goal whereas GeoGraphicsItems would observe the GeoData.
 
Multiple options are available for an observer pattern implementation:
* use signal/slots
After all, this is one of Qt's best success.
 
For reference, [http://doc.trolltech.com/4.6-snapshot/animation-overview.html#animations-and-the-graphics-view-framework Qt4.6 snapshot doc] regarding animation proposes for GraphicsItems to inherit QObject to receive signals from animation framework.
 
A less obtrusive solution is possible with some intermediary QObject-derived class which would manipulate GeoGraphicsItems when GeoData updates.
 
 
* implement light event handling methods (like java event listener classes)
 
* use qt's model-view framework of itemviews-ng
More info needed to see if it fits the observer solution...
 
A first glance at [[http://labs.trolltech.com/docs/Projects/itemviews-ng/ ItemView-ng Project API]] shows not much radical change in the model interaction compared to previous itemview...
 
=== Edit the data ===
We should think carefully about storing data to provide the second goal, so that editing is done in the GeoData and then updates happen in GeoGraphicsItems as a result.
 
=== Rethink the GeoData classes ===
It's unclear, if it is reasonable to save ALL GeoData* classes as a value, with "implicit sharing" making it fast. Multi-level data stored as a value is a bit complicated. This will be discussed in [[Marble/GeoData/PointerVsImplicitShare]]

Latest revision as of 10:47, 21 October 2016

The Problem

Data is read from files with the GeoDataParser framework in order to be displayed.

The GeoData framework is used to manipulate GeoDataObject classes. GeoData should be accessed in a sensible way because of its "shared data" logic.

Items to be displayed are GeoGraphicsItems, following the GeoGraphicsView framework.

The Link between GeoData and GeoGraphicsItems has to permit:

  • To display corresponding items, and get the data updates.
  • To edit data through interaction (i.e. clicking on the map, dragging an item, changing the text of a placemark, adding placemarks)

A bit of history and issues

GeoData manipulation

Previously, GeoData has been accessed through shallow copy from the rendering objects. this posed problems as GeoData uses data sharing internally and updates in GeoData were thus not seen in Items.

Model-View framework

Also, the Model-View framework from Qt has been used many times with various shades of success for that specific matter (see Model View status for more info).

A "Model" in the Model-view framework in Qt is an interface to facilitate access to lists of data from widgets which need not know what data is inside. The interface may sound nice, but the abstraction is a bit too much when the interaction between data and its representation increases. These "Model" are also not data stores in order to avoid the previous issue.

Possible Solutions and discussion

Multiple Inheritance try

Multiple inheritance could be possible where GeoGraphicsItems would also be GeoNodes:

  • but that raises issues regarding modularity, because both the model and its representation would be in the same object
    • Somebody could want to display the GeoData as a list for example.
  • we try not to have multiple inheritance at all (please add reasons)

Time of creation of GeoGraphicsItems

To display the GeoDataFeature- and GeoDataGeometry-objects we want to use GeoGraphicsItems on a global GeoGraphicsScene. This leads to the problem when to create the GeoGraphicsItems for displaying on the scene:

  • Creating the items as they were read.
    • This will probably be really slow as GeoGraphicsItems shouldn't be created in the thread which parses the file (why not?)
    • This will use (lots of) memory as everything has to be ready for painting.
  • Using a proxy concept: In another Thread runs a check for the GeoDataFeatures and GeoDataGeometries which entered the scene (because of moving around). This will probably go through a list of say 20000 entries, but, as it runs in a thread it won't stop the user interface from repainting. As the user interface repaints (in main thread), the GeoGraphicsItems for the new GeoData...-objects are created (we know which are needed because of our Proxy-Thread). Our GeoGraphicsScene allows to add items temporary, removing them when they are out of the viewport for some time. Our GeoGraphicsScene would hold about 200 entries, which can be access via a list or a BSP-tree (depending on which turns out to be more reasonable).
    • Using a BSP-tree here, it should be possible to keep many entries in GeoGraphicsScene.

Display the data

We should follow an Observer Pattern logic for the first goal whereas GeoGraphicsItems would observe the GeoData.

Multiple options are available for an observer pattern implementation:

  • use signal/slots

After all, this is one of Qt's best success.

For reference, Qt4.6 snapshot doc regarding animation proposes for GraphicsItems to inherit QObject to receive signals from animation framework.

A less obtrusive solution is possible with some intermediary QObject-derived class which would manipulate GeoGraphicsItems when GeoData updates.


  • implement light event handling methods (like java event listener classes)
  • use qt's model-view framework of itemviews-ng

More info needed to see if it fits the observer solution...

A first glance at [ItemView-ng Project API] shows not much radical change in the model interaction compared to previous itemview...

Edit the data

We should think carefully about storing data to provide the second goal, so that editing is done in the GeoData and then updates happen in GeoGraphicsItems as a result.

Rethink the GeoData classes

It's unclear, if it is reasonable to save ALL GeoData* classes as a value, with "implicit sharing" making it fast. Multi-level data stored as a value is a bit complicated. This will be discussed in Marble/GeoData/PointerVsImplicitShare