Updates from David Megginson to support the USGS global land use/cover raster
data.
This commit is contained in:
parent
25034ea180
commit
5619a6b473
10 changed files with 310 additions and 115 deletions
|
@ -303,6 +303,7 @@ AC_OUTPUT( \
|
||||||
src/Lib/Array/Makefile \
|
src/Lib/Array/Makefile \
|
||||||
src/Lib/DEM/Makefile \
|
src/Lib/DEM/Makefile \
|
||||||
src/Lib/Geometry/Makefile \
|
src/Lib/Geometry/Makefile \
|
||||||
|
src/Lib/landcover/Makefile \
|
||||||
src/Lib/Optimize/Makefile \
|
src/Lib/Optimize/Makefile \
|
||||||
src/Lib/Polygon/Makefile \
|
src/Lib/Polygon/Makefile \
|
||||||
src/Lib/poly2tri/Makefile \
|
src/Lib/poly2tri/Makefile \
|
||||||
|
|
|
@ -10,6 +10,7 @@ testclipper_LDADD = \
|
||||||
$(top_builddir)/src/Construct/Clipper/libClipper.a \
|
$(top_builddir)/src/Construct/Clipper/libClipper.a \
|
||||||
$(top_builddir)/src/Construct/Triangulate/libTriangulate.a \
|
$(top_builddir)/src/Construct/Triangulate/libTriangulate.a \
|
||||||
$(top_builddir)/src/Lib/Polygon/libPolygon.a \
|
$(top_builddir)/src/Lib/Polygon/libPolygon.a \
|
||||||
|
$(top_builddir)/src/Lib/landcover/liblandcover.a \
|
||||||
$(top_builddir)/src/Lib/poly2tri/libpoly2tri.a \
|
$(top_builddir)/src/Lib/poly2tri/libpoly2tri.a \
|
||||||
-lsgdebug -lsgmisc -lz -lgpc
|
-lsgdebug -lsgmisc -lz -lgpc
|
||||||
|
|
||||||
|
|
|
@ -146,13 +146,7 @@ bool FGClipper::load_polys(const string& path) {
|
||||||
// TEST - Ignore
|
// TEST - Ignore
|
||||||
// } else
|
// } else
|
||||||
|
|
||||||
if ( area < FG_MAX_AREA_TYPES ) {
|
add_poly(area, poly);
|
||||||
polys_in.polys[area].push_back(poly);
|
|
||||||
} else {
|
|
||||||
FG_LOG( FG_CLIPPER, FG_ALERT, "Polygon type out of range = "
|
|
||||||
<< (int)poly_type);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE *ofp= fopen("outfile", "w");
|
// FILE *ofp= fopen("outfile", "w");
|
||||||
// gpc_write_polygon(ofp, &polys.landuse);
|
// gpc_write_polygon(ofp, &polys.landuse);
|
||||||
|
@ -161,6 +155,18 @@ bool FGClipper::load_polys(const string& path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FGClipper::add_poly (int area, const FGPolygon &poly)
|
||||||
|
{
|
||||||
|
if ( area < FG_MAX_AREA_TYPES ) {
|
||||||
|
polys_in.polys[area].push_back(poly);
|
||||||
|
} else {
|
||||||
|
FG_LOG( FG_CLIPPER, FG_ALERT, "Polygon type out of range = "
|
||||||
|
<< area);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// remove any slivers from in polygon and move them to out polygon.
|
// remove any slivers from in polygon and move them to out polygon.
|
||||||
void FGClipper::move_slivers( FGPolygon& in, FGPolygon& out ) {
|
void FGClipper::move_slivers( FGPolygon& in, FGPolygon& out ) {
|
||||||
cout << "Begin move slivers" << endl;
|
cout << "Begin move slivers" << endl;
|
||||||
|
@ -300,11 +306,28 @@ bool FGClipper::clip_all(const point2d& min, const point2d& max) {
|
||||||
// best representation of land vs. ocean. If we have other less
|
// best representation of land vs. ocean. If we have other less
|
||||||
// accurate data that spills out into the ocean, we want to just
|
// accurate data that spills out into the ocean, we want to just
|
||||||
// clip it.
|
// clip it.
|
||||||
FGPolygon mask;
|
FGPolygon land_mask;
|
||||||
mask.erase();
|
land_mask.erase();
|
||||||
for ( int i = 0; i < (int)polys_in.polys[DefaultArea].size(); ++i ) {
|
for ( int i = 0; i < (int)polys_in.polys[DefaultArea].size(); ++i ) {
|
||||||
result_union = polygon_union( mask, polys_in.polys[DefaultArea][i] );
|
result_union =
|
||||||
mask = result_union;
|
polygon_union( land_mask, polys_in.polys[DefaultArea][i] );
|
||||||
|
land_mask = result_union;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up island mask, for cutting holes in lakes
|
||||||
|
FGPolygon island_mask;
|
||||||
|
island_mask.erase();
|
||||||
|
for ( int i = 0; i < (int)polys_in.polys[IslandArea].size(); ++i ) {
|
||||||
|
island_mask =
|
||||||
|
polygon_union( island_mask, polys_in.polys[IslandArea][i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up pond mask, for cutting holes in islands
|
||||||
|
FGPolygon pond_mask;
|
||||||
|
pond_mask.erase();
|
||||||
|
for ( int i = 0; i < (int)polys_in.polys[PondArea].size(); ++i ) {
|
||||||
|
pond_mask =
|
||||||
|
polygon_union( pond_mask, polys_in.polys[PondArea][i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// int count = 0;
|
// int count = 0;
|
||||||
|
@ -322,11 +345,19 @@ bool FGClipper::clip_all(const point2d& min, const point2d& max) {
|
||||||
|
|
||||||
if ( i > HoleArea ) {
|
if ( i > HoleArea ) {
|
||||||
// clip to land mask
|
// clip to land mask
|
||||||
tmp = polygon_int( current, mask );
|
tmp = polygon_int( current, land_mask );
|
||||||
} else {
|
} else {
|
||||||
tmp = current;
|
tmp = current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( i == LakeArea ) {
|
||||||
|
// clip against island mask
|
||||||
|
tmp = polygon_diff( tmp, island_mask );
|
||||||
|
} else if ( i == IslandArea ) {
|
||||||
|
// clip to pond mask
|
||||||
|
tmp = polygon_diff( tmp, pond_mask );
|
||||||
|
}
|
||||||
|
|
||||||
// clip current polygon against previous higher priority
|
// clip current polygon against previous higher priority
|
||||||
// stuff
|
// stuff
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,8 @@ FG_USING_STD(vector);
|
||||||
// typedef gpcpoly_container::const_iterator const_gpcpoly_iterator;
|
// typedef gpcpoly_container::const_iterator const_gpcpoly_iterator;
|
||||||
|
|
||||||
|
|
||||||
#define FG_MAX_AREA_TYPES 20
|
#define FG_MAX_AREA_TYPES 40 // FIXME also defined in
|
||||||
|
// MergerClipper/clipper.hxx
|
||||||
#define EXTRA_SAFETY_CLIP
|
#define EXTRA_SAFETY_CLIP
|
||||||
// #define FG_MAX_VERTICES 100000
|
// #define FG_MAX_VERTICES 100000
|
||||||
|
|
||||||
|
@ -84,6 +85,9 @@ public:
|
||||||
// Load a polygon definition file
|
// Load a polygon definition file
|
||||||
bool load_polys(const string& path);
|
bool load_polys(const string& path);
|
||||||
|
|
||||||
|
// Add a polygon.
|
||||||
|
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 );
|
||||||
|
|
|
@ -13,6 +13,7 @@ fgfs_construct_LDADD = \
|
||||||
$(top_builddir)/src/Lib/Geometry/libGeometry.a \
|
$(top_builddir)/src/Lib/Geometry/libGeometry.a \
|
||||||
$(top_builddir)/src/Lib/Optimize/libOptimize.a \
|
$(top_builddir)/src/Lib/Optimize/libOptimize.a \
|
||||||
$(top_builddir)/src/Lib/Polygon/libPolygon.a \
|
$(top_builddir)/src/Lib/Polygon/libPolygon.a \
|
||||||
|
$(top_builddir)/src/Lib/landcover/liblandcover.a \
|
||||||
$(top_builddir)/src/Lib/poly2tri/libpoly2tri.a \
|
$(top_builddir)/src/Lib/poly2tri/libpoly2tri.a \
|
||||||
$(top_builddir)/src/Lib/TriangleJRS/libTriangleJRS.a \
|
$(top_builddir)/src/Lib/TriangleJRS/libTriangleJRS.a \
|
||||||
-lsgbucket -lsgmath -lsgmisc -lsgdebug -lplibsg -lz -lgpc
|
-lsgbucket -lsgmath -lsgmisc -lsgdebug -lplibsg -lz -lgpc
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include <GenOutput/genobj.hxx>
|
#include <GenOutput/genobj.hxx>
|
||||||
#include <Match/match.hxx>
|
#include <Match/match.hxx>
|
||||||
#include <Triangulate/triangle.hxx>
|
#include <Triangulate/triangle.hxx>
|
||||||
|
#include <landcover/landcover.hxx>
|
||||||
|
|
||||||
#include "construct.hxx"
|
#include "construct.hxx"
|
||||||
|
|
||||||
|
@ -62,8 +63,73 @@ FG_USING_STD(vector);
|
||||||
vector<string> load_dirs;
|
vector<string> load_dirs;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate USGS land cover into TerraGear.
|
||||||
|
*/
|
||||||
|
static AreaType translateUSGSCover (int usgs_value)
|
||||||
|
{
|
||||||
|
switch (usgs_value) {
|
||||||
|
|
||||||
|
case 1: // Urban and Built-Up Land
|
||||||
|
return BuiltUpCover;
|
||||||
|
case 2: // Dryland Cropland and Pasture
|
||||||
|
return DryCropPastureCover;
|
||||||
|
case 3: // Irrigated Cropland and Pasture
|
||||||
|
return IrrCropPastureCover;
|
||||||
|
case 4: // Mixed Dryland/Irrigated Cropland and Pasture
|
||||||
|
return MixedCropPastureCover;
|
||||||
|
case 5: // Cropland/Grassland Mosaic
|
||||||
|
return CropGrassCover;
|
||||||
|
case 6: // Cropland/Woodland Mosaic
|
||||||
|
return CropWoodCover;
|
||||||
|
case 7: // Grassland
|
||||||
|
return GrassCover;
|
||||||
|
case 8: // Shrubland
|
||||||
|
return ShrubCover;
|
||||||
|
case 9: // Mixed Shrubland/Grassland
|
||||||
|
return ShrubGrassCover;
|
||||||
|
case 10: // Savanna
|
||||||
|
return SavannaCover;
|
||||||
|
case 11: // Deciduous Broadleaf Forest
|
||||||
|
return DeciduousBroadCover;
|
||||||
|
case 12: // Deciduous Needleleaf Forest
|
||||||
|
return DeciduousNeedleCover;
|
||||||
|
case 13: // Evergreen Broadleaf Forest
|
||||||
|
return EvergreenBroadCover;
|
||||||
|
case 14: // Evergreen Needleleaf Forest
|
||||||
|
return EvergreenNeedleCover;
|
||||||
|
case 15: // Mixed Forest
|
||||||
|
return MixedForestCover;
|
||||||
|
case 16: // Water Bodies
|
||||||
|
// FIXME: use the type of an adjoining area if possible
|
||||||
|
// return WaterBodyCover;
|
||||||
|
return DefaultArea;
|
||||||
|
case 17: // Herbaceous Wetland
|
||||||
|
return HerbWetlandCover;
|
||||||
|
case 18: // Wooded Wetland
|
||||||
|
return WoodedWetlandCover;
|
||||||
|
case 19: // Barren or Sparsely Vegetated
|
||||||
|
return BarrenCover;
|
||||||
|
case 20: // Herbaceous Tundra
|
||||||
|
return HerbTundraCover;
|
||||||
|
case 21: // Wooded Tundra
|
||||||
|
return WoodedTundraCover;
|
||||||
|
case 22: // Mixed Tundra
|
||||||
|
return MixedTundraCover;
|
||||||
|
case 23: // Bare Ground Tundra
|
||||||
|
return BareTundraCover;
|
||||||
|
case 24: // Snow or Ice
|
||||||
|
return SnowCover;
|
||||||
|
default: // Unknown
|
||||||
|
return DefaultArea;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// do actual scan of directory and loading of files
|
// do actual scan of directory and loading of files
|
||||||
int actual_load_polys( const string& dir, FGConstruct& c, FGClipper& clipper ) {
|
static int actual_load_polys( const string& dir,
|
||||||
|
FGConstruct& c,
|
||||||
|
FGClipper& clipper ) {
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
string base = c.get_bucket().gen_base_path();
|
string base = c.get_bucket().gen_base_path();
|
||||||
string tile_str = c.get_bucket().gen_index_str();
|
string tile_str = c.get_bucket().gen_index_str();
|
||||||
|
@ -105,9 +171,56 @@ int actual_load_polys( const string& dir, FGConstruct& c, FGClipper& clipper ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// generate polygons from land-cover raster.
|
||||||
|
static int actual_load_landcover ( LandCover &cover, FGConstruct & c,
|
||||||
|
FGClipper &clipper ) {
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
double lon, lat;
|
||||||
|
FGPolygon poly;
|
||||||
|
|
||||||
|
// Get the top corner of the tile
|
||||||
|
lon =
|
||||||
|
c.get_bucket().get_center_lon() - (0.5 * c.get_bucket().get_width());
|
||||||
|
lat =
|
||||||
|
c.get_bucket().get_center_lat() - (0.5 * c.get_bucket().get_height());
|
||||||
|
|
||||||
|
cout << "DPM: tile at " << lon << ',' << lat << endl;
|
||||||
|
|
||||||
|
// FIXME: this may still be wrong
|
||||||
|
int x_span = int(120 * bucket_span(lat)); // arcsecs of longitude
|
||||||
|
int y_span = int(120 * FG_BUCKET_SPAN); // arcsecs of latitude
|
||||||
|
for (int x = 0; x < x_span; x++) {
|
||||||
|
for (int y = 0; y < y_span; y++) {
|
||||||
|
double x1 = lon + (x * (1.0/120.0));
|
||||||
|
double y1 = lat + (y * (1.0/120.0));
|
||||||
|
double x2 = x1 + (1.0/120.0);
|
||||||
|
double y2 = y1 + (1.0/120.0);
|
||||||
|
int cover_value = cover.getValue(x1 + (1.0/240.0), y1 + (1.0/240.0));
|
||||||
|
cout << " position: " << x1 << ',' << y1 << ','
|
||||||
|
<< cover.getDescUSGS(cover_value) << endl;
|
||||||
|
AreaType area = translateUSGSCover(cover_value);
|
||||||
|
if (area != DefaultArea) {
|
||||||
|
poly.erase();
|
||||||
|
poly.add_node(0, Point3D(x1, y1, 0.0));
|
||||||
|
poly.add_node(0, Point3D(x1, y2, 0.0));
|
||||||
|
poly.add_node(0, Point3D(x2, y2, 0.0));
|
||||||
|
poly.add_node(0, Point3D(x2, y1, 0.0));
|
||||||
|
clipper.add_poly(area, poly);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
// load all 2d polygons matching the specified base path and clip
|
// load all 2d polygons matching the specified base path and clip
|
||||||
// against each other to resolve any overlaps
|
// against each other to resolve any overlaps
|
||||||
int load_polys( FGConstruct& c ) {
|
static int load_polys( FGConstruct& c ) {
|
||||||
|
string glc = c.get_work_base();
|
||||||
|
glc += "/LC-Global/gusgs2_0ll.img";
|
||||||
|
LandCover cover( glc );
|
||||||
FGClipper clipper;
|
FGClipper clipper;
|
||||||
|
|
||||||
string base = c.get_bucket().gen_base_path();
|
string base = c.get_bucket().gen_base_path();
|
||||||
|
@ -125,6 +238,9 @@ int load_polys( FGConstruct& c ) {
|
||||||
cout << " loaded " << count << " total polys" << endl;
|
cout << " loaded " << count << " total polys" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load the land use polygons
|
||||||
|
count += actual_load_landcover ( cover, c, clipper );
|
||||||
|
|
||||||
point2d min, max;
|
point2d min, max;
|
||||||
min.x = c.get_bucket().get_center_lon() - 0.5 * c.get_bucket().get_width();
|
min.x = c.get_bucket().get_center_lon() - 0.5 * c.get_bucket().get_width();
|
||||||
min.y = c.get_bucket().get_center_lat() - 0.5 * c.get_bucket().get_height();
|
min.y = c.get_bucket().get_center_lat() - 0.5 * c.get_bucket().get_height();
|
||||||
|
@ -144,7 +260,7 @@ int load_polys( FGConstruct& c ) {
|
||||||
|
|
||||||
// load regular grid of elevation data (dem based), return list of
|
// load regular grid of elevation data (dem based), return list of
|
||||||
// fitted nodes
|
// fitted nodes
|
||||||
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();
|
||||||
|
|
||||||
|
@ -169,14 +285,14 @@ int load_dem( FGConstruct& c, FGArray& array) {
|
||||||
|
|
||||||
|
|
||||||
// fit dem nodes, return number of fitted nodes
|
// fit dem nodes, return number of fitted nodes
|
||||||
int fit_dem(FGArray& array, int error) {
|
static int fit_dem(FGArray& array, int error) {
|
||||||
return array.fit( error );
|
return array.fit( error );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// triangulate the data for each polygon ( first time before splitting )
|
// triangulate the data for each polygon ( first time before splitting )
|
||||||
void first_triangulate( FGConstruct& c, const FGArray& array,
|
static void first_triangulate( FGConstruct& c, const FGArray& array,
|
||||||
FGTriangle& t ) {
|
FGTriangle& t ) {
|
||||||
// first we need to consolidate the points of the DEM fit list and
|
// first we need to consolidate the points of the DEM fit list and
|
||||||
// all the polygons into a more "Triangle" friendly format
|
// all the polygons into a more "Triangle" friendly format
|
||||||
|
|
||||||
|
@ -196,7 +312,7 @@ void first_triangulate( FGConstruct& c, const FGArray& array,
|
||||||
|
|
||||||
// triangulate the data for each polygon ( second time after splitting
|
// triangulate the data for each polygon ( second time after splitting
|
||||||
// and reassembling )
|
// and reassembling )
|
||||||
void second_triangulate( FGConstruct& c, FGTriangle& t ) {
|
static void second_triangulate( FGConstruct& c, FGTriangle& t ) {
|
||||||
t.rebuild( c );
|
t.rebuild( c );
|
||||||
cout << "done re building node list and polygons" << endl;
|
cout << "done re building node list and polygons" << endl;
|
||||||
|
|
||||||
|
@ -463,14 +579,14 @@ static point_list gen_point_normals( FGConstruct& c ) {
|
||||||
|
|
||||||
|
|
||||||
// generate the flight gear scenery file
|
// generate the flight gear scenery file
|
||||||
void do_output( FGConstruct& c, FGGenOutput& output ) {
|
static void do_output( FGConstruct& c, FGGenOutput& output ) {
|
||||||
output.build( c );
|
output.build( c );
|
||||||
output.write( c );
|
output.write( c );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// collect custom objects and move to scenery area
|
// collect custom objects and move to scenery area
|
||||||
void do_custom_objects( const FGConstruct& c ) {
|
static void do_custom_objects( const FGConstruct& c ) {
|
||||||
FGBucket b = c.get_bucket();
|
FGBucket b = c.get_bucket();
|
||||||
|
|
||||||
for (int i = 0; i < load_dirs.size(); i++) {
|
for (int i = 0; i < load_dirs.size(); i++) {
|
||||||
|
@ -515,7 +631,7 @@ void do_custom_objects( const FGConstruct& c ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// master construction routine
|
// master construction routine
|
||||||
void construct_tile( FGConstruct& c ) {
|
static void construct_tile( FGConstruct& c ) {
|
||||||
cout << "Construct tile, bucket = " << c.get_bucket() << endl;
|
cout << "Construct tile, bucket = " << c.get_bucket() << endl;
|
||||||
|
|
||||||
// fit with ever increasing error tolerance until we produce <=
|
// fit with ever increasing error tolerance until we produce <=
|
||||||
|
@ -655,7 +771,7 @@ void construct_tile( FGConstruct& c ) {
|
||||||
|
|
||||||
|
|
||||||
// display usage and exit
|
// display usage and exit
|
||||||
void usage( const string name ) {
|
static void usage( const string name ) {
|
||||||
cout << "Usage: " << name << endl;
|
cout << "Usage: " << name << endl;
|
||||||
cout << "[ --output-dir=<directory>" << endl;
|
cout << "[ --output-dir=<directory>" << endl;
|
||||||
cout << " --work-dir=<directory>" << endl;
|
cout << " --work-dir=<directory>" << endl;
|
||||||
|
|
|
@ -2,6 +2,7 @@ SUBDIRS = \
|
||||||
Array \
|
Array \
|
||||||
DEM \
|
DEM \
|
||||||
Geometry \
|
Geometry \
|
||||||
|
landcover \
|
||||||
Optimize \
|
Optimize \
|
||||||
Polygon \
|
Polygon \
|
||||||
poly2tri \
|
poly2tri \
|
||||||
|
|
|
@ -21,59 +21,100 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include STL_IOSTREAM
|
#include STL_IOSTREAM
|
||||||
#include STL_STRING
|
#include STL_STRING
|
||||||
|
|
||||||
#include "names.hxx"
|
#include "names.hxx"
|
||||||
|
|
||||||
|
FG_USING_STD(string);
|
||||||
|
FG_USING_STD(map);
|
||||||
FG_USING_STD(cout);
|
FG_USING_STD(cout);
|
||||||
FG_USING_STD(endl);
|
FG_USING_STD(endl);
|
||||||
|
|
||||||
|
|
||||||
|
typedef map<AreaType, string> area_type_map;
|
||||||
|
typedef map<string, AreaType> area_name_map;
|
||||||
|
|
||||||
|
static area_type_map area_types;
|
||||||
|
static area_name_map area_names;
|
||||||
|
|
||||||
|
|
||||||
|
inline static void set_area (const string &name, AreaType type)
|
||||||
|
{
|
||||||
|
area_types[type] = name;
|
||||||
|
area_names[name] = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool _initialized = false;
|
||||||
|
|
||||||
|
|
||||||
|
inline static void init ()
|
||||||
|
{
|
||||||
|
if (_initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
set_area("SomeSort", SomeSortOfArea);
|
||||||
|
set_area("Hole", HoleArea);
|
||||||
|
set_area("Island", IslandArea);
|
||||||
|
set_area("Pond", PondArea);
|
||||||
|
set_area("Swamp or Marsh", MarshArea);
|
||||||
|
set_area("Marsh", MarshArea);
|
||||||
|
set_area("Lake", LakeArea);
|
||||||
|
set_area("Lake Dry", DryLakeArea);
|
||||||
|
set_area("DryLake", DryLakeArea);
|
||||||
|
set_area("Lake Intermittent", IntLakeArea);
|
||||||
|
set_area("IntermittentLake", IntLakeArea);
|
||||||
|
set_area("Reservoir", ReservoirArea);
|
||||||
|
set_area("Reservoir Intermittent", IntReservoirArea);
|
||||||
|
set_area("IntermittentReservoir", IntReservoirArea);
|
||||||
|
set_area("Stream", StreamArea);
|
||||||
|
set_area("Canal", CanalArea);
|
||||||
|
set_area("Glacier", GlacierArea);
|
||||||
|
set_area("Urban", UrbanArea);
|
||||||
|
set_area("BuiltUpCover", BuiltUpCover);
|
||||||
|
set_area("DryCropPastureCover", DryCropPastureCover);
|
||||||
|
set_area("IrrCropPastureCover", IrrCropPastureCover);
|
||||||
|
set_area("MixedCropPastureCover", MixedCropPastureCover);
|
||||||
|
set_area("CropGrassCover", CropGrassCover);
|
||||||
|
set_area("CropWoodCover", CropWoodCover);
|
||||||
|
set_area("GrassCover", GrassCover);
|
||||||
|
set_area("ShrubCover", ShrubCover);
|
||||||
|
set_area("ShrubGrassCover", ShrubGrassCover);
|
||||||
|
set_area("SavannaCover", SavannaCover);
|
||||||
|
set_area("DeciduousBroadCover", DeciduousBroadCover);
|
||||||
|
set_area("DeciduousNeedleCover", DeciduousNeedleCover);
|
||||||
|
set_area("EvergreenBroadCover", EvergreenBroadCover);
|
||||||
|
set_area("EvergreenNeedleCover", EvergreenNeedleCover);
|
||||||
|
set_area("MixedForestCover", MixedForestCover);
|
||||||
|
set_area("WaterBodyCover", WaterBodyCover);
|
||||||
|
set_area("HerbWetlandCover", HerbWetlandCover);
|
||||||
|
set_area("WoodedWetlandCover", WoodedWetlandCover);
|
||||||
|
set_area("BarrenCover", BarrenCover);
|
||||||
|
set_area("HerbTundraCover", HerbTundraCover);
|
||||||
|
set_area("WoodedTundraCover", WoodedTundraCover);
|
||||||
|
set_area("MixedTundraCover", MixedTundraCover);
|
||||||
|
set_area("BareTundraCover", BareTundraCover);
|
||||||
|
set_area("SnowCover", SnowCover);
|
||||||
|
set_area("Default", DefaultArea);
|
||||||
|
set_area("Bay Estuary or Ocean", OceanArea);
|
||||||
|
set_area("Ocean", OceanArea);
|
||||||
|
set_area("Void Area", VoidArea);
|
||||||
|
set_area("Null", NullArea);
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// return area type from text name
|
// return area type from text name
|
||||||
AreaType get_area_type( string area ) {
|
AreaType
|
||||||
if ( area == "SomeSort" ) {
|
get_area_type (const string &area) {
|
||||||
return SomeSortOfArea;
|
init();
|
||||||
} else if ( area == "Hole" ) {
|
area_name_map::const_iterator it = area_names.find(area);
|
||||||
return HoleArea;
|
if (it != area_names.end()) {
|
||||||
} else if ( area == "Island" ) {
|
return it->second;
|
||||||
return IslandArea;
|
|
||||||
} else if ( area == "Pond" ) {
|
|
||||||
return PondArea;
|
|
||||||
} else if ( (area == "Swamp or Marsh")
|
|
||||||
|| (area == "Marsh") ) {
|
|
||||||
return MarshArea;
|
|
||||||
} else if ( area == "Lake" ) {
|
|
||||||
return LakeArea;
|
|
||||||
} else if ( (area == "Lake Dry")
|
|
||||||
|| (area == "DryLake") ) {
|
|
||||||
return DryLakeArea;
|
|
||||||
} else if ( (area == "Lake Intermittent")
|
|
||||||
|| (area == "IntermittentLake") ) {
|
|
||||||
return IntLakeArea;
|
|
||||||
} else if ( area == "Reservoir" ) {
|
|
||||||
return ReservoirArea;
|
|
||||||
} else if ( (area == "Reservoir Intermittent")
|
|
||||||
|| (area == "IntermittentReservoir") ) {
|
|
||||||
return IntReservoirArea;
|
|
||||||
} else if ( area == "Stream" ) {
|
|
||||||
return StreamArea;
|
|
||||||
} else if ( area == "Canal" ) {
|
|
||||||
return CanalArea;
|
|
||||||
} else if ( area == "Glacier" ) {
|
|
||||||
return GlacierArea;
|
|
||||||
} else if ( area == "Urban" ) {
|
|
||||||
return UrbanArea;
|
|
||||||
} else if ( area == "Default" ) {
|
|
||||||
return DefaultArea;
|
|
||||||
} else if ( (area == "Bay Estuary or Ocean")
|
|
||||||
|| (area == "Ocean") ) {
|
|
||||||
return OceanArea;
|
|
||||||
} else if ( area == "Void Area" ) {
|
|
||||||
return VoidArea;
|
|
||||||
} else if ( area == "Null" ) {
|
|
||||||
return NullArea;
|
|
||||||
} else {
|
} else {
|
||||||
cout << "unknown area = '" << area << "'" << endl;
|
cout << "unknown area = '" << area << "'" << endl;
|
||||||
// cout << "area = " << area << endl;
|
// cout << "area = " << area << endl;
|
||||||
|
@ -87,40 +128,10 @@ AreaType get_area_type( string area ) {
|
||||||
|
|
||||||
// return text from of area name
|
// return text from of area name
|
||||||
string get_area_name( AreaType area ) {
|
string get_area_name( AreaType area ) {
|
||||||
if ( area == DefaultArea ) {
|
init();
|
||||||
return "Default";
|
area_type_map::const_iterator it = area_types.find(area);
|
||||||
} else if ( area == HoleArea ) {
|
if (it != area_types.end()) {
|
||||||
return "Hole";
|
return it->second;
|
||||||
} else if ( area == MarshArea ) {
|
|
||||||
return "Marsh";
|
|
||||||
} else if ( area == PondArea ) {
|
|
||||||
return "Pond";
|
|
||||||
} else if ( area == IslandArea ) {
|
|
||||||
return "Island";
|
|
||||||
} else if ( area == LakeArea ) {
|
|
||||||
return "Lake";
|
|
||||||
} else if ( area == DryLakeArea ) {
|
|
||||||
return "DryLake";
|
|
||||||
} else if ( area == IntLakeArea ) {
|
|
||||||
return "IntermittentLake";
|
|
||||||
} else if ( area == ReservoirArea ) {
|
|
||||||
return "Reservoir";
|
|
||||||
} else if ( area == IntReservoirArea ) {
|
|
||||||
return "IntermittentReservoir";
|
|
||||||
} else if ( area == StreamArea ) {
|
|
||||||
return "Stream";
|
|
||||||
} else if ( area == CanalArea ) {
|
|
||||||
return "Canal";
|
|
||||||
} else if ( area == GlacierArea ) {
|
|
||||||
return "Glacier";
|
|
||||||
} else if ( area == UrbanArea ) {
|
|
||||||
return "Urban";
|
|
||||||
} else if ( area == OceanArea ) {
|
|
||||||
return "Ocean";
|
|
||||||
} else if ( area == VoidArea ) {
|
|
||||||
return "VoidArea";
|
|
||||||
} else if ( area == NullArea ) {
|
|
||||||
return "Null";
|
|
||||||
} else {
|
} else {
|
||||||
cout << "unknown area code = " << (int)area << endl;
|
cout << "unknown area code = " << (int)area << endl;
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
|
|
|
@ -39,19 +39,48 @@ enum AreaType {
|
||||||
SomeSortOfArea = 0,
|
SomeSortOfArea = 0,
|
||||||
HoleArea = 1,
|
HoleArea = 1,
|
||||||
PondArea = 2,
|
PondArea = 2,
|
||||||
IslandArea = 3,
|
LakeArea = 3,
|
||||||
LakeArea = 4,
|
DryLakeArea = 4,
|
||||||
DryLakeArea = 5,
|
IntLakeArea = 5,
|
||||||
IntLakeArea = 6,
|
ReservoirArea = 6,
|
||||||
ReservoirArea = 7,
|
IntReservoirArea = 7,
|
||||||
IntReservoirArea = 8,
|
StreamArea = 8,
|
||||||
StreamArea = 9,
|
CanalArea = 9,
|
||||||
CanalArea = 10,
|
GlacierArea = 10,
|
||||||
GlacierArea = 11,
|
OceanArea = 11,
|
||||||
OceanArea = 12,
|
UrbanArea = 12,
|
||||||
UrbanArea = 13,
|
MarshArea = 13,
|
||||||
MarshArea = 14,
|
|
||||||
DefaultArea = 15,
|
// USGS Land Covers
|
||||||
|
// These are low-priority, since known polygons should always win.
|
||||||
|
|
||||||
|
BuiltUpCover = 14, // Urban and Built-Up Land
|
||||||
|
DryCropPastureCover = 15, // Dryland Cropland and Pasture
|
||||||
|
IrrCropPastureCover = 16, // Irrigated Cropland and Pasture
|
||||||
|
MixedCropPastureCover = 17, // Mixed Dryland/Irrigated Cropland and Pasture
|
||||||
|
CropGrassCover = 18, // Cropland/Grassland Mosaic
|
||||||
|
CropWoodCover = 19, // Cropland/Woodland Mosaic
|
||||||
|
GrassCover = 20, // Grassland
|
||||||
|
ShrubCover = 21, // Shrubland
|
||||||
|
ShrubGrassCover = 22, // Mixed Shrubland/Grassland
|
||||||
|
SavannaCover = 23, // Savanna
|
||||||
|
DeciduousBroadCover = 24, // Deciduous Broadleaf Forest
|
||||||
|
DeciduousNeedleCover = 25, // Deciduous Needleleaf Forest
|
||||||
|
EvergreenBroadCover = 26, // Evergreen Broadleaf Forest
|
||||||
|
EvergreenNeedleCover = 27, // Evergreen Needleleaf Forest
|
||||||
|
MixedForestCover = 28, // Mixed Forest
|
||||||
|
WaterBodyCover = 29, // Water Bodies
|
||||||
|
HerbWetlandCover = 30, // Herbaceous Wetland
|
||||||
|
WoodedWetlandCover = 31, // Wooded Wetland
|
||||||
|
BarrenCover = 32, // Barren or Sparsely Vegetated
|
||||||
|
HerbTundraCover = 33, // Herbaceous Tundra
|
||||||
|
WoodedTundraCover = 34, // Wooded Tundra
|
||||||
|
MixedTundraCover = 35, // Mixed Tundra
|
||||||
|
BareTundraCover = 36, // Bare Ground Tundra
|
||||||
|
SnowCover = 37, // Snow or Ice
|
||||||
|
|
||||||
|
IslandArea = 38,
|
||||||
|
DefaultArea = 39,
|
||||||
VoidArea = 9997,
|
VoidArea = 9997,
|
||||||
NullArea = 9998,
|
NullArea = 9998,
|
||||||
UnknownArea = 9999
|
UnknownArea = 9999
|
||||||
|
@ -59,7 +88,7 @@ enum AreaType {
|
||||||
|
|
||||||
|
|
||||||
// return area type from text name
|
// return area type from text name
|
||||||
AreaType get_area_type( string area );
|
AreaType get_area_type( const string &area );
|
||||||
|
|
||||||
// return text form of area name
|
// return text form of area name
|
||||||
string get_area_name( AreaType area );
|
string get_area_name( AreaType area );
|
||||||
|
|
|
@ -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 20
|
#define FG_MAX_AREA_TYPES 40 // FIXME: also defined in clipper.hxx
|
||||||
|
|
||||||
class FGPolyList {
|
class FGPolyList {
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue