1 /******************************************************************************
2 * $Id
3 *
4 * Project: CartoDB Translator
5 * Purpose: Implements OGRCARTODBResultLayer class.
6 * Author: Even Rouault, <even dot rouault at mines dash paris dot org>
7 *
8 ******************************************************************************
9 * Copyright (c) 2013, Even Rouault <even dot rouault at mines-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_cartodb.h"
31
32 CPL_CVSID("$Id");
33
34 /************************************************************************/
35 /* OGRCARTODBResultLayer() */
36 /************************************************************************/
37
OGRCARTODBResultLayer(OGRCARTODBDataSource * poDS,const char * pszRawQueryIn)38 OGRCARTODBResultLayer::OGRCARTODBResultLayer( OGRCARTODBDataSource* poDS,
39 const char * pszRawQueryIn ) :
40 OGRCARTODBLayer(poDS)
41 {
42 osBaseSQL = pszRawQueryIn;
43 SetDescription( "result" );
44 poFirstFeature = NULL;
45 }
46
47 /************************************************************************/
48 /* ~OGRCARTODBResultLayer() */
49 /************************************************************************/
50
~OGRCARTODBResultLayer()51 OGRCARTODBResultLayer::~OGRCARTODBResultLayer()
52
53 {
54 delete poFirstFeature;
55 }
56
57 /************************************************************************/
58 /* GetLayerDefnInternal() */
59 /************************************************************************/
60
GetLayerDefnInternal(json_object * poObjIn)61 OGRFeatureDefn * OGRCARTODBResultLayer::GetLayerDefnInternal(json_object* poObjIn)
62 {
63 if( poFeatureDefn != NULL )
64 return poFeatureDefn;
65
66 EstablishLayerDefn("result", poObjIn);
67
68 return poFeatureDefn;
69 }
70
71 /************************************************************************/
72 /* GetNextRawFeature() */
73 /************************************************************************/
74
GetNextRawFeature()75 OGRFeature *OGRCARTODBResultLayer::GetNextRawFeature()
76 {
77 if( poFirstFeature )
78 {
79 OGRFeature* poRet = poFirstFeature;
80 poFirstFeature = NULL;
81 return poRet;
82 }
83 else
84 return OGRCARTODBLayer::GetNextRawFeature();
85 }
86
87 /************************************************************************/
88 /* IsOK() */
89 /************************************************************************/
90
IsOK()91 int OGRCARTODBResultLayer::IsOK()
92 {
93 CPLErrorReset();
94 poFirstFeature = GetNextFeature();
95 return CPLGetLastErrorType() == 0;
96 }
97
98 /************************************************************************/
99 /* GetSRS_SQL() */
100 /************************************************************************/
101
GetSRS_SQL(const char * pszGeomCol)102 CPLString OGRCARTODBResultLayer::GetSRS_SQL(const char* pszGeomCol)
103 {
104 CPLString osSQL;
105 CPLString osLimitedSQL;
106
107 size_t nPos = osBaseSQL.ifind(" LIMIT ");
108 if( nPos != std::string::npos )
109 {
110 osLimitedSQL = osBaseSQL;
111 size_t nSize = osLimitedSQL.size();
112 for(size_t i = nPos + strlen(" LIMIT "); i < nSize; i++)
113 {
114 if( osLimitedSQL[i] == ' ' && osLimitedSQL[i-1] == '0')
115 {
116 osLimitedSQL[i-1] = '1';
117 break;
118 }
119 osLimitedSQL[i] = '0';
120 }
121 }
122 else
123 osLimitedSQL.Printf("%s LIMIT 1", osBaseSQL.c_str());
124
125 /* Assuming that the SRID of the first non-NULL geometry applies */
126 /* to geometries of all rows. */
127 osSQL.Printf("SELECT srid, srtext FROM spatial_ref_sys WHERE srid IN "
128 "(SELECT ST_SRID(%s) FROM (%s) ogr_subselect)",
129 OGRCARTODBEscapeIdentifier(pszGeomCol).c_str(),
130 osLimitedSQL.c_str());
131
132 return osSQL;
133 }
134