// main.cxx -- process shapefiles and extract polygon outlines, // clipping against and sorting them into the revelant // tiles. // // Written by Curtis Olson, started February 1999. // // Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // // $Id$ // (Log is kept at end of this file) // Include Geographic Foundation Classes library // libgfc.a includes need this bit o' strangeness #if defined ( linux ) # define _LINUX_ #endif #include #include #include #undef E #undef DEG_TO_RAD #undef RAD_TO_DEG // include Generic Polygon Clipping Library extern "C" { #include } #include #include STL_STRING #include #include #include #include "shape.hxx" int main( int argc, char **argv ) { gpc_polygon gpc_shape; int i, j; fglog().setLogLevels( FG_ALL, FG_DEBUG ); if ( argc != 3 ) { FG_LOG( FG_GENERAL, FG_ALERT, "Usage: " << argv[0] << " " ); exit(-1); } FG_LOG( FG_GENERAL, FG_DEBUG, "Opening " << argv[1] << " for reading." ); // initialize persistant polygon counter string counter_file = argv[2]; counter_file += "/polygon.counter"; poly_index_init( counter_file ); // initialize structure for building gpc polygons shape_utils_init(); GShapeFile * sf = new GShapeFile( argv[1] ); GDBFile *dbf = new GDBFile( argv[1] ); string path = argv[2]; GPolygon shape; double *coords; // in decimal degrees int n_vertices; FG_LOG( FG_GENERAL, FG_INFO, "shape file records = " << sf->numRecords() ); GShapeFile::ShapeType t = sf->shapeType(); if ( t != GShapeFile::av_Polygon ) { FG_LOG( FG_GENERAL, FG_ALERT, "Can't handle non-polygon shape files" ); exit(-1); } for ( i = 0; i < sf->numRecords(); i++ ) { //fetch i-th record (shape) sf->getShapeRec(i, &shape); FG_LOG( FG_GENERAL, FG_DEBUG, "Record = " << i << " rings = " << shape.numRings() ); AreaType area = get_shapefile_type(dbf, i); FG_LOG( FG_GENERAL, FG_DEBUG, "area type = " << get_area_name(area) << " (" << (int)area << ")" ); FG_LOG( FG_GENERAL, FG_INFO, " record = " << i << " ring = " << 0 ); if ( area == MarshArea ) { // interior of polygon is marsh, holes are water // do main outline first init_shape(&gpc_shape); n_vertices = shape.getRing(0, coords); add_to_shape(n_vertices, coords, &gpc_shape); process_shape(path, area, &gpc_shape); free_shape(&gpc_shape); // do lakes (individually) next for ( j = 1; j < shape.numRings(); j++ ) { FG_LOG( FG_GENERAL, FG_INFO, " record = " << i << " ring = " << j ); init_shape(&gpc_shape); n_vertices = shape.getRing(j, coords); add_to_shape(n_vertices, coords, &gpc_shape); process_shape(path, LakeArea, &gpc_shape); free_shape(&gpc_shape); } } else if ( area == OceanArea ) { // interior of polygon is ocean, holes are islands init_shape(&gpc_shape); for ( j = 0; j < shape.numRings(); j++ ) { n_vertices = shape.getRing(j, coords); add_to_shape(n_vertices, coords, &gpc_shape); } process_shape(path, area, &gpc_shape); free_shape(&gpc_shape); } else if ( area == LakeArea ) { // interior of polygon is lake, holes are islands init_shape(&gpc_shape); for ( j = 0; j < shape.numRings(); j++ ) { n_vertices = shape.getRing(j, coords); add_to_shape(n_vertices, coords, &gpc_shape); } process_shape(path, area, &gpc_shape); free_shape(&gpc_shape); } else if ( area == DryLakeArea ) { // interior of polygon is dry lake, holes are islands init_shape(&gpc_shape); for ( j = 0; j < shape.numRings(); j++ ) { n_vertices = shape.getRing(j, coords); add_to_shape(n_vertices, coords, &gpc_shape); } process_shape(path, area, &gpc_shape); free_shape(&gpc_shape); } else if ( area == IntLakeArea ) { // interior of polygon is intermittent lake, holes are islands init_shape(&gpc_shape); for ( j = 0; j < shape.numRings(); j++ ) { n_vertices = shape.getRing(j, coords); add_to_shape(n_vertices, coords, &gpc_shape); } process_shape(path, area, &gpc_shape); free_shape(&gpc_shape); } else if ( area == ReservoirArea ) { // interior of polygon is reservoir, holes are islands init_shape(&gpc_shape); for ( j = 0; j < shape.numRings(); j++ ) { n_vertices = shape.getRing(j, coords); add_to_shape(n_vertices, coords, &gpc_shape); } process_shape(path, area, &gpc_shape); free_shape(&gpc_shape); } else if ( area == IntReservoirArea ) { // interior of polygon is intermittent reservoir, holes are islands init_shape(&gpc_shape); for ( j = 0; j < shape.numRings(); j++ ) { n_vertices = shape.getRing(j, coords); add_to_shape(n_vertices, coords, &gpc_shape); } process_shape(path, area, &gpc_shape); free_shape(&gpc_shape); } else if ( area == StreamArea ) { // interior of polygon is stream, holes are islands init_shape(&gpc_shape); for ( j = 0; j < shape.numRings(); j++ ) { n_vertices = shape.getRing(j, coords); add_to_shape(n_vertices, coords, &gpc_shape); } process_shape(path, area, &gpc_shape); free_shape(&gpc_shape); } else if ( area == CanalArea ) { // interior of polygon is canal, holes are islands init_shape(&gpc_shape); for ( j = 0; j < shape.numRings(); j++ ) { n_vertices = shape.getRing(j, coords); add_to_shape(n_vertices, coords, &gpc_shape); } process_shape(path, area, &gpc_shape); free_shape(&gpc_shape); } else if ( area == GlacierArea ) { // interior of polygon is glacier, holes are dry land init_shape(&gpc_shape); for ( j = 0; j < shape.numRings(); j++ ) { n_vertices = shape.getRing(j, coords); add_to_shape(n_vertices, coords, &gpc_shape); } process_shape(path, area, &gpc_shape); free_shape(&gpc_shape); } else if ( area == VoidArea ) { // interior is ???? // skip for now FG_LOG( FG_GENERAL, FG_ALERT, "Void area ... SKIPPING!" ); if ( shape.numRings() > 1 ) { FG_LOG( FG_GENERAL, FG_ALERT, " Void area with holes!" ); // exit(-1); } init_shape(&gpc_shape); for ( j = 0; j < shape.numRings(); j++ ) { n_vertices = shape.getRing(j, coords); add_to_shape(n_vertices, coords, &gpc_shape); } // process_shape(path, area, &gpc_shape); free_shape(&gpc_shape); } else if ( area == NullArea ) { // interior is ???? // skip for now FG_LOG( FG_GENERAL, FG_ALERT, "Null area ... SKIPPING!" ); if ( shape.numRings() > 1 ) { FG_LOG( FG_GENERAL, FG_ALERT, " Null area with holes!" ); // exit(-1); } init_shape(&gpc_shape); for ( j = 0; j < shape.numRings(); j++ ) { n_vertices = shape.getRing(j, coords); add_to_shape(n_vertices, coords, &gpc_shape); } // process_shape(path, area, &gpc_shape); free_shape(&gpc_shape); } else { FG_LOG( FG_GENERAL, FG_ALERT, "Uknown area!" ); exit(-1); } } return 0; } // $Log$ // Revision 1.5 1999/03/01 15:36:28 curt // Tweaked a function call name in "names.hxx". // // Revision 1.4 1999/02/25 21:31:05 curt // First working version??? // // Revision 1.3 1999/02/23 01:29:04 curt // Additional progress. // // Revision 1.2 1999/02/19 19:05:18 curt // Working on clipping shapes and distributing into buckets. // // Revision 1.1 1999/02/15 19:10:23 curt // Initial revision. //