~ubuntu-branches/ubuntu/quantal/marble/quantal

« back to all changes in this revision

Viewing changes to src/lib/geodata/data/README.html

  • Committer: Bazaar Package Importer
  • Author(s): Philip Muškovac
  • Date: 2011-07-11 15:43:02 UTC
  • Revision ID: james.westby@ubuntu.com-20110711154302-lq69ftcx125g1jx5
Tags: upstream-4.6.90+repack
Import upstream version 4.6.90+repack

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<html>
 
2
<head>
 
3
    <title>GeoData API - Internal programming documentation</title>
 
4
</head>
 
5
<body>
 
6
<h1>GeoData API - Internal programming documentation</h1>
 
7
<a name="topics"><h2>Topics</h2></a>
 
8
<ol>
 
9
<a href="#topics"><li>Topics</li></a>
 
10
<a href="#Introduction"><li>Introduction</li></a>
 
11
<a href="#implicit sharing"><li>"implicit sharing"</li></a>
 
12
<a href="#How implicit sharing and derivation can work together"><li>How "implicit sharing" and derivation can work together</li></a>
 
13
<a href="#serialization and deserialization"><li>serialization and deserialization</li></a>
 
14
</ol>
 
15
<a name="Introduction"><h2>Introduction</h2></a>
 
16
<p>The geodata-API should be used to contain easy and complex geographical data.
 
17
It consists currently of three main types:
 
18
<ul>
 
19
<li>GeoDataFeature</li>
 
20
<li>GeoDataGeometry</li>
 
21
<li>GeoDataColorStyle</li>
 
22
</ul>
 
23
From each of those three multiple classes are derived. The first two are most 
 
24
interesting because of a feature seldom found in APIs. Each derived class can
 
25
be stored in its base class and can later be transformed back again. This means
 
26
that the following code is possible:
 
27
<pre><code>
 
28
GeoDataPlacemark placemark;
 
29
GeoDataFeature placemarkAsFeature = placemark;
 
30
GeoDataPlacemark other = placemarkAsFeature;
 
31
 
 
32
return (placemark == other); // should return true
 
33
</code></pre>
 
34
This feature is useful so that you can easily store classes which inherit GeoDataFeature in a QVector&lt;GeoDataFeature&gt;
 
35
which would only be possible with Vectors normally. This is roughly the same as storing a QString in a QVariant (there are no 
 
36
GeoDataFeatures though that can be added at runtime). As an example:
 
37
<pre><code>
 
38
GeoDataPlacemark placemark;
 
39
QVector&lt;GeoDataFeature&gt; m_vector;
 
40
 
 
41
m_vector.append( placemark );
 
42
GeoDataFeature placeMarkAsFeature = m_vector.last();
 
43
GeoDataPlacemark other = placemarkAsFeature;
 
44
 
 
45
return (placemark == other); // should return true
 
46
</code></pre>
 
47
This feature is the base for the GeoDataContainer classes and for the GeoDataMultiGeometry class.
 
48
</p>
 
49
<a name="implicit sharing"><h2>"implicit sharing"</h2></a>
 
50
<p>The <code>GeoDataFeature</code> and <code>GeoDataGeometry</code> classes do use 
 
51
implicit-sharing which means that after copying, only a shallow copy is done. Only 
 
52
after a write access to the data of the object (calling a non-<code>const</code> function) a 
 
53
copy of the whole data is done. This makes copying those data structures rather 
 
54
cheap, even if they contain a lot of other <code>GeoDataObjects</code> (as without 
 
55
writing there is not much more copying done than with a pointer.<p/>
 
56
<p>As done already now, there is a private class which contains all the data members 
 
57
and gets accessed from the main classes accessor functions. This way you can keep 
 
58
binary compatibility over a long time without being restricted to the data members 
 
59
you chose in the beginning. When copying a <code>d</code>-pointer'ed class, you must put a 
 
60
new private class object on the stack though and copy the values from its origin.
 
61
Implicit sharing now means, that in the moment of copying, you only copy the 
 
62
address of the private d pointer but you increment the reference counter of that
 
63
object. After that there are two objects with the same private class object. If 
 
64
somebody tries to change something in one of those two objects, he must call 
 
65
a non-const function which in return will call a function called 
 
66
<code>void detach()</code>. This function copies the private object and decrements 
 
67
the reference counter. If one of the base objects gets deleted, it decrements the 
 
68
reference counter too as long as there are more objects connected to this private 
 
69
object. If the counter reaches 0 again, the private object gets deleted too.
 
70
This is mostly hidden by <code>QSharedData</code>/<code>QSharedDataPointer</code> 
 
71
so that you don't have to worry about that.<p/>
 
72
<p>The problems arise, when you try to derive from an implicitly shared 
 
73
class. The <code>detach()</code> function is not virtual in the current implementation of 
 
74
QVector and thus will not call the function from the derived class if 
 
75
changes occur through the interface of the base class. This leads to both GeoDataContainer
 
76
and GeoDataMultiGeometry not inheriting QVector but rather rebuilding the interface.</p>
 
77
 
 
78
<a name="How implicit sharing and derivation can work together"><h2>How "implicit sharing" and derivation can work together</h2></a>
 
79
<p>As described above, we can't use <code>QSharedData</code> directly if we want 
 
80
to use implicit sharing and derivation. Instead we do this on our own.
 
81
Our Private classes are all contained in a *_p.h header file. They are derived 
 
82
from the private class of the base class (of the current class).
 
83
Besides the data members, each private class contains a function <code>void *copy()
 
84
</code> which returns a new copy of the private object. As needed an assignment 
 
85
operator may occur. The private classes also do contain a function 
 
86
<code>virtual EnumFeatureId featureId() const</code> / <code>virtual EnumGeometryId geometryId() const</code>
 
87
but those are mostly a convenience solution to provide a way to check the type 
 
88
of your data when it is contained in the base class.
 
89
Each of the base classes contains a <code>void*</code> pointer which holds the address of the 
 
90
private <code>d</code> pointer. Instead of having one <code>d</code> pointer per derivation step, we only 
 
91
have one per object. With a function <code>p()</code> which is contained by each derived class
 
92
a pointer casted to the Private class of the class is returned. All of the private 
 
93
classes are derived from each other, in the same way as their connected classes.
 
94
In the base class (in this case <code>GeoDataFeature</code> and <code>GeoDataGeometry</code>) a function 
 
95
<code>void detach()</code> is implemented which calls the <code>void* copy()</code> function of the private class.
 
96
This way a copy will always result in the same type as the original, even though 
 
97
it might occur in a different wrapper (one of the type classes e.g.).
 
98
Above mentioned reference counting is done in the detach function.
 
99
</p>
 
100
<a name="serialization and deserialization"><h2>serialization and deserialization</h2></a>
 
101
<p>The idea of a full serialization of GeoData-API is to use that for saving and
 
102
reloading binary representations of GeoData-objects. For this to happen you simply
 
103
need to call the <code>pack()</code> or <code>unpack()</code> function for the base
 
104
<code>GeoDataDocument</code> providing a <code>QDataStream</code>. As the saved
 
105
amount in space, is very small, Marble itself still uses a lossy implementation
 
106
for that.</p>
 
107
</body>
 
108
</html>
 
 
b'\\ No newline at end of file'