1 #ifndef MERKATOR_MAPFEATURE_H_
2 #define MERKATOR_MAPFEATURE_H_
3 
4 class Feature;
5 
6 #include "IFeature.h"
7 #include "Coord.h"
8 #include "MapView.h"
9 #include "FeaturePainter.h"
10 
11 #include <QList>
12 #include <QPainter>
13 #include <QPainterPath>
14 #include <QString>
15 
16 #define CAST_FEATURE(x) (dynamic_cast<Feature*>(x))
17 #define CAST_NODE(x) (dynamic_cast<Node*>(x))
18 #define CAST_TRACKNODE(x) (dynamic_cast<TrackNode*>(x))
19 #define CAST_WAY(x) (dynamic_cast<Way*>(x))
20 #define CAST_RELATION(x) (dynamic_cast<Relation*>(x))
21 #define CAST_SEGMENT(x) (dynamic_cast<TrackSegment*>(x))
22 
23 #define STATIC_CAST_FEATURE(x) (static_cast<Feature*>(x))
24 #define STATIC_CAST_NODE(x) (static_cast<Node*>(x))
25 #define STATIC_CAST_TRACKNODE(x) (static_cast<TrackNode*>(x))
26 #define STATIC_CAST_WAY(x) (static_cast<Way*>(x))
27 #define STATIC_CAST_RELATION(x) (static_cast<Relation*>(x))
28 #define STATIC_CAST_SEGMENT(x) (static_cast<TrackSegment*>(x))
29 
30 #define CHECK_NODE(x) ((x)->getType() & IFeature::Point)
31 #define CHECK_WAY(x) ((x)->getType() & IFeature::LineString)
32 #define CHECK_RELATION(x) ((x)->getType() & IFeature::OsmRelation)
33 #define CHECK_SEGMENT(x) ((x)->getType() & IFeature::GpxSegment)
34 
35 class CommandList;
36 class Document;
37 class Layer;
38 class Projection;
39 class TrackNode;
40 
41 class QPointF;
42 class QPainter;
43 class QPen;
44 class QProgressDialog;
45 
46 class FeaturePrivate;
47 
48 class RenderPriority
49 {
50 public:
51     typedef enum { IsArea, IsLinear, IsSingular } Class;
RenderPriority()52     RenderPriority()
53         : theClass(IsLinear), InClassPriority(0.0), theLayer(0) { }
RenderPriority(Class C,qreal IC,int L)54     RenderPriority(Class C, qreal IC, int L)
55         : theClass(C), InClassPriority(IC), theLayer(L) { }
RenderPriority(const RenderPriority & other)56     RenderPriority(const RenderPriority& other)
57         : theClass(other.theClass), InClassPriority(other.InClassPriority), theLayer(other.theLayer) { }
58     bool operator<(const RenderPriority& R) const
59     {
60         return (theClass < R.theClass) ||
61                 ( (theClass == R.theClass) && (InClassPriority < R.InClassPriority) );
62     }
63     bool operator==(const RenderPriority& R) const
64     {
65         return ((theClass == R.theClass) && (InClassPriority == R.InClassPriority));
66     }
67     RenderPriority &operator=(const RenderPriority &other)
68     {
69         if (this != &other) {
70             theClass = other.theClass;
71             InClassPriority = other.InClassPriority;
72             theLayer = other.theLayer;
73         }
74         return *this;
75     }
layer()76     int layer() const
77     {
78         return theLayer;
79     }
80 
81 private:
82     Class theClass;
83     qreal InClassPriority;
84     int theLayer;
85 };
86 
87 
88 /// Used to store objects of the map
89 class Feature : public IFeature
90 {
91     friend class FeaturePrivate;
92     friend class MemoryBackend;
93 
94 public:
95     typedef enum { User, UserResolved, OSMServer, OSMServerConflict, NotYetDownloaded, Log } ActorType;
96     typedef enum { UnknownDirection, BothWays, OneWay, OtherWay } TrafficDirectionType;
97 public:
98     /// Constructor for an empty map feature
99     Feature();
100     /// Copy constructor
101     /// @param other the MapFeature
102     Feature(const Feature& other);
103     /// Destructor
104     virtual ~Feature();
105 
106     /** Return the smalest box contening all the MapFeature
107          * @return A coord box
108          */
109     virtual const CoordBox& boundingBox(bool update=true) const = 0;
110 
111     /** Draw the feature using the given QPainter an Projection
112          * @param P The QPainter used to draw
113          * @param theProjection the Projection used to convert real coordinates to screen coordinates
114          */
115     virtual void drawSimple(QPainter& P, MapView* theView) = 0;
116     virtual void drawTouchup(QPainter& P, MapView* theView) = 0;
117 
118     virtual void drawSpecial(QPainter& P, QPen& Pen, MapView* theView) = 0;
119     virtual void drawParentsSpecial(QPainter& P, QPen& Pen, MapView* theView) = 0;
120     virtual void drawChildrenSpecial(QPainter & P, QPen& Pen, MapView* theView, int depth) = 0;
121     virtual void drawHover(QPainter& P, MapView* theView);
122     virtual void drawHighlight(QPainter& P, MapView* theView);
123     virtual void drawFocus(QPainter& P, MapView* theView);
124 
125     virtual qreal pixelDistance(const QPointF& Target, qreal ClearEndDistance, const QList<Feature*>& NoSnap, MapView* theView) const = 0;
126     virtual void cascadedRemoveIfUsing(Document* theDocument, Feature* aFeature, CommandList* theList, const QList<Feature*>& Alternatives) = 0;
127     virtual bool notEverythingDownloaded() = 0;
128 
129     /** Set the id for the current feature.
130          */
131     void setId(const IFeature::FId& id);
132 
133     /** Reset the id for the current feature to a random one.
134          */
135     const IFeature::FId& resetId() const;
136 
137     /** Give the id of the feature.
138          *  If the feature has no id, a random id is generated
139          * @return the id of the current feature
140          */
141     const IFeature::FId& id() const;
142 
143     QString xmlId() const;
144     bool hasOSMId() const;
145     ActorType lastUpdated() const;
146     void setLastUpdated(ActorType A);
147 #ifndef FRISIUS_BUILD
148     const QDateTime time() const;
149     void setTime(const QDateTime& aTime);
150     void setTime(uint epoch);
151     const QString& user() const;
152     void setUser(const QString& aUser);
153     int versionNumber() const;
154     void setVersionNumber(int vn);
155 #endif
156     virtual void setLayer(Layer* aLayer);
157     virtual Layer* layer() const;
158     virtual QString description() const = 0;
159 
160     /** Set the tag "key=value" to the current object
161          * If a tag with the same key exist, it is replaced
162          * Otherwise the tag is added at the end
163          * @param key the key of the tag
164          * @param value the value corresponding to the key
165          */
166     virtual void setTag(const QString& key, const QString& value);
167 
168     /** Set the tag "key=value" at the position index
169          * If a tag with the same key exist, it is replaced
170          * Otherwise the tag is added at the index position
171          * @param index the place for the given tag. Start at 0.
172          * @param key the key of the tag
173          * @param value the value corresponding to the key
174         */
175     virtual void setTag(int index, const QString& key, const QString& value);
176 
177     /** remove all the tags for the curent feature
178          */
179     virtual void clearTags();
180 
181     /** remove the tag with the key "k".
182          * if no corresponding tag, don't do anything
183          */
184     virtual void clearTag(const QString& k);
185 
186     /** @return the number of tags for the current object
187          */
188     virtual int tagSize() const;
189 
190     /** if a tag with the key "k" exists, return its index.
191          * if the key doesn't exist, return the number of tags
192          * @return index of tag
193          */
194     virtual int findKey(const QString& k) const;
195 
196     /** return the value of the tag at the position "i".
197          * position start at 0.
198          * Be carefull: no verification is made on i.
199          * @return the value
200          */
201     virtual QString tagValue(int i) const;
202 
203     /** return the value of the tag with the key "k".
204          * if such a tag doesn't exists, return Default.
205          * @return value or Default
206          */
207     virtual QString tagValue(const QString& k, const QString& Default) const;
208 
209     /** return the value of the tag at the position "i".
210          * position start at 0.
211          * Be carefull: no verification is made on i.
212          * @return the value
213         */
214     virtual QString tagKey(int i) const;
215 
216     /** remove the tag at the position "i".
217          * position start at 0.
218          * Be carefull: no verification is made on i.
219          */
220     virtual void removeTag(int i);
221 
222     /** check if the dirty status of the feature
223          * @return true if the feature is dirty
224          */
225     virtual bool isDirty() const;
226 
227     virtual int incDirtyLevel(int inc=1);
228     virtual int decDirtyLevel(int inc=1);
229     virtual int getDirtyLevel() const;
230     virtual int setDirtyLevel(int newLevel);
231 
232     /** check if the feature is on an uploadable layer
233          * @return true if on an uploadable layer
234          */
235     virtual bool isUploadable() const;
236 
237     /** check if the feature is read-only
238          * @return true if is read-only
239          */
240     virtual bool isReadonly();
241     virtual void setReadonly(bool val);
242 
243     /** set the logical delete state of the feature
244          */
245     virtual void setDeleted(bool delState);
246 
247     /** check if the feature is logically deleted
248          * @return true if logically deleted
249          */
250     virtual bool isDeleted() const;
251 
252     /** set the visibility state of the feature
253          */
254     virtual void setVisible(bool val);
255 
256     /** check if the feature is visible
257          * @return true if visible
258          */
259     virtual bool isVisible();
260 
261     /** check if the feature is hidden
262          * @return true if hidden
263          */
264     virtual bool isHidden();
265 
266     /** check if the feature has been uploaded
267          * @return true if uploaded
268          */
269     virtual bool isUploaded() const;
270     virtual void setUploaded(bool state);
271 
272     /** check if the feature is virtual
273          * @return true if virtual
274          */
275     virtual bool isVirtual() const;
276     virtual void setVirtual(bool val);
277 
278     /** check if the feature is a special one (cannot be uploaded)
279          * @return true if special
280          */
281     virtual bool isSpecial() const;
282     virtual void setSpecial(bool val);
283 
284     virtual void buildPath(const Projection& aProjection);
285     virtual const QPainterPath& getPath() const;
286 
287     const FeaturePainter* getPainter(qreal PixelPerM) const;
288     const FeaturePainter* getCurrentPainter() const;
289     bool hasPainter() const;
290     bool hasPainter(qreal PixelPerM) const;
291     void invalidatePainter();
292     QVector<qreal> getParentDashes() const;
293 
294     virtual qreal getAlpha();
295 
296     virtual void remove(int Idx) = 0;
297     virtual void remove(Feature* F) = 0;
298     virtual int size() const = 0;
299     virtual int find(Feature* Pt) const = 0;
300     virtual Feature* get(int idx) = 0;
301     virtual const Feature* get(int Idx) const = 0;
302     virtual bool isNull() const = 0;
303 
304     int sizeParents() const;
305     IFeature* getParent(int i);
306     const IFeature* getParent(int i) const;
307 
308     void setParentFeature(Feature* F);
309     void unsetParentFeature(Feature* F);
310     virtual void partChanged(Feature* F, int ChangeId) = 0;
311     void notifyChanges();
312     void notifyParents(int Id);
313 
314     static void fromXML(QXmlStreamReader& stream, Feature* F);
315     virtual void toXML(QXmlStreamWriter& stream, bool strict, QString changetsetid = QString());
316 
317     virtual QString toXML(int lvl=0, QProgressDialog * progress=NULL);
318     virtual bool toXML(QXmlStreamWriter& stream, QProgressDialog * progress=NULL, bool strict=false, QString changetsetid = QString()) = 0;
319 
320     QString toMainHtml(QString type, QString systemtype);
toHtml()321     virtual QString toHtml() { return QString(); }
322 
323     virtual QString getClass() const = 0;
324     virtual char getType() const = 0;
325     virtual void updateMeta();
326     virtual void updateFilters();
327     virtual void invalidateMeta();
328 
deleteChildren(Document *,CommandList *)329     virtual bool deleteChildren(Document* , CommandList* ) { return true; }
330 
331     static Relation * GetSingleParentRelation(Feature * mapFeature);
332     static Node* getNodeOrCreatePlaceHolder(Document *theDocument, Layer *theLayer, const IFeature::FId& Id);
333     static TrackNode* getTrackNodeOrCreatePlaceHolder(Document *theDocument, Layer *theLayer, const IFeature::FId& Id);
334     static Way* getWayOrCreatePlaceHolder(Document *theDocument, Layer *theLayer, const IFeature::FId& Id);
335     static Relation* getRelationOrCreatePlaceHolder(Document *theDocument, Layer *theLayer, const IFeature::FId& Id);
336     static void mergeTags(Document* theDocument, CommandList* L, Feature* Dest, Feature* Src);
337 
338     static QString stripToOSMId(const IFeature::FId& id);
339 
340     void getLock();
341     void releaseLock();
342 
343 private:
344     FeaturePrivate* p;
345 
346 protected:
347     mutable CoordBox BBox;
348     bool ReadOnly; // 1
349     bool MetaUpToDate;
350     IFeature::FId newId(IFeature::FeatureType type) const;
351     QMutex featMutex;
352 
353     bool tagsToXML(QXmlStreamWriter& stream, bool strict);
354     static void tagsFromXML(Document* d, Feature* f, QXmlStreamReader& stream);
355 
356     QPainterPath thePath;
357 };
358 
359 Q_DECLARE_METATYPE( Feature * );
360 
361 extern qint64 g_feat_rndId;
362 
363 void copyTags(Feature* Dest, Feature* Src);
364 bool hasOSMId(const Feature* aFeature);
365 
366 #endif
367 
368 
369