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 97 : OGRGFTTableLayer::OGRGFTTableLayer(OGRGFTDataSource* poDS,
39 : const char* pszTableName,
40 : const char* pszTableId,
41 97 : const char* pszGeomColumnName) : OGRGFTLayer(poDS)
42 :
43 : {
44 97 : osTableName = pszTableName;
45 97 : osTableId = pszTableId;
46 97 : osGeomColumnName = pszGeomColumnName ? pszGeomColumnName : "";
47 :
48 97 : bHasTriedCreateTable = FALSE;
49 97 : bInTransaction = FALSE;
50 97 : nFeaturesInTransaction = 0;
51 :
52 97 : bFirstTokenIsFID = TRUE;
53 97 : eGTypeForCreation = wkbUnknown;
54 97 : }
55 :
56 : /************************************************************************/
57 : /* ~OGRGFTTableLayer() */
58 : /************************************************************************/
59 :
60 97 : OGRGFTTableLayer::~OGRGFTTableLayer()
61 :
62 : {
63 97 : CreateTableIfNecessary();
64 97 : }
65 :
66 : /************************************************************************/
67 : /* ResetReading() */
68 : /************************************************************************/
69 :
70 4 : void OGRGFTTableLayer::ResetReading()
71 :
72 : {
73 4 : OGRGFTLayer::ResetReading();
74 4 : aosRows.resize(0);
75 4 : }
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 8 : int OGRGFTTableLayer::FetchDescribe()
106 : {
107 8 : poFeatureDefn = new OGRFeatureDefn( osTableName );
108 8 : poFeatureDefn->Reference();
109 :
110 8 : const CPLString& osAuth = poDS->GetAuth();
111 8 : std::vector<CPLString> aosHeaderAndFirstDataLine;
112 16 : if (osAuth.size())
113 : {
114 7 : CPLString osSQL("DESCRIBE ");
115 7 : osSQL += osTableId;
116 7 : CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
117 :
118 7 : if (psResult == NULL)
119 3 : return FALSE;
120 :
121 4 : char* pszLine = (char*) psResult->pabyData;
122 4 : 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 4 : pszLine = OGRGFTGotoNextLine(pszLine);
132 :
133 4 : std::vector<CPLString> aosLines;
134 4 : ParseCSVResponse(pszLine, aosLines);
135 15 : for(int i=0;i<(int)aosLines.size();i++)
136 : {
137 11 : char** papszTokens = OGRGFTCSVSplitLine(aosLines[i], ',');
138 11 : if (CSLCount(papszTokens) == 3)
139 : {
140 11 : aosColumnInternalName.push_back(papszTokens[0]);
141 :
142 : //CPLDebug("GFT", "%s %s %s", papszTokens[0], papszTokens[1], papszTokens[2]);
143 11 : OGRFieldType eType = OFTString;
144 11 : if (EQUAL(papszTokens[2], "number"))
145 3 : eType = OFTReal;
146 8 : else if (EQUAL(papszTokens[2], "datetime"))
147 0 : eType = OFTDateTime;
148 :
149 11 : if (EQUAL(papszTokens[2], "location") && osGeomColumnName.size() == 0)
150 : {
151 3 : if (iGeometryField < 0)
152 3 : iGeometryField = poFeatureDefn->GetFieldCount();
153 : else
154 : CPLDebug("GFT", "Multiple geometry fields detected. "
155 0 : "Only first encountered one is handled");
156 : }
157 :
158 11 : CPLString osLaunderedColName(LaunderColName(papszTokens[1]));
159 11 : OGRFieldDefn oFieldDefn(osLaunderedColName, eType);
160 11 : poFeatureDefn->AddFieldDefn(&oFieldDefn);
161 : }
162 11 : CSLDestroy(papszTokens);
163 : }
164 :
165 4 : 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 1 : CPLString osSQL("SELECT * FROM ");
172 1 : osSQL += osTableId;
173 1 : osSQL += " OFFSET 0 LIMIT 1";
174 :
175 1 : CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
176 :
177 1 : if (psResult == NULL)
178 0 : return FALSE;
179 :
180 1 : char* pszLine = (char*) psResult->pabyData;
181 1 : if (pszLine == NULL || psResult->pszErrBuf != NULL)
182 : {
183 0 : CPLHTTPDestroyResult(psResult);
184 0 : return FALSE;
185 : }
186 :
187 1 : ParseCSVResponse(pszLine, aosHeaderAndFirstDataLine);
188 1 : if (aosHeaderAndFirstDataLine.size() > 0)
189 : {
190 1 : char** papszTokens = OGRGFTCSVSplitLine(aosHeaderAndFirstDataLine[0], ',');
191 31 : for(int i=0;papszTokens && papszTokens[i];i++)
192 : {
193 30 : CPLString osLaunderedColName(LaunderColName(papszTokens[i]));
194 30 : OGRFieldDefn oFieldDefn(osLaunderedColName, OFTString);
195 30 : poFeatureDefn->AddFieldDefn(&oFieldDefn);
196 : }
197 1 : CSLDestroy(papszTokens);
198 : }
199 :
200 1 : CPLHTTPDestroyResult(psResult);
201 : }
202 :
203 5 : 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 46 : for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
214 : {
215 41 : const char* pszName = poFeatureDefn->GetFieldDefn(i)->GetNameRef();
216 42 : if (EQUAL(pszName, "latitude") || EQUAL(pszName, "lat") ||
217 : EQUAL(pszName, "latdec"))
218 1 : iLatitudeField = i;
219 40 : else if (EQUAL(pszName, "longitude") || EQUAL(pszName, "lon") ||
220 : EQUAL(pszName, "londec") || EQUAL(pszName, "long"))
221 1 : iLongitudeField = i;
222 : }
223 :
224 6 : if (iLatitudeField >= 0 && iLongitudeField >= 0)
225 : {
226 1 : if (iGeometryField < 0)
227 1 : iGeometryField = iLatitudeField;
228 1 : poFeatureDefn->GetFieldDefn(iLatitudeField)->SetType(OFTReal);
229 1 : poFeatureDefn->GetFieldDefn(iLongitudeField)->SetType(OFTReal);
230 1 : poFeatureDefn->SetGeomType( wkbPoint );
231 : }
232 4 : else if (iGeometryField < 0 && osGeomColumnName.size() == 0)
233 : {
234 1 : iLatitudeField = iLongitudeField = -1;
235 :
236 : /* In the unauthentified case, we try to parse the first record to */
237 : /* autodetect the geometry field */
238 1 : OGRwkbGeometryType eType = wkbUnknown;
239 1 : 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 1 : if (iGeometryField < 0)
292 1 : poFeatureDefn->SetGeomType( wkbNone );
293 : else
294 0 : poFeatureDefn->SetGeomType( eType );
295 : }
296 :
297 5 : return TRUE;
298 : }
299 :
300 : /************************************************************************/
301 : /* EscapeAndQuote() */
302 : /************************************************************************/
303 :
304 63 : static CPLString EscapeAndQuote(const char* pszStr)
305 : {
306 : char ch;
307 63 : CPLString osRes("'");
308 431 : while((ch = *pszStr) != 0)
309 : {
310 305 : if (ch == '\'')
311 3 : osRes += "\\\'";
312 : else
313 302 : osRes += ch;
314 305 : pszStr ++;
315 : }
316 63 : osRes += "'";
317 0 : return osRes;
318 : }
319 :
320 : /************************************************************************/
321 : /* FetchNextRows() */
322 : /************************************************************************/
323 :
324 4 : int OGRGFTTableLayer::FetchNextRows()
325 : {
326 4 : aosRows.resize(0);
327 :
328 4 : CPLString osSQL("SELECT ROWID");
329 15 : for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
330 : {
331 11 : osSQL += ",";
332 :
333 11 : if (i < (int)aosColumnInternalName.size())
334 9 : osSQL += aosColumnInternalName[i];
335 : else
336 : {
337 : const char* pszFieldName =
338 2 : poFeatureDefn->GetFieldDefn(i)->GetNameRef();
339 2 : osSQL += EscapeAndQuote(pszFieldName);
340 : }
341 : }
342 4 : if (bHiddenGeometryField)
343 : {
344 1 : osSQL += ",";
345 1 : osSQL += EscapeAndQuote(GetGeometryColumn());
346 : }
347 4 : osSQL += " FROM ";
348 4 : osSQL += osTableId;
349 4 : if (osWHERE.size())
350 : {
351 0 : osSQL += " ";
352 0 : osSQL += osWHERE;
353 : }
354 :
355 4 : int nFeaturesToFetch = GetFeaturesToFetch();
356 4 : if (nFeaturesToFetch > 0)
357 4 : osSQL += CPLSPrintf(" OFFSET %d LIMIT %d", nOffset, nFeaturesToFetch);
358 :
359 4 : CPLPushErrorHandler(CPLQuietErrorHandler);
360 4 : CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
361 4 : CPLPopErrorHandler();
362 :
363 4 : if (psResult == NULL)
364 : {
365 0 : bEOF = TRUE;
366 0 : return FALSE;
367 : }
368 :
369 4 : char* pszLine = (char*) psResult->pabyData;
370 4 : 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 4 : ParseCSVResponse(pszLine, aosRows);
379 :
380 4 : if (aosRows.size() > 0)
381 4 : aosRows.erase(aosRows.begin());
382 :
383 4 : if (nFeaturesToFetch > 0)
384 4 : bEOF = (int)aosRows.size() < GetFeaturesToFetch();
385 : else
386 0 : bEOF = TRUE;
387 :
388 4 : CPLHTTPDestroyResult(psResult);
389 :
390 4 : return TRUE;
391 : }
392 : /************************************************************************/
393 : /* GetFeature() */
394 : /************************************************************************/
395 :
396 1 : OGRFeature * OGRGFTTableLayer::GetFeature( long nFID )
397 : {
398 1 : GetLayerDefn();
399 :
400 1 : CPLString osSQL("SELECT ROWID");
401 3 : for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
402 : {
403 2 : osSQL += ",";
404 :
405 : const char* pszFieldName =
406 2 : poFeatureDefn->GetFieldDefn(i)->GetNameRef();
407 2 : osSQL += EscapeAndQuote(pszFieldName);
408 : }
409 1 : if (bHiddenGeometryField)
410 : {
411 1 : osSQL += ",";
412 1 : osSQL += EscapeAndQuote(GetGeometryColumn());
413 : }
414 1 : osSQL += " FROM ";
415 1 : osSQL += osTableId;
416 1 : osSQL += CPLSPrintf(" WHERE ROWID='%ld'", nFID);
417 :
418 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
419 1 : CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
420 1 : CPLPopErrorHandler();
421 :
422 1 : if (psResult == NULL)
423 0 : return NULL;
424 :
425 1 : char* pszLine = (char*) psResult->pabyData;
426 1 : if (pszLine == NULL || psResult->pszErrBuf != NULL)
427 : {
428 0 : CPLHTTPDestroyResult(psResult);
429 0 : return NULL;
430 : }
431 :
432 : /* skip header line */
433 1 : pszLine = OGRGFTGotoNextLine(pszLine);
434 1 : if (pszLine == NULL || pszLine[0] == 0)
435 : {
436 0 : CPLHTTPDestroyResult(psResult);
437 0 : return NULL;
438 : }
439 :
440 1 : int nLen = (int)strlen(pszLine);
441 1 : if (nLen > 0 && pszLine[nLen-1] == '\n')
442 1 : pszLine[nLen-1] = '\0';
443 :
444 1 : OGRFeature* poFeature = BuildFeatureFromSQL(pszLine);
445 :
446 1 : CPLHTTPDestroyResult(psResult);
447 :
448 1 : return poFeature;
449 : }
450 :
451 : /************************************************************************/
452 : /* GetLayerDefn() */
453 : /************************************************************************/
454 :
455 61 : OGRFeatureDefn * OGRGFTTableLayer::GetLayerDefn()
456 : {
457 61 : if (poFeatureDefn == NULL)
458 : {
459 11 : if (osTableId.size() == 0)
460 3 : return NULL;
461 8 : FetchDescribe();
462 : }
463 :
464 58 : return poFeatureDefn;
465 : }
466 :
467 : /************************************************************************/
468 : /* GetFeatureCount() */
469 : /************************************************************************/
470 :
471 5 : int OGRGFTTableLayer::GetFeatureCount(int bForce)
472 : {
473 5 : GetLayerDefn();
474 :
475 5 : CPLString osSQL("SELECT COUNT() FROM ");
476 5 : osSQL += osTableId;
477 5 : if (osWHERE.size())
478 : {
479 1 : osSQL += " ";
480 1 : osSQL += osWHERE;
481 : }
482 :
483 5 : CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
484 :
485 5 : if (psResult == NULL)
486 0 : return 0;
487 :
488 5 : char* pszLine = (char*) psResult->pabyData;
489 5 : 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 5 : pszLine = OGRGFTGotoNextLine(pszLine);
499 5 : if (pszLine == NULL)
500 : {
501 0 : CPLError(CE_Failure, CPLE_AppDefined, "GetFeatureCount() failed");
502 0 : CPLHTTPDestroyResult(psResult);
503 0 : return 0;
504 : }
505 :
506 5 : char* pszNextLine = OGRGFTGotoNextLine(pszLine);
507 5 : if (pszNextLine)
508 5 : pszNextLine[-1] = 0;
509 :
510 5 : int nFeatureCount = atoi(pszLine);
511 :
512 5 : CPLHTTPDestroyResult(psResult);
513 :
514 5 : return nFeatureCount;
515 : }
516 :
517 : /************************************************************************/
518 : /* CreateField() */
519 : /************************************************************************/
520 :
521 9 : OGRErr OGRGFTTableLayer::CreateField( OGRFieldDefn *poField,
522 : int bApproxOK )
523 : {
524 :
525 9 : 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 9 : 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 9 : 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 9 : if (poFeatureDefn == NULL)
547 : {
548 4 : poFeatureDefn = new OGRFeatureDefn( osTableName );
549 4 : poFeatureDefn->Reference();
550 : }
551 :
552 9 : poFeatureDefn->AddFieldDefn(poField);
553 :
554 9 : return OGRERR_NONE;
555 : }
556 :
557 : /************************************************************************/
558 : /* CreateTableIfNecessary() */
559 : /************************************************************************/
560 :
561 101 : void OGRGFTTableLayer::CreateTableIfNecessary()
562 : {
563 101 : if (bHasTriedCreateTable || osTableId.size() != 0)
564 97 : return;
565 :
566 4 : bHasTriedCreateTable = TRUE;
567 :
568 4 : CPLString osSQL("CREATE TABLE '");
569 4 : osSQL += osTableName;
570 4 : osSQL += "' (";
571 :
572 : int i;
573 :
574 4 : 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 13 : for(i=0;i<poFeatureDefn->GetFieldCount();i++)
584 : {
585 9 : const char* pszName = poFeatureDefn->GetFieldDefn(i)->GetNameRef();
586 9 : if (EQUAL(pszName, "latitude") || EQUAL(pszName, "lat") ||
587 : EQUAL(pszName, "latdec"))
588 0 : iLatitudeField = i;
589 9 : else if (EQUAL(pszName, "longitude") || EQUAL(pszName, "lon") ||
590 : EQUAL(pszName, "londec") || EQUAL(pszName, "long"))
591 0 : iLongitudeField = i;
592 : }
593 :
594 4 : 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 7 : else if (iGeometryField < 0 && eGTypeForCreation != wkbNone)
603 : {
604 3 : iGeometryField = poFeatureDefn->GetFieldIndex(GetDefaultGeometryColumnName());
605 3 : poFeatureDefn->SetGeomType( eGTypeForCreation );
606 : }
607 : /* The user doesn't want geometries, so don't create one */
608 1 : else if (eGTypeForCreation == wkbNone)
609 : {
610 1 : poFeatureDefn->SetGeomType( eGTypeForCreation );
611 : }
612 :
613 13 : for(i=0;i<poFeatureDefn->GetFieldCount();i++)
614 : {
615 9 : if (i > 0)
616 5 : osSQL += ", ";
617 :
618 : const char* pszFieldName =
619 9 : poFeatureDefn->GetFieldDefn(i)->GetNameRef();
620 9 : osSQL += EscapeAndQuote(pszFieldName);
621 9 : osSQL += ": ";
622 :
623 9 : if (iGeometryField == i)
624 : {
625 1 : osSQL += "LOCATION";
626 : }
627 : else
628 : {
629 8 : switch(poFeatureDefn->GetFieldDefn(i)->GetType())
630 : {
631 : case OFTInteger:
632 : case OFTReal:
633 3 : osSQL += "NUMBER";
634 3 : break;
635 : default:
636 5 : 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 4 : if (iGeometryField < 0 && eGTypeForCreation != wkbNone)
648 : {
649 2 : if (i > 0)
650 2 : osSQL += ", ";
651 2 : osSQL += EscapeAndQuote(GetDefaultGeometryColumnName());
652 2 : osSQL += ": LOCATION";
653 :
654 2 : iGeometryField = poFeatureDefn->GetFieldCount();
655 2 : bHiddenGeometryField = TRUE;
656 : }
657 4 : osSQL += ")";
658 :
659 4 : CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
660 4 : if (psResult == NULL)
661 : {
662 0 : CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed");
663 : return;
664 : }
665 :
666 4 : char* pszLine = (char*) psResult->pabyData;
667 4 : 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 4 : pszLine = OGRGFTGotoNextLine(pszLine);
677 4 : if (pszLine == NULL)
678 : {
679 0 : CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed");
680 0 : CPLHTTPDestroyResult(psResult);
681 : return;
682 : }
683 :
684 4 : char* pszNextLine = OGRGFTGotoNextLine(pszLine);
685 4 : if (pszNextLine)
686 4 : pszNextLine[-1] = 0;
687 :
688 4 : osTableId = pszLine;
689 4 : CPLDebug("GFT", "Table %s --> id = %s", osTableName.c_str(), osTableId.c_str());
690 :
691 4 : CPLHTTPDestroyResult(psResult);
692 : }
693 :
694 : /************************************************************************/
695 : /* CreateFeature() */
696 : /************************************************************************/
697 :
698 10 : OGRErr OGRGFTTableLayer::CreateFeature( OGRFeature *poFeature )
699 :
700 : {
701 10 : 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 10 : if (osTableId.size() == 0)
709 : {
710 1 : CreateTableIfNecessary();
711 1 : 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 10 : 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 10 : CPLString osCommand;
727 :
728 10 : osCommand += "INSERT INTO ";
729 10 : osCommand += osTableId;
730 10 : osCommand += " (";
731 :
732 : int iField;
733 10 : int nFieldCount = poFeatureDefn->GetFieldCount();
734 33 : for(iField = 0; iField < nFieldCount; iField++)
735 : {
736 23 : if (iField > 0)
737 13 : osCommand += ", ";
738 :
739 : const char* pszFieldName =
740 23 : poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
741 23 : osCommand += EscapeAndQuote(pszFieldName);
742 : }
743 10 : if (bHiddenGeometryField)
744 : {
745 4 : if (iField > 0)
746 4 : osCommand += ", ";
747 4 : osCommand += EscapeAndQuote(GetGeometryColumn());
748 : }
749 10 : osCommand += ") VALUES (";
750 37 : for(iField = 0; iField < nFieldCount + bHiddenGeometryField; iField++)
751 : {
752 27 : if (iField > 0)
753 17 : osCommand += ", ";
754 :
755 27 : 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 27 : if (iGeometryField != iLatitudeField && iField == iGeometryField &&
759 : (iField == nFieldCount || poGeom != NULL || !poFeature->IsFieldSet( iField )))
760 : {
761 7 : if (poGeom == NULL)
762 0 : osCommand += "''";
763 : else
764 : {
765 : char* pszKML;
766 7 : 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 7 : pszKML = poGeom->exportToKML();
777 : }
778 7 : osCommand += "'";
779 7 : osCommand += pszKML;
780 7 : osCommand += "'";
781 7 : CPLFree(pszKML);
782 : }
783 7 : continue;
784 : }
785 :
786 20 : if( !poFeature->IsFieldSet( iField ) )
787 : {
788 0 : osCommand += "''";
789 : }
790 : else
791 : {
792 20 : OGRFieldType eType = poFeatureDefn->GetFieldDefn(iField)->GetType();
793 33 : if (eType != OFTInteger && eType != OFTReal)
794 : {
795 13 : CPLString osTmp;
796 13 : const char* pszVal = poFeature->GetFieldAsString(iField);
797 :
798 13 : 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 13 : osCommand += EscapeAndQuote(pszVal);
820 : }
821 : else
822 7 : osCommand += poFeature->GetFieldAsString(iField);
823 : }
824 : }
825 :
826 10 : osCommand += ")";
827 :
828 : //CPLDebug("GFT", "%s", osCommand.c_str());
829 :
830 10 : if (bInTransaction)
831 : {
832 9 : nFeaturesInTransaction ++;
833 9 : if (nFeaturesInTransaction > 1)
834 6 : osTransaction += "; ";
835 9 : osTransaction += osCommand;
836 9 : return OGRERR_NONE;
837 : }
838 :
839 1 : CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
840 1 : if (psResult == NULL)
841 : {
842 0 : CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
843 0 : return OGRERR_FAILURE;
844 : }
845 :
846 1 : char* pszLine = (char*) psResult->pabyData;
847 1 : 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 1 : pszLine = OGRGFTGotoNextLine(pszLine);
857 1 : 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 1 : char* pszNextLine = OGRGFTGotoNextLine(pszLine);
865 1 : if (pszNextLine)
866 1 : pszNextLine[-1] = 0;
867 :
868 1 : CPLDebug("GFT", "Feature id = %s", pszLine);
869 :
870 1 : int nFID = atoi(pszLine);
871 1 : if (strcmp(CPLSPrintf("%d", nFID), pszLine) == 0)
872 1 : poFeature->SetFID(nFID);
873 :
874 1 : CPLHTTPDestroyResult(psResult);
875 :
876 1 : return OGRERR_NONE;
877 : }
878 :
879 : /************************************************************************/
880 : /* SetFeature() */
881 : /************************************************************************/
882 :
883 1 : OGRErr OGRGFTTableLayer::SetFeature( OGRFeature *poFeature )
884 : {
885 1 : GetLayerDefn();
886 :
887 1 : 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 1 : 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 1 : 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 1 : 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 1 : CPLString osCommand;
916 :
917 1 : osCommand += "UPDATE ";
918 1 : osCommand += osTableId;
919 1 : osCommand += " SET ";
920 :
921 : int iField;
922 1 : int nFieldCount = poFeatureDefn->GetFieldCount();
923 4 : for(iField = 0; iField < nFieldCount + bHiddenGeometryField; iField++)
924 : {
925 3 : if (iField > 0)
926 2 : osCommand += ", ";
927 :
928 3 : if (iField == nFieldCount)
929 : {
930 1 : osCommand += EscapeAndQuote(GetGeometryColumn());
931 : }
932 : else
933 : {
934 : const char* pszFieldName =
935 2 : poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
936 2 : osCommand += EscapeAndQuote(pszFieldName);
937 : }
938 :
939 3 : osCommand += " = ";
940 :
941 3 : OGRGeometry* poGeom = poFeature->GetGeometryRef();
942 3 : if (iGeometryField != iLatitudeField && iField == iGeometryField &&
943 : (iField == nFieldCount || poGeom != NULL || !poFeature->IsFieldSet( iField )))
944 : {
945 1 : if (poGeom == NULL)
946 0 : osCommand += "''";
947 : else
948 : {
949 : char* pszKML;
950 1 : 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 1 : pszKML = poGeom->exportToKML();
961 : }
962 1 : osCommand += "'";
963 1 : osCommand += pszKML;
964 1 : osCommand += "'";
965 1 : CPLFree(pszKML);
966 : }
967 1 : continue;
968 : }
969 :
970 2 : if( !poFeature->IsFieldSet( iField ) )
971 : {
972 0 : osCommand += "''";
973 : }
974 : else
975 : {
976 2 : OGRFieldType eType = poFeatureDefn->GetFieldDefn(iField)->GetType();
977 3 : if (eType != OFTInteger && eType != OFTReal)
978 : {
979 1 : CPLString osTmp;
980 1 : const char* pszVal = poFeature->GetFieldAsString(iField);
981 :
982 1 : 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 1 : osCommand += EscapeAndQuote(pszVal);
1004 : }
1005 : else
1006 1 : osCommand += poFeature->GetFieldAsString(iField);
1007 : }
1008 : }
1009 :
1010 1 : osCommand += " WHERE ROWID = '";
1011 1 : osCommand += CPLSPrintf("%ld", poFeature->GetFID());
1012 1 : osCommand += "'";
1013 :
1014 : //CPLDebug("GFT", "%s", osCommand.c_str());
1015 :
1016 1 : CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
1017 1 : if (psResult == NULL)
1018 : {
1019 0 : CPLError(CE_Failure, CPLE_AppDefined, "Feature update failed");
1020 0 : return OGRERR_FAILURE;
1021 : }
1022 :
1023 1 : char* pszLine = (char*) psResult->pabyData;
1024 1 : 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 1 : CPLHTTPDestroyResult(psResult);
1034 :
1035 1 : return OGRERR_NONE;
1036 : }
1037 :
1038 : /************************************************************************/
1039 : /* DeleteFeature() */
1040 : /************************************************************************/
1041 :
1042 1 : OGRErr OGRGFTTableLayer::DeleteFeature( long nFID )
1043 : {
1044 1 : GetLayerDefn();
1045 :
1046 1 : 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 1 : 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 1 : 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 1 : CPLString osCommand;
1068 :
1069 1 : osCommand += "DELETE FROM ";
1070 1 : osCommand += osTableId;
1071 1 : osCommand += " WHERE ROWID = '";
1072 1 : osCommand += CPLSPrintf("%ld", nFID);
1073 1 : osCommand += "'";
1074 :
1075 : //CPLDebug("GFT", "%s", osCommand.c_str());
1076 :
1077 1 : CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
1078 1 : if (psResult == NULL)
1079 : {
1080 0 : CPLError(CE_Failure, CPLE_AppDefined, "Feature deletion failed");
1081 0 : return OGRERR_FAILURE;
1082 : }
1083 :
1084 1 : char* pszLine = (char*) psResult->pabyData;
1085 1 : 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 1 : CPLHTTPDestroyResult(psResult);
1095 :
1096 1 : return OGRERR_NONE;
1097 : }
1098 :
1099 : /************************************************************************/
1100 : /* StartTransaction() */
1101 : /************************************************************************/
1102 :
1103 3 : OGRErr OGRGFTTableLayer::StartTransaction()
1104 : {
1105 3 : GetLayerDefn();
1106 :
1107 3 : if (bInTransaction)
1108 : {
1109 0 : CPLError(CE_Failure, CPLE_AppDefined, "Already in transaction");
1110 0 : return OGRERR_FAILURE;
1111 : }
1112 :
1113 3 : 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 3 : if (osTableId.size() == 0)
1121 : {
1122 3 : CreateTableIfNecessary();
1123 3 : 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 3 : 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 3 : bInTransaction = TRUE;
1139 3 : osTransaction.resize(0);
1140 3 : nFeaturesInTransaction = 0;
1141 :
1142 3 : return OGRERR_NONE;
1143 : }
1144 :
1145 : /************************************************************************/
1146 : /* CommitTransaction() */
1147 : /************************************************************************/
1148 :
1149 3 : OGRErr OGRGFTTableLayer::CommitTransaction()
1150 : {
1151 3 : GetLayerDefn();
1152 :
1153 3 : if (!bInTransaction)
1154 : {
1155 0 : CPLError(CE_Failure, CPLE_AppDefined, "Should be in transaction");
1156 0 : return OGRERR_FAILURE;
1157 : }
1158 :
1159 3 : bInTransaction = FALSE;
1160 :
1161 3 : if (nFeaturesInTransaction > 0)
1162 : {
1163 3 : if (nFeaturesInTransaction > 1)
1164 3 : osTransaction += ";";
1165 :
1166 3 : CPLHTTPResult * psResult = poDS->RunSQL(osTransaction);
1167 3 : osTransaction.resize(0);
1168 3 : nFeaturesInTransaction = 0;
1169 :
1170 3 : if (psResult == NULL)
1171 : {
1172 0 : CPLError(CE_Failure, CPLE_AppDefined, "CommitTransaction failed");
1173 0 : return OGRERR_FAILURE;
1174 : }
1175 :
1176 3 : char* pszLine = (char*) psResult->pabyData;
1177 3 : 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 3 : pszLine = OGRGFTGotoNextLine(pszLine);
1188 15 : while(pszLine && *pszLine != 0)
1189 : {
1190 9 : char* pszNextLine = OGRGFTGotoNextLine(pszLine);
1191 9 : if (pszNextLine)
1192 9 : pszNextLine[-1] = 0;
1193 : //CPLDebug("GFT", "Feature id = %s", pszLine);
1194 :
1195 9 : pszLine = pszNextLine;
1196 : }
1197 :
1198 3 : CPLHTTPDestroyResult(psResult);
1199 : }
1200 :
1201 3 : 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 1 : OGRErr OGRGFTTableLayer::SetAttributeFilter( const char *pszQuery )
1228 :
1229 : {
1230 1 : GetLayerDefn();
1231 :
1232 1 : if( pszQuery == NULL )
1233 0 : osQuery = "";
1234 : else
1235 : {
1236 1 : osQuery = PatchSQL(pszQuery);
1237 : }
1238 :
1239 1 : BuildWhere();
1240 :
1241 1 : ResetReading();
1242 :
1243 1 : return OGRERR_NONE;
1244 : }
1245 :
1246 :
1247 : /************************************************************************/
1248 : /* SetSpatialFilter() */
1249 : /************************************************************************/
1250 :
1251 1 : void OGRGFTTableLayer::SetSpatialFilter( OGRGeometry * poGeomIn )
1252 :
1253 : {
1254 1 : GetLayerDefn();
1255 :
1256 1 : if( InstallFilter( poGeomIn ) )
1257 : {
1258 1 : BuildWhere();
1259 :
1260 1 : ResetReading();
1261 : }
1262 1 : }
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 2 : void OGRGFTTableLayer::BuildWhere()
1272 :
1273 : {
1274 2 : osWHERE = "";
1275 :
1276 4 : if( m_poFilterGeom != NULL && iGeometryField >= 0)
1277 : {
1278 2 : OGREnvelope sEnvelope;
1279 :
1280 2 : m_poFilterGeom->getEnvelope( &sEnvelope );
1281 :
1282 2 : 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 2 : MIN(90.,sEnvelope.MaxY + 1e-11), MIN(180.,sEnvelope.MaxX + 1e-11));
1288 : }
1289 :
1290 2 : if( strlen(osQuery) > 0 )
1291 : {
1292 1 : if( strlen(osWHERE) == 0 )
1293 0 : osWHERE = "WHERE ";
1294 : else
1295 1 : osWHERE += " AND ";
1296 1 : osWHERE += osQuery;
1297 : }
1298 2 : }
1299 :
1300 : /************************************************************************/
1301 : /* SetGeometryType() */
1302 : /************************************************************************/
1303 :
1304 4 : void OGRGFTTableLayer::SetGeometryType(OGRwkbGeometryType eGType)
1305 : {
1306 4 : eGTypeForCreation = eGType;
1307 4 : }
|