--- /dev/null
+// clipper.cxx -- top level routines to take a series of arbitrary areas and
+// produce a tight fitting puzzle pieces that combine to make a
+// tile
+//
+// 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 "clipper.hxx"
+
+#include <Debug/logstream.hxx>
+#include <Include/fg_constants.h>
+#include <Misc/fgstream.hxx>
+#include <Polygon/names.hxx>
+
+
+#define EXTRA_SAFETY_CLIP
+
+#define FG_MAX_VERTICES 100000
+
+static gpc_vertex_list v_list;
+// static gpc_polygon poly;
+static FGPolyList polys_in, polys_out;
+
+
+// Initialize Clipper (allocate and/or connect structures)
+bool fgClipperInit() {
+ v_list.num_vertices = 0;
+ v_list.vertex = new gpc_vertex[FG_MAX_VERTICES];;
+
+ return true;
+}
+
+
+// Load a polygon definition file
+bool fgClipperLoadPolygons(const string& path) {
+ string poly_name;
+ AreaType poly_type;
+ int contours, count, i, j;
+ double startx, starty, x, y, lastx, lasty;
+
+ FG_LOG( FG_CLIPPER, FG_INFO, "Loading " << path << " ..." );
+
+ fg_gzifstream in( path );
+
+ if ( !in ) {
+ FG_LOG( FG_CLIPPER, FG_ALERT, "Cannot open file: " << path );
+ exit(-1);
+ }
+
+ in >> skipcomment;
+ while ( !in.eof() ) {
+ in >> poly_name;
+ cout << "poly name = " << poly_name << endl;
+ poly_type = get_area_type( poly_name );
+ cout << "poly type (int) = " << (int)poly_type << endl;
+ in >> contours;
+ cout << "num contours = " << contours << endl;
+
+ for ( i = 0; i < contours; ++i ) {
+ in >> count;
+
+ if ( count < 3 ) {
+ FG_LOG( FG_CLIPPER, FG_ALERT,
+ "Polygon with less than 3 data points." );
+ exit(-1);
+ }
+
+ in >> startx;
+ in >> starty;
+ v_list.vertex[0].x = startx;
+ v_list.vertex[0].y = starty;
+ FG_LOG( FG_CLIPPER, FG_BULK, "0 = "
+ << startx << ", " << starty );
+
+ for ( j = 1; j < count - 1; ++j ) {
+ in >> x;
+ in >> y;
+ v_list.vertex[j].x = x;
+ v_list.vertex[j].y = y;
+ FG_LOG( FG_CLIPPER, FG_BULK, j << " = " << x << ", " << y );
+ }
+ v_list.num_vertices = count - 1;
+
+ in >> lastx;
+ in >> lasty;
+
+ if ( (fabs(startx - lastx) < FG_EPSILON)
+ && (fabs(starty - lasty) < FG_EPSILON) ) {
+ // last point same as first, discard
+ } else {
+ v_list.vertex[count - 1].x = lastx;
+ v_list.vertex[count - 1].y = lasty;
+ ++v_list.num_vertices;
+ FG_LOG( FG_CLIPPER, FG_BULK, count - 1 << " = "
+ << lastx << ", " << lasty );
+ }
+
+ gpc_polygon *poly = new gpc_polygon;
+ poly->num_contours = 0;
+ poly->contour = NULL;
+ gpc_add_contour( poly, &v_list );
+
+ int area = (int)poly_type;
+ if ( area < FG_MAX_AREAS ) {
+ polys_in.polys[area].push_back(poly);
+ } else {
+ FG_LOG( FG_CLIPPER, FG_ALERT, "Polygon type out of range = "
+ << poly_type);
+ exit(-1);
+ }
+ }
+
+ in >> skipcomment;
+ }
+
+ // FILE *ofp= fopen("outfile", "w");
+ // gpc_write_polygon(ofp, &polys.landuse);
+
+ return true;
+}
+
+
+// Do actually clipping work
+bool fgClipperMaster(const point2d& min, const point2d& max) {
+ gpc_polygon accum, result_diff, result_union, tmp;
+ polylist_iterator current, last;
+
+ FG_LOG( FG_CLIPPER, FG_INFO, "Running master clipper" );
+
+ accum.num_contours = 0;
+
+ cout << " (" << min.x << "," << min.y << ") ("
+ << max.x << "," << max.y << ")" << endl;
+
+ // set up clipping tile
+ v_list.vertex[0].x = min.x;
+ v_list.vertex[0].y = min.y;
+
+ v_list.vertex[1].x = max.x;
+ v_list.vertex[1].y = min.y;
+
+ v_list.vertex[2].x = max.x;
+ v_list.vertex[2].y = max.y;
+
+ v_list.vertex[3].x = min.x;
+ v_list.vertex[3].y = max.y;
+
+ v_list.num_vertices = 4;
+
+ polys_in.safety_base.num_contours = 0;
+ polys_in.safety_base.contour = NULL;
+ gpc_add_contour( &polys_in.safety_base, &v_list );
+
+ // process polygons in priority order
+ for ( int i = 0; i < FG_MAX_AREAS; ++i ) {
+
+ current = polys_in.polys[i].begin();
+ last = polys_in.polys[i].end();
+ for ( ; current != last; ++current ) {
+ FG_LOG( FG_CLIPPER, FG_DEBUG, get_area_name( (AreaType)i )
+ << " = " << (*current)->contour->num_vertices );
+
+#ifdef EXTRA_SAFETY_CLIP
+ // clip to base tile
+ gpc_polygon_clip(GPC_INT, &polys_in.safety_base, *current, &tmp);
+#else
+ &tmp = *current;
+#endif
+
+ // clip current polygon against previous higher priority
+ // stuff
+ if ( accum.num_contours == 0 ) {
+ result_diff = tmp;
+ result_union = tmp;
+ } else {
+ gpc_polygon_clip(GPC_DIFF, &accum, &tmp, &result_diff);
+ gpc_polygon_clip(GPC_UNION, &accum, &tmp, &result_union);
+ }
+
+ polys_out.polys[i].push_back(&result_diff);
+ accum = result_union;
+ }
+ }
+
+ // finally, what ever is left over goes to base terrain
+
+ // clip to accum against original base tile
+ gpc_polygon_clip(GPC_DIFF, &polys_in.safety_base, &accum,
+ &polys_out.safety_base);
+
+ // tmp output accum
+ FILE *ofp= fopen("accum", "w");
+ gpc_write_polygon(ofp, &accum);
+
+ // tmp output safety_base
+ ofp= fopen("safety_base", "w");
+ gpc_write_polygon(ofp, &polys_out.safety_base);
+
+ return true;
+}
+
+
+// $Log$
+// Revision 1.1 1999/03/01 15:39:39 curt
+// Initial revision.
+//
--- /dev/null
+// clipper.hxx -- top level routines to take a series of arbitrary areas and
+// produce a tight fitting puzzle pieces that combine to make a
+// tile
+//
+// 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)
+
+
+
+#ifndef _CLIPPER_HXX
+#define _CLIPPER_HXX
+
+
+#ifndef __cplusplus
+# error This library requires C++
+#endif
+
+
+#include <Include/compiler.h>
+
+
+// include Generic Polygon Clipping Library
+//
+// http://www.cs.man.ac.uk/aig/staff/alan/software/
+//
+extern "C" {
+#include <gpc.h>
+}
+
+#include STL_STRING
+#include <vector>
+
+typedef vector < gpc_polygon * > polylist;
+typedef polylist::iterator polylist_iterator;
+
+#define FG_MAX_AREAS 20
+
+class point2d {
+public:
+ double x, y;
+};
+
+
+class FGPolyList {
+public:
+ polylist polys[FG_MAX_AREAS];
+ gpc_polygon safety_base;
+};
+
+
+// Initialize Clipper (allocate and/or connect structures)
+bool fgClipperInit();
+
+
+// Load a polygon definition file
+bool fgClipperLoadPolygons(const string& path);
+
+
+// Do actually clipping work
+bool fgClipperMaster(const point2d& min, const point2d& max);
+
+
+#endif // _CLIPPER_HXX
+
+
+// $Log$
+// Revision 1.1 1999/03/01 15:39:39 curt
+// Initial revision.
+//
--- /dev/null
+// main.cxx -- sample use of the clipper lib
+//
+// 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 "clipper.hxx"
+
+#include <Debug/logstream.hxx>
+#include <Bucket/newbucket.hxx>
+
+
+int main( int argc, char **argv ) {
+ point2d global_min, global_max;
+
+ fglog().setLogLevels( FG_ALL, FG_DEBUG );
+
+ global_min.x = global_min.y = 200;
+ global_max.y = global_max.x = -200;
+
+ fgClipperInit();
+
+ if ( argc < 2 ) {
+ FG_LOG( FG_CLIPPER, FG_ALERT, "Usage: " << argv[0]
+ << " file1 file2 ..." );
+ exit(-1);
+ }
+
+ // process all specified polygon files
+ for ( int i = 1; i < argc; i++ ) {
+ string full_path = argv[i];
+
+ // determine bucket for this polygon
+ int pos = full_path.rfind("/");
+ string file_name = full_path.substr(pos + 1);
+ cout << "file name = " << file_name << endl;
+
+ pos = file_name.find(".");
+ string base_name = file_name.substr(0, pos);
+ cout << "base_name = " << base_name << endl;
+
+ long int index;
+ sscanf( base_name.c_str(), "%ld", &index);
+ FGBucket b(index);
+ cout << "bucket = " << b << endl;
+
+ // calculate bucket dimensions
+ point2d c, min, max;
+
+ c.x = b.get_center_lon();
+ c.y = b.get_center_lat();
+ double span = bucket_span(c.y);
+
+ if ( (c.y >= -89.0) && (c.y < 89.0) ) {
+ min.x = c.x - span / 2.0;
+ max.x = c.x + span / 2.0;
+ min.y = c.y - FG_HALF_BUCKET_SPAN;
+ max.y = c.y + FG_HALF_BUCKET_SPAN;
+ } else if ( c.y < -89.0) {
+ min.x = -90.0;
+ max.x = -89.0;
+ min.y = -180.0;
+ max.y = 180.0;
+ } else if ( c.y >= 89.0) {
+ min.x = 89.0;
+ max.x = 90.0;
+ min.y = -180.0;
+ max.y = 180.0;
+ } else {
+ FG_LOG ( FG_GENERAL, FG_ALERT,
+ "Out of range latitude in clip_and_write_poly() = "
+ << c.y );
+ }
+
+ if ( min.x < global_min.x ) global_min.x = min.x;
+ if ( min.y < global_min.y ) global_min.y = min.y;
+ if ( max.x > global_max.x ) global_max.x = max.x;
+ if ( max.y > global_max.y ) global_max.y = max.y;
+
+ // finally, load the polygon(s) from this file
+ fgClipperLoadPolygons( full_path );
+ }
+
+ // do the clipping
+ fgClipperMaster(global_min, global_max);
+
+ FG_LOG( FG_CLIPPER, FG_INFO, "finished main" );
+
+ return 0;
+}
+
+// $Log$
+// Revision 1.1 1999/03/01 15:39:39 curt
+// Initial revision.
+//