1 : /******************************************************************************
2 : *
3 : * Purpose: PCIDSK Vector Shape interface. Declaration.
4 : *
5 : ******************************************************************************
6 : * Copyright (c) 2009
7 : * PCI Geomatics, 50 West Wilmot Street, Richmond Hill, Ont, Canada
8 : *
9 : * Permission is hereby granted, free of charge, to any person obtaining a
10 : * copy of this software and associated documentation files (the "Software"),
11 : * to deal in the Software without restriction, including without limitation
12 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 : * and/or sell copies of the Software, and to permit persons to whom the
14 : * Software is furnished to do so, subject to the following conditions:
15 : *
16 : * The above copyright notice and this permission notice shall be included
17 : * in all copies or substantial portions of the Software.
18 : *
19 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 : * DEALINGS IN THE SOFTWARE.
26 : ****************************************************************************/
27 :
28 : #ifndef __INCLUDE_PCIDSK_SHAPE_H
29 : #define __INCLUDE_PCIDSK_SHAPE_H
30 :
31 : #include <string>
32 : #include <vector>
33 : #include <cstdlib>
34 : #include <cstring>
35 :
36 : namespace PCIDSK
37 : {
38 :
39 : //! Type used for shape identifier, use constant NullShapeId as a NULL value
40 : typedef int32 ShapeId;
41 :
42 : static const ShapeId NullShapeId = -1;
43 :
44 : //! Structure for an x,y,z point.
45 : typedef struct
46 : {
47 : double x;
48 : double y;
49 : double z;
50 : } ShapeVertex;
51 :
52 : /************************************************************************/
53 : /* ShapeFieldType */
54 : /************************************************************************/
55 : //! Attribute field types.
56 : typedef enum // These deliberately match GDBFieldType values.
57 : {
58 : FieldTypeNone = 0,
59 : FieldTypeFloat = 1,
60 : FieldTypeDouble = 2,
61 : FieldTypeString = 3,
62 : FieldTypeInteger = 4,
63 : FieldTypeCountedInt = 5
64 : } ShapeFieldType;
65 :
66 : /************************************************************************/
67 : /* ShapeFieldTypeName() */
68 : /************************************************************************/
69 : /**
70 : \brief Translate field type into a textual description.
71 : @param type the type enumeration value to translate.
72 : @return name for field type.
73 : */
74 : inline std::string ShapeFieldTypeName( ShapeFieldType type )
75 : {
76 : switch( type ) {
77 : case FieldTypeNone: return "None";
78 : case FieldTypeFloat: return "Float";
79 : case FieldTypeDouble: return "Double";
80 : case FieldTypeString: return "String";
81 : case FieldTypeInteger: return "Integer";
82 : case FieldTypeCountedInt: return "CountedInt";
83 : }
84 : return "";
85 : }
86 :
87 :
88 : /************************************************************************/
89 : /* ShapeField */
90 : /************************************************************************/
91 : /**
92 : \brief Attribute field value.
93 :
94 : This class encapsulates any of the supported vector attribute field
95 : types in a convenient way that avoids memory leaks or ownership confusion.
96 : The object has a field type (initially FieldTypeNone on construction)
97 : and a value of the specified type. Note that the appropriate value
98 : accessor (ie. GetValueInteger()) must be used that corresponds to the
99 : fields type. No attempt is made to automatically convert (ie. float to
100 : double) if the wrong accessor is used.
101 :
102 : */
103 :
104 : class ShapeField
105 : {
106 : private:
107 : ShapeFieldType type; // use FieldTypeNone for NULL fields.
108 :
109 : union
110 : {
111 : float float_val;
112 : double double_val;
113 : char *string_val;
114 : int32 integer_val;
115 : int32 *integer_list_val;
116 : } v;
117 :
118 : public:
119 : //! Simple constructor.
120 0 : ShapeField()
121 0 : { v.string_val = NULL; type = FieldTypeNone; }
122 :
123 : //! Copy constructor.
124 0 : ShapeField( const ShapeField &src )
125 0 : { v.string_val = NULL; type = FieldTypeNone; *this = src; }
126 :
127 0 : ~ShapeField()
128 0 : { Clear(); }
129 :
130 : //! Assignment operator.
131 0 : ShapeField &operator=( const ShapeField &src )
132 : {
133 0 : switch( src.GetType() )
134 : {
135 : case FieldTypeFloat:
136 0 : SetValue( src.GetValueFloat() );
137 0 : break;
138 : case FieldTypeDouble:
139 0 : SetValue( src.GetValueDouble() );
140 0 : break;
141 : case FieldTypeInteger:
142 0 : SetValue( src.GetValueInteger() );
143 0 : break;
144 : case FieldTypeCountedInt:
145 0 : SetValue( src.GetValueCountedInt() );
146 0 : break;
147 : case FieldTypeString:
148 0 : SetValue( src.GetValueString() );
149 0 : break;
150 : case FieldTypeNone:
151 0 : Clear();
152 : break;
153 : }
154 0 : return *this;
155 : }
156 :
157 : //! Clear field value.
158 0 : void Clear()
159 : {
160 0 : if( (type == FieldTypeString || type == FieldTypeCountedInt)
161 : && v.string_val != NULL )
162 : {
163 0 : free( v.string_val );
164 0 : v.string_val = NULL;
165 : }
166 0 : type = FieldTypeNone;
167 0 : }
168 :
169 : //! Fetch field type
170 0 : ShapeFieldType GetType() const
171 0 : { return type; }
172 :
173 : //! Set integer value on field.
174 0 : void SetValue( int32 val )
175 : {
176 0 : Clear();
177 0 : type = FieldTypeInteger;
178 0 : v.integer_val = val;
179 0 : }
180 :
181 : //! Set integer list value on field.
182 0 : void SetValue( const std::vector<int32> &val )
183 : {
184 0 : Clear();
185 0 : type = FieldTypeCountedInt;
186 : v.integer_list_val = (int32*)
187 0 : malloc(sizeof(int32) * (val.size()+1) );
188 0 : v.integer_list_val[0] = val.size();
189 : memcpy( v.integer_list_val+1, &(val[0]),
190 0 : sizeof(int32) * val.size() );
191 0 : }
192 :
193 : //! Set string value on field.
194 0 : void SetValue( const std::string &val )
195 : {
196 0 : Clear();
197 0 : type = FieldTypeString;
198 0 : v.string_val = strdup(val.c_str());
199 0 : }
200 :
201 : //! Set double precision floating point value on field.
202 0 : void SetValue( double val )
203 : {
204 0 : Clear();
205 0 : type = FieldTypeDouble;
206 0 : v.double_val = val;
207 0 : }
208 :
209 : //! Set single precision floating point value on field.
210 0 : void SetValue( float val )
211 : {
212 0 : Clear();
213 0 : type = FieldTypeFloat;
214 0 : v.float_val = val;
215 0 : }
216 :
217 : //! Fetch value as integer or zero if field not of appropriate type.
218 0 : int32 GetValueInteger() const
219 0 : { if( type == FieldTypeInteger ) return v.integer_val; else return 0; }
220 : //! Fetch value as integer list or empty list if field not of appropriate type.
221 0 : std::vector<int32> GetValueCountedInt() const
222 : {
223 0 : std::vector<int32> result;
224 0 : if( type == FieldTypeCountedInt )
225 : {
226 0 : result.resize( v.integer_list_val[0] );
227 : memcpy( &(result[0]), &(v.integer_list_val[1]),
228 0 : (v.integer_list_val[0]) * sizeof(int32) );
229 : }
230 0 : return result;
231 : }
232 : //! Fetch value as string or "" if field not of appropriate type.
233 0 : std::string GetValueString() const
234 0 : { if( type == FieldTypeString ) return v.string_val; else return ""; }
235 : //! Fetch value as float or 0.0 if field not of appropriate type.
236 0 : float GetValueFloat() const
237 0 : { if( type == FieldTypeFloat ) return v.float_val; else return 0.0; }
238 : //! Fetch value as double or 0.0 if field not of appropriate type.
239 0 : double GetValueDouble() const
240 0 : { if( type == FieldTypeDouble ) return v.double_val; else return 0.0; }
241 : };
242 :
243 : } // end namespace PCIDSK
244 :
245 : #endif // __INCLUDE_PCIDSK_SHAPE_H
|