1 // main.cxx -- process shapefiles and extract polygon outlines,
2 // clipping against and sorting them into the revelant
5 // Written by Curtis Olson, started February 1999.
7 // Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 // (Log is kept at end of this file)
27 // Include Geographic Foundation Classes library
29 // libgfc.a includes need this bit o' strangeness
33 #include <gfc/gadt_polygon.h>
35 #include <gfc/gshapefile.h>
40 // include Generic Polygon Clipping Library
45 #include <Include/compiler.h>
49 #include <Debug/logstream.hxx>
51 #include <Polygon/index.hxx>
52 #include <Polygon/names.hxx>
56 int main( int argc, char **argv ) {
57 gpc_polygon gpc_shape;
60 fglog().setLogLevels( FG_ALL, FG_DEBUG );
63 FG_LOG( FG_GENERAL, FG_ALERT, "Usage: " << argv[0]
64 << " <shape_file> <work_dir>" );
68 FG_LOG( FG_GENERAL, FG_DEBUG, "Opening " << argv[1] << " for reading." );
70 // make work directory
71 string work_dir = argv[2];
72 string command = "mkdir -p " + work_dir;
73 system( command.c_str() );
75 // initialize persistant polygon counter
76 string counter_file = work_dir + "/../work.counter";
77 poly_index_init( counter_file );
79 // initialize structure for building gpc polygons
82 GShapeFile * sf = new GShapeFile( argv[1] );
83 GDBFile *dbf = new GDBFile( argv[1] );
84 string path = argv[2];
87 double *coords; // in decimal degrees
90 FG_LOG( FG_GENERAL, FG_INFO, "shape file records = " << sf->numRecords() );
92 GShapeFile::ShapeType t = sf->shapeType();
93 if ( t != GShapeFile::av_Polygon ) {
94 FG_LOG( FG_GENERAL, FG_ALERT, "Can't handle non-polygon shape files" );
98 for ( i = 0; i < sf->numRecords(); i++ ) {
99 //fetch i-th record (shape)
100 sf->getShapeRec(i, &shape);
101 FG_LOG( FG_GENERAL, FG_DEBUG, "Record = " << i << " rings = "
102 << shape.numRings() );
104 AreaType area = get_shapefile_type(dbf, i);
105 FG_LOG( FG_GENERAL, FG_DEBUG, "area type = " << get_area_name(area)
106 << " (" << (int)area << ")" );
108 FG_LOG( FG_GENERAL, FG_INFO, " record = " << i
109 << " ring = " << 0 );
111 if ( area == MarshArea ) {
112 // interior of polygon is marsh, holes are water
114 // do main outline first
115 init_shape(&gpc_shape);
116 n_vertices = shape.getRing(0, coords);
117 add_to_shape(n_vertices, coords, &gpc_shape);
118 process_shape(path, area, &gpc_shape);
119 free_shape(&gpc_shape);
121 // do lakes (individually) next
122 for ( j = 1; j < shape.numRings(); j++ ) {
123 FG_LOG( FG_GENERAL, FG_INFO, " record = " << i
124 << " ring = " << j );
125 init_shape(&gpc_shape);
126 n_vertices = shape.getRing(j, coords);
127 add_to_shape(n_vertices, coords, &gpc_shape);
128 process_shape(path, LakeArea, &gpc_shape);
129 free_shape(&gpc_shape);
131 } else if ( area == OceanArea ) {
132 // interior of polygon is ocean, holes are islands
134 init_shape(&gpc_shape);
135 for ( j = 0; j < shape.numRings(); j++ ) {
136 n_vertices = shape.getRing(j, coords);
137 add_to_shape(n_vertices, coords, &gpc_shape);
139 process_shape(path, area, &gpc_shape);
140 free_shape(&gpc_shape);
141 } else if ( area == LakeArea ) {
142 // interior of polygon is lake, holes are islands
144 init_shape(&gpc_shape);
145 for ( j = 0; j < shape.numRings(); j++ ) {
146 n_vertices = shape.getRing(j, coords);
147 add_to_shape(n_vertices, coords, &gpc_shape);
149 process_shape(path, area, &gpc_shape);
150 free_shape(&gpc_shape);
151 } else if ( area == DryLakeArea ) {
152 // interior of polygon is dry lake, holes are islands
154 init_shape(&gpc_shape);
155 for ( j = 0; j < shape.numRings(); j++ ) {
156 n_vertices = shape.getRing(j, coords);
157 add_to_shape(n_vertices, coords, &gpc_shape);
159 process_shape(path, area, &gpc_shape);
160 free_shape(&gpc_shape);
161 } else if ( area == IntLakeArea ) {
162 // interior of polygon is intermittent lake, holes are islands
164 init_shape(&gpc_shape);
165 for ( j = 0; j < shape.numRings(); j++ ) {
166 n_vertices = shape.getRing(j, coords);
167 add_to_shape(n_vertices, coords, &gpc_shape);
169 process_shape(path, area, &gpc_shape);
170 free_shape(&gpc_shape);
171 } else if ( area == ReservoirArea ) {
172 // interior of polygon is reservoir, holes are islands
174 init_shape(&gpc_shape);
175 for ( j = 0; j < shape.numRings(); j++ ) {
176 n_vertices = shape.getRing(j, coords);
177 add_to_shape(n_vertices, coords, &gpc_shape);
179 process_shape(path, area, &gpc_shape);
180 free_shape(&gpc_shape);
181 } else if ( area == IntReservoirArea ) {
182 // interior of polygon is intermittent reservoir, holes are islands
184 init_shape(&gpc_shape);
185 for ( j = 0; j < shape.numRings(); j++ ) {
186 n_vertices = shape.getRing(j, coords);
187 add_to_shape(n_vertices, coords, &gpc_shape);
189 process_shape(path, area, &gpc_shape);
190 free_shape(&gpc_shape);
191 } else if ( area == StreamArea ) {
192 // interior of polygon is stream, holes are islands
194 init_shape(&gpc_shape);
195 for ( j = 0; j < shape.numRings(); j++ ) {
196 n_vertices = shape.getRing(j, coords);
197 add_to_shape(n_vertices, coords, &gpc_shape);
199 process_shape(path, area, &gpc_shape);
200 free_shape(&gpc_shape);
201 } else if ( area == CanalArea ) {
202 // interior of polygon is canal, holes are islands
204 init_shape(&gpc_shape);
205 for ( j = 0; j < shape.numRings(); j++ ) {
206 n_vertices = shape.getRing(j, coords);
207 add_to_shape(n_vertices, coords, &gpc_shape);
209 process_shape(path, area, &gpc_shape);
210 free_shape(&gpc_shape);
211 } else if ( area == GlacierArea ) {
212 // interior of polygon is glacier, holes are dry land
214 init_shape(&gpc_shape);
215 for ( j = 0; j < shape.numRings(); j++ ) {
216 n_vertices = shape.getRing(j, coords);
217 add_to_shape(n_vertices, coords, &gpc_shape);
219 process_shape(path, area, &gpc_shape);
220 free_shape(&gpc_shape);
221 } else if ( area == VoidArea ) {
225 FG_LOG( FG_GENERAL, FG_ALERT, "Void area ... SKIPPING!" );
227 if ( shape.numRings() > 1 ) {
228 FG_LOG( FG_GENERAL, FG_ALERT, " Void area with holes!" );
232 init_shape(&gpc_shape);
233 for ( j = 0; j < shape.numRings(); j++ ) {
234 n_vertices = shape.getRing(j, coords);
235 add_to_shape(n_vertices, coords, &gpc_shape);
237 // process_shape(path, area, &gpc_shape);
238 free_shape(&gpc_shape);
239 } else if ( area == NullArea ) {
243 FG_LOG( FG_GENERAL, FG_ALERT, "Null area ... SKIPPING!" );
245 if ( shape.numRings() > 1 ) {
246 FG_LOG( FG_GENERAL, FG_ALERT, " Null area with holes!" );
250 init_shape(&gpc_shape);
251 for ( j = 0; j < shape.numRings(); j++ ) {
252 n_vertices = shape.getRing(j, coords);
253 add_to_shape(n_vertices, coords, &gpc_shape);
255 // process_shape(path, area, &gpc_shape);
256 free_shape(&gpc_shape);
258 FG_LOG( FG_GENERAL, FG_ALERT, "Uknown area!" );
268 // Revision 1.7 1999/03/17 23:51:29 curt
269 // Changed polygon index counter file.
271 // Revision 1.6 1999/03/02 01:04:28 curt
272 // Don't crash when work directory doesn't exist ... create it.
274 // Revision 1.5 1999/03/01 15:36:28 curt
275 // Tweaked a function call name in "names.hxx".
277 // Revision 1.4 1999/02/25 21:31:05 curt
278 // First working version???
280 // Revision 1.3 1999/02/23 01:29:04 curt
281 // Additional progress.
283 // Revision 1.2 1999/02/19 19:05:18 curt
284 // Working on clipping shapes and distributing into buckets.
286 // Revision 1.1 1999/02/15 19:10:23 curt