1 : /******************************************************************************
2 : * $Id: ogrgfttablelayer.cpp 22407 2011-05-20 19:31:11Z rouault $
3 : *
4 : * Project: GFT Translator
5 : * Purpose: Implements OGRGFTTableLayer class.
6 : * Author: Even Rouault, <even dot rouault at mines dash paris dot org>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2011, Even Rouault <even dot rouault at mines dash paris dot org>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "ogr_gft.h"
31 :
32 : CPL_CVSID("$Id: ogrgfttablelayer.cpp 22407 2011-05-20 19:31:11Z rouault $");
33 :
34 : /************************************************************************/
35 : /* OGRGFTTableLayer() */
36 : /************************************************************************/
37 :
38 292 : OGRGFTTableLayer::OGRGFTTableLayer(OGRGFTDataSource* poDS,
39 : const char* pszTableName,
40 : const char* pszTableId,
41 292 : const char* pszGeomColumnName) : OGRGFTLayer(poDS)
42 :
43 : {
44 292 : osTableName = pszTableName;
45 292 : osTableId = pszTableId;
46 292 : osGeomColumnName = pszGeomColumnName ? pszGeomColumnName : "";
47 :
48 292 : bHasTriedCreateTable = FALSE;
49 292 : bInTransaction = FALSE;
50 292 : nFeaturesInTransaction = 0;
51 :
52 292 : bFirstTokenIsFID = TRUE;
53 292 : eGTypeForCreation = wkbUnknown;
54 292 : }
55 :
56 : /************************************************************************/
57 : /* ~OGRGFTTableLayer() */
58 : /************************************************************************/
59 :
60 292 : OGRGFTTableLayer::~OGRGFTTableLayer()
61 :
62 : {
63 292 : CreateTableIfNecessary();
64 292 : }
65 :
66 : /************************************************************************/
67 : /* ResetReading() */
68 : /************************************************************************/
69 :
70 8 : void OGRGFTTableLayer::ResetReading()
71 :
72 : {
73 8 : OGRGFTLayer::ResetReading();
74 8 : aosRows.resize(0);
75 8 : }
76 :
77 : /************************************************************************/
78 : /* TestCapability() */
79 : /************************************************************************/
80 :
81 0 : int OGRGFTTableLayer::TestCapability( const char * pszCap )
82 :
83 : {
84 0 : if( EQUAL(pszCap,OLCRandomRead) )
85 0 : return TRUE;
86 :
87 0 : else if( EQUAL(pszCap,OLCSequentialWrite)
88 : || EQUAL(pszCap,OLCRandomWrite)
89 : || EQUAL(pszCap,OLCDeleteFeature) )
90 0 : return poDS->IsReadWrite();
91 :
92 0 : else if( EQUAL(pszCap,OLCCreateField) )
93 0 : return poDS->IsReadWrite();
94 :
95 0 : else if( EQUAL(pszCap, OLCTransactions) )
96 0 : return poDS->IsReadWrite();
97 :
98 0 : return OGRGFTLayer::TestCapability(pszCap);
99 : }
100 :
101 : /************************************************************************/
102 : /* FetchDescribe() */
103 : /************************************************************************/
104 :
105 16 : int OGRGFTTableLayer::FetchDescribe()
106 : {
107 16 : poFeatureDefn = new OGRFeatureDefn( osTableName );
108 16 : poFeatureDefn->Reference();
109 :
110 16 : const CPLString& osAuth = poDS->GetAuth();
111 16 : std::vector<CPLString> aosHeaderAndFirstDataLine;
112 32 : if (osAuth.size())
113 : {
114 14 : CPLString osSQL("DESCRIBE ");
115 14 : osSQL += osTableId;
116 14 : CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
117 :
118 14 : if (psResult == NULL)
119 6 : return FALSE;
120 :
121 8 : char* pszLine = (char*) psResult->pabyData;
122 8 : if (pszLine == NULL ||
123 : psResult->pszErrBuf != NULL ||
124 : strncmp(pszLine, "column id,name,type",
125 : strlen("column id,name,type")) != 0)
126 : {
127 0 : CPLHTTPDestroyResult(psResult);
128 0 : return FALSE;
129 : }
130 :
131 8 : pszLine = OGRGFTGotoNextLine(pszLine);
132 :
133 8 : std::vector<CPLString> aosLines;
134 8 : ParseCSVResponse(pszLine, aosLines);
135 30 : for(int i=0;i<(int)aosLines.size();i++)
136 : {
137 22 : char** papszTokens = OGRGFTCSVSplitLine(aosLines[i], ',');
138 22 : if (CSLCount(papszTokens) == 3)
139 : {
140 22 : aosColumnInternalName.push_back(papszTokens[0]);
141 :
142 : //CPLDebug("GFT", "%s %s %s", papszTokens[0], papszTokens[1], papszTokens[2]);
143 22 : OGRFieldType eType = OFTString;
144 22 : if (EQUAL(papszTokens[2], "number"))
145 6 : eType = OFTReal;
146 16 : else if (EQUAL(papszTokens[2], "datetime"))
147 0 : eType = OFTDateTime;
148 :
149 22 : if (EQUAL(papszTokens[2], "location") && osGeomColumnName.size() == 0)
150 : {
151 6 : if (iGeometryField < 0)
152 6 : iGeometryField = poFeatureDefn->GetFieldCount();
153 : else
154 : CPLDebug("GFT", "Multiple geometry fields detected. "
155 0 : "Only first encountered one is handled");
156 : }
157 :
158 22 : CPLString osLaunderedColName(LaunderColName(papszTokens[1]));
159 22 : OGRFieldDefn oFieldDefn(osLaunderedColName, eType);
160 22 : poFeatureDefn->AddFieldDefn(&oFieldDefn);
161 : }
162 22 : CSLDestroy(papszTokens);
163 : }
164 :
165 8 : CPLHTTPDestroyResult(psResult);
166 : }
167 : else
168 : {
169 : /* http://code.google.com/intl/fr/apis/fusiontables/docs/developers_guide.html#Exploring states */
170 : /* that DESCRIBE should work on public tables without authentication, but it is not true... */
171 2 : CPLString osSQL("SELECT * FROM ");
172 2 : osSQL += osTableId;
173 2 : osSQL += " OFFSET 0 LIMIT 1";
174 :
175 2 : CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
176 :
177 2 : if (psResult == NULL)
178 0 : return FALSE;
179 :
180 2 : char* pszLine = (char*) psResult->pabyData;
181 2 : if (pszLine == NULL || psResult->pszErrBuf != NULL)
182 : {
183 0 : CPLHTTPDestroyResult(psResult);
184 0 : return FALSE;
185 : }
186 :
187 2 : ParseCSVResponse(pszLine, aosHeaderAndFirstDataLine);
188 2 : if (aosHeaderAndFirstDataLine.size() > 0)
189 : {
190 2 : char** papszTokens = OGRGFTCSVSplitLine(aosHeaderAndFirstDataLine[0], ',');
191 62 : for(int i=0;papszTokens && papszTokens[i];i++)
192 : {
193 60 : CPLString osLaunderedColName(LaunderColName(papszTokens[i]));
194 60 : OGRFieldDefn oFieldDefn(osLaunderedColName, OFTString);
195 60 : poFeatureDefn->AddFieldDefn(&oFieldDefn);
196 : }
197 2 : CSLDestroy(papszTokens);
198 : }
199 :
200 2 : CPLHTTPDestroyResult(psResult);
201 : }
202 :
203 10 : if (osGeomColumnName.size() > 0)
204 : {
205 0 : iGeometryField = poFeatureDefn->GetFieldIndex(osGeomColumnName);
206 0 : if (iGeometryField < 0)
207 : {
208 : CPLError(CE_Warning, CPLE_AppDefined,
209 0 : "Cannot find column called %s", osGeomColumnName.c_str());
210 : }
211 : }
212 :
213 92 : for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
214 : {
215 82 : const char* pszName = poFeatureDefn->GetFieldDefn(i)->GetNameRef();
216 84 : if (EQUAL(pszName, "latitude") || EQUAL(pszName, "lat") ||
217 : EQUAL(pszName, "latdec"))
218 2 : iLatitudeField = i;
219 80 : else if (EQUAL(pszName, "longitude") || EQUAL(pszName, "lon") ||
220 : EQUAL(pszName, "londec") || EQUAL(pszName, "long"))
221 2 : iLongitudeField = i;
222 : }
223 :
224 12 : if (iLatitudeField >= 0 && iLongitudeField >= 0)
225 : {
226 2 : if (iGeometryField < 0)
227 2 : iGeometryField = iLatitudeField;
228 2 : poFeatureDefn->GetFieldDefn(iLatitudeField)->SetType(OFTReal);
229 2 : poFeatureDefn->GetFieldDefn(iLongitudeField)->SetType(OFTReal);
230 2 : poFeatureDefn->SetGeomType( wkbPoint );
231 : }
232 8 : else if (iGeometryField < 0 && osGeomColumnName.size() == 0)
233 : {
234 2 : iLatitudeField = iLongitudeField = -1;
235 :
236 : /* In the unauthentified case, we try to parse the first record to */
237 : /* autodetect the geometry field */
238 2 : OGRwkbGeometryType eType = wkbUnknown;
239 2 : if (aosHeaderAndFirstDataLine.size() == 2)
240 : {
241 0 : char** papszTokens = OGRGFTCSVSplitLine(aosHeaderAndFirstDataLine[1], ',');
242 0 : if (CSLCount(papszTokens) == poFeatureDefn->GetFieldCount())
243 : {
244 0 : for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
245 : {
246 0 : const char* pszVal = papszTokens[i];
247 0 : if (pszVal != NULL &&
248 : (strncmp(pszVal, "<Point>", 7) == 0 ||
249 : strncmp(pszVal, "<LineString>", 12) == 0 ||
250 : strncmp(pszVal, "<Polygon>", 9) == 0 ||
251 : strncmp(pszVal, "<MultiGeometry>", 15) == 0))
252 : {
253 0 : if (iGeometryField < 0)
254 : {
255 0 : iGeometryField = i;
256 : }
257 : else
258 : {
259 : CPLDebug("GFT", "Multiple geometry fields detected. "
260 0 : "Only first encountered one is handled");
261 : }
262 : }
263 0 : else if (pszVal)
264 : {
265 : /* http://www.google.com/fusiontables/DataSource?dsrcid=423292 */
266 0 : char** papszTokens2 = CSLTokenizeString2(pszVal, " ,", 0);
267 0 : if (CSLCount(papszTokens2) == 2 &&
268 0 : CPLGetValueType(papszTokens2[0]) == CPL_VALUE_REAL &&
269 0 : CPLGetValueType(papszTokens2[1]) == CPL_VALUE_REAL &&
270 0 : fabs(CPLAtof(papszTokens2[0])) <= 90 &&
271 0 : fabs(CPLAtof(papszTokens2[1])) <= 180 )
272 : {
273 0 : if (iGeometryField < 0)
274 : {
275 0 : iGeometryField = i;
276 0 : eType = wkbPoint;
277 : }
278 : else
279 : {
280 : CPLDebug("GFT", "Multiple geometry fields detected. "
281 0 : "Only first encountered one is handled");
282 : }
283 : }
284 0 : CSLDestroy(papszTokens2);
285 : }
286 : }
287 : }
288 0 : CSLDestroy(papszTokens);
289 : }
290 :
291 2 : if (iGeometryField < 0)
292 2 : poFeatureDefn->SetGeomType( wkbNone );
293 : else
294 0 : poFeatureDefn->SetGeomType( eType );
295 : }
296 :
297 10 : return TRUE;
298 : }
299 :
300 : /************************************************************************/
301 : /* EscapeAndQuote() */
302 : /************************************************************************/
303 :
304 126 : static CPLString EscapeAndQuote(const char* pszStr)
305 : {
306 : char ch;
307 126 : CPLString osRes("'");
308 862 : while((ch = *pszStr) != 0)
309 : {
310 610 : if (ch == '\'')
311 6 : osRes += "\\\'";
312 : else
313 604 : osRes += ch;
314 610 : pszStr ++;
315 : }
316 126 : osRes += "'";
317 0 : return osRes;
318 : }
319 :
320 : /************************************************************************/
321 : /* FetchNextRows() */
322 : /************************************************************************/
323 :
324 8 : int OGRGFTTableLayer::FetchNextRows()
325 : {
326 8 : aosRows.resize(0);
327 :
328 8 : CPLString osSQL("SELECT ROWID");
329 30 : for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
330 : {
331 22 : osSQL += ",";
332 :
333 22 : if (i < (int)aosColumnInternalName.size())
334 18 : osSQL += aosColumnInternalName[i];
335 : else
336 : {
337 : const char* pszFieldName =
338 4 : poFeatureDefn->GetFieldDefn(i)->GetNameRef();
339 4 : osSQL += EscapeAndQuote(pszFieldName);
340 : }
341 : }
342 8 : if (bHiddenGeometryField)
343 : {
344 2 : osSQL += ",";
345 2 : osSQL += EscapeAndQuote(GetGeometryColumn());
346 : }
347 8 : osSQL += " FROM ";
348 8 : osSQL += osTableId;
349 8 : if (osWHERE.size())
350 : {
351 0 : osSQL += " ";
352 0 : osSQL += osWHERE;
353 : }
354 :
355 8 : int nFeaturesToFetch = GetFeaturesToFetch();
356 8 : if (nFeaturesToFetch > 0)
357 8 : osSQL += CPLSPrintf(" OFFSET %d LIMIT %d", nOffset, nFeaturesToFetch);
358 :
359 8 : CPLPushErrorHandler(CPLQuietErrorHandler);
360 8 : CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
361 8 : CPLPopErrorHandler();
362 :
363 8 : if (psResult == NULL)
364 : {
365 0 : bEOF = TRUE;
366 0 : return FALSE;
367 : }
368 :
369 8 : char* pszLine = (char*) psResult->pabyData;
370 8 : if (pszLine == NULL || psResult->pszErrBuf != NULL)
371 : {
372 0 : CPLDebug("GFT", "Error : %s", pszLine ? pszLine : psResult->pszErrBuf);
373 0 : CPLHTTPDestroyResult(psResult);
374 0 : bEOF = TRUE;
375 0 : return FALSE;
376 : }
377 :
378 8 : ParseCSVResponse(pszLine, aosRows);
379 :
380 8 : if (aosRows.size() > 0)
381 8 : aosRows.erase(aosRows.begin());
382 :
383 8 : if (nFeaturesToFetch > 0)
384 8 : bEOF = (int)aosRows.size() < GetFeaturesToFetch();
385 : else
386 0 : bEOF = TRUE;
387 :
388 8 : CPLHTTPDestroyResult(psResult);
389 :
390 8 : return TRUE;
391 : }
392 : /************************************************************************/
393 : /* GetFeature() */
394 : /************************************************************************/
395 :
396 2 : OGRFeature * OGRGFTTableLayer::GetFeature( long nFID )
397 : {
398 2 : GetLayerDefn();
399 :
400 2 : CPLString osSQL("SELECT ROWID");
401 6 : for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
402 : {
403 4 : osSQL += ",";
404 :
405 : const char* pszFieldName =
406 4 : poFeatureDefn->GetFieldDefn(i)->GetNameRef();
407 4 : osSQL += EscapeAndQuote(pszFieldName);
408 : }
409 2 : if (bHiddenGeometryField)
410 : {
411 2 : osSQL += ",";
412 2 : osSQL += EscapeAndQuote(GetGeometryColumn());
413 : }
414 2 : osSQL += " FROM ";
415 2 : osSQL += osTableId;
416 2 : osSQL += CPLSPrintf(" WHERE ROWID='%ld'", nFID);
417 :
418 2 : CPLPushErrorHandler(CPLQuietErrorHandler);
419 2 : CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
420 2 : CPLPopErrorHandler();
421 :
422 2 : if (psResult == NULL)
423 0 : return NULL;
424 :
425 2 : char* pszLine = (char*) psResult->pabyData;
426 2 : if (pszLine == NULL || psResult->pszErrBuf != NULL)
427 : {
428 0 : CPLHTTPDestroyResult(psResult);
429 0 : return NULL;
430 : }
431 :
432 : /* skip header line */
433 2 : pszLine = OGRGFTGotoNextLine(pszLine);
434 2 : if (pszLine == NULL || pszLine[0] == 0)
435 : {
436 0 : CPLHTTPDestroyResult(psResult);
437 0 : return NULL;
438 : }
439 :
440 2 : int nLen = (int)strlen(pszLine);
441 2 : if (nLen > 0 && pszLine[nLen-1] == '\n')
442 2 : pszLine[nLen-1] = '\0';
443 :
444 2 : OGRFeature* poFeature = BuildFeatureFromSQL(pszLine);
445 :
446 2 : CPLHTTPDestroyResult(psResult);
447 :
448 2 : return poFeature;
449 : }
450 :
451 : /************************************************************************/
452 : /* GetLayerDefn() */
453 : /************************************************************************/
454 :
455 122 : OGRFeatureDefn * OGRGFTTableLayer::GetLayerDefn()
456 : {
457 122 : if (poFeatureDefn == NULL)
458 : {
459 22 : if (osTableId.size() == 0)
460 6 : return NULL;
461 16 : FetchDescribe();
462 : }
463 :
464 116 : return poFeatureDefn;
465 : }
466 :
467 : /************************************************************************/
468 : /* GetFeatureCount() */
469 : /************************************************************************/
470 :
471 10 : int OGRGFTTableLayer::GetFeatureCount(int bForce)
472 : {
473 10 : GetLayerDefn();
474 :
475 10 : CPLString osSQL("SELECT COUNT() FROM ");
476 10 : osSQL += osTableId;
477 10 : if (osWHERE.size())
478 : {
479 2 : osSQL += " ";
480 2 : osSQL += osWHERE;
481 : }
482 :
483 10 : CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
484 :
485 10 : if (psResult == NULL)
486 0 : return 0;
487 :
488 10 : char* pszLine = (char*) psResult->pabyData;
489 10 : if (pszLine == NULL ||
490 : strncmp(pszLine, "count()", 7) != 0 ||
491 : psResult->pszErrBuf != NULL)
492 : {
493 0 : CPLError(CE_Failure, CPLE_AppDefined, "GetFeatureCount() failed");
494 0 : CPLHTTPDestroyResult(psResult);
495 0 : return 0;
496 : }
497 :
498 10 : pszLine = OGRGFTGotoNextLine(pszLine);
499 10 : if (pszLine == NULL)
500 : {
501 0 : CPLError(CE_Failure, CPLE_AppDefined, "GetFeatureCount() failed");
502 0 : CPLHTTPDestroyResult(psResult);
503 0 : return 0;
504 : }
505 :
506 10 : char* pszNextLine = OGRGFTGotoNextLine(pszLine);
507 10 : if (pszNextLine)
508 10 : pszNextLine[-1] = 0;
509 :
510 10 : int nFeatureCount = atoi(pszLine);
511 :
512 10 : CPLHTTPDestroyResult(psResult);
513 :
514 10 : return nFeatureCount;
515 : }
516 :
517 : /************************************************************************/
518 : /* CreateField() */
519 : /************************************************************************/
520 :
521 18 : OGRErr OGRGFTTableLayer::CreateField( OGRFieldDefn *poField,
522 : int bApproxOK )
523 : {
524 :
525 18 : if (!poDS->IsReadWrite())
526 : {
527 : CPLError(CE_Failure, CPLE_AppDefined,
528 0 : "Operation not available in read-only mode");
529 0 : return OGRERR_FAILURE;
530 : }
531 :
532 18 : if (osTableId.size() != 0)
533 : {
534 : CPLError(CE_Failure, CPLE_NotSupported,
535 0 : "Cannot add field to already created table");
536 0 : return OGRERR_FAILURE;
537 : }
538 :
539 18 : if (poDS->GetAuth().size() == 0)
540 : {
541 : CPLError(CE_Failure, CPLE_AppDefined,
542 0 : "Operation not available in unauthenticated mode");
543 0 : return OGRERR_FAILURE;
544 : }
545 :
546 18 : if (poFeatureDefn == NULL)
547 : {
548 8 : poFeatureDefn = new OGRFeatureDefn( osTableName );
549 8 : poFeatureDefn->Reference();
550 : }
551 :
552 18 : poFeatureDefn->AddFieldDefn(poField);
553 :
554 18 : return OGRERR_NONE;
555 : }
556 :
557 : /************************************************************************/
558 : /* CreateTableIfNecessary() */
559 : /************************************************************************/
560 :
561 300 : void OGRGFTTableLayer::CreateTableIfNecessary()
562 : {
563 300 : if (bHasTriedCreateTable || osTableId.size() != 0)
564 292 : return;
565 :
566 8 : bHasTriedCreateTable = TRUE;
567 :
568 8 : CPLString osSQL("CREATE TABLE '");
569 8 : osSQL += osTableName;
570 8 : osSQL += "' (";
571 :
572 : int i;
573 :
574 8 : if (poFeatureDefn == NULL)
575 : {
576 : /* In case CreateField() hasn't yet been called */
577 0 : poFeatureDefn = new OGRFeatureDefn( osTableName );
578 0 : poFeatureDefn->Reference();
579 : }
580 :
581 : /* If there are longitude and latitude fields, use the latitude */
582 : /* field as the LOCATION field */
583 26 : for(i=0;i<poFeatureDefn->GetFieldCount();i++)
584 : {
585 18 : const char* pszName = poFeatureDefn->GetFieldDefn(i)->GetNameRef();
586 18 : if (EQUAL(pszName, "latitude") || EQUAL(pszName, "lat") ||
587 : EQUAL(pszName, "latdec"))
588 0 : iLatitudeField = i;
589 18 : else if (EQUAL(pszName, "longitude") || EQUAL(pszName, "lon") ||
590 : EQUAL(pszName, "londec") || EQUAL(pszName, "long"))
591 0 : iLongitudeField = i;
592 : }
593 :
594 8 : if (iLatitudeField >= 0 && iLongitudeField >= 0)
595 : {
596 0 : iGeometryField = iLatitudeField;
597 0 : poFeatureDefn->SetGeomType( wkbPoint );
598 : }
599 : /* If no longitude/latitude field exist, let's look at a column */
600 : /* named 'geometry' and use it as the LOCATION column if the layer */
601 : /* hasn't been created with a none geometry type */
602 14 : else if (iGeometryField < 0 && eGTypeForCreation != wkbNone)
603 : {
604 6 : iGeometryField = poFeatureDefn->GetFieldIndex(GetDefaultGeometryColumnName());
605 6 : poFeatureDefn->SetGeomType( eGTypeForCreation );
606 : }
607 : /* The user doesn't want geometries, so don't create one */
608 2 : else if (eGTypeForCreation == wkbNone)
609 : {
610 2 : poFeatureDefn->SetGeomType( eGTypeForCreation );
611 : }
612 :
613 26 : for(i=0;i<poFeatureDefn->GetFieldCount();i++)
614 : {
615 18 : if (i > 0)
616 10 : osSQL += ", ";
617 :
618 : const char* pszFieldName =
619 18 : poFeatureDefn->GetFieldDefn(i)->GetNameRef();
620 18 : osSQL += EscapeAndQuote(pszFieldName);
621 18 : osSQL += ": ";
622 :
623 18 : if (iGeometryField == i)
624 : {
625 2 : osSQL += "LOCATION";
626 : }
627 : else
628 : {
629 16 : switch(poFeatureDefn->GetFieldDefn(i)->GetType())
630 : {
631 : case OFTInteger:
632 : case OFTReal:
633 6 : osSQL += "NUMBER";
634 6 : break;
635 : default:
636 10 : osSQL += "STRING";
637 : }
638 : }
639 : }
640 :
641 : /* If there's not yet a geometry field and the user didn't forbid */
642 : /* the creation of one, then let's add it to the CREATE TABLE, but */
643 : /* DO NOT add it to the feature defn as a feature might already have */
644 : /* been created with it, so it is not safe to alter it at that point. */
645 : /* So we set the bHiddenGeometryField flag to be able to fetch/set this */
646 : /* column but not try to get/set a related feature field */
647 8 : if (iGeometryField < 0 && eGTypeForCreation != wkbNone)
648 : {
649 4 : if (i > 0)
650 4 : osSQL += ", ";
651 4 : osSQL += EscapeAndQuote(GetDefaultGeometryColumnName());
652 4 : osSQL += ": LOCATION";
653 :
654 4 : iGeometryField = poFeatureDefn->GetFieldCount();
655 4 : bHiddenGeometryField = TRUE;
656 : }
657 8 : osSQL += ")";
658 :
659 8 : CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
660 8 : if (psResult == NULL)
661 : {
662 0 : CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed");
663 : return;
664 : }
665 :
666 8 : char* pszLine = (char*) psResult->pabyData;
667 8 : if (pszLine == NULL ||
668 : strncmp(pszLine, "tableid", 7) != 0 ||
669 : psResult->pszErrBuf != NULL)
670 : {
671 0 : CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed");
672 0 : CPLHTTPDestroyResult(psResult);
673 : return;
674 : }
675 :
676 8 : pszLine = OGRGFTGotoNextLine(pszLine);
677 8 : if (pszLine == NULL)
678 : {
679 0 : CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed");
680 0 : CPLHTTPDestroyResult(psResult);
681 : return;
682 : }
683 :
684 8 : char* pszNextLine = OGRGFTGotoNextLine(pszLine);
685 8 : if (pszNextLine)
686 8 : pszNextLine[-1] = 0;
687 :
688 8 : osTableId = pszLine;
689 8 : CPLDebug("GFT", "Table %s --> id = %s", osTableName.c_str(), osTableId.c_str());
690 :
691 8 : CPLHTTPDestroyResult(psResult);
692 : }
693 :
694 : /************************************************************************/
695 : /* CreateFeature() */
696 : /************************************************************************/
697 :
698 20 : OGRErr OGRGFTTableLayer::CreateFeature( OGRFeature *poFeature )
699 :
700 : {
701 20 : if (!poDS->IsReadWrite())
702 : {
703 : CPLError(CE_Failure, CPLE_AppDefined,
704 0 : "Operation not available in read-only mode");
705 0 : return OGRERR_FAILURE;
706 : }
707 :
708 20 : if (osTableId.size() == 0)
709 : {
710 2 : CreateTableIfNecessary();
711 2 : if (osTableId.size() == 0)
712 : {
713 : CPLError(CE_Failure, CPLE_NotSupported,
714 0 : "Cannot add feature to non-created table");
715 0 : return OGRERR_FAILURE;
716 : }
717 : }
718 :
719 20 : if (poDS->GetAuth().size() == 0)
720 : {
721 : CPLError(CE_Failure, CPLE_AppDefined,
722 0 : "Operation not available in unauthenticated mode");
723 0 : return OGRERR_FAILURE;
724 : }
725 :
726 20 : CPLString osCommand;
727 :
728 20 : osCommand += "INSERT INTO ";
729 20 : osCommand += osTableId;
730 20 : osCommand += " (";
731 :
732 : int iField;
733 20 : int nFieldCount = poFeatureDefn->GetFieldCount();
734 66 : for(iField = 0; iField < nFieldCount; iField++)
735 : {
736 46 : if (iField > 0)
737 26 : osCommand += ", ";
738 :
739 : const char* pszFieldName =
740 46 : poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
741 46 : osCommand += EscapeAndQuote(pszFieldName);
742 : }
743 20 : if (bHiddenGeometryField)
744 : {
745 8 : if (iField > 0)
746 8 : osCommand += ", ";
747 8 : osCommand += EscapeAndQuote(GetGeometryColumn());
748 : }
749 20 : osCommand += ") VALUES (";
750 74 : for(iField = 0; iField < nFieldCount + bHiddenGeometryField; iField++)
751 : {
752 54 : if (iField > 0)
753 34 : osCommand += ", ";
754 :
755 54 : OGRGeometry* poGeom = poFeature->GetGeometryRef();
756 : /* If there's a geometry, let's use it in priority over the textual */
757 : /* content of the field. */
758 54 : if (iGeometryField != iLatitudeField && iField == iGeometryField &&
759 : (iField == nFieldCount || poGeom != NULL || !poFeature->IsFieldSet( iField )))
760 : {
761 14 : if (poGeom == NULL)
762 0 : osCommand += "''";
763 : else
764 : {
765 : char* pszKML;
766 14 : if (poGeom->getSpatialReference() != NULL &&
767 : !poGeom->getSpatialReference()->IsSame(poSRS))
768 : {
769 0 : OGRGeometry* poGeom4326 = poGeom->clone();
770 0 : poGeom4326->transformTo(poSRS);
771 0 : pszKML = poGeom4326->exportToKML();
772 0 : delete poGeom4326;
773 : }
774 : else
775 : {
776 14 : pszKML = poGeom->exportToKML();
777 : }
778 14 : osCommand += "'";
779 14 : osCommand += pszKML;
780 14 : osCommand += "'";
781 14 : CPLFree(pszKML);
782 : }
783 14 : continue;
784 : }
785 :
786 40 : if( !poFeature->IsFieldSet( iField ) )
787 : {
788 0 : osCommand += "''";
789 : }
790 : else
791 : {
792 40 : OGRFieldType eType = poFeatureDefn->GetFieldDefn(iField)->GetType();
793 66 : if (eType != OFTInteger && eType != OFTReal)
794 : {
795 26 : CPLString osTmp;
796 26 : const char* pszVal = poFeature->GetFieldAsString(iField);
797 :
798 26 : if (!CPLIsUTF8(pszVal, -1))
799 : {
800 : static int bFirstTime = TRUE;
801 0 : if (bFirstTime)
802 : {
803 0 : bFirstTime = FALSE;
804 : CPLError(CE_Warning, CPLE_AppDefined,
805 : "%s is not a valid UTF-8 string. Forcing it to ASCII.\n"
806 0 : "This warning won't be issued anymore", pszVal);
807 : }
808 : else
809 : {
810 : CPLDebug("OGR", "%s is not a valid UTF-8 string. Forcing it to ASCII",
811 0 : pszVal);
812 : }
813 0 : char* pszEscaped = CPLForceToASCII(pszVal, -1, '?');
814 0 : osTmp = pszEscaped;
815 0 : CPLFree(pszEscaped);
816 0 : pszVal = osTmp.c_str();
817 : }
818 :
819 26 : osCommand += EscapeAndQuote(pszVal);
820 : }
821 : else
822 14 : osCommand += poFeature->GetFieldAsString(iField);
823 : }
824 : }
825 :
826 20 : osCommand += ")";
827 :
828 : //CPLDebug("GFT", "%s", osCommand.c_str());
829 :
830 20 : if (bInTransaction)
831 : {
832 18 : nFeaturesInTransaction ++;
833 18 : if (nFeaturesInTransaction > 1)
834 12 : osTransaction += "; ";
835 18 : osTransaction += osCommand;
836 18 : return OGRERR_NONE;
837 : }
838 :
839 2 : CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
840 2 : if (psResult == NULL)
841 : {
842 0 : CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
843 0 : return OGRERR_FAILURE;
844 : }
845 :
846 2 : char* pszLine = (char*) psResult->pabyData;
847 2 : if (pszLine == NULL ||
848 : strncmp(pszLine, "rowid", 5) != 0 ||
849 : psResult->pszErrBuf != NULL)
850 : {
851 0 : CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
852 0 : CPLHTTPDestroyResult(psResult);
853 0 : return OGRERR_FAILURE;
854 : }
855 :
856 2 : pszLine = OGRGFTGotoNextLine(pszLine);
857 2 : if (pszLine == NULL)
858 : {
859 0 : CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
860 0 : CPLHTTPDestroyResult(psResult);
861 0 : return OGRERR_FAILURE;
862 : }
863 :
864 2 : char* pszNextLine = OGRGFTGotoNextLine(pszLine);
865 2 : if (pszNextLine)
866 2 : pszNextLine[-1] = 0;
867 :
868 2 : CPLDebug("GFT", "Feature id = %s", pszLine);
869 :
870 2 : int nFID = atoi(pszLine);
871 2 : if (strcmp(CPLSPrintf("%d", nFID), pszLine) == 0)
872 2 : poFeature->SetFID(nFID);
873 :
874 2 : CPLHTTPDestroyResult(psResult);
875 :
876 2 : return OGRERR_NONE;
877 : }
878 :
879 : /************************************************************************/
880 : /* SetFeature() */
881 : /************************************************************************/
882 :
883 2 : OGRErr OGRGFTTableLayer::SetFeature( OGRFeature *poFeature )
884 : {
885 2 : GetLayerDefn();
886 :
887 2 : if (!poDS->IsReadWrite())
888 : {
889 : CPLError(CE_Failure, CPLE_AppDefined,
890 0 : "Operation not available in read-only mode");
891 0 : return OGRERR_FAILURE;
892 : }
893 :
894 2 : if (osTableId.size() == 0)
895 : {
896 : CPLError(CE_Failure, CPLE_NotSupported,
897 0 : "Cannot set feature to non-created table");
898 0 : return OGRERR_FAILURE;
899 : }
900 :
901 2 : if (poDS->GetAuth().size() == 0)
902 : {
903 : CPLError(CE_Failure, CPLE_AppDefined,
904 0 : "Operation not available in unauthenticated mode");
905 0 : return OGRERR_FAILURE;
906 : }
907 :
908 2 : if (poFeature->GetFID() == OGRNullFID)
909 : {
910 : CPLError( CE_Failure, CPLE_AppDefined,
911 0 : "FID required on features given to SetFeature()." );
912 0 : return OGRERR_FAILURE;
913 : }
914 :
915 2 : CPLString osCommand;
916 :
917 2 : osCommand += "UPDATE ";
918 2 : osCommand += osTableId;
919 2 : osCommand += " SET ";
920 :
921 : int iField;
922 2 : int nFieldCount = poFeatureDefn->GetFieldCount();
923 8 : for(iField = 0; iField < nFieldCount + bHiddenGeometryField; iField++)
924 : {
925 6 : if (iField > 0)
926 4 : osCommand += ", ";
927 :
928 6 : if (iField == nFieldCount)
929 : {
930 2 : osCommand += EscapeAndQuote(GetGeometryColumn());
931 : }
932 : else
933 : {
934 : const char* pszFieldName =
935 4 : poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
936 4 : osCommand += EscapeAndQuote(pszFieldName);
937 : }
938 :
939 6 : osCommand += " = ";
940 :
941 6 : OGRGeometry* poGeom = poFeature->GetGeometryRef();
942 6 : if (iGeometryField != iLatitudeField && iField == iGeometryField &&
943 : (iField == nFieldCount || poGeom != NULL || !poFeature->IsFieldSet( iField )))
944 : {
945 2 : if (poGeom == NULL)
946 0 : osCommand += "''";
947 : else
948 : {
949 : char* pszKML;
950 2 : if (poGeom->getSpatialReference() != NULL &&
951 : !poGeom->getSpatialReference()->IsSame(poSRS))
952 : {
953 0 : OGRGeometry* poGeom4326 = poGeom->clone();
954 0 : poGeom4326->transformTo(poSRS);
955 0 : pszKML = poGeom4326->exportToKML();
956 0 : delete poGeom4326;
957 : }
958 : else
959 : {
960 2 : pszKML = poGeom->exportToKML();
961 : }
962 2 : osCommand += "'";
963 2 : osCommand += pszKML;
964 2 : osCommand += "'";
965 2 : CPLFree(pszKML);
966 : }
967 2 : continue;
968 : }
969 :
970 4 : if( !poFeature->IsFieldSet( iField ) )
971 : {
972 0 : osCommand += "''";
973 : }
974 : else
975 : {
976 4 : OGRFieldType eType = poFeatureDefn->GetFieldDefn(iField)->GetType();
977 6 : if (eType != OFTInteger && eType != OFTReal)
978 : {
979 2 : CPLString osTmp;
980 2 : const char* pszVal = poFeature->GetFieldAsString(iField);
981 :
982 2 : if (!CPLIsUTF8(pszVal, -1))
983 : {
984 : static int bFirstTime = TRUE;
985 0 : if (bFirstTime)
986 : {
987 0 : bFirstTime = FALSE;
988 : CPLError(CE_Warning, CPLE_AppDefined,
989 : "%s is not a valid UTF-8 string. Forcing it to ASCII.\n"
990 0 : "This warning won't be issued anymore", pszVal);
991 : }
992 : else
993 : {
994 : CPLDebug("OGR", "%s is not a valid UTF-8 string. Forcing it to ASCII",
995 0 : pszVal);
996 : }
997 0 : char* pszEscaped = CPLForceToASCII(pszVal, -1, '?');
998 0 : osTmp = pszEscaped;
999 0 : CPLFree(pszEscaped);
1000 0 : pszVal = osTmp.c_str();
1001 : }
1002 :
1003 2 : osCommand += EscapeAndQuote(pszVal);
1004 : }
1005 : else
1006 2 : osCommand += poFeature->GetFieldAsString(iField);
1007 : }
1008 : }
1009 :
1010 2 : osCommand += " WHERE ROWID = '";
1011 2 : osCommand += CPLSPrintf("%ld", poFeature->GetFID());
1012 2 : osCommand += "'";
1013 :
1014 : //CPLDebug("GFT", "%s", osCommand.c_str());
1015 :
1016 2 : CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
1017 2 : if (psResult == NULL)
1018 : {
1019 0 : CPLError(CE_Failure, CPLE_AppDefined, "Feature update failed");
1020 0 : return OGRERR_FAILURE;
1021 : }
1022 :
1023 2 : char* pszLine = (char*) psResult->pabyData;
1024 2 : if (pszLine == NULL ||
1025 : strncmp(pszLine, "OK", 2) != 0 ||
1026 : psResult->pszErrBuf != NULL)
1027 : {
1028 0 : CPLError(CE_Failure, CPLE_AppDefined, "Feature update failed");
1029 0 : CPLHTTPDestroyResult(psResult);
1030 0 : return OGRERR_FAILURE;
1031 : }
1032 :
1033 2 : CPLHTTPDestroyResult(psResult);
1034 :
1035 2 : return OGRERR_NONE;
1036 : }
1037 :
1038 : /************************************************************************/
1039 : /* DeleteFeature() */
1040 : /************************************************************************/
1041 :
1042 2 : OGRErr OGRGFTTableLayer::DeleteFeature( long nFID )
1043 : {
1044 2 : GetLayerDefn();
1045 :
1046 2 : if (!poDS->IsReadWrite())
1047 : {
1048 : CPLError(CE_Failure, CPLE_AppDefined,
1049 0 : "Operation not available in read-only mode");
1050 0 : return OGRERR_FAILURE;
1051 : }
1052 :
1053 2 : if (osTableId.size() == 0)
1054 : {
1055 : CPLError(CE_Failure, CPLE_NotSupported,
1056 0 : "Cannot delete feature in non-created table");
1057 0 : return OGRERR_FAILURE;
1058 : }
1059 :
1060 2 : if (poDS->GetAuth().size() == 0)
1061 : {
1062 : CPLError(CE_Failure, CPLE_AppDefined,
1063 0 : "Operation not available in unauthenticated mode");
1064 0 : return OGRERR_FAILURE;
1065 : }
1066 :
1067 2 : CPLString osCommand;
1068 :
1069 2 : osCommand += "DELETE FROM ";
1070 2 : osCommand += osTableId;
1071 2 : osCommand += " WHERE ROWID = '";
1072 2 : osCommand += CPLSPrintf("%ld", nFID);
1073 2 : osCommand += "'";
1074 :
1075 : //CPLDebug("GFT", "%s", osCommand.c_str());
1076 :
1077 2 : CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
1078 2 : if (psResult == NULL)
1079 : {
1080 0 : CPLError(CE_Failure, CPLE_AppDefined, "Feature deletion failed");
1081 0 : return OGRERR_FAILURE;
1082 : }
1083 :
1084 2 : char* pszLine = (char*) psResult->pabyData;
1085 2 : if (pszLine == NULL ||
1086 : strncmp(pszLine, "OK", 2) != 0 ||
1087 : psResult->pszErrBuf != NULL)
1088 : {
1089 0 : CPLError(CE_Failure, CPLE_AppDefined, "Feature deletion failed");
1090 0 : CPLHTTPDestroyResult(psResult);
1091 0 : return OGRERR_FAILURE;
1092 : }
1093 :
1094 2 : CPLHTTPDestroyResult(psResult);
1095 :
1096 2 : return OGRERR_NONE;
1097 : }
1098 :
1099 : /************************************************************************/
1100 : /* StartTransaction() */
1101 : /************************************************************************/
1102 :
1103 6 : OGRErr OGRGFTTableLayer::StartTransaction()
1104 : {
1105 6 : GetLayerDefn();
1106 :
1107 6 : if (bInTransaction)
1108 : {
1109 0 : CPLError(CE_Failure, CPLE_AppDefined, "Already in transaction");
1110 0 : return OGRERR_FAILURE;
1111 : }
1112 :
1113 6 : if (!poDS->IsReadWrite())
1114 : {
1115 : CPLError(CE_Failure, CPLE_AppDefined,
1116 0 : "Operation not available in read-only mode");
1117 0 : return OGRERR_FAILURE;
1118 : }
1119 :
1120 6 : if (osTableId.size() == 0)
1121 : {
1122 6 : CreateTableIfNecessary();
1123 6 : if (osTableId.size() == 0)
1124 : {
1125 : CPLError(CE_Failure, CPLE_NotSupported,
1126 0 : "Cannot add feature to non-created table");
1127 0 : return OGRERR_FAILURE;
1128 : }
1129 : }
1130 :
1131 6 : if (poDS->GetAuth().size() == 0)
1132 : {
1133 : CPLError(CE_Failure, CPLE_AppDefined,
1134 0 : "Operation not available in unauthenticated mode");
1135 0 : return OGRERR_FAILURE;
1136 : }
1137 :
1138 6 : bInTransaction = TRUE;
1139 6 : osTransaction.resize(0);
1140 6 : nFeaturesInTransaction = 0;
1141 :
1142 6 : return OGRERR_NONE;
1143 : }
1144 :
1145 : /************************************************************************/
1146 : /* CommitTransaction() */
1147 : /************************************************************************/
1148 :
1149 6 : OGRErr OGRGFTTableLayer::CommitTransaction()
1150 : {
1151 6 : GetLayerDefn();
1152 :
1153 6 : if (!bInTransaction)
1154 : {
1155 0 : CPLError(CE_Failure, CPLE_AppDefined, "Should be in transaction");
1156 0 : return OGRERR_FAILURE;
1157 : }
1158 :
1159 6 : bInTransaction = FALSE;
1160 :
1161 6 : if (nFeaturesInTransaction > 0)
1162 : {
1163 6 : if (nFeaturesInTransaction > 1)
1164 6 : osTransaction += ";";
1165 :
1166 6 : CPLHTTPResult * psResult = poDS->RunSQL(osTransaction);
1167 6 : osTransaction.resize(0);
1168 6 : nFeaturesInTransaction = 0;
1169 :
1170 6 : if (psResult == NULL)
1171 : {
1172 0 : CPLError(CE_Failure, CPLE_AppDefined, "CommitTransaction failed");
1173 0 : return OGRERR_FAILURE;
1174 : }
1175 :
1176 6 : char* pszLine = (char*) psResult->pabyData;
1177 6 : if (pszLine == NULL ||
1178 : strncmp(pszLine, "rowid", 5) != 0 ||
1179 : psResult->pszErrBuf != NULL)
1180 : {
1181 : CPLError(CE_Failure, CPLE_AppDefined, "CommitTransaction failed : %s",
1182 0 : pszLine ? pszLine : psResult->pszErrBuf);
1183 0 : CPLHTTPDestroyResult(psResult);
1184 0 : return OGRERR_FAILURE;
1185 : }
1186 :
1187 6 : pszLine = OGRGFTGotoNextLine(pszLine);
1188 30 : while(pszLine && *pszLine != 0)
1189 : {
1190 18 : char* pszNextLine = OGRGFTGotoNextLine(pszLine);
1191 18 : if (pszNextLine)
1192 18 : pszNextLine[-1] = 0;
1193 : //CPLDebug("GFT", "Feature id = %s", pszLine);
1194 :
1195 18 : pszLine = pszNextLine;
1196 : }
1197 :
1198 6 : CPLHTTPDestroyResult(psResult);
1199 : }
1200 :
1201 6 : return OGRERR_NONE;
1202 : }
1203 :
1204 : /************************************************************************/
1205 : /* RollbackTransaction() */
1206 : /************************************************************************/
1207 :
1208 0 : OGRErr OGRGFTTableLayer::RollbackTransaction()
1209 : {
1210 0 : GetLayerDefn();
1211 :
1212 0 : if (!bInTransaction)
1213 : {
1214 0 : CPLError(CE_Failure, CPLE_AppDefined, "Should be in transaction");
1215 0 : return OGRERR_FAILURE;
1216 : }
1217 0 : bInTransaction = FALSE;
1218 0 : nFeaturesInTransaction = 0;
1219 0 : osTransaction.resize(0);
1220 0 : return OGRERR_NONE;
1221 : }
1222 :
1223 : /************************************************************************/
1224 : /* SetAttributeFilter() */
1225 : /************************************************************************/
1226 :
1227 2 : OGRErr OGRGFTTableLayer::SetAttributeFilter( const char *pszQuery )
1228 :
1229 : {
1230 2 : GetLayerDefn();
1231 :
1232 2 : if( pszQuery == NULL )
1233 0 : osQuery = "";
1234 : else
1235 : {
1236 2 : osQuery = PatchSQL(pszQuery);
1237 : }
1238 :
1239 2 : BuildWhere();
1240 :
1241 2 : ResetReading();
1242 :
1243 2 : return OGRERR_NONE;
1244 : }
1245 :
1246 :
1247 : /************************************************************************/
1248 : /* SetSpatialFilter() */
1249 : /************************************************************************/
1250 :
1251 2 : void OGRGFTTableLayer::SetSpatialFilter( OGRGeometry * poGeomIn )
1252 :
1253 : {
1254 2 : GetLayerDefn();
1255 :
1256 2 : if( InstallFilter( poGeomIn ) )
1257 : {
1258 2 : BuildWhere();
1259 :
1260 2 : ResetReading();
1261 : }
1262 2 : }
1263 :
1264 : /************************************************************************/
1265 : /* BuildWhere() */
1266 : /* */
1267 : /* Build the WHERE statement appropriate to the current set of */
1268 : /* criteria (spatial and attribute queries). */
1269 : /************************************************************************/
1270 :
1271 4 : void OGRGFTTableLayer::BuildWhere()
1272 :
1273 : {
1274 4 : osWHERE = "";
1275 :
1276 8 : if( m_poFilterGeom != NULL && iGeometryField >= 0)
1277 : {
1278 4 : OGREnvelope sEnvelope;
1279 :
1280 4 : m_poFilterGeom->getEnvelope( &sEnvelope );
1281 :
1282 4 : CPLString osQuotedGeomColumn(EscapeAndQuote(GetGeometryColumn()));
1283 :
1284 : osWHERE.Printf("WHERE ST_INTERSECTS(%s, RECTANGLE(LATLNG(%.12f, %.12f), LATLNG(%.12f, %.12f)))",
1285 : osQuotedGeomColumn.c_str(),
1286 : MAX(-90.,sEnvelope.MinY - 1e-11), MAX(-180., sEnvelope.MinX - 1e-11),
1287 4 : MIN(90.,sEnvelope.MaxY + 1e-11), MIN(180.,sEnvelope.MaxX + 1e-11));
1288 : }
1289 :
1290 4 : if( strlen(osQuery) > 0 )
1291 : {
1292 2 : if( strlen(osWHERE) == 0 )
1293 0 : osWHERE = "WHERE ";
1294 : else
1295 2 : osWHERE += " AND ";
1296 2 : osWHERE += osQuery;
1297 : }
1298 4 : }
1299 :
1300 : /************************************************************************/
1301 : /* SetGeometryType() */
1302 : /************************************************************************/
1303 :
1304 8 : void OGRGFTTableLayer::SetGeometryType(OGRwkbGeometryType eGType)
1305 : {
1306 8 : eGTypeForCreation = eGType;
1307 8 : }
|