1 /******************************************************************************
2 *
3 * Project: OpenGIS Simple Features Reference Implementation
4 * Purpose: Implements OGRGmtDataSource class.
5 * Author: Frank Warmerdam, warmerdam@pobox.com
6 *
7 ******************************************************************************
8 * Copyright (c) 2007, Frank Warmerdam <warmerdam@pobox.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 ****************************************************************************/
28
29 #include "cpl_conv.h"
30 #include "cpl_string.h"
31 #include "ogr_gmt.h"
32
33 CPL_CVSID("$Id: ogrgmtdatasource.cpp 8e5eeb35bf76390e3134a4ea7076dab7d478ea0e 2018-11-14 22:55:13 +0100 Even Rouault $")
34
35 /************************************************************************/
36 /* OGRGmtDataSource() */
37 /************************************************************************/
38
OGRGmtDataSource()39 OGRGmtDataSource::OGRGmtDataSource() :
40 papoLayers(nullptr),
41 nLayers(0),
42 pszName(nullptr),
43 bUpdate(false)
44 {}
45
46 /************************************************************************/
47 /* ~OGRGmtDataSource() */
48 /************************************************************************/
49
~OGRGmtDataSource()50 OGRGmtDataSource::~OGRGmtDataSource()
51
52 {
53 for( int i = 0; i < nLayers; i++ )
54 delete papoLayers[i];
55 CPLFree( papoLayers );
56 CPLFree( pszName );
57 }
58
59 /************************************************************************/
60 /* Open() */
61 /************************************************************************/
62
Open(const char * pszFilename,int bUpdateIn)63 int OGRGmtDataSource::Open( const char *pszFilename, int bUpdateIn )
64
65 {
66 bUpdate = CPL_TO_BOOL( bUpdateIn );
67
68 OGRGmtLayer *poLayer = new OGRGmtLayer( pszFilename, bUpdate );
69 if( !poLayer->bValidFile )
70 {
71 delete poLayer;
72 return FALSE;
73 }
74
75 papoLayers = static_cast<OGRGmtLayer **>( CPLRealloc( papoLayers,
76 (nLayers + 1) *sizeof(OGRGmtLayer*)) );
77 papoLayers[nLayers] = poLayer;
78 nLayers ++;
79
80 CPLFree (pszName);
81 pszName = CPLStrdup( pszFilename );
82
83 return TRUE;
84 }
85
86 /************************************************************************/
87 /* Create() */
88 /* */
89 /* Create a new datasource. This does not really do anything */
90 /* currently but save the name. */
91 /************************************************************************/
92
Create(const char * pszDSName,char **)93 int OGRGmtDataSource::Create( const char *pszDSName, char ** /* papszOptions */)
94
95 {
96 pszName = CPLStrdup( pszDSName );
97
98 return TRUE;
99 }
100
101 /************************************************************************/
102 /* ICreateLayer() */
103 /************************************************************************/
104
105 OGRLayer *
ICreateLayer(const char * pszLayerName,OGRSpatialReference * poSRS,OGRwkbGeometryType eType,CPL_UNUSED char ** papszOptions)106 OGRGmtDataSource::ICreateLayer( const char * pszLayerName,
107 OGRSpatialReference *poSRS,
108 OGRwkbGeometryType eType,
109 CPL_UNUSED char ** papszOptions )
110 {
111 if( nLayers != 0 )
112 return nullptr;
113
114 /* -------------------------------------------------------------------- */
115 /* Establish the geometry type. Note this logic */
116 /* -------------------------------------------------------------------- */
117 const char *pszGeom = nullptr;
118
119 switch( wkbFlatten(eType) )
120 {
121 case wkbPoint:
122 pszGeom = " @GPOINT";
123 break;
124 case wkbLineString:
125 pszGeom = " @GLINESTRING";
126 break;
127 case wkbPolygon:
128 pszGeom = " @GPOLYGON";
129 break;
130 case wkbMultiPoint:
131 pszGeom = " @GMULTIPOINT";
132 break;
133 case wkbMultiLineString:
134 pszGeom = " @GMULTILINESTRING";
135 break;
136 case wkbMultiPolygon:
137 pszGeom = " @GMULTIPOLYGON";
138 break;
139 default:
140 pszGeom = "";
141 break;
142 }
143
144 /* -------------------------------------------------------------------- */
145 /* If this is the first layer for this datasource, and if the */
146 /* datasource name ends in .gmt we will override the provided */
147 /* layer name with the name from the gmt. */
148 /* -------------------------------------------------------------------- */
149 CPLString osPath = CPLGetPath( pszName );
150 CPLString osFilename;
151
152 if( EQUAL(CPLGetExtension(pszName),"gmt") )
153 osFilename = pszName;
154 else
155 osFilename = CPLFormFilename( osPath, pszLayerName, "gmt" );
156
157 /* -------------------------------------------------------------------- */
158 /* Open the file. */
159 /* -------------------------------------------------------------------- */
160 VSILFILE *fp = VSIFOpenL( osFilename, "w" );
161 if( fp == nullptr )
162 {
163 CPLError( CE_Failure, CPLE_OpenFailed,
164 "open(%s) failed: %s",
165 osFilename.c_str(), VSIStrerror(errno) );
166 return nullptr;
167 }
168
169 /* -------------------------------------------------------------------- */
170 /* Write out header. */
171 /* -------------------------------------------------------------------- */
172 VSIFPrintfL( fp, "# @VGMT1.0%s\n", pszGeom );
173 VSIFPrintfL( fp, "# REGION_STUB "
174 " \n" );
175
176 /* -------------------------------------------------------------------- */
177 /* Write the projection, if possible. */
178 /* -------------------------------------------------------------------- */
179 if( poSRS != nullptr )
180 {
181 if( poSRS->GetAuthorityName(nullptr)
182 && EQUAL(poSRS->GetAuthorityName(nullptr),"EPSG") )
183 {
184 VSIFPrintfL( fp, "# @Je%s\n",
185 poSRS->GetAuthorityCode(nullptr) );
186 }
187
188 char *pszValue = nullptr;
189 if( poSRS->exportToProj4( &pszValue ) == OGRERR_NONE )
190 {
191 VSIFPrintfL( fp, "# @Jp\"%s\"\n", pszValue );
192 }
193 CPLFree( pszValue );
194 pszValue = nullptr;
195
196 if( poSRS->exportToWkt( &pszValue ) == OGRERR_NONE )
197 {
198 char *pszEscapedWkt = CPLEscapeString( pszValue, -1,
199 CPLES_BackslashQuotable );
200
201 VSIFPrintfL( fp, "# @Jw\"%s\"\n", pszEscapedWkt );
202 CPLFree( pszEscapedWkt );
203 }
204 CPLFree( pszValue );
205 }
206
207 /* -------------------------------------------------------------------- */
208 /* Finish header and close. */
209 /* -------------------------------------------------------------------- */
210 VSIFCloseL( fp );
211
212 /* -------------------------------------------------------------------- */
213 /* Return open layer handle. */
214 /* -------------------------------------------------------------------- */
215 if( Open( osFilename, TRUE ) )
216 return papoLayers[nLayers-1];
217
218 return nullptr;
219 }
220
221 /************************************************************************/
222 /* TestCapability() */
223 /************************************************************************/
224
TestCapability(const char * pszCap)225 int OGRGmtDataSource::TestCapability( const char * pszCap )
226
227 {
228 if( EQUAL(pszCap,ODsCCreateLayer) )
229 return TRUE;
230
231 return FALSE;
232 }
233
234 /************************************************************************/
235 /* GetLayer() */
236 /************************************************************************/
237
GetLayer(int iLayer)238 OGRLayer *OGRGmtDataSource::GetLayer( int iLayer )
239
240 {
241 if( iLayer < 0 || iLayer >= nLayers )
242 return nullptr;
243
244 return papoLayers[iLayer];
245 }
246