From: curt Date: Mon, 1 Mar 1999 15:39:39 +0000 (+0000) Subject: Initial revision. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=ad2505c880df3b4002a95343b2bfb91324c9f912;p=flightgear.git Initial revision. --- diff --git a/Clipper/Makefile.am b/Clipper/Makefile.am new file mode 100644 index 000000000..21d1948aa --- /dev/null +++ b/Clipper/Makefile.am @@ -0,0 +1,14 @@ +noinst_LIBRARIES = libClipper.a +bin_PROGRAMS = clipper + +libClipper_a_SOURCES = clipper.cxx clipper.hxx +clipper_SOURCES = main.cxx + +clipper_LDADD = $(top_builddir)/Tools/Clipper/libClipper.a \ + $(top_builddir)/Tools/Polygon/libPolygon.a \ + $(top_builddir)/Lib/Debug/libDebug.a \ + $(top_builddir)/Lib/Misc/libMisc.a \ + $(top_builddir)/Lib/zlib/libz.a \ + -lgfc -lgpc + +INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Tools diff --git a/Clipper/clipper.cxx b/Clipper/clipper.cxx new file mode 100644 index 000000000..e4aaa76f0 --- /dev/null +++ b/Clipper/clipper.cxx @@ -0,0 +1,226 @@ +// 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 +#include +#include +#include + + +#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. +// diff --git a/Clipper/clipper.hxx b/Clipper/clipper.hxx new file mode 100644 index 000000000..79b7e16da --- /dev/null +++ b/Clipper/clipper.hxx @@ -0,0 +1,87 @@ +// 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 Generic Polygon Clipping Library +// +// http://www.cs.man.ac.uk/aig/staff/alan/software/ +// +extern "C" { +#include +} + +#include STL_STRING +#include + +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. +// diff --git a/Clipper/main.cxx b/Clipper/main.cxx new file mode 100644 index 000000000..4aa613a4e --- /dev/null +++ b/Clipper/main.cxx @@ -0,0 +1,114 @@ +// 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 +#include + + +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. +//