Contributions from David Megginson.
- increased maximum areas to 128 (for future growth), and added Road and Railroad areas - changed the method of calculating the triangle centre in poly_support.hxx - added a has_holes() method to polygon.hxx - added a new library, e00, for reading ArcInfo e00 files (i.e. the free online ones from DCW and GeoGratis); it needs more work - added a new prep utility, e00lines, for creating textured polygons out of e00 line data (with user-specified width and area type); this is useful for roads, railroads, rivers, and utility lines
This commit is contained in:
parent
8a82c389ec
commit
e08b755290
12 changed files with 80 additions and 65 deletions
|
@ -302,6 +302,7 @@ AC_OUTPUT( \
|
||||||
src/Lib/Makefile \
|
src/Lib/Makefile \
|
||||||
src/Lib/Array/Makefile \
|
src/Lib/Array/Makefile \
|
||||||
src/Lib/DEM/Makefile \
|
src/Lib/DEM/Makefile \
|
||||||
|
src/Lib/e00/Makefile \
|
||||||
src/Lib/Geometry/Makefile \
|
src/Lib/Geometry/Makefile \
|
||||||
src/Lib/landcover/Makefile \
|
src/Lib/landcover/Makefile \
|
||||||
src/Lib/Optimize/Makefile \
|
src/Lib/Optimize/Makefile \
|
||||||
|
@ -313,6 +314,7 @@ AC_OUTPUT( \
|
||||||
src/Prep/DemChop/Makefile \
|
src/Prep/DemChop/Makefile \
|
||||||
src/Prep/DemInfo/Makefile \
|
src/Prep/DemInfo/Makefile \
|
||||||
src/Prep/DemRaw2ascii/Makefile \
|
src/Prep/DemRaw2ascii/Makefile \
|
||||||
|
src/Prep/E00Lines/Makefile \
|
||||||
src/Prep/GenAirports/Makefile \
|
src/Prep/GenAirports/Makefile \
|
||||||
src/Prep/GSHHS/Makefile \
|
src/Prep/GSHHS/Makefile \
|
||||||
src/Prep/MergerClipper/Makefile \
|
src/Prep/MergerClipper/Makefile \
|
||||||
|
|
|
@ -38,21 +38,18 @@ FG_USING_STD(cout);
|
||||||
#define MASK_CLIP 1
|
#define MASK_CLIP 1
|
||||||
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor.
|
||||||
FGClipper::FGClipper( void ) {
|
FGClipper::FGClipper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
// Destructor.
|
||||||
FGClipper::~FGClipper( void ) {
|
FGClipper::~FGClipper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Initialize Clipper (allocate and/or connect structures)
|
// Initialize the clipper (empty all the polygon buckets.)
|
||||||
bool FGClipper::init() {
|
bool FGClipper::init() {
|
||||||
// v_list.num_vertices = 0;
|
|
||||||
// v_list.vertex = new gpc_vertex[FG_MAX_VERTICES];;
|
|
||||||
|
|
||||||
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
|
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
|
||||||
polys_in.polys[i].clear();
|
polys_in.polys[i].clear();
|
||||||
}
|
}
|
||||||
|
@ -61,7 +58,7 @@ bool FGClipper::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Load a polygon definition file
|
// Load a polygon definition file.
|
||||||
bool FGClipper::load_polys(const string& path) {
|
bool FGClipper::load_polys(const string& path) {
|
||||||
string poly_name;
|
string poly_name;
|
||||||
AreaType poly_type = DefaultArea;
|
AreaType poly_type = DefaultArea;
|
||||||
|
@ -78,9 +75,6 @@ bool FGClipper::load_polys(const string& path) {
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// gpc_polygon *poly = new gpc_polygon;
|
|
||||||
// poly->num_contours = 0;
|
|
||||||
// poly->contour = NULL;
|
|
||||||
FGPolygon poly;
|
FGPolygon poly;
|
||||||
|
|
||||||
Point3D p;
|
Point3D p;
|
||||||
|
@ -133,8 +127,6 @@ bool FGClipper::load_polys(const string& path) {
|
||||||
// cout << "poly pt = " << p << endl;
|
// cout << "poly pt = " << p << endl;
|
||||||
poly.add_node( i, p );
|
poly.add_node( i, p );
|
||||||
}
|
}
|
||||||
|
|
||||||
// gpc_add_contour( poly, &v_list, hole_flag );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
in >> skipcomment;
|
in >> skipcomment;
|
||||||
|
@ -142,10 +134,6 @@ bool FGClipper::load_polys(const string& path) {
|
||||||
|
|
||||||
int area = (int)poly_type;
|
int area = (int)poly_type;
|
||||||
|
|
||||||
// if ( area == OceanArea ) {
|
|
||||||
// TEST - Ignore
|
|
||||||
// } else
|
|
||||||
|
|
||||||
add_poly(area, poly);
|
add_poly(area, poly);
|
||||||
|
|
||||||
// FILE *ofp= fopen("outfile", "w");
|
// FILE *ofp= fopen("outfile", "w");
|
||||||
|
@ -154,7 +142,7 @@ bool FGClipper::load_polys(const string& path) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a polygon to the clipper.
|
||||||
void FGClipper::add_poly( int area, const FGPolygon &poly )
|
void FGClipper::add_poly( int area, const FGPolygon &poly )
|
||||||
{
|
{
|
||||||
if ( area < FG_MAX_AREA_TYPES ) {
|
if ( area < FG_MAX_AREA_TYPES ) {
|
||||||
|
@ -167,7 +155,7 @@ void FGClipper::add_poly (int area, const FGPolygon &poly)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// remove any slivers from in polygon and move them to out polygon.
|
// Move slivers from in polygon to out polygon.
|
||||||
void FGClipper::move_slivers( FGPolygon& in, FGPolygon& out ) {
|
void FGClipper::move_slivers( FGPolygon& in, FGPolygon& out ) {
|
||||||
// traverse each contour of the polygon and attempt to identify
|
// traverse each contour of the polygon and attempt to identify
|
||||||
// likely slivers
|
// likely slivers
|
||||||
|
@ -221,7 +209,9 @@ void FGClipper::move_slivers( FGPolygon& in, FGPolygon& out ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// for each sliver contour, see if a union with another polygon yields
|
// Attempt to merge slivers into a list of polygons.
|
||||||
|
//
|
||||||
|
// For each sliver contour, see if a union with another polygon yields
|
||||||
// a polygon with no increased contours (i.e. the sliver is adjacent
|
// a polygon with no increased contours (i.e. the sliver is adjacent
|
||||||
// and can be merged.) If so, replace the clipped polygon with the
|
// and can be merged.) If so, replace the clipped polygon with the
|
||||||
// new polygon that has the sliver merged in.
|
// new polygon that has the sliver merged in.
|
||||||
|
@ -289,7 +279,8 @@ void FGClipper::merge_slivers( FGPolyList& clipped, FGPolygon& slivers ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Do actually clipping work
|
// Clip all the polygons against each other in a priority scheme based
|
||||||
|
// on order of the polygon type in the polygon type enum.
|
||||||
bool FGClipper::clip_all(const point2d& min, const point2d& max) {
|
bool FGClipper::clip_all(const point2d& min, const point2d& max) {
|
||||||
FGPolygon accum, tmp;
|
FGPolygon accum, tmp;
|
||||||
FGPolygon slivers, remains;
|
FGPolygon slivers, remains;
|
||||||
|
@ -339,7 +330,6 @@ bool FGClipper::clip_all(const point2d& min, const point2d& max) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// int count = 0;
|
|
||||||
// process polygons in priority order
|
// process polygons in priority order
|
||||||
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
|
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
|
||||||
cout << "num polys of type (" << i << ") = "
|
cout << "num polys of type (" << i << ") = "
|
||||||
|
@ -377,13 +367,6 @@ bool FGClipper::clip_all(const point2d& min, const point2d& max) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// clip current polygon against previous higher priority
|
|
||||||
// stuff
|
|
||||||
|
|
||||||
// result_diff = new gpc_polygon;
|
|
||||||
// result_diff->num_contours = 0;
|
|
||||||
// result_diff->contour = NULL;
|
|
||||||
|
|
||||||
FGPolygon result_union, result_diff;
|
FGPolygon result_union, result_diff;
|
||||||
|
|
||||||
if ( accum.contours() == 0 ) {
|
if ( accum.contours() == 0 ) {
|
||||||
|
|
|
@ -45,41 +45,35 @@ FG_USING_STD(string);
|
||||||
FG_USING_STD(vector);
|
FG_USING_STD(vector);
|
||||||
|
|
||||||
|
|
||||||
// typedef vector < gpc_polygon * > gpcpoly_container;
|
#define FG_MAX_AREA_TYPES 128 // FIXME also defined in
|
||||||
// typedef gpcpoly_container::iterator gpcpoly_iterator;
|
|
||||||
// typedef gpcpoly_container::const_iterator const_gpcpoly_iterator;
|
|
||||||
|
|
||||||
|
|
||||||
#define FG_MAX_AREA_TYPES 40 // FIXME also defined in
|
|
||||||
// MergerClipper/clipper.hxx
|
// MergerClipper/clipper.hxx
|
||||||
#define EXTRA_SAFETY_CLIP
|
#define EXTRA_SAFETY_CLIP
|
||||||
// #define FG_MAX_VERTICES 100000
|
|
||||||
|
|
||||||
|
|
||||||
class FGPolyList {
|
class FGPolyList
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
poly_list polys[FG_MAX_AREA_TYPES];
|
poly_list polys[FG_MAX_AREA_TYPES];
|
||||||
FGPolygon safety_base;
|
FGPolygon safety_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class FGClipper {
|
class FGClipper
|
||||||
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// gpc_vertex_list v_list;
|
|
||||||
// static gpc_polygon poly;
|
|
||||||
FGPolyList polys_in, polys_clipped;
|
FGPolyList polys_in, polys_clipped;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructor
|
// Constructor.
|
||||||
FGClipper (void);
|
FGClipper (void);
|
||||||
|
|
||||||
// Destructor
|
// Destructor.
|
||||||
~FGClipper (void);
|
~FGClipper (void);
|
||||||
|
|
||||||
// Initialize Clipper (allocate and/or connect structures)
|
// Initialize Clipper (allocate and/or connect structures.)
|
||||||
bool init();
|
bool init();
|
||||||
|
|
||||||
// Load a polygon definition file
|
// Load a polygon definition file
|
||||||
|
@ -88,20 +82,20 @@ public:
|
||||||
// Add a polygon.
|
// Add a polygon.
|
||||||
void add_poly(int area, const FGPolygon &poly);
|
void add_poly(int area, const FGPolygon &poly);
|
||||||
|
|
||||||
// remove any slivers from in polygon and move them to out
|
// Remove any slivers from in polygon and move them to out
|
||||||
// polygon.
|
// polygon.
|
||||||
void move_slivers( FGPolygon& in, FGPolygon& out );
|
void move_slivers( FGPolygon& in, FGPolygon& out );
|
||||||
|
|
||||||
// for each sliver contour, see if a union with another polygon
|
// For each sliver contour, see if a union with another polygon
|
||||||
// yields a polygon with no increased contours (i.e. the sliver is
|
// yields a polygon with no increased contours (i.e. the sliver is
|
||||||
// adjacent and can be merged.) If so, replace the clipped
|
// adjacent and can be merged.) If so, replace the clipped
|
||||||
// polygon with the new polygon that has the sliver merged in.
|
// polygon with the new polygon that has the sliver merged in.
|
||||||
void merge_slivers( FGPolyList& clipped, FGPolygon& slivers );
|
void merge_slivers( FGPolyList& clipped, FGPolygon& slivers );
|
||||||
|
|
||||||
// Do actually clipping work
|
// Do actual clipping work.
|
||||||
bool clip_all(const point2d& min, const point2d& max);
|
bool clip_all(const point2d& min, const point2d& max);
|
||||||
|
|
||||||
// return output poly list
|
// Return output poly list
|
||||||
inline FGPolyList get_polys_clipped() const { return polys_clipped; }
|
inline FGPolyList get_polys_clipped() const { return polys_clipped; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -64,9 +64,7 @@ FG_USING_STD(vector);
|
||||||
vector<string> load_dirs;
|
vector<string> load_dirs;
|
||||||
|
|
||||||
|
|
||||||
/**
|
// Translate USGS land cover values into TerraGear area types.
|
||||||
* Translate USGS land cover into TerraGear.
|
|
||||||
*/
|
|
||||||
static AreaType translateUSGSCover (int usgs_value)
|
static AreaType translateUSGSCover (int usgs_value)
|
||||||
{
|
{
|
||||||
switch (usgs_value) {
|
switch (usgs_value) {
|
||||||
|
@ -127,7 +125,7 @@ static AreaType translateUSGSCover (int usgs_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// do actual scan of directory and loading of files
|
// Scan a directory and load polygon files.
|
||||||
static int actual_load_polys( const string& dir,
|
static int actual_load_polys( const string& dir,
|
||||||
FGConstruct& c,
|
FGConstruct& c,
|
||||||
FGClipper& clipper ) {
|
FGClipper& clipper ) {
|
||||||
|
@ -172,8 +170,10 @@ static int actual_load_polys( const string& dir,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Merge a polygon with an existing one if possible, append a new
|
// Add a polygon to a list, merging if possible.
|
||||||
// one otherwise; this function is used by actual_load_landcover, below,
|
//
|
||||||
|
// Merge a polygon with an existing one if possible, append a new one
|
||||||
|
// otherwise; this function is used by actual_load_landcover, below,
|
||||||
// to reduce the number of separate polygons.
|
// to reduce the number of separate polygons.
|
||||||
static void inline add_to_polys ( FGPolygon &accum, const FGPolygon &poly) {
|
static void inline add_to_polys ( FGPolygon &accum, const FGPolygon &poly) {
|
||||||
if ( accum.contours() > 0 ) {
|
if ( accum.contours() > 0 ) {
|
||||||
|
@ -184,7 +184,7 @@ static void inline add_to_polys ( FGPolygon &accum, const FGPolygon &poly) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Generate polygons from land-cover raster. Horizontally- or
|
// Generate polygons from la and-cover raster. Horizontally- or
|
||||||
// vertically-adjacent polygons will be merged automatically.
|
// vertically-adjacent polygons will be merged automatically.
|
||||||
static int actual_load_landcover ( LandCover &cover, FGConstruct & c,
|
static int actual_load_landcover ( LandCover &cover, FGConstruct & c,
|
||||||
FGClipper &clipper ) {
|
FGClipper &clipper ) {
|
||||||
|
@ -261,8 +261,8 @@ static int actual_load_landcover ( LandCover &cover, FGConstruct & c,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// load all 2d polygons matching the specified base path and clip
|
// load all 2d polygons from the specified load disk directories and
|
||||||
// against each other to resolve any overlaps
|
// clip against each other to resolve any overlaps
|
||||||
static int load_polys( FGConstruct& c ) {
|
static int load_polys( FGConstruct& c ) {
|
||||||
FGClipper clipper;
|
FGClipper clipper;
|
||||||
|
|
||||||
|
@ -304,8 +304,8 @@ static int load_polys( FGConstruct& c ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// load regular grid of elevation data (dem based), return list of
|
// Load elevation data from a DEM file, a regular grid of elevation
|
||||||
// fitted nodes
|
// data--dem based) and return list of fitted nodes.
|
||||||
static int load_dem( FGConstruct& c, FGArray& array) {
|
static int load_dem( FGConstruct& c, FGArray& array) {
|
||||||
point_list result;
|
point_list result;
|
||||||
string base = c.get_bucket().gen_base_path();
|
string base = c.get_bucket().gen_base_path();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
Array \
|
Array \
|
||||||
DEM \
|
DEM \
|
||||||
|
e00 \
|
||||||
Geometry \
|
Geometry \
|
||||||
landcover \
|
landcover \
|
||||||
Optimize \
|
Optimize \
|
||||||
|
|
|
@ -70,6 +70,8 @@ inline static void init ()
|
||||||
set_area("Reservoir", ReservoirArea);
|
set_area("Reservoir", ReservoirArea);
|
||||||
set_area("Reservoir Intermittent", IntReservoirArea);
|
set_area("Reservoir Intermittent", IntReservoirArea);
|
||||||
set_area("IntermittentReservoir", IntReservoirArea);
|
set_area("IntermittentReservoir", IntReservoirArea);
|
||||||
|
set_area("Road", RoadArea);
|
||||||
|
set_area("Railroad", RailroadArea);
|
||||||
set_area("Stream", StreamArea);
|
set_area("Stream", StreamArea);
|
||||||
set_area("Canal", CanalArea);
|
set_area("Canal", CanalArea);
|
||||||
set_area("Glacier", GlacierArea);
|
set_area("Glacier", GlacierArea);
|
||||||
|
|
|
@ -44,6 +44,8 @@ enum AreaType {
|
||||||
IntLakeArea,
|
IntLakeArea,
|
||||||
ReservoirArea,
|
ReservoirArea,
|
||||||
IntReservoirArea,
|
IntReservoirArea,
|
||||||
|
RoadArea,
|
||||||
|
RailroadArea,
|
||||||
StreamArea,
|
StreamArea,
|
||||||
CanalArea,
|
CanalArea,
|
||||||
GlacierArea,
|
GlacierArea,
|
||||||
|
|
|
@ -533,3 +533,20 @@ FGPolygon polygon_to_tristrip_old( const FGPolygon& in_poly ) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Send a polygon to standard output.
|
||||||
|
ostream &
|
||||||
|
operator<< (ostream &output, const FGPolygon &poly)
|
||||||
|
{
|
||||||
|
int nContours = poly.contours();
|
||||||
|
output << nContours << endl;
|
||||||
|
for (int i = 0; i < nContours; i++) {
|
||||||
|
int nPoints = poly.contour_size(i);
|
||||||
|
output << nPoints << endl;
|
||||||
|
output << poly.get_hole_flag(i) << endl;
|
||||||
|
for (int j = 0; j < nPoints; j++) {
|
||||||
|
output << poly.get_pt(i, j) << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -33,9 +33,11 @@
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
#include <simgear/math/sg_types.hxx>
|
#include <simgear/math/sg_types.hxx>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
FG_USING_STD(ostream);
|
||||||
FG_USING_STD(string);
|
FG_USING_STD(string);
|
||||||
FG_USING_STD(vector);
|
FG_USING_STD(vector);
|
||||||
|
|
||||||
|
@ -139,6 +141,13 @@ public:
|
||||||
inline void set_hole_flag( const int contour, const int flag ) {
|
inline void set_hole_flag( const int contour, const int flag ) {
|
||||||
hole_list[contour] = flag;
|
hole_list[contour] = flag;
|
||||||
}
|
}
|
||||||
|
inline bool has_holes () const {
|
||||||
|
for (int i = 0; i < contours(); i++) {
|
||||||
|
if (get_hole_flag(i))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// shift every point in the polygon by lon, lat
|
// shift every point in the polygon by lon, lat
|
||||||
void shift( double lon, double lat );
|
void shift( double lon, double lat );
|
||||||
|
@ -200,6 +209,9 @@ FGPolygon polygon_xor( const FGPolygon& subject, const FGPolygon& clip );
|
||||||
// Union
|
// Union
|
||||||
FGPolygon polygon_union( const FGPolygon& subject, const FGPolygon& clip );
|
FGPolygon polygon_union( const FGPolygon& subject, const FGPolygon& clip );
|
||||||
|
|
||||||
|
// Output
|
||||||
|
ostream &operator<< (ostream &output, const FGPolygon &poly);
|
||||||
|
|
||||||
|
|
||||||
#endif // _POLYGON_HXX
|
#endif // _POLYGON_HXX
|
||||||
|
|
||||||
|
|
|
@ -303,6 +303,7 @@
|
||||||
#define ONETHIRD 0.333333333333333333333333333333333333333333333333333333333333
|
#define ONETHIRD 0.333333333333333333333333333333333333333333333333333333333333
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#ifndef NO_TIMER
|
#ifndef NO_TIMER
|
||||||
|
@ -2728,7 +2729,7 @@ char **argv;
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
workstring[k] = '\0';
|
workstring[k] = '\0';
|
||||||
minangle = (REAL) strtod(workstring, (char **) NULL);
|
minangle = (REAL) atof(workstring);
|
||||||
} else {
|
} else {
|
||||||
minangle = 20.0;
|
minangle = 20.0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ SUBDIRS = \
|
||||||
DemChop \
|
DemChop \
|
||||||
DemInfo \
|
DemInfo \
|
||||||
DemRaw2ascii \
|
DemRaw2ascii \
|
||||||
|
E00Lines \
|
||||||
GenAirports \
|
GenAirports \
|
||||||
GSHHS \
|
GSHHS \
|
||||||
MergerClipper \
|
MergerClipper \
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
FG_USING_STD(string);
|
FG_USING_STD(string);
|
||||||
FG_USING_STD(vector);
|
FG_USING_STD(vector);
|
||||||
|
|
||||||
#define FG_MAX_AREA_TYPES 40 // FIXME: also defined in clipper.hxx
|
#define FG_MAX_AREA_TYPES 128 // FIXME: also defined in clipper.hxx
|
||||||
|
|
||||||
class FGPolyList {
|
class FGPolyList {
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue