1 : /******************************************************************************
2 : * $Id: ogrgeomedialayer.cpp 21547 2011-01-22 14:47:01Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Implements OGRGeomediaLayer class, code shared between
6 : * the direct table access, and the generic SQL results.
7 : * Author: Even Rouault, <even dot rouault at mines dash paris dot org>
8 : *
9 : ******************************************************************************
10 : * Copyright (c) 2011, Even Rouault, <even dot rouault at mines dash paris dot org>
11 : * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
12 : *
13 : * Permission is hereby granted, free of charge, to any person obtaining a
14 : * copy of this software and associated documentation files (the "Software"),
15 : * to deal in the Software without restriction, including without limitation
16 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 : * and/or sell copies of the Software, and to permit persons to whom the
18 : * Software is furnished to do so, subject to the following conditions:
19 : *
20 : * The above copyright notice and this permission notice shall be included
21 : * in all copies or substantial portions of the Software.
22 : *
23 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 : * DEALINGS IN THE SOFTWARE.
30 : ****************************************************************************/
31 :
32 : #include "cpl_conv.h"
33 : #include "ogr_geomedia.h"
34 : #include "cpl_string.h"
35 : #include "ogrgeomediageometry.h"
36 :
37 : CPL_CVSID("$Id: ogrgeomedialayer.cpp 21547 2011-01-22 14:47:01Z rouault $");
38 :
39 : /************************************************************************/
40 : /* OGRGeomediaLayer() */
41 : /************************************************************************/
42 :
43 0 : OGRGeomediaLayer::OGRGeomediaLayer()
44 :
45 : {
46 0 : poDS = NULL;
47 :
48 0 : pszGeomColumn = NULL;
49 0 : pszFIDColumn = NULL;
50 :
51 0 : poStmt = NULL;
52 :
53 0 : iNextShapeId = 0;
54 :
55 0 : poSRS = NULL;
56 0 : nSRSId = -2; // we haven't even queried the database for it yet.
57 0 : }
58 :
59 : /************************************************************************/
60 : /* ~OGRGeomediaLayer() */
61 : /************************************************************************/
62 :
63 0 : OGRGeomediaLayer::~OGRGeomediaLayer()
64 :
65 : {
66 0 : if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
67 : {
68 : CPLDebug( "Geomedia", "%d features read on layer '%s'.",
69 : (int) m_nFeaturesRead,
70 0 : poFeatureDefn->GetName() );
71 : }
72 :
73 0 : if( poStmt != NULL )
74 : {
75 0 : delete poStmt;
76 0 : poStmt = NULL;
77 : }
78 :
79 0 : if( poFeatureDefn != NULL )
80 : {
81 0 : poFeatureDefn->Release();
82 0 : poFeatureDefn = NULL;
83 : }
84 :
85 0 : CPLFree( pszGeomColumn );
86 0 : CPLFree( panFieldOrdinals );
87 0 : CPLFree( pszFIDColumn );
88 :
89 0 : if( poSRS != NULL )
90 : {
91 0 : poSRS->Release();
92 0 : poSRS = NULL;
93 : }
94 0 : }
95 :
96 : /************************************************************************/
97 : /* BuildFeatureDefn() */
98 : /* */
99 : /* Build feature definition from a set of column definitions */
100 : /* set on a statement. Sift out geometry and FID fields. */
101 : /************************************************************************/
102 :
103 0 : CPLErr OGRGeomediaLayer::BuildFeatureDefn( const char *pszLayerName,
104 : CPLODBCStatement *poStmt )
105 :
106 : {
107 0 : poFeatureDefn = new OGRFeatureDefn( pszLayerName );
108 0 : int nRawColumns = poStmt->GetColCount();
109 :
110 0 : poFeatureDefn->Reference();
111 :
112 0 : panFieldOrdinals = (int *) CPLMalloc( sizeof(int) * nRawColumns );
113 :
114 0 : for( int iCol = 0; iCol < nRawColumns; iCol++ )
115 : {
116 0 : OGRFieldDefn oField( poStmt->GetColName(iCol), OFTString );
117 :
118 0 : oField.SetWidth( MAX(0,poStmt->GetColSize( iCol )) );
119 :
120 0 : if( pszGeomColumn != NULL
121 : && EQUAL(poStmt->GetColName(iCol),pszGeomColumn) )
122 0 : continue;
123 :
124 0 : if( pszGeomColumn == NULL
125 : && EQUAL(poStmt->GetColName(iCol),"Geometry")
126 : && (poStmt->GetColType(iCol) == SQL_BINARY ||
127 : poStmt->GetColType(iCol) == SQL_VARBINARY ||
128 : poStmt->GetColType(iCol) == SQL_LONGVARBINARY) )
129 : {
130 0 : pszGeomColumn = CPLStrdup(poStmt->GetColName(iCol));
131 0 : continue;
132 : }
133 :
134 0 : switch( poStmt->GetColType(iCol) )
135 : {
136 : case SQL_INTEGER:
137 : case SQL_SMALLINT:
138 0 : oField.SetType( OFTInteger );
139 0 : break;
140 :
141 : case SQL_BINARY:
142 : case SQL_VARBINARY:
143 : case SQL_LONGVARBINARY:
144 0 : oField.SetType( OFTBinary );
145 0 : break;
146 :
147 : case SQL_DECIMAL:
148 0 : oField.SetType( OFTReal );
149 0 : oField.SetPrecision( poStmt->GetColPrecision(iCol) );
150 0 : break;
151 :
152 : case SQL_FLOAT:
153 : case SQL_REAL:
154 : case SQL_DOUBLE:
155 0 : oField.SetType( OFTReal );
156 0 : oField.SetWidth( 0 );
157 0 : break;
158 :
159 : case SQL_C_DATE:
160 0 : oField.SetType( OFTDate );
161 0 : break;
162 :
163 : case SQL_C_TIME:
164 0 : oField.SetType( OFTTime );
165 0 : break;
166 :
167 : case SQL_C_TIMESTAMP:
168 0 : oField.SetType( OFTDateTime );
169 : break;
170 :
171 : default:
172 : /* leave it as OFTString */;
173 : }
174 :
175 0 : poFeatureDefn->AddFieldDefn( &oField );
176 0 : panFieldOrdinals[poFeatureDefn->GetFieldCount() - 1] = iCol+1;
177 : }
178 :
179 0 : return CE_None;
180 : }
181 :
182 :
183 : /************************************************************************/
184 : /* ResetReading() */
185 : /************************************************************************/
186 :
187 0 : void OGRGeomediaLayer::ResetReading()
188 :
189 : {
190 0 : iNextShapeId = 0;
191 0 : }
192 :
193 : /************************************************************************/
194 : /* GetNextFeature() */
195 : /************************************************************************/
196 :
197 0 : OGRFeature *OGRGeomediaLayer::GetNextFeature()
198 :
199 : {
200 0 : for( ; TRUE; )
201 : {
202 : OGRFeature *poFeature;
203 :
204 0 : poFeature = GetNextRawFeature();
205 0 : if( poFeature == NULL )
206 0 : return NULL;
207 :
208 0 : if( (m_poFilterGeom == NULL
209 : || FilterGeometry( poFeature->GetGeometryRef() ) )
210 : && (m_poAttrQuery == NULL
211 : || m_poAttrQuery->Evaluate( poFeature )) )
212 0 : return poFeature;
213 :
214 0 : delete poFeature;
215 : }
216 : }
217 :
218 : /************************************************************************/
219 : /* GetNextRawFeature() */
220 : /************************************************************************/
221 :
222 0 : OGRFeature *OGRGeomediaLayer::GetNextRawFeature()
223 :
224 : {
225 0 : OGRErr err = OGRERR_NONE;
226 :
227 0 : if( GetStatement() == NULL )
228 0 : return NULL;
229 :
230 : /* -------------------------------------------------------------------- */
231 : /* If we are marked to restart then do so, and fetch a record. */
232 : /* -------------------------------------------------------------------- */
233 0 : if( !poStmt->Fetch() )
234 : {
235 0 : delete poStmt;
236 0 : poStmt = NULL;
237 0 : return NULL;
238 : }
239 :
240 : /* -------------------------------------------------------------------- */
241 : /* Create a feature from the current result. */
242 : /* -------------------------------------------------------------------- */
243 : int iField;
244 0 : OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
245 :
246 0 : if( pszFIDColumn != NULL && poStmt->GetColId(pszFIDColumn) > -1 )
247 : poFeature->SetFID(
248 0 : atoi(poStmt->GetColData(poStmt->GetColId(pszFIDColumn))) );
249 : else
250 0 : poFeature->SetFID( iNextShapeId );
251 :
252 0 : iNextShapeId++;
253 0 : m_nFeaturesRead++;
254 :
255 : /* -------------------------------------------------------------------- */
256 : /* Set the fields. */
257 : /* -------------------------------------------------------------------- */
258 0 : for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
259 : {
260 0 : int iSrcField = panFieldOrdinals[iField]-1;
261 0 : const char *pszValue = poStmt->GetColData( iSrcField );
262 :
263 0 : if( pszValue == NULL )
264 : /* no value */;
265 0 : else if( poFeature->GetFieldDefnRef(iField)->GetType() == OFTBinary )
266 : poFeature->SetField( iField,
267 : poStmt->GetColDataLength(iSrcField),
268 0 : (GByte *) pszValue );
269 : else
270 0 : poFeature->SetField( iField, pszValue );
271 : }
272 :
273 : /* -------------------------------------------------------------------- */
274 : /* Try to extract a geometry. */
275 : /* -------------------------------------------------------------------- */
276 0 : if( pszGeomColumn != NULL )
277 : {
278 0 : int iField = poStmt->GetColId( pszGeomColumn );
279 0 : GByte *pabyShape = (GByte *) poStmt->GetColData( iField );
280 0 : int nBytes = poStmt->GetColDataLength(iField);
281 0 : OGRGeometry *poGeom = NULL;
282 :
283 0 : if( pabyShape != NULL )
284 : {
285 0 : err = OGRCreateFromGeomedia( pabyShape, &poGeom, nBytes );
286 0 : if( OGRERR_NONE != err )
287 : {
288 : CPLDebug( "Geomedia",
289 : "Translation geomedia binary to OGR geometry failed (FID=%ld)",
290 0 : (long)poFeature->GetFID() );
291 : }
292 : }
293 :
294 0 : if( poGeom != NULL && OGRERR_NONE == err )
295 : {
296 0 : poGeom->assignSpatialReference( poSRS );
297 0 : poFeature->SetGeometryDirectly( poGeom );
298 : }
299 : }
300 :
301 0 : return poFeature;
302 : }
303 :
304 : /************************************************************************/
305 : /* GetFeature() */
306 : /************************************************************************/
307 :
308 0 : OGRFeature *OGRGeomediaLayer::GetFeature( long nFeatureId )
309 :
310 : {
311 : /* This should be implemented directly! */
312 :
313 0 : return OGRLayer::GetFeature( nFeatureId );
314 : }
315 :
316 : /************************************************************************/
317 : /* TestCapability() */
318 : /************************************************************************/
319 :
320 0 : int OGRGeomediaLayer::TestCapability( const char * pszCap )
321 :
322 : {
323 0 : return FALSE;
324 : }
325 :
326 : /************************************************************************/
327 : /* GetSpatialRef() */
328 : /************************************************************************/
329 :
330 0 : OGRSpatialReference *OGRGeomediaLayer::GetSpatialRef()
331 :
332 : {
333 0 : return poSRS;
334 : }
335 :
336 : /************************************************************************/
337 : /* GetFIDColumn() */
338 : /************************************************************************/
339 :
340 0 : const char *OGRGeomediaLayer::GetFIDColumn()
341 :
342 : {
343 0 : if( pszFIDColumn != NULL )
344 0 : return pszFIDColumn;
345 : else
346 0 : return "";
347 : }
348 :
349 : /************************************************************************/
350 : /* GetGeometryColumn() */
351 : /************************************************************************/
352 :
353 0 : const char *OGRGeomediaLayer::GetGeometryColumn()
354 :
355 : {
356 0 : if( pszGeomColumn != NULL )
357 0 : return pszGeomColumn;
358 : else
359 0 : return "";
360 : }
|