1 : /******************************************************************************
2 : * $Id: ogrvfklayer.cpp 24217 2012-04-11 14:25:09Z 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: ogrvfklayer.cpp 24217 2012-04-11 14:25:09Z martinl $");
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 122 : OGRVFKLayer::OGRVFKLayer(const char *pszName,
47 : OGRSpatialReference *poSRSIn,
48 : OGRwkbGeometryType eReqType,
49 122 : OGRVFKDataSource *poDSIn)
50 : {
51 : /* set spatial reference */
52 122 : if( poSRSIn == NULL ) {
53 : /* default is S-JTSK
54 : const char *wktString = "PROJCS[\"Krovak\","
55 : "GEOGCS[\"GCS_Bessel 1841\","
56 : "DATUM[\"D_unknown\","
57 : "SPHEROID[\"bessel\","
58 : "6377397.155,299.1528128]],"
59 : "PRIMEM[\"Greenwich\",0],"
60 : "UNIT[\"Degree\",0.017453292519943295]],"
61 : "PROJECTION[\"Krovak\"],"
62 : "PARAMETER[\"latitude_of_center\",49.5],"
63 : "PARAMETER[\"longitude_of_center\",24.83333333333333],"
64 : "PARAMETER[\"azimuth\",0],"
65 : "PARAMETER[\"pseudo_standard_parallel_1\",0],"
66 : "PARAMETER[\"scale_factor\",0.9999],"
67 : "PARAMETER[\"false_easting\",0],"
68 : "PARAMETER[\"false_northing\",0],"
69 : "UNIT[\"Meter\",1]]";
70 : */
71 :
72 122 : poSRS = new OGRSpatialReference();
73 : /*
74 : if (poSRS->importFromWkt((char **)&wktString) != OGRERR_NONE) {
75 : */
76 244 : if (poSRS->importFromEPSG(2065) != OGRERR_NONE) {
77 0 : delete poSRS;
78 0 : poSRS = NULL;
79 : }
80 : }
81 : else {
82 0 : poSRS = poSRSIn->Clone();
83 : }
84 :
85 : /* layer datasource */
86 122 : poDS = poDSIn;
87 :
88 : /* feature definition */
89 122 : poFeatureDefn = new OGRFeatureDefn(pszName);
90 :
91 122 : poFeatureDefn->Reference();
92 122 : poFeatureDefn->SetGeomType(eReqType);
93 :
94 : /* data block reference */
95 122 : poDataBlock = poDS->GetReader()->GetDataBlock(pszName);
96 122 : }
97 :
98 : /*!
99 : \brief OGRVFKLayer() destructor
100 : */
101 122 : OGRVFKLayer::~OGRVFKLayer()
102 : {
103 122 : if(poFeatureDefn)
104 122 : poFeatureDefn->Release();
105 :
106 122 : if(poSRS)
107 122 : poSRS->Release();
108 122 : }
109 :
110 : /*!
111 : \brief Test capability (random access, etc.)
112 :
113 : \param pszCap capability name
114 : */
115 0 : int OGRVFKLayer::TestCapability(const char * pszCap)
116 : {
117 0 : if (EQUAL(pszCap, OLCRandomRead)) {
118 0 : return TRUE; /* ? */
119 : }
120 :
121 0 : return FALSE;
122 : }
123 :
124 : /*!
125 : \brief Reset reading
126 :
127 : \todo To be implemented
128 : */
129 6 : void OGRVFKLayer::ResetReading()
130 : {
131 6 : m_iNextFeature = 0;
132 6 : poDataBlock->ResetReading();
133 6 : }
134 :
135 : /*!
136 : \brief Create geometry from VFKFeature
137 :
138 : \param poVfkFeature pointer to VFKFeature
139 :
140 : \return pointer to OGRGeometry
141 : \return NULL on error
142 : */
143 30 : OGRGeometry *OGRVFKLayer::CreateGeometry(IVFKFeature * poVfkFeature)
144 : {
145 30 : return poVfkFeature->GetGeometry();
146 : }
147 :
148 : /*!
149 : \brief Get spatial reference information
150 : */
151 0 : OGRSpatialReference *OGRVFKLayer::GetSpatialRef()
152 : {
153 0 : return poSRS;
154 : }
155 :
156 : /*!
157 : \brief Get feature count
158 :
159 : This method overwrites OGRLayer::GetFeatureCount(),
160 :
161 : \param bForce skip (return -1)
162 :
163 : \return number of features
164 : */
165 4 : int OGRVFKLayer::GetFeatureCount(int bForce)
166 : {
167 : int nfeatures;
168 :
169 4 : if(!bForce)
170 0 : return -1;
171 :
172 4 : if (m_poFilterGeom || m_poAttrQuery)
173 0 : nfeatures = OGRLayer::GetFeatureCount(bForce);
174 : else
175 4 : nfeatures = poDataBlock->GetMaxFID();
176 :
177 4 : CPLDebug("OGR_VFK", "OGRVFKLayer::GetFeatureCount(): n=%d", nfeatures);
178 :
179 4 : return nfeatures;
180 : }
181 :
182 : /*!
183 : \brief Get next feature
184 :
185 : \return pointer to OGRFeature instance
186 : */
187 6 : OGRFeature *OGRVFKLayer::GetNextFeature()
188 : {
189 : VFKFeature *poVFKFeature;
190 :
191 : OGRFeature *poOGRFeature;
192 : OGRGeometry *poOGRGeom;
193 :
194 6 : poOGRFeature = NULL;
195 6 : poOGRGeom = NULL;
196 :
197 : /* loop till we find and translate a feature meeting all our
198 : requirements
199 : */
200 24 : while (TRUE) {
201 : /* cleanup last feature, and get a new raw vfk feature */
202 30 : if (poOGRGeom != NULL) {
203 0 : delete poOGRGeom;
204 0 : poOGRGeom = NULL;
205 : }
206 :
207 30 : poVFKFeature = (VFKFeature *) poDataBlock->GetNextFeature();
208 30 : if (!poVFKFeature)
209 2 : return NULL;
210 :
211 : /* skip feature with unknown geometry type */
212 28 : if (poVFKFeature->GetGeometryType() == wkbUnknown)
213 0 : continue;
214 :
215 28 : poOGRFeature = GetFeature(poVFKFeature);
216 : // CPLDebug("OGR_VFK", "OGRVFKLayer::GetNextFeature(): fid=%d", m_iNextFeature);
217 :
218 28 : if (poOGRFeature)
219 4 : return poOGRFeature;
220 : }
221 : }
222 :
223 : /*!
224 : \brief Get feature by fid
225 :
226 : \param nFID feature id (-1 for next)
227 :
228 : \return pointer to OGRFeature
229 : \return NULL not found
230 : */
231 2 : OGRFeature *OGRVFKLayer::GetFeature(long nFID)
232 : {
233 : IVFKFeature *poVFKFeature;
234 :
235 2 : poVFKFeature = poDataBlock->GetFeature(nFID);
236 2 : if (!poVFKFeature)
237 0 : return NULL;
238 :
239 2 : CPLDebug("OGR_VFK", "OGRVFKLayer::GetFeature(): fid=%ld", nFID);
240 :
241 2 : return GetFeature(poVFKFeature);
242 : }
243 :
244 : /*!
245 : \brief Get feature (private)
246 :
247 : \return pointer to OGRFeature
248 : \return NULL not found
249 : */
250 30 : OGRFeature *OGRVFKLayer::GetFeature(IVFKFeature *poVFKFeature)
251 : {
252 : OGRGeometry *poGeom;
253 :
254 : /* skip feature with unknown geometry type */
255 30 : if (poVFKFeature->GetGeometryType() == wkbUnknown)
256 0 : return NULL;
257 :
258 : /* get features geometry */
259 30 : poGeom = CreateGeometry(poVFKFeature);
260 30 : if (poGeom != NULL)
261 30 : poGeom->assignSpatialReference(poSRS);
262 :
263 : /* does it satisfy the spatial query, if there is one? */
264 30 : if (m_poFilterGeom != NULL && poGeom && !FilterGeometry(poGeom)) {
265 0 : return NULL;
266 : }
267 :
268 : /* convert the whole feature into an OGRFeature */
269 30 : OGRFeature *poOGRFeature = new OGRFeature(GetLayerDefn());
270 30 : poOGRFeature->SetFID(poVFKFeature->GetFID());
271 : // poOGRFeature->SetFID(++m_iNextFeature);
272 :
273 30 : poVFKFeature->LoadProperties(poOGRFeature);
274 :
275 : /* test against the attribute query */
276 56 : if (m_poAttrQuery != NULL &&
277 : !m_poAttrQuery->Evaluate(poOGRFeature)) {
278 24 : delete poOGRFeature;
279 24 : return NULL;
280 : }
281 :
282 6 : if (poGeom)
283 6 : poOGRFeature->SetGeometryDirectly(poGeom->clone());
284 :
285 6 : return poOGRFeature;
286 : }
|