1 : /******************************************************************************
2 : * $Id: ogrgmtdatasource.cpp 10645 2007-01-18 02:22:39Z warmerdam $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Implements OGRGmtDataSource class.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2007, Frank Warmerdam <warmerdam@pobox.com>
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_gmt.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 :
34 : CPL_CVSID("$Id: ogrgmtdatasource.cpp 10645 2007-01-18 02:22:39Z warmerdam $");
35 :
36 : /************************************************************************/
37 : /* OGRGmtDataSource() */
38 : /************************************************************************/
39 :
40 2 : OGRGmtDataSource::OGRGmtDataSource()
41 :
42 : {
43 2 : pszName = NULL;
44 2 : papoLayers = NULL;
45 2 : nLayers = 0;
46 :
47 2 : bUpdate = FALSE;
48 2 : }
49 :
50 : /************************************************************************/
51 : /* ~OGRGmtDataSource() */
52 : /************************************************************************/
53 :
54 4 : OGRGmtDataSource::~OGRGmtDataSource()
55 :
56 : {
57 2 : CPLFree( pszName );
58 :
59 4 : for( int i = 0; i < nLayers; i++ )
60 2 : delete papoLayers[i];
61 :
62 2 : CPLFree( papoLayers );
63 4 : }
64 :
65 : /************************************************************************/
66 : /* Open() */
67 : /************************************************************************/
68 :
69 2 : int OGRGmtDataSource::Open( const char *pszFilename, int bUpdate )
70 :
71 : {
72 2 : this->bUpdate = bUpdate;
73 :
74 2 : OGRGmtLayer *poLayer = new OGRGmtLayer( pszFilename, bUpdate );
75 2 : if( !poLayer->bValidFile )
76 : {
77 0 : delete poLayer;
78 0 : return FALSE;
79 : }
80 :
81 2 : nLayers = 1;
82 2 : papoLayers = (OGRGmtLayer **) CPLMalloc(sizeof(void*));
83 2 : papoLayers[0] = poLayer;
84 :
85 2 : CPLFree (pszName);
86 2 : pszName = CPLStrdup( pszFilename );
87 :
88 2 : return TRUE;
89 : }
90 :
91 : /************************************************************************/
92 : /* Create() */
93 : /* */
94 : /* Create a new datasource. This doesn't really do anything */
95 : /* currently but save the name. */
96 : /************************************************************************/
97 :
98 1 : int OGRGmtDataSource::Create( const char *pszDSName, char **papszOptions )
99 :
100 : {
101 : (void) papszOptions;
102 :
103 1 : pszName = CPLStrdup( pszDSName );
104 :
105 1 : return TRUE;
106 : }
107 :
108 : /************************************************************************/
109 : /* CreateLayer() */
110 : /************************************************************************/
111 :
112 : OGRLayer *
113 1 : OGRGmtDataSource::CreateLayer( const char * pszLayerName,
114 : OGRSpatialReference *poSRS,
115 : OGRwkbGeometryType eType,
116 : char ** papszOptions )
117 :
118 : {
119 : /* -------------------------------------------------------------------- */
120 : /* Establish the geometry type. Note this logic */
121 : /* -------------------------------------------------------------------- */
122 : const char *pszGeom;
123 :
124 1 : switch( wkbFlatten(eType) )
125 : {
126 : case wkbPoint:
127 0 : pszGeom = " @GPOINT";
128 0 : break;
129 : case wkbLineString:
130 0 : pszGeom = " @GLINESTRING";
131 0 : break;
132 : case wkbPolygon:
133 0 : pszGeom = " @GPOLYGON";
134 0 : break;
135 : case wkbMultiPoint:
136 0 : pszGeom = " @GMULTIPOINT";
137 0 : break;
138 : case wkbMultiLineString:
139 0 : pszGeom = " @GMULTILINESTRING";
140 0 : break;
141 : case wkbMultiPolygon:
142 0 : pszGeom = " @GMULTIPOLYGON";
143 0 : break;
144 : default:
145 1 : pszGeom = "";
146 : break;
147 : }
148 :
149 : /* -------------------------------------------------------------------- */
150 : /* If this is the first layer for this datasource, and if the */
151 : /* datasource name ends in .gmt we will override the provided */
152 : /* layer name with the name from the gmt. */
153 : /* -------------------------------------------------------------------- */
154 1 : CPLString osPath = CPLGetPath( pszName );
155 1 : CPLString osFilename;
156 :
157 1 : if( EQUAL(CPLGetExtension(pszName),"gmt") )
158 1 : osFilename = pszName;
159 : else
160 0 : osFilename = CPLFormFilename( osPath, pszLayerName, "gmt" );
161 :
162 : /* -------------------------------------------------------------------- */
163 : /* Open the file. */
164 : /* -------------------------------------------------------------------- */
165 1 : FILE *fp = VSIFOpenL( osFilename, "w" );
166 1 : if( fp == NULL )
167 : {
168 : CPLError( CE_Failure, CPLE_OpenFailed,
169 : "open(%s) failed: %s",
170 0 : osFilename.c_str(), VSIStrerror(errno) );
171 0 : return NULL;
172 : }
173 :
174 : /* -------------------------------------------------------------------- */
175 : /* Write out header. */
176 : /* -------------------------------------------------------------------- */
177 1 : VSIFPrintfL( fp, "# @VGMT1.0%s\n", pszGeom );
178 1 : VSIFPrintfL( fp, "# REGION_STUB \n" );
179 :
180 : /* -------------------------------------------------------------------- */
181 : /* Write the projection, if possible. */
182 : /* -------------------------------------------------------------------- */
183 1 : if( poSRS != NULL )
184 : {
185 0 : char *pszValue = NULL;
186 :
187 0 : if( poSRS->IsProjected()
188 : && poSRS->GetAuthorityName("PROJCS")
189 : && EQUAL(poSRS->GetAuthorityName("PROJCS"),"EPSG") )
190 : {
191 : VSIFPrintfL( fp, "# @Je%s\n",
192 0 : poSRS->GetAuthorityCode("PROJCS") );
193 : }
194 0 : else if( poSRS->IsGeographic()
195 : && poSRS->GetAuthorityName("GEOGCS")
196 : && EQUAL(poSRS->GetAuthorityName("GEOGCS"),"EPSG") )
197 : {
198 : VSIFPrintfL( fp, "# @Je%s\n",
199 0 : poSRS->GetAuthorityCode("GEOGCS") );
200 : }
201 :
202 0 : if( poSRS->exportToProj4( &pszValue ) == OGRERR_NONE )
203 : {
204 0 : VSIFPrintfL( fp, "# @Jp\"%s\"\n", pszValue );
205 0 : CPLFree( pszValue );
206 0 : pszValue = NULL;
207 : }
208 :
209 0 : if( poSRS->exportToWkt( &pszValue ) == OGRERR_NONE )
210 : {
211 : char *pszEscapedWkt = CPLEscapeString( pszValue, -1,
212 0 : CPLES_BackslashQuotable );
213 :
214 0 : VSIFPrintfL( fp, "# @Jw\"%s\"\n", pszEscapedWkt );
215 0 : CPLFree( pszValue );
216 0 : CPLFree( pszEscapedWkt );
217 0 : pszValue = NULL;
218 : }
219 : }
220 :
221 : /* -------------------------------------------------------------------- */
222 : /* Finish header and close. */
223 : /* -------------------------------------------------------------------- */
224 1 : VSIFCloseL( fp );
225 :
226 : /* -------------------------------------------------------------------- */
227 : /* Return open layer handle. */
228 : /* -------------------------------------------------------------------- */
229 1 : if( Open( osFilename, TRUE ) )
230 1 : return papoLayers[nLayers-1];
231 : else
232 0 : return NULL;
233 : }
234 :
235 : /************************************************************************/
236 : /* TestCapability() */
237 : /************************************************************************/
238 :
239 0 : int OGRGmtDataSource::TestCapability( const char * pszCap )
240 :
241 : {
242 0 : if( EQUAL(pszCap,ODsCCreateLayer) )
243 0 : return TRUE;
244 : else
245 0 : return FALSE;
246 : }
247 :
248 : /************************************************************************/
249 : /* GetLayer() */
250 : /************************************************************************/
251 :
252 1 : OGRLayer *OGRGmtDataSource::GetLayer( int iLayer )
253 :
254 : {
255 1 : if( iLayer < 0 || iLayer >= nLayers )
256 0 : return NULL;
257 : else
258 1 : return papoLayers[iLayer];
259 : }
260 :
|