Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Purpose: PCIDSK Vector Shape interface. Declaration. 4 : * 5 : ****************************************************************************** 6 : * Copyright (c) 2009 7 : * PCI Geomatics, 90 Allstate Parkway, Markham, Ontario, 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 (i.e. GetValueInteger()) must be used that corresponds to the 99 : fields type. No attempt is made to automatically convert (i.e. 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 3010 : ShapeField() 121 3010 : { v.string_val = nullptr; type = FieldTypeNone; } 122 : 123 : //! Copy constructor. 124 544 : ShapeField( const ShapeField &src ) 125 544 : { v.string_val = nullptr; type = FieldTypeNone; *this = src; } 126 : 127 3554 : ~ShapeField() 128 3554 : { Clear(); } 129 : 130 : //! Assignment operator. 131 544 : ShapeField &operator=( const ShapeField &src ) 132 : { 133 544 : switch( src.GetType() ) 134 : { 135 0 : case FieldTypeFloat: 136 0 : SetValue( src.GetValueFloat() ); 137 0 : break; 138 84 : case FieldTypeDouble: 139 84 : SetValue( src.GetValueDouble() ); 140 84 : break; 141 129 : case FieldTypeInteger: 142 129 : SetValue( src.GetValueInteger() ); 143 129 : break; 144 0 : case FieldTypeCountedInt: 145 0 : SetValue( src.GetValueCountedInt() ); 146 0 : break; 147 331 : case FieldTypeString: 148 331 : SetValue( src.GetValueString() ); 149 331 : break; 150 0 : case FieldTypeNone: 151 0 : Clear(); 152 0 : break; 153 : } 154 544 : return *this; 155 : } 156 : 157 : //! Assignment operator. 158 : bool operator==( const ShapeField &other ) 159 : { 160 : if( GetType() != other.GetType() ) 161 : return false; 162 : 163 : switch( other.GetType() ) 164 : { 165 : case FieldTypeFloat: 166 : return GetValueFloat() == other.GetValueFloat(); 167 : case FieldTypeDouble: 168 : return GetValueDouble() == other.GetValueDouble(); 169 : case FieldTypeInteger: 170 : return GetValueInteger() == other.GetValueInteger(); 171 : case FieldTypeString: 172 : return GetValueString() == other.GetValueString(); 173 : case FieldTypeCountedInt: 174 : return GetValueCountedInt() == other.GetValueCountedInt(); 175 : case FieldTypeNone: 176 : return false; 177 : default: 178 : return false; 179 : } 180 : } 181 : 182 : //! Clear field value. 183 9452 : void Clear() 184 : { 185 9452 : if( (type == FieldTypeString || type == FieldTypeCountedInt) 186 3910 : && v.string_val != nullptr ) 187 : { 188 3910 : free( v.string_val ); 189 3910 : v.string_val = nullptr; 190 : } 191 9452 : type = FieldTypeNone; 192 9452 : } 193 : 194 : //! Fetch field type 195 2614 : ShapeFieldType GetType() const 196 2614 : { return type; } 197 : 198 : //! Set integer value on field. 199 1752 : void SetValue( int32 val ) 200 : { 201 1752 : Clear(); 202 1752 : type = FieldTypeInteger; 203 1752 : v.integer_val = val; 204 1752 : } 205 : 206 : //! Set integer list value on field. 207 0 : void SetValue( const std::vector<int32> &val ) 208 : { 209 0 : Clear(); 210 0 : type = FieldTypeCountedInt; 211 0 : v.integer_list_val = (int32*) 212 0 : malloc(sizeof(int32) * (val.size()+1) ); 213 0 : v.integer_list_val[0] = static_cast<int32>(val.size()); 214 0 : if( !val.empty() ) 215 0 : memcpy( v.integer_list_val+1, &(val[0]), 216 0 : sizeof(int32) * val.size() ); 217 0 : } 218 : 219 : //! Set string value on field. 220 3910 : void SetValue( const std::string &val ) 221 : { 222 3910 : Clear(); 223 3910 : type = FieldTypeString; 224 3910 : v.string_val = strdup(val.c_str()); 225 3910 : } 226 : 227 : //! Set double precision floating point value on field. 228 236 : void SetValue( double val ) 229 : { 230 236 : Clear(); 231 236 : type = FieldTypeDouble; 232 236 : v.double_val = val; 233 236 : } 234 : 235 : //! Set single precision floating point value on field. 236 0 : void SetValue( float val ) 237 : { 238 0 : Clear(); 239 0 : type = FieldTypeFloat; 240 0 : v.float_val = val; 241 0 : } 242 : 243 : //! Fetch value as integer or zero if field not of appropriate type. 244 1725 : int32 GetValueInteger() const 245 1725 : { if( type == FieldTypeInteger ) return v.integer_val; else return 0; } 246 : //! Fetch value as integer list or empty list if field not of appropriate type. 247 0 : std::vector<int32> GetValueCountedInt() const 248 : { 249 0 : std::vector<int32> result; 250 0 : if( type == FieldTypeCountedInt ) 251 : { 252 0 : result.resize( v.integer_list_val[0] ); 253 0 : if( v.integer_list_val[0] > 0 ) 254 0 : memcpy( &(result[0]), &(v.integer_list_val[1]), 255 0 : (v.integer_list_val[0]) * sizeof(int32) ); 256 : } 257 0 : return result; 258 : } 259 : //! Fetch value as string or "" if field not of appropriate type. 260 3229 : std::string GetValueString() const 261 3229 : { if( type == FieldTypeString ) return v.string_val; else return ""; } 262 : //! Fetch value as float or 0.0 if field not of appropriate type. 263 0 : float GetValueFloat() const 264 0 : { if( type == FieldTypeFloat ) return v.float_val; else return 0.0; } 265 : //! Fetch value as double or 0.0 if field not of appropriate type. 266 209 : double GetValueDouble() const 267 209 : { if( type == FieldTypeDouble ) return v.double_val; else return 0.0; } 268 : }; 269 : 270 : } // end namespace PCIDSK 271 : 272 : #endif // INCLUDE_PCIDSK_SHAPE_H