1 : /******************************************************************************
2 : * $Id: ogrvfklayer.cpp 18475 2010-01-08 10:17:13Z martinl $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Implements OGRVFKLayer class.
6 : * Author: Martin Landa, landa.martin gmail.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2009-2010, Martin Landa <landa.martin gmail.com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person
12 : * obtaining a copy of this software and associated documentation
13 : * files (the "Software"), to deal in the Software without
14 : * restriction, including without limitation the rights to use, copy,
15 : * modify, merge, publish, distribute, sublicense, and/or sell copies
16 : * of the Software, and to permit persons to whom the Software is
17 : * furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be
20 : * included in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 : * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
26 : * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 : * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
28 : * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 : * SOFTWARE.
30 : ****************************************************************************/
31 :
32 : #include "ogr_vfk.h"
33 : #include "cpl_conv.h"
34 : #include "cpl_string.h"
35 :
36 : CPL_CVSID("$Id:");
37 :
38 : /*!
39 : \brief OGRVFKLayer constructor
40 :
41 : \param pszName layer name
42 : \param poSRSIn spatial reference
43 : \param eReqType WKB geometry type
44 : \param poDSIn data source where to registrate OGR layer
45 : */
46 61 : OGRVFKLayer::OGRVFKLayer(const char *pszName,
47 : OGRSpatialReference *poSRSIn,
48 : OGRwkbGeometryType eReqType,
49 61 : OGRVFKDataSource *poDSIn)
50 : {
51 : /* set spatial reference */
52 61 : if( poSRSIn == NULL ) {
53 : /* default is S-JTSK */
54 : const char *wktString = "PROJCS[\"S-JTSK_Krovak_East_North\","
55 : "GEOGCS[\"GCS_S_JTSK\","
56 : "DATUM[\"Jednotne_Trigonometricke_Site_Katastralni\","
57 : "SPHEROID[\"Bessel_1841\",6377397.155,299.1528128]],"
58 : "PRIMEM[\"Greenwich\",0.0],"
59 : "UNIT[\"Degree\",0.0174532925199433]],"
60 : "PROJECTION[\"Krovak\"],"
61 : "PARAMETER[\"False_Easting\",0.0],"
62 : "PARAMETER[\"False_Northing\",0.0],"
63 : "PARAMETER[\"Pseudo_Standard_Parallel_1\",78.5],"
64 : "PARAMETER[\"Scale_Factor\",0.9999],"
65 : "PARAMETER[\"Azimuth\",30.28813975277778],"
66 : "PARAMETER[\"Longitude_Of_Center\",24.83333333333333],"
67 : "PARAMETER[\"Latitude_Of_Center\",49.5],"
68 : "PARAMETER[\"X_Scale\",-1.0],"
69 : "PARAMETER[\"Y_Scale\",1.0],"
70 : "PARAMETER[\"XY_Plane_Rotation\",90.0],"
71 61 : "UNIT[\"Meter\",1.0]]";
72 61 : poSRS = new OGRSpatialReference();
73 122 : if (poSRS->importFromWkt((char **)&wktString) != OGRERR_NONE) {
74 0 : delete poSRS;
75 0 : poSRS = NULL;
76 : }
77 : }
78 : else {
79 0 : poSRS = poSRSIn->Clone();
80 : }
81 :
82 : /* layer datasource */
83 61 : poDS = poDSIn;
84 :
85 : /* feature definition */
86 61 : poFeatureDefn = new OGRFeatureDefn(pszName);
87 :
88 61 : poFeatureDefn->Reference();
89 61 : poFeatureDefn->SetGeomType(eReqType);
90 :
91 : /* data block reference */
92 61 : poDataBlock = poDS->GetReader()->GetDataBlock(pszName);
93 61 : }
94 :
95 : /*!
96 : \brief OGRVFKLayer() destructor
97 : */
98 122 : OGRVFKLayer::~OGRVFKLayer()
99 : {
100 61 : if(poFeatureDefn)
101 61 : poFeatureDefn->Release();
102 :
103 61 : if(poSRS)
104 61 : poSRS->Release();
105 122 : }
106 :
107 : /*!
108 : \brief Test capability (random access, etc.)
109 :
110 : \param pszCap capability name
111 : */
112 0 : int OGRVFKLayer::TestCapability(const char * pszCap)
113 : {
114 0 : if (EQUAL(pszCap, OLCRandomRead)) {
115 0 : return TRUE; /* ? */
116 : }
117 :
118 0 : return FALSE;
119 : }
120 :
121 : /*!
122 : \brief Reset reading
123 :
124 : \todo To be implemented
125 : */
126 3 : void OGRVFKLayer::ResetReading()
127 : {
128 3 : m_iNextFeature = 0;
129 3 : poDataBlock->ResetReading();
130 3 : }
131 :
132 : /*!
133 : \brief Create geometry from VFKFeature
134 :
135 : \param poVfkFeature pointer to VFKFeature
136 :
137 : \return pointer to OGRGeometry
138 : \return NULL on error
139 : */
140 14 : OGRGeometry *OGRVFKLayer::CreateGeometry(VFKFeature * poVfkFeature)
141 : {
142 14 : return poVfkFeature->GetGeometry();
143 : }
144 :
145 : /*!
146 : \brief Get spatial reference information
147 : */
148 0 : OGRSpatialReference *OGRVFKLayer::GetSpatialRef()
149 : {
150 0 : return poSRS;
151 : }
152 :
153 : /*!
154 : \brief Get feature count
155 :
156 : This method overwrites OGRLayer::GetFeatureCount(),
157 :
158 : \param bForce skip (return -1)
159 :
160 : \return number of features
161 : */
162 1 : int OGRVFKLayer::GetFeatureCount(int bForce)
163 : {
164 : int nfeatures;
165 :
166 1 : if(!bForce)
167 0 : return -1;
168 :
169 1 : if (m_poFilterGeom || m_poAttrQuery)
170 0 : nfeatures = OGRLayer::GetFeatureCount(bForce);
171 : else
172 1 : nfeatures = poDataBlock->GetMaxFID();
173 :
174 1 : CPLDebug("OGR_VFK", "OGRVFKLayer::GetFeatureCount(): n=%d", nfeatures);
175 :
176 1 : return nfeatures;
177 : }
178 :
179 : /*!
180 : \brief Get next feature
181 :
182 : \return pointer to OGRFeature instance
183 : */
184 5 : OGRFeature *OGRVFKLayer::GetNextFeature()
185 : {
186 : VFKFeature *poVFKFeature;
187 :
188 : OGRFeature *poOGRFeature;
189 : OGRGeometry *poOGRGeom;
190 :
191 5 : poOGRFeature = NULL;
192 5 : poOGRGeom = NULL;
193 :
194 : /* loop till we find and translate a feature meeting all our
195 : requirements
196 : */
197 10 : while (TRUE) {
198 : /* cleanup last feature, and get a new raw vfk feature */
199 15 : if (poOGRGeom != NULL) {
200 0 : delete poOGRGeom;
201 0 : poOGRGeom = NULL;
202 : }
203 :
204 15 : poVFKFeature = poDataBlock->GetNextFeature();
205 15 : if (!poVFKFeature)
206 1 : return NULL;
207 :
208 : /* skip feature with unknown geometry type */
209 14 : if (poVFKFeature->GetGeometryType() == wkbUnknown)
210 0 : continue;
211 :
212 14 : poOGRFeature = GetFeature(poVFKFeature);
213 : // CPLDebug("OGR_VFK", "OGRVFKLayer::GetNextFeature(): fid=%d", m_iNextFeature);
214 :
215 14 : if (poOGRFeature)
216 4 : return poOGRFeature;
217 : }
218 : }
219 :
220 : /*!
221 : \brief Get feature by fid
222 :
223 : \param nFID feature id (-1 for next)
224 :
225 : \return pointer to OGRFeature
226 : \return NULL not found
227 : */
228 0 : OGRFeature *OGRVFKLayer::GetFeature(long nFID)
229 : {
230 : VFKFeature *poVFKFeature;
231 :
232 0 : poVFKFeature = poDataBlock->GetFeature(nFID);
233 0 : if (!poVFKFeature)
234 0 : return NULL;
235 :
236 0 : CPLDebug("OGR_VFK", "OGRVFKLayer::GetFeature(): fid=%ld", nFID);
237 :
238 0 : return GetFeature(poVFKFeature);
239 : }
240 :
241 : /*!
242 : \brief Get feature (private)
243 :
244 : \return pointer to OGRFeature
245 : \return NULL not found
246 : */
247 14 : OGRFeature *OGRVFKLayer::GetFeature(VFKFeature *poVFKFeature)
248 : {
249 : OGRGeometry *poGeom;
250 :
251 : /* skip feature with unknown geometry type */
252 14 : if (poVFKFeature->GetGeometryType() == wkbUnknown)
253 0 : return NULL;
254 :
255 : /* get features geometry */
256 14 : poGeom = CreateGeometry(poVFKFeature);
257 14 : if (poGeom != NULL)
258 14 : poGeom->assignSpatialReference(poSRS);
259 :
260 : /* does it satisfy the spatial query, if there is one? */
261 14 : if (m_poFilterGeom != NULL && poGeom && !FilterGeometry(poGeom)) {
262 0 : return NULL;
263 : }
264 :
265 : /* convert the whole feature into an OGRFeature */
266 14 : OGRFeature *poOGRFeature = new OGRFeature(GetLayerDefn());
267 14 : poOGRFeature->SetFID(poVFKFeature->GetFID());
268 : // poOGRFeature->SetFID(++m_iNextFeature);
269 :
270 172 : for (int iField = 0; iField < poDataBlock->GetPropertyCount(); iField++) {
271 158 : if (poVFKFeature->GetProperty(iField)->IsNull())
272 24 : continue;
273 134 : OGRFieldType fType = poOGRFeature->GetDefnRef()->GetFieldDefn(iField)->GetType();
274 134 : if (fType == OFTInteger)
275 : poOGRFeature->SetField(iField,
276 105 : poVFKFeature->GetProperty(iField)->GetValueI());
277 29 : else if (fType == OFTReal)
278 : poOGRFeature->SetField(iField,
279 26 : poVFKFeature->GetProperty(iField)->GetValueD());
280 : else
281 : poOGRFeature->SetField(iField,
282 3 : poVFKFeature->GetProperty(iField)->GetValueS());
283 : }
284 :
285 : /* test against the attribute query */
286 14 : if (m_poAttrQuery != NULL &&
287 : !m_poAttrQuery->Evaluate(poOGRFeature)) {
288 10 : delete poOGRFeature;
289 10 : return NULL;
290 : }
291 :
292 4 : if (poGeom)
293 4 : poOGRFeature->SetGeometryDirectly(poGeom->clone());
294 :
295 4 : return poOGRFeature;
296 : }
|