1 // Copyright 2008, Google Inc. All rights reserved.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are met:
5 //
6 //  1. Redistributions of source code must retain the above copyright notice,
7 //     this list of conditions and the following disclaimer.
8 //  2. Redistributions in binary form must reproduce the above copyright notice,
9 //     this list of conditions and the following disclaimer in the documentation
10 //     and/or other materials provided with the distribution.
11 //  3. Neither the name of Google Inc. nor the names of its contributors may be
12 //     used to endorse or promote products derived from this software without
13 //     specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 // This file contains the declarations for the abstract Geometry element
27 // and concrete coordinates, Point, LineString, LinearRing, Polygon,
28 // outerBoundaryIs, and innerBoundaryIs elements.
29 
30 // In addition to classes for the abstract and concrete elements in the
31 // KML standard there are internal convenience classes used here to hold
32 // common code.  Each such class is named *GeometryCommon and follows
33 // this general pattern: constructor is protected, implements set,get,has,clear
34 // for the field it owns, and parses that field (implements AddElement).
35 // Each concrete element owns serialization of all fields for itself as per
36 // the order the KML standard.  The KML standard does not specify the common
37 // simple elements in an order that maps well to a type hierarchy hence
38 // the more typical pattern of abstract types serializing their own
39 // fields is not followed here.
40 //
41 // Here is a quick summary of the type hierarchy used and what fields
42 // are associated with each type:
43 //
44 // class Geometry : public Object
45 //   AbstractGeometryGroup in the KML standard.  No child elements.
46 // class AltitudeGeometryCommon : public Geometry
47 //   Geometry with <altitudeMode>
48 // class ExtrudeGeometryCommon : public AltitudeGeometryCommon
49 //   Geometry with <altitudeMode> + <extrude>
50 // class CoordinatesGeometryCommon : public ExtrudeGeometryCommon
51 //   Geometry with <altitudeMode> + <extrude> + <coordinates>
52 // class Point : public CoordinatesGeometryCommon
53 //   <Point> has <altitudeMode> + <extrude> + <coordinates>
54 // class LineCommon : public CoordinatesGeometryCommon
55 //   LineCommon has <altitudeMode> + <extrude> + <coordinates> + <tessellate>
56 // class LineString : public LineCommon
57 //   <LineString> is an instantiation of LineCommon
58 // class LinearRing : public LineCommon
59 //   <LinearRing> is an instantiation of LineCommon
60 // class BoundaryCommon : public Element
61 //   BoundaryCommon has <LinearRing>
62 // class OuterBoundaryIs : public BoundaryCommon
63 //  <outerBoundaryIs> is an instantiation of BoundaryCommon
64 // class InnerBoundaryIs : public BoundaryCommon
65 //  <innerBoundaryIs> is an instantiation of BoundaryCommon
66 // class Polygon : public ExtrudeGeometryCommon
67 //   <Polygon> has <altitudeMode> + <extrude> + <tessellate> +
68 //      <outerBoundaryIs> and N x <innerBoundaryIs>
69 // class MultiGeometry : public Geometry
70 // Note: class Model : public AltitudeGeometryCommon
71 
72 #ifndef KML_DOM_GEOMETRY_H__
73 #define KML_DOM_GEOMETRY_H__
74 
75 #include <vector>
76 #include "kml/base/util.h"
77 #include "kml/base/vec3.h"
78 #include "kml/dom/extendeddata.h"
79 #include "kml/dom/kml22.h"
80 #include "kml/dom/kml_ptr.h"
81 #include "kml/dom/link.h"  // Remove when model.h is repaired.
82 #include "kml/dom/object.h"
83 
84 namespace kmldom {
85 
86 class Serializer;
87 class Visitor;
88 class VisitorDriver;
89 
90 // <coordinates>
91 class Coordinates : public BasicElement<Type_coordinates> {
92  public:
93   virtual ~Coordinates();
94 
95   // The main KML-specific API
add_latlngalt(double latitude,double longitude,double altitude)96   void add_latlngalt(double latitude, double longitude, double altitude) {
97     coordinates_array_.push_back(kmlbase::Vec3(longitude, latitude, altitude));
98   }
99 
add_latlng(double latitude,double longitude)100   void add_latlng(double latitude, double longitude) {
101     coordinates_array_.push_back(kmlbase::Vec3(longitude, latitude));
102   }
103 
add_vec3(const kmlbase::Vec3 & vec3)104   void add_vec3(const kmlbase::Vec3& vec3) {
105     coordinates_array_.push_back(vec3);
106   }
107 
get_coordinates_array_size()108   size_t get_coordinates_array_size() const {
109     return coordinates_array_.size();
110   }
111 
get_coordinates_array_at(size_t index)112   const kmlbase::Vec3 get_coordinates_array_at(size_t index) const {
113     return coordinates_array_[index];
114   }
115 
116   // Internal methods used in parser.  Public for unittest purposes.
117   // See .cc for more details.
118   void Parse(const string& char_data);
119   static bool ParseVec3(const char* coords, char** nextp, kmlbase::Vec3* vec);
120 
121   // This clears the internal coordinates array.
Clear()122   void Clear() {
123     coordinates_array_.clear();
124   }
125 
126   // Visitor API methods, see visitor.h.
127   virtual void Accept(Visitor* visitor);
128 
129  private:
130   friend class KmlFactory;
131   Coordinates();
132   friend class KmlHandler;
133   virtual void AddElement(const ElementPtr& element);
134   friend class Serializer;
135   virtual void Serialize(Serializer& serializer) const;
136 
137   std::vector<kmlbase::Vec3> coordinates_array_;
138   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(Coordinates);
139 };
140 
141 // OGC KML 2.2 Standard: 10.1 kml:AbstractGeometryGroup
142 // OGC KML 2.2 XSD: <element name="AbstractGeometryGroup"...
143 class Geometry : public Object {
144  public:
145   virtual ~Geometry();
Type()146   virtual KmlDomType Type() const { return Type_Geometry; }
IsA(KmlDomType type)147   virtual bool IsA(KmlDomType type) const {
148     return type == Type_Geometry || Object::IsA(type);
149   }
150 
151  protected:
152   // Geometry is abstract.
153   Geometry();
154 
155  private:
156   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(Geometry);
157 };
158 
159 // Internal convenience class for any Geometry with <altitudeMode>.
160 // This is not in the KML standard, hence there is no type info.
161 class AltitudeGeometryCommon : public Geometry {
162  public:
163   virtual ~AltitudeGeometryCommon();
164 
165  protected:
166   AltitudeGeometryCommon();
167 
168  public:
169   // <altitudeMode>
get_altitudemode()170   int get_altitudemode() const { return altitudemode_; }
has_altitudemode()171   bool has_altitudemode() const { return has_altitudemode_; }
set_altitudemode(int value)172   void set_altitudemode(int value) {
173     altitudemode_ = value;
174     has_altitudemode_ = true;
175   }
clear_altitudemode()176   void clear_altitudemode() {
177     altitudemode_ = ALTITUDEMODE_CLAMPTOGROUND;
178     has_altitudemode_ = false;
179   }
180 
181   // <gx:altitudeMode>
get_gx_altitudemode()182   int get_gx_altitudemode() const { return gx_altitudemode_; }
has_gx_altitudemode()183   bool has_gx_altitudemode() const { return has_gx_altitudemode_; }
set_gx_altitudemode(int value)184   void set_gx_altitudemode(int value) {
185     gx_altitudemode_ = value;
186     has_gx_altitudemode_ = true;
187   }
clear_gx_altitudemode()188   void clear_gx_altitudemode() {
189     gx_altitudemode_ = GX_ALTITUDEMODE_CLAMPTOSEAFLOOR;
190     has_gx_altitudemode_ = false;
191   }
192 
193   virtual void AddElement(const ElementPtr& element);
194 
195  private:
196   int altitudemode_;
197   bool has_altitudemode_;
198   int gx_altitudemode_;
199   bool has_gx_altitudemode_;
200   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(AltitudeGeometryCommon);
201 };
202 
203 // Internal convenience class for any Geometry with <altitudeMode> + <extrude>
204 // This is not in the KML standard, hence there is no type info.
205 class ExtrudeGeometryCommon : public AltitudeGeometryCommon {
206  public:
207   virtual ~ExtrudeGeometryCommon();
208 
209   // <extrude>
get_extrude()210   bool get_extrude() const { return extrude_; }
has_extrude()211   bool has_extrude() const { return has_extrude_; }
set_extrude(bool value)212   void set_extrude(bool value) {
213     extrude_ = value;
214     has_extrude_ = true;
215   }
clear_extrude()216   void clear_extrude() {
217     extrude_ = false;
218     has_extrude_ = false;
219   }
220 
221  protected:
222   ExtrudeGeometryCommon();
223   virtual void AddElement(const ElementPtr& element);
224 
225  private:
226   bool extrude_;
227   bool has_extrude_;
228   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(ExtrudeGeometryCommon);
229 };
230 
231 // Internal convenience class for any Geometry with
232 // <altitudeMode> + <extrude> + <coordinates>.
233 // This is not in the KML standard, hence there is no type info.
234 class CoordinatesGeometryCommon : public ExtrudeGeometryCommon {
235  public:
236   virtual ~CoordinatesGeometryCommon();
237 
238  public:
239   // <coordinates>
get_coordinates()240   const CoordinatesPtr& get_coordinates() const { return coordinates_; }
has_coordinates()241   bool has_coordinates() const { return coordinates_ != NULL; }
set_coordinates(const CoordinatesPtr & coordinates)242   void set_coordinates(const CoordinatesPtr& coordinates) {
243     SetComplexChild(coordinates, &coordinates_);
244   }
clear_coordinates()245   void clear_coordinates() {
246     set_coordinates(NULL);
247   }
248 
249   // Visitor API methods, see visitor.h.
250   virtual void AcceptChildren(VisitorDriver* driver);
251 
252  protected:
253   CoordinatesGeometryCommon();
254   // Parser support
255   virtual void AddElement(const ElementPtr& element);
256 
257  private:
258   CoordinatesPtr coordinates_;
259   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(CoordinatesGeometryCommon);
260 };
261 
262 // <Point>
263 class Point : public CoordinatesGeometryCommon {
264  public:
265   virtual ~Point();
Type()266   virtual KmlDomType Type() const { return Type_Point; }
IsA(KmlDomType type)267   virtual bool IsA(KmlDomType type) const {
268     return type == Type_Point || Geometry::IsA(type);
269   }
270 
271   // Visitor API methods, see visitor.h.
272   virtual void Accept(Visitor* visitor);
273 
274  private:
275   friend class KmlFactory;
276   Point();
277   friend class Serializer;
278   void Serialize(Serializer& serializer) const;
279   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(Point);
280 };
281 
282 // Internal convenience class for code common to LineString and LinearRing.
283 // This is not in the KML standard, hence there is no type info.
284 class LineCommon : public CoordinatesGeometryCommon {
285  public:
286   virtual ~LineCommon();
287 
288  public:
289   // <tessellate>
get_tessellate()290   bool get_tessellate() const { return tessellate_; }
has_tessellate()291   bool has_tessellate() const { return has_tessellate_; }
set_tessellate(bool value)292   void set_tessellate(bool value) {
293     tessellate_ = value;
294     has_tessellate_ = true;
295   }
clear_tessellate()296   void clear_tessellate() {
297     tessellate_ = false;
298     has_tessellate_ = false;
299   }
300 
301  protected:
302   LineCommon();
303   // Parser support
304   virtual void AddElement(const ElementPtr& element);
305 
306  private:
307   friend class Serializer;
308   void Serialize(Serializer& serializer) const;
309   bool tessellate_;
310   bool has_tessellate_;
311   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(LineCommon);
312 };
313 
314 // <LineString>
315 class LineString : public LineCommon {
316  public:
317   virtual ~LineString();
Type()318   virtual KmlDomType Type() const { return Type_LineString; }
IsA(KmlDomType type)319   virtual bool IsA(KmlDomType type) const {
320     return type == Type_LineString || Geometry::IsA(type);
321   }
322 
323   // Visitor API methods, see visitor.h.
324   virtual void Accept(Visitor* visitor);
325 
326  private:
327   friend class KmlFactory;
328   LineString();
329   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(LineString);
330 };
331 
332 // <LinearRing>
333 class LinearRing : public LineCommon {
334  public:
335   virtual ~LinearRing();
Type()336   virtual KmlDomType Type() const { return Type_LinearRing; }
IsA(KmlDomType type)337   virtual bool IsA(KmlDomType type) const {
338     return type == Type_LinearRing || Geometry::IsA(type);
339   }
340 
341   // Visitor API methods, see visitor.h.
342   virtual void Accept(Visitor* visitor);
343 
344  private:
345   friend class KmlFactory;
346   LinearRing();
347   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(LinearRing);
348 };
349 
350 // Internal class for code common to OuterBoundaryIs and InnerBoundaryIs.
351 // This is not in the KML standard, hence there is no type info.
352 class BoundaryCommon : public Element {
353  public:
354   virtual ~BoundaryCommon();
355 
356  public:
get_linearring()357   const LinearRingPtr& get_linearring() const { return linearring_; }
has_linearring()358   bool has_linearring() const { return linearring_ != NULL; }
set_linearring(const LinearRingPtr & linearring)359   void set_linearring(const LinearRingPtr& linearring) {
360     SetComplexChild(linearring, &linearring_);
361   }
clear_linearring()362   void clear_linearring() {
363     set_linearring(NULL);
364   }
365 
366   // Parser support
367   virtual void AddElement(const ElementPtr& element);
368 
369   // Visitor API methods, see visitor.h.
370   virtual void AcceptChildren(VisitorDriver* driver);
371 
372  protected:
373   BoundaryCommon();
374   virtual void Serialize(Serializer& serializer) const;
375 
376  private:
377   LinearRingPtr linearring_;
378   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(BoundaryCommon);
379 };
380 
381 // <outerBoundaryIs>
382 class OuterBoundaryIs : public BoundaryCommon {
383  public:
384   virtual ~OuterBoundaryIs();
Type()385   virtual KmlDomType Type() const { return Type_outerBoundaryIs; }
IsA(KmlDomType type)386   virtual bool IsA(KmlDomType type) const {
387     return type == Type_outerBoundaryIs;
388   }
389 
390   // Visitor API methods, see visitor.h.
391   virtual void Accept(Visitor* visitor);
392 
393  private:
394   friend class KmlFactory;
395   OuterBoundaryIs();
396   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(OuterBoundaryIs);
397 };
398 
399 // <innerBoundaryIs>
400 class InnerBoundaryIs : public BoundaryCommon {
401  public:
402   virtual ~InnerBoundaryIs();
Type()403   virtual KmlDomType Type() const { return Type_innerBoundaryIs; }
IsA(KmlDomType type)404   virtual bool IsA(KmlDomType type) const {
405     return type == Type_innerBoundaryIs;
406   }
407 
408   // Visitor API methods, see visitor.h.
409   virtual void Accept(Visitor* visitor);
410 
411  private:
412   friend class KmlFactory;
413   InnerBoundaryIs();
414   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(InnerBoundaryIs);
415 };
416 
417 // <Polygon>
418 class Polygon : public ExtrudeGeometryCommon {
419  public:
420   virtual ~Polygon();
Type()421   virtual KmlDomType Type() const { return Type_Polygon; }
IsA(KmlDomType type)422   virtual bool IsA(KmlDomType type) const {
423     return type == Type_Polygon || Geometry::IsA(type);
424   }
425 
426   // <tessellate>
get_tessellate()427   bool get_tessellate() const { return tessellate_; }
has_tessellate()428   bool has_tessellate() const { return has_tessellate_; }
set_tessellate(bool value)429   void set_tessellate(bool value) {
430     tessellate_ = value;
431     has_tessellate_ = true;
432   }
clear_tessellate()433   void clear_tessellate() {
434     tessellate_ = false;
435     has_tessellate_ = false;
436   }
437 
438   // <outerBoundaryIs>
get_outerboundaryis()439   const OuterBoundaryIsPtr& get_outerboundaryis() const {
440     return outerboundaryis_;
441   }
has_outerboundaryis()442   bool has_outerboundaryis() const { return outerboundaryis_ != NULL; }
set_outerboundaryis(const OuterBoundaryIsPtr & outerboundaryis)443   void set_outerboundaryis(const OuterBoundaryIsPtr& outerboundaryis) {
444     SetComplexChild(outerboundaryis, &outerboundaryis_);
445   }
clear_outerboundaryis()446   void clear_outerboundaryis() {
447     set_outerboundaryis(NULL);
448   }
449 
450   // <innerBoundaryIs>
add_innerboundaryis(const InnerBoundaryIsPtr & innerboundaryis)451   void add_innerboundaryis(const InnerBoundaryIsPtr& innerboundaryis) {
452     AddComplexChild(innerboundaryis, &innerboundaryis_array_);
453   }
454 
get_innerboundaryis_array_size()455   size_t get_innerboundaryis_array_size() const {
456     return innerboundaryis_array_.size();
457   }
458 
get_innerboundaryis_array_at(size_t index)459   const InnerBoundaryIsPtr& get_innerboundaryis_array_at(size_t index) {
460     return innerboundaryis_array_[index];
461   }
462 
463   // Visitor API methods, see visitor.h.
464   virtual void Accept(Visitor* visitor);
465   virtual void AcceptChildren(VisitorDriver* driver);
466 
467  private:
468   friend class KmlFactory;
469   Polygon();
470 
471   friend class KmlHandler;
472   virtual void AddElement(const ElementPtr& element);
473 
474   friend class Serializer;
475   virtual void Serialize(Serializer& serializer) const;
476 
477   bool tessellate_;
478   bool has_tessellate_;
479   OuterBoundaryIsPtr outerboundaryis_;
480   std::vector<InnerBoundaryIsPtr> innerboundaryis_array_;
481   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(Polygon);
482 };
483 
484 // <MultiGeometry>
485 class MultiGeometry : public Geometry {
486  public:
487   virtual ~MultiGeometry();
Type()488   virtual KmlDomType Type() const { return Type_MultiGeometry; }
IsA(KmlDomType type)489   virtual bool IsA(KmlDomType type) const {
490     return type == Type_MultiGeometry || Geometry::IsA(type);
491   }
492 
493   // The main KML-specific API
494   void add_geometry(const GeometryPtr& geometry);
495 
get_geometry_array_size()496   size_t get_geometry_array_size() const {
497     return geometry_array_.size();
498   }
499 
get_geometry_array_at(size_t index)500   const GeometryPtr& get_geometry_array_at(size_t index) const {
501     return geometry_array_[index];
502   }
503 
504   // Visitor API methods, see visitor.h.
505   virtual void Accept(Visitor* visitor);
506   virtual void AcceptChildren(VisitorDriver* driver);
507 
508  private:
509   friend class KmlFactory;
510   MultiGeometry();
511   friend class KmlHandler;
512   virtual void AddElement(const ElementPtr& element);
513   friend class Serializer;
514   virtual void Serialize(Serializer& serializer) const;
515   std::vector<GeometryPtr> geometry_array_;
516   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(MultiGeometry);
517 };
518 
519 // <gx:Track>
520 class GxTrack : public AltitudeGeometryCommon {
521  public:
522   virtual ~GxTrack();
ElementType()523   static KmlDomType ElementType() { return Type_GxTrack; }
Type()524   virtual KmlDomType Type() const { return ElementType(); }
IsA(KmlDomType type)525   virtual bool IsA(KmlDomType type) const {
526     return type == ElementType() || Geometry::IsA(type);
527   }
528 
529   // <when>
get_when_array_size()530   size_t get_when_array_size() {
531     return when_array_.size();
532   }
add_when(const string & when)533   void add_when(const string& when) {
534     when_array_.push_back(when);
535   }
get_when_array_at(size_t index)536   const string& get_when_array_at(size_t index) const {
537     return when_array_[index];
538   }
539 
540   // <gx:coord>
get_gx_coord_array_size()541   size_t get_gx_coord_array_size() {
542     return gx_coord_array_.size();
543   }
add_gx_coord(const kmlbase::Vec3 & gx_coord)544   void add_gx_coord(const kmlbase::Vec3& gx_coord) {
545     gx_coord_array_.push_back(gx_coord);
546   }
get_gx_coord_array_at(size_t index)547   const kmlbase::Vec3& get_gx_coord_array_at(size_t index) const {
548     return gx_coord_array_[index];
549   }
550 
551   // <gx:angles>
get_gx_angles_array_size()552   size_t get_gx_angles_array_size() {
553     return gx_angles_array_.size();
554   }
add_gx_angles(const kmlbase::Vec3 & gx_angles)555   void add_gx_angles(const kmlbase::Vec3& gx_angles) {
556     gx_angles_array_.push_back(gx_angles);
557   }
get_gx_angles_array_at(size_t index)558   const kmlbase::Vec3& get_gx_angles_array_at(size_t index) const {
559     return gx_angles_array_[index];
560   }
561 
562   // <Model>
get_model()563   const ModelPtr& get_model() const { return model_; }
set_model(const ModelPtr & model)564   void set_model(const ModelPtr& model) {
565     SetComplexChild(model, &model_);
566   }
has_model()567   bool has_model() const { return model_ != NULL; }
clear_model()568   void clear_model() { set_model(NULL); }
569 
570   // <ExtendedData>
get_extendeddata()571   const ExtendedDataPtr& get_extendeddata() const { return extendeddata_; }
has_extendeddata()572   bool has_extendeddata() const { return extendeddata_ != NULL; }
set_extendeddata(const ExtendedDataPtr & extendeddata)573   void set_extendeddata(const ExtendedDataPtr& extendeddata) {
574     SetComplexChild(extendeddata, &extendeddata_);
575   }
clear_extendeddata()576   void clear_extendeddata() {
577     set_extendeddata(NULL);
578   }
579 
580   // Visitor API methods, see visitor.h.
581   virtual void Accept(Visitor* visitor);
582   virtual void AcceptChildren(VisitorDriver* driver);
583 
584   // Internal methods used in parser.  Public for unittest purposes.
585   // See .cc for more details.
586   void Parse(const string& char_data, std::vector<kmlbase::Vec3>* out);
587 
588  private:
589   friend class KmlFactory;
590   GxTrack();
591   friend class KmlHandler;
592   virtual void AddElement(const ElementPtr& element);
593   friend class Serializer;
594   virtual void Serialize(Serializer& serializer) const;
595   std::vector<string> when_array_;
596   std::vector<kmlbase::Vec3> gx_coord_array_;
597   std::vector<kmlbase::Vec3> gx_angles_array_;
598   ModelPtr model_;
599   ExtendedDataPtr  extendeddata_;
600   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(GxTrack);
601 };
602 
603 // <gx:MultiTrack>
604 class GxMultiTrack : public Geometry {
605  public:
606   virtual ~GxMultiTrack();
ElementType()607   static KmlDomType ElementType() { return Type_GxMultiTrack; }
Type()608   virtual KmlDomType Type() const { return ElementType(); }
IsA(KmlDomType type)609   virtual bool IsA(KmlDomType type) const {
610     return type == ElementType() || Geometry::IsA(type);
611   }
612 
get_gx_interpolate()613   bool get_gx_interpolate() const { return gx_interpolate_; }
has_gx_interpolate()614   bool has_gx_interpolate() const { return has_gx_interpolate_; }
set_gx_interpolate(bool value)615   void set_gx_interpolate(bool value) {
616     gx_interpolate_ = value;
617     has_gx_interpolate_ = true;
618   }
clear_gx_interpolate()619   void clear_gx_interpolate() {
620     gx_interpolate_ = false;  // Default <gx:interpolate> is false.
621     has_gx_interpolate_ = false;
622   }
623 
624   void add_gx_track(const GxTrackPtr& gx_track);
625 
get_gx_track_array_size()626   size_t get_gx_track_array_size() const {
627     return gx_track_array_.size();
628   }
629 
get_gx_track_array_at(size_t index)630   const GxTrackPtr& get_gx_track_array_at(size_t index) const {
631     return gx_track_array_[index];
632   }
633 
634   // Visitor API methods, see visitor.h.
635   virtual void Accept(Visitor* visitor);
636   virtual void AcceptChildren(VisitorDriver* driver);
637 
638  private:
639   friend class KmlFactory;
640   GxMultiTrack();
641   friend class KmlHandler;
642   virtual void AddElement(const ElementPtr& element);
643   friend class Serializer;
644   virtual void Serialize(Serializer& serializer) const;
645   bool gx_interpolate_;
646   bool has_gx_interpolate_;
647   std::vector<GxTrackPtr> gx_track_array_;
648   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(GxMultiTrack);
649 };
650 
651 
652 // HACK: the rest of this file contains what was in, and what should return to,
653 // kml/dom/model.h. GxTrack was added to this file, which has a <Model>. Since
654 // Model is defined in its own file, this double inclusion, coupled with the
655 // inline implementation of most methods in the headers, caused the builds of
656 // other dependent projects to break. The correct solution is to ensure that
657 // the headers are pure and all implementation is in the .cc files.
658 
659 // <Location>
660 class Location : public Object {
661  public:
662   virtual ~Location();
Type()663   virtual KmlDomType Type() const { return Type_Location; }
IsA(KmlDomType type)664   virtual bool IsA(KmlDomType type) const {
665     return type == Type_Location || Object::IsA(type);
666   }
667 
668   // <longitude>
get_longitude()669   double get_longitude() const {
670     return longitude_;
671   }
has_longitude()672   bool has_longitude() const {
673     return has_longitude_;
674   }
set_longitude(double longitude)675   void set_longitude(double longitude) {
676     longitude_ = longitude;
677     has_longitude_ = true;
678   }
clear_longitude()679   void clear_longitude() {
680     longitude_ = 0.0;
681     has_longitude_ = false;
682   }
683 
684   // <latitude>
get_latitude()685   double get_latitude() const {
686     return latitude_;
687   }
has_latitude()688   bool has_latitude() const {
689     return has_latitude_;
690   }
set_latitude(double latitude)691   void set_latitude(double latitude) {
692     latitude_ = latitude;
693     has_latitude_ = true;
694   }
clear_latitude()695   void clear_latitude() {
696     latitude_ = 0.0;
697     has_latitude_ = false;
698   }
699 
700   // <altitude>
get_altitude()701   double get_altitude() const {
702     return altitude_;
703   }
has_altitude()704   bool has_altitude() const {
705     return has_altitude_;
706   }
set_altitude(double altitude)707   void set_altitude(double altitude) {
708     altitude_ = altitude;
709     has_altitude_ = true;
710   }
clear_altitude()711   void clear_altitude() {
712     altitude_ = 0.0;
713     has_altitude_ = false;
714   }
715 
716   // Visitor API methods, see visitor.h.
717   virtual void Accept(Visitor* visitor);
718 
719  private:
720   friend class KmlFactory;
721   Location();
722   friend class KmlHandler;
723   virtual void AddElement(const ElementPtr& element);
724   friend class Serializer;
725   virtual void Serialize(Serializer& serializer) const;
726   double longitude_;
727   bool has_longitude_;
728   double latitude_;
729   bool has_latitude_;
730   double altitude_;
731   bool has_altitude_;
732   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(Location);
733 };
734 
735 // <Orientation>
736 class Orientation : public Object {
737  public:
738   virtual ~Orientation();
Type()739   virtual KmlDomType Type() const { return Type_Orientation; }
IsA(KmlDomType type)740   virtual bool IsA(KmlDomType type) const {
741     return type == Type_Orientation || Object::IsA(type);
742   }
743 
744   // <heading>
get_heading()745   double get_heading() const {
746     return heading_;
747   }
has_heading()748   bool has_heading() const {
749     return has_heading_;
750   }
set_heading(double heading)751   void set_heading(double heading) {
752     heading_ = heading;
753     has_heading_ = true;
754   }
clear_heading()755   void clear_heading() {
756     heading_ = 0.0;
757     has_heading_ = false;
758   }
759 
760   // <tilt>
get_tilt()761   double get_tilt() const {
762     return tilt_;
763   }
has_tilt()764   bool has_tilt() const {
765     return has_tilt_;
766   }
set_tilt(double tilt)767   void set_tilt(double tilt) {
768     tilt_ = tilt;
769     has_tilt_ = true;
770   }
clear_tilt()771   void clear_tilt() {
772     tilt_ = 0.0;
773     has_tilt_ = false;
774   }
775 
776   // <roll>
get_roll()777   double get_roll() const {
778     return roll_;
779   }
has_roll()780   bool has_roll() const {
781     return has_roll_;
782   }
set_roll(double roll)783   void set_roll(double roll) {
784     roll_ = roll;
785     has_roll_ = true;
786   }
clear_roll()787   void clear_roll() {
788     roll_ = 0.0;
789     has_roll_ = false;
790   }
791 
792   // Visitor API methods, see visitor.h.
793   virtual void Accept(Visitor* visitor);
794 
795  private:
796   friend class KmlFactory;
797   Orientation();
798   friend class KmlHandler;
799   virtual void AddElement(const ElementPtr& element);
800   friend class Serializer;
801   virtual void Serialize(Serializer& serializer) const;
802   double heading_;
803   bool has_heading_;
804   double tilt_;
805   bool has_tilt_;
806   double roll_;
807   bool has_roll_;
808   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(Orientation);
809 };
810 
811 // <Scale>
812 class Scale : public Object {
813  public:
814   virtual ~Scale();
Type()815   virtual KmlDomType Type() const { return Type_Scale; }
IsA(KmlDomType type)816   virtual bool IsA(KmlDomType type) const {
817     return type == Type_Scale || Object::IsA(type);
818   }
819 
820   // <x>
get_x()821   double get_x() const {
822     return x_;
823   }
has_x()824   bool has_x() const {
825     return has_x_;
826   }
set_x(double x)827   void set_x(double x) {
828     x_ = x;
829     has_x_ = true;
830   }
clear_x()831   void clear_x() {
832     x_ = 1.0;
833     has_x_ = false;
834   }
835 
836   // <y>
get_y()837   double get_y() const {
838     return y_;
839   }
has_y()840   bool has_y() const {
841     return has_y_;
842   }
set_y(double y)843   void set_y(double y) {
844     y_ = y;
845     has_y_ = true;
846   }
clear_y()847   void clear_y() {
848     y_ = 1.0;
849     has_y_ = false;
850   }
851 
852   // <z>
get_z()853   double get_z() const {
854     return z_;
855   }
has_z()856   bool has_z() const {
857     return has_z_;
858   }
set_z(double z)859   void set_z(double z) {
860     z_ = z;
861     has_z_ = true;
862   }
clear_z()863   void clear_z() {
864     z_ = 1.0;
865     has_z_ = false;
866   }
867 
868   // Visitor API methods, see visitor.h.
869   virtual void Accept(Visitor* visitor);
870 
871  private:
872   friend class KmlFactory;
873   Scale();
874   friend class KmlHandler;
875   virtual void AddElement(const ElementPtr& element);
876   friend class Serializer;
877   virtual void Serialize(Serializer& serializer) const;
878   double x_;
879   bool has_x_;
880   double y_;
881   bool has_y_;
882   double z_;
883   bool has_z_;
884   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(Scale);
885 };
886 
887 // <Alias>
888 class Alias : public Object {
889  public:
890   virtual ~Alias();
Type()891   virtual KmlDomType Type() const { return Type_Alias; }
IsA(KmlDomType type)892   virtual bool IsA(KmlDomType type) const {
893     return type == Type_Alias || Object::IsA(type);
894   }
895 
896   // <targetHref>
get_targethref()897   const string& get_targethref() const {
898     return targethref_;
899   }
has_targethref()900   bool has_targethref() const {
901     return has_targethref_;
902   }
set_targethref(const string & targethref)903   void set_targethref(const string& targethref) {
904     targethref_ = targethref;
905     has_targethref_ = true;
906   }
clear_targethref()907   void clear_targethref() {
908     targethref_.clear();
909     has_targethref_ = false;
910   }
911 
912   // <sourceHref>
get_sourcehref()913   const string& get_sourcehref() const {
914     return sourcehref_;
915   }
has_sourcehref()916   bool has_sourcehref() const {
917     return has_sourcehref_;
918   }
set_sourcehref(const string & sourcehref)919   void set_sourcehref(const string& sourcehref) {
920     sourcehref_ = sourcehref;
921     has_sourcehref_ = true;
922   }
clear_sourcehref()923   void clear_sourcehref() {
924     sourcehref_.clear();
925     has_sourcehref_ = false;
926   }
927 
928   // Visitor API methods, see visitor.h.
929   virtual void Accept(Visitor* visitor);
930 
931  private:
932   friend class KmlFactory;
933   Alias();
934   friend class KmlHandler;
935   virtual void AddElement(const ElementPtr& element);
936   friend class Serializer;
937   virtual void Serialize(Serializer& serializer) const;
938   string targethref_;
939   bool has_targethref_;
940   string sourcehref_;
941   bool has_sourcehref_;
942   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(Alias);
943 };
944 
945 // <ResourceMap>
946 class ResourceMap : public Object {
947  public:
948   virtual ~ResourceMap();
Type()949   virtual KmlDomType Type() const { return Type_ResourceMap; }
IsA(KmlDomType type)950   virtual bool IsA(KmlDomType type) const {
951     return type == Type_ResourceMap || Object::IsA(type);
952   }
953 
954   void add_alias(const AliasPtr& alias);
955 
get_alias_array_size()956   size_t get_alias_array_size() const {
957     return alias_array_.size();
958   }
959 
get_alias_array_at(size_t index)960   const AliasPtr& get_alias_array_at(size_t index) const {
961     return alias_array_[index];
962   }
963 
964   // Visitor API methods, see visitor.h.
965   virtual void Accept(Visitor* visitor);
966   virtual void AcceptChildren(VisitorDriver* driver);
967 
968  private:
969   friend class KmlFactory;
970   ResourceMap();
971   friend class KmlHandler;
972   virtual void AddElement(const ElementPtr& element);
973   friend class Serializer;
974   virtual void Serialize(Serializer& serializer) const;
975   std::vector<AliasPtr> alias_array_;
976   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(ResourceMap);
977 };
978 
979 // <Model>
980 class Model : public AltitudeGeometryCommon {
981  public:
982   virtual ~Model();
Type()983   virtual KmlDomType Type() const { return Type_Model; }
IsA(KmlDomType type)984   virtual bool IsA(KmlDomType type) const {
985     return type == Type_Model || Geometry::IsA(type);
986   }
987 
988   // <Location>
get_location()989   const LocationPtr& get_location() const { return location_; }
has_location()990   bool has_location() const { return location_ != NULL; }
set_location(const LocationPtr & location)991   void set_location(const LocationPtr& location) {
992     SetComplexChild(location, &location_);
993   }
clear_location()994   void clear_location() {
995     set_location(NULL);
996   }
997 
998   // <Orientation>
get_orientation()999   const OrientationPtr& get_orientation() const { return orientation_; }
has_orientation()1000   bool has_orientation() const { return orientation_ != NULL; }
set_orientation(const OrientationPtr & orientation)1001   void set_orientation(const OrientationPtr& orientation) {
1002     SetComplexChild(orientation, &orientation_);
1003   }
clear_orientation()1004   void clear_orientation() {
1005     set_orientation(NULL);
1006   }
1007 
1008   // <Scale>
get_scale()1009   const ScalePtr& get_scale() const { return scale_; }
has_scale()1010   bool has_scale() const { return scale_ != NULL; }
set_scale(const ScalePtr & scale)1011   void set_scale(const ScalePtr& scale) {
1012     SetComplexChild(scale, &scale_);
1013   }
clear_scale()1014   void clear_scale() {
1015     set_scale(NULL);
1016   }
1017 
1018   // <Link>
get_link()1019   const LinkPtr& get_link() const { return link_; }
has_link()1020   bool has_link() const { return link_ != NULL; }
set_link(const LinkPtr & link)1021   void set_link(const LinkPtr& link) {
1022     SetComplexChild(link, &link_);
1023   }
clear_link()1024   void clear_link() {
1025     set_link(NULL);
1026   }
1027 
1028   // <ResourceMap>
get_resourcemap()1029   const ResourceMapPtr& get_resourcemap() const { return resourcemap_; }
has_resourcemap()1030   bool has_resourcemap() const { return resourcemap_ != NULL; }
set_resourcemap(const ResourceMapPtr & resourcemap)1031   void set_resourcemap(const ResourceMapPtr& resourcemap) {
1032     SetComplexChild(resourcemap, &resourcemap_);
1033   }
clear_resourcemap()1034   void clear_resourcemap() {
1035     resourcemap_ = NULL;
1036   }
1037 
1038   // Visitor API methods, see visitor.h.
1039   virtual void Accept(Visitor* visitor);
1040   virtual void AcceptChildren(VisitorDriver* driver);
1041 
1042  private:
1043   friend class KmlFactory;
1044   Model();
1045   friend class KmlHandler;
1046   virtual void AddElement(const ElementPtr& element);
1047   friend class Serializer;
1048   virtual void Serialize(Serializer& serializer) const;
1049   LocationPtr location_;
1050   OrientationPtr orientation_;
1051   ScalePtr scale_;
1052   LinkPtr link_;
1053   ResourceMapPtr resourcemap_;
1054   LIBKML_DISALLOW_EVIL_CONSTRUCTORS(Model);
1055 };
1056 
1057 }  // namespace kmldom
1058 
1059 #endif  // KML_DOM_GEOMETRY_H__
1060 
1061