Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Purpose: PCIDSK Vector Segment public interface. Declaration. 4 : * 5 : ****************************************************************************** 6 : * Copyright (c) 2009 7 : * PCI Geomatics, 90 Allstate Parkway, Markham, Ontario, Canada. 8 : * 9 : * SPDX-License-Identifier: MIT 10 : ****************************************************************************/ 11 : 12 : #ifndef INCLUDE_PCIDSK_VECTORSEGMENT_H 13 : #define INCLUDE_PCIDSK_VECTORSEGMENT_H 14 : 15 : #include <string> 16 : #include <vector> 17 : #include <iterator> 18 : #include "pcidsk_shape.h" 19 : 20 : #define ATT_RINGSTART "RingStart" 21 : 22 : namespace PCIDSK 23 : { 24 : class ShapeIterator; 25 : 26 : /************************************************************************/ 27 : /* PCIDSKVectorSegment */ 28 : /************************************************************************/ 29 : 30 : /** 31 : \brief Interface to PCIDSK vector segment. 32 : 33 : The vector segment contains a set of vector features with a common set 34 : of attribute data (fields). Each feature has a numeric identifier (ShapeId), 35 : a set of field values, and a set of geometric vertices. The layer as a 36 : whole has a description of the attribute fields, and an RST (Representation 37 : Style Table). 38 : 39 : The geometry and attribute fields of shapes can be fetched with the 40 : GetVertices() and GetFields() methods by giving the ShapeId of the desired 41 : feature. The set of shapeid's can be identified using the FindFirst(), 42 : and FindNext() methods or the STL compatible ShapeIterator (begin() and 43 : end() methods). 44 : 45 : The PCIDSKSegment interface for the segment can be used to fetch the 46 : LAYER_TYPE metadata describing how the vertices should be interpreted 47 : as a geometry. Some layers will also have a RingStart attribute field 48 : which is used in conjunction with the LAYER_TYPE to interpret the 49 : geometry. Some vector segments may have no LAYER_TYPE metadata in which 50 : case single vertices are interpreted as points, and multiple vertices 51 : as linestrings. 52 : 53 : More details are available in the GDB.HLP description of the GDB vector 54 : data model. 55 : 56 : Note that there are no mechanisms for fast spatial or attribute searches 57 : in a PCIDSK vector segment. Accessing features randomly (rather than 58 : in the order shapeids are returned by FindFirst()/FindNext() or ShapeIterator 59 : ) may result in reduced performance, and the use of large amounts of memory 60 : for large vector segments. 61 : 62 : */ 63 : 64 : class PCIDSK_DLL PCIDSKVectorSegment 65 : { 66 : public: 67 1185 : virtual ~PCIDSKVectorSegment() {} 68 : 69 : /** 70 : \brief Fetch RST. 71 : 72 : No attempt is made to parse the RST, it is up to the caller to decode it. 73 : 74 : NOTE: There is some header info on RST format that may be needed to do this 75 : for older RSTs. 76 : 77 : @return RST as a string. 78 : */ 79 : virtual std::string GetRst() = 0; 80 : 81 : 82 : /** 83 : \brief Fetch Projection 84 : 85 : The returned values are the projection parameters in the same form returned 86 : by PCIDSKGeoref::GetParameters() and the passed in geosys argument is 87 : updated with the coordinate system string. 88 : 89 : @return Projection parameters as a vector. 90 : */ 91 : virtual std::vector<double> GetProjection( std::string &geosys ) = 0; 92 : 93 : /** 94 : \brief Get field count. 95 : 96 : Note that this includes any system attributes, like RingStart, that would 97 : not normally be shown to the user. 98 : 99 : @return the number of attribute fields defined on this layer. 100 : */ 101 : 102 : virtual int GetFieldCount() = 0; 103 : 104 : /** 105 : \brief Get field name. 106 : 107 : @param field_index index of the field requested from zero to GetFieldCount()-1. 108 : @return the field name. 109 : */ 110 : virtual std::string GetFieldName(int field_index) = 0; 111 : 112 : /** 113 : \brief Get field description. 114 : 115 : @param field_index index of the field requested from zero to GetFieldCount()-1. 116 : @return the field description, often empty. 117 : */ 118 : virtual std::string GetFieldDescription(int field_index) = 0; 119 : 120 : /** 121 : \brief Get field type. 122 : 123 : @param field_index index of the field requested from zero to GetFieldCount()-1. 124 : @return the field type. 125 : */ 126 : virtual ShapeFieldType GetFieldType(int field_index) = 0; 127 : 128 : /** 129 : \brief Get field format. 130 : 131 : @param field_index index of the field requested from zero to GetFieldCount()-1. 132 : @return the field format as a C style format string suitable for use with printf. 133 : */ 134 : virtual std::string GetFieldFormat(int field_index) = 0; 135 : 136 : /** 137 : \brief Get field default. 138 : 139 : @param field_index index of the field requested from zero to GetFieldCount()-1. 140 : @return the field default value. 141 : */ 142 : virtual ShapeField GetFieldDefault(int field_index) = 0; 143 : 144 : /** 145 : \brief Get iterator to first shape. 146 : @return iterator. 147 : */ 148 : virtual ShapeIterator begin() = 0; 149 : 150 : /** 151 : \brief Get iterator to end of shape lib (a wrapper for NullShapeId). 152 : @return iterator. 153 : */ 154 : virtual ShapeIterator end() = 0; 155 : 156 : /** 157 : \brief Fetch first shapeid in the layer. 158 : @return first shape's shapeid. 159 : */ 160 : virtual ShapeId FindFirst() = 0; 161 : 162 : /** 163 : \brief Fetch the next shape id after the indicated shape id. 164 : @param id the previous shapes id. 165 : @return next shape's shapeid. 166 : */ 167 : virtual ShapeId FindNext(ShapeId id) = 0; 168 : 169 : 170 : /** 171 : \brief Fetch the number of shapes in this segment. 172 : @return the shape count. 173 : */ 174 : 175 : virtual int GetShapeCount() = 0; 176 : 177 : /** 178 : \brief Fetch the vertices for the indicated shape. 179 : @param id the shape to fetch 180 : @param list the list is updated with the vertices for this shape. 181 : */ 182 : virtual void GetVertices( ShapeId id, 183 : std::vector<ShapeVertex>& list ) = 0; 184 : 185 : /** 186 : \brief Fetch the fields for the indicated shape. 187 : @param id the shape to fetch 188 : @param list the field list is updated with the field values for this shape. 189 : */ 190 : virtual void GetFields( ShapeId id, 191 : std::vector<ShapeField>& list ) = 0; 192 : 193 : 194 : /** 195 : \brief Set the projection for the segment. 196 : 197 : For details on the geosys and params values see the PCIDSKGeoref class. 198 : 199 : @param geosys the usual 16 character coordinate system string. 200 : @param params additional parameters needed for user parametrized projection. 201 : */ 202 : virtual void SetProjection(const std::string& geosys, 203 : const std::vector<double>& params ) = 0; 204 : 205 : /** 206 : \brief Create new attribute field. 207 : 208 : @param name the field name, should be unique in layer. 209 : @param type the field type. 210 : @param description the field description. 211 : @param format the C style format string or "" for default formatting. 212 : @param default_value the default value for this field or NULL for system default. 213 : */ 214 : 215 : virtual void AddField( const std::string& name, ShapeFieldType type, 216 : const std::string& description, 217 : const std::string& format, 218 : ShapeField *default_value=nullptr ) = 0; 219 : 220 : /** 221 : \brief Create a new shape. 222 : 223 : Newly created shapes have no geometry or attribute values. 224 : 225 : @param id The ShapeId to assign to the new shape, or default to assign the next available shapeid. 226 : 227 : @return the shapeid assigned to the newly created shape. 228 : */ 229 : 230 : virtual ShapeId CreateShape( ShapeId id = NullShapeId ) = 0; 231 : 232 : /** 233 : \brief Delete a shape. 234 : 235 : An exception is thrown if the shape does not exist. 236 : 237 : @param id the shapeid to delete. 238 : 239 : */ 240 : virtual void DeleteShape( ShapeId id ) = 0; 241 : 242 : /** 243 : \brief Assign vertices to shape. 244 : 245 : @param id the shape to assign vertices to. 246 : @param list the list of vertices to assign. 247 : */ 248 : 249 : virtual void SetVertices( ShapeId id, 250 : const std::vector<ShapeVertex> &list ) = 0; 251 : 252 : 253 : /** 254 : \brief Assign attribute value to a shape. 255 : 256 : The list of fields should match the types and length from the schema 257 : (GetFieldCount(), GetFieldType()). 258 : 259 : @param id the shape to update. 260 : @param list the list of field value to assign. 261 : */ 262 : virtual void SetFields( ShapeId id, 263 : const std::vector<ShapeField>& list) = 0; 264 : 265 : // Methods needed 266 : // DeleteField 267 : }; 268 : 269 : /************************************************************************/ 270 : /* ShapeIterator */ 271 : /************************************************************************/ 272 : 273 : //! Iterator over shapeids in a vector segment. 274 : 275 : class ShapeIterator 276 : { 277 : ShapeId id; 278 : PCIDSKVectorSegment *seg; 279 : 280 : public: 281 : using iterator_category = std::input_iterator_tag; 282 : using value_type = ShapeId; 283 : using difference_type = std::ptrdiff_t; 284 : using pointer = ShapeId*; 285 : using reference = ShapeId&; 286 : 287 10 : ShapeIterator(PCIDSKVectorSegment *seg_in) 288 10 : : seg(seg_in) { id = seg->FindFirst(); } 289 20 : ShapeIterator(PCIDSKVectorSegment *seg_in, ShapeId id_in ) 290 20 : : id(id_in), seg(seg_in) {} 291 : ShapeIterator(const ShapeIterator& mit) : id(mit.id), seg(mit.seg) {} 292 : ShapeIterator& operator++() { id=seg->FindNext(id); return *this;} 293 10 : ShapeIterator& operator++(int) { id=seg->FindNext(id); return *this;} 294 : friend bool operator==(const ShapeIterator& lhs, const ShapeIterator& rhs); 295 : friend bool operator!=(const ShapeIterator& lhs, const ShapeIterator& rhs); 296 10 : ShapeId& operator*() {return id;} 297 : }; 298 : 299 : inline bool operator==(const ShapeIterator& lhs, const ShapeIterator& rhs) {return lhs.id == rhs.id;} 300 20 : inline bool operator!=(const ShapeIterator& lhs, const ShapeIterator& rhs) {return lhs.id != rhs.id;} 301 : 302 : } // end namespace PCIDSK 303 : 304 : #endif // INCLUDE_PCIDSK_VECTORSEGMENT_H