1 : /******************************************************************************
2 : * $Id: gdal_contour.cpp 25643 2013-02-12 13:50:42Z bishop $
3 : *
4 : * Project: Contour Generator
5 : * Purpose: Contour Generator mainline.
6 : * Author: Frank Warmerdam <warmerdam@pobox.com>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2003, Applied Coherent Technology (www.actgate.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 "gdal.h"
31 : #include "gdal_alg.h"
32 : #include "cpl_conv.h"
33 : #include "cpl_string.h"
34 : #include "ogr_api.h"
35 : #include "ogr_srs_api.h"
36 :
37 : CPL_CVSID("$Id: gdal_contour.cpp 25643 2013-02-12 13:50:42Z bishop $");
38 :
39 : /************************************************************************/
40 : /* ArgIsNumeric() */
41 : /************************************************************************/
42 :
43 4 : static int ArgIsNumeric( const char *pszArg )
44 :
45 : {
46 4 : return CPLGetValueType(pszArg) != CPL_VALUE_STRING;
47 : }
48 :
49 : /************************************************************************/
50 : /* Usage() */
51 : /************************************************************************/
52 :
53 0 : static void Usage(const char* pszErrorMsg = NULL)
54 :
55 : {
56 : printf(
57 : "Usage: gdal_contour [-b <band>] [-a <attribute_name>] [-3d] [-inodata]\n"
58 : " [-snodata n] [-f <formatname>] [-i <interval>]\n"
59 : " [-f <formatname>] [[-dsco NAME=VALUE] ...] [[-lco NAME=VALUE] ...]\n"
60 : " [-off <offset>] [-fl <level> <level>...]\n"
61 : " [-nln <outlayername>] [-q]\n"
62 0 : " <src_filename> <dst_filename>\n" );
63 :
64 0 : if( pszErrorMsg != NULL )
65 0 : fprintf(stderr, "\nFAILURE: %s\n", pszErrorMsg);
66 :
67 0 : exit( 1 );
68 : }
69 :
70 : /************************************************************************/
71 : /* main() */
72 : /************************************************************************/
73 :
74 : #define CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(nExtraArg) \
75 : do { if (i + nExtraArg >= argc) \
76 : Usage(CPLSPrintf("%s option requires %d argument(s)", argv[i], nExtraArg)); } while(0)
77 :
78 7 : int main( int argc, char ** argv )
79 :
80 : {
81 : GDALDatasetH hSrcDS;
82 7 : int i, b3D = FALSE, bNoDataSet = FALSE, bIgnoreNoData = FALSE;
83 7 : int nBandIn = 1;
84 7 : double dfInterval = 0.0, dfNoData = 0.0, dfOffset = 0.0;
85 7 : const char *pszSrcFilename = NULL;
86 7 : const char *pszDstFilename = NULL;
87 7 : const char *pszElevAttrib = NULL;
88 7 : const char *pszFormat = "ESRI Shapefile";
89 7 : char **papszDSCO = NULL, **papszLCO = NULL;
90 : double adfFixedLevels[1000];
91 7 : int nFixedLevelCount = 0;
92 7 : const char *pszNewLayerName = "contour";
93 7 : int bQuiet = FALSE;
94 7 : GDALProgressFunc pfnProgress = NULL;
95 :
96 : /* Check that we are running against at least GDAL 1.4 */
97 : /* Note to developers : if we use newer API, please change the requirement */
98 7 : if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400)
99 : {
100 : fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, "
101 0 : "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME);
102 0 : exit(1);
103 : }
104 :
105 7 : GDALAllRegister();
106 7 : OGRRegisterAll();
107 :
108 7 : argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
109 :
110 : /* -------------------------------------------------------------------- */
111 : /* Parse arguments. */
112 : /* -------------------------------------------------------------------- */
113 32 : for( i = 1; i < argc; i++ )
114 : {
115 26 : if( EQUAL(argv[i], "--utility_version") )
116 : {
117 : printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
118 1 : argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
119 1 : return 0;
120 : }
121 25 : else if( EQUAL(argv[i], "--help") )
122 0 : Usage();
123 25 : else if( EQUAL(argv[i],"-a") )
124 : {
125 5 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
126 5 : pszElevAttrib = argv[++i];
127 : }
128 20 : else if( EQUAL(argv[i],"-off") )
129 : {
130 0 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
131 0 : dfOffset = atof(argv[++i]);
132 : }
133 20 : else if( EQUAL(argv[i],"-i") )
134 : {
135 5 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
136 5 : dfInterval = atof(argv[++i]);
137 : }
138 15 : else if( EQUAL(argv[i],"-fl") )
139 : {
140 1 : if( i >= argc-1 )
141 0 : Usage(CPLSPrintf("%s option requires at least 1 argument", argv[i]));
142 9 : while( i < argc-1
143 : && nFixedLevelCount
144 : < (int)(sizeof(adfFixedLevels)/sizeof(double))
145 4 : && ArgIsNumeric(argv[i+1]) )
146 3 : adfFixedLevels[nFixedLevelCount++] = atof(argv[++i]);
147 : }
148 14 : else if( EQUAL(argv[i],"-b") )
149 : {
150 0 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
151 0 : nBandIn = atoi(argv[++i]);
152 : }
153 14 : else if( EQUAL(argv[i],"-f") )
154 : {
155 0 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
156 0 : pszFormat = argv[++i];
157 : }
158 14 : else if( EQUAL(argv[i],"-dsco") )
159 : {
160 0 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
161 0 : papszDSCO = CSLAddString(papszDSCO, argv[++i] );
162 : }
163 14 : else if( EQUAL(argv[i],"-lco") )
164 : {
165 0 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
166 0 : papszLCO = CSLAddString(papszLCO, argv[++i] );
167 : }
168 14 : else if( EQUAL(argv[i],"-3d") )
169 : {
170 2 : b3D = TRUE;
171 : }
172 12 : else if( EQUAL(argv[i],"-snodata") )
173 : {
174 0 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
175 0 : bNoDataSet = TRUE;
176 0 : dfNoData = atof(argv[++i]);
177 : }
178 12 : else if( EQUAL(argv[i],"-nln") )
179 : {
180 0 : CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
181 0 : pszNewLayerName = argv[++i];
182 : }
183 12 : else if( EQUAL(argv[i],"-inodata") )
184 : {
185 0 : bIgnoreNoData = TRUE;
186 : }
187 12 : else if ( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") )
188 : {
189 0 : bQuiet = TRUE;
190 : }
191 12 : else if( pszSrcFilename == NULL )
192 : {
193 6 : pszSrcFilename = argv[i];
194 : }
195 6 : else if( pszDstFilename == NULL )
196 : {
197 6 : pszDstFilename = argv[i];
198 : }
199 : else
200 0 : Usage("Too many command options.");
201 : }
202 :
203 6 : if( dfInterval == 0.0 && nFixedLevelCount == 0 )
204 : {
205 0 : Usage("Neither -i nor -fl are specified.");
206 : }
207 :
208 6 : if (pszSrcFilename == NULL)
209 : {
210 0 : Usage("Missing source filename.");
211 : }
212 :
213 6 : if (pszDstFilename == NULL)
214 : {
215 0 : Usage("Missing destination filename.");
216 : }
217 :
218 6 : if (!bQuiet)
219 6 : pfnProgress = GDALTermProgress;
220 :
221 : /* -------------------------------------------------------------------- */
222 : /* Open source raster file. */
223 : /* -------------------------------------------------------------------- */
224 : GDALRasterBandH hBand;
225 :
226 6 : hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly );
227 6 : if( hSrcDS == NULL )
228 0 : exit( 2 );
229 :
230 6 : hBand = GDALGetRasterBand( hSrcDS, nBandIn );
231 6 : if( hBand == NULL )
232 : {
233 : CPLError( CE_Failure, CPLE_AppDefined,
234 : "Band %d does not exist on dataset.",
235 0 : nBandIn );
236 0 : exit(2);
237 : }
238 :
239 6 : if( !bNoDataSet && !bIgnoreNoData )
240 6 : dfNoData = GDALGetRasterNoDataValue( hBand, &bNoDataSet );
241 :
242 : /* -------------------------------------------------------------------- */
243 : /* Try to get a coordinate system from the raster. */
244 : /* -------------------------------------------------------------------- */
245 6 : OGRSpatialReferenceH hSRS = NULL;
246 :
247 6 : const char *pszWKT = GDALGetProjectionRef( hSrcDS );
248 :
249 6 : if( pszWKT != NULL && strlen(pszWKT) != 0 )
250 5 : hSRS = OSRNewSpatialReference( pszWKT );
251 :
252 : /* -------------------------------------------------------------------- */
253 : /* Create the outputfile. */
254 : /* -------------------------------------------------------------------- */
255 : OGRDataSourceH hDS;
256 6 : OGRSFDriverH hDriver = OGRGetDriverByName( pszFormat );
257 : OGRFieldDefnH hFld;
258 : OGRLayerH hLayer;
259 :
260 6 : if( hDriver == NULL )
261 : {
262 : fprintf( stderr, "Unable to find format driver named %s.\n",
263 0 : pszFormat );
264 0 : exit( 10 );
265 : }
266 :
267 6 : hDS = OGR_Dr_CreateDataSource( hDriver, pszDstFilename, papszDSCO );
268 6 : if( hDS == NULL )
269 0 : exit( 1 );
270 :
271 : hLayer = OGR_DS_CreateLayer( hDS, pszNewLayerName, hSRS,
272 : b3D ? wkbLineString25D : wkbLineString,
273 6 : papszLCO );
274 6 : if( hLayer == NULL )
275 0 : exit( 1 );
276 :
277 6 : hFld = OGR_Fld_Create( "ID", OFTInteger );
278 6 : OGR_Fld_SetWidth( hFld, 8 );
279 6 : OGR_L_CreateField( hLayer, hFld, FALSE );
280 6 : OGR_Fld_Destroy( hFld );
281 :
282 6 : if( pszElevAttrib )
283 : {
284 5 : hFld = OGR_Fld_Create( pszElevAttrib, OFTReal );
285 5 : OGR_Fld_SetWidth( hFld, 12 );
286 5 : OGR_Fld_SetPrecision( hFld, 3 );
287 5 : OGR_L_CreateField( hLayer, hFld, FALSE );
288 5 : OGR_Fld_Destroy( hFld );
289 : }
290 :
291 : /* -------------------------------------------------------------------- */
292 : /* Invoke. */
293 : /* -------------------------------------------------------------------- */
294 : CPLErr eErr;
295 :
296 : eErr = GDALContourGenerate( hBand, dfInterval, dfOffset,
297 : nFixedLevelCount, adfFixedLevels,
298 : bNoDataSet, dfNoData, hLayer,
299 : OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hLayer ),
300 : "ID" ),
301 : (pszElevAttrib == NULL) ? -1 :
302 : OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hLayer ),
303 : pszElevAttrib ),
304 6 : pfnProgress, NULL );
305 :
306 6 : OGR_DS_Destroy( hDS );
307 6 : GDALClose( hSrcDS );
308 :
309 6 : if (hSRS)
310 5 : OSRDestroySpatialReference( hSRS );
311 :
312 6 : CSLDestroy( argv );
313 6 : CSLDestroy( papszDSCO );
314 6 : CSLDestroy( papszLCO );
315 6 : GDALDestroyDriverManager();
316 6 : OGRCleanupAll();
317 :
318 6 : return 0;
319 : }
|