1
0
Fork 0

Rename tgSplitPolygon() -> tgChopPolygon() which is slightly more descriptive

and doesn't sound so much like the split long edges function.
This commit is contained in:
curt 2004-04-08 19:47:39 +00:00
parent b6be77e5da
commit 1399eb9de3
13 changed files with 191 additions and 93 deletions

175
README
View file

@ -1,75 +1,164 @@
FG Scenery Tools README
=======================
TerraGear Scenery Tools README
==============================
Contained here-in are the FG scenery creation tools. These can be
used to convert 3 arcsec ASCII format DEM files and 30 arcsec binary
format DEM files into Flight Gear scenery.
TerraGear is a collection of tools for building scenery for the
FlightGear project. Generally, the process is done in two steps:
Eventually these tools will expand to support insertion of airports,
roads, rivers, lakes, etc.
1. Preprocess the original raw data. This chops up the data into
the FG tiling scheme and saves it in a simple, intermediate
format.
2. Collect all the different pieces of intermediate data and
assemble them into a 3d model of the terrain.
There is currently no graphical front end for these tools so you will
need to run them from the command line. Be prepaired, when building
scenery on a world wide scale, be prepaired to burn through multiple
gigabytes of disk space and days or weeks of crunching. Building
smaller chunks is much more doable though.
Building the Tools
==================
These tools are compiled and tested under Linux. I'm all for
portability, but I just haven't been as motivated to port these tools,
since scenery creation is less of a general need ... especially at
this stage. However, if anyone wants to work on porting to other
platforms, I will be happy to incorporate patches.
These tools are primarily compiled and tested under Unix with the gnu
compilers. I believe they also build and run on windows with Cygwin.
If anyone has patches for supporting other platforms, I will be happy
to incorporate them.
The process for building these tools is very similar to building the
main FG source code.
1. Set the FG_ROOT, FG_ROOT_SRC, and FG_ROOT_LIB environment
variables.
1. If you are using the CVS version of the source, run the
"autogen.sh" script. If you downloaded the source tarball, then
don't.
2. Run ``make depend''
2. Run the "configure" script, with optional arguments for setting
the install prefix, etc..
3. Run ``make clean''
3. Run "make"
4. Run ``make''
4. Run "make install"
3 Arcsec ASCII DEM files
========================
Preprocessing Terrain
=====================
Data files for the USA are available in this format from:
TerraGear supports several terrain data sources:
http://edcwww.cr.usgs.gov/doc/edchome/ndcdb/ndcdb.html
1. 30-arcsec SRTM based terrain data covering the world (recommended
over other 30-arcsec data sources):
To generate FG scenery from one of these dem files, run:
ftp://edcsgs9.cr.usgs.gov/pub/data/srtm/SRTM30/
./process-dem.pl <error-tolerance-squared> dem-file-1 [ dem-file-2 ...]
I don't recall the details at the moment for processing this data.
Probably similar to the processing of the GLOBE data.
You can vary the error tolerance to control the level of detail (and
size) of the resulting scenery. Note, you must specify the error
tolerance squared. So, if you wish to allow up to a 10 meter error
margin (very high level of detail) you would specify a value of 100.
If you desire an error tolerance of 200 meters (medium detail level)
you would specify a value of 40000.
2. 30-arcsec world wide data: GLOBE project:
The process-dem.pl script will automatically dump the resulting .obj
files in the proper directory tree.
http://www.ngdc.noaa.gov/seg/topo/globe.shtml
a) First convert the "bin" DEM format to "ascii" DEM format using
"Prep/DemRaw2ascii/raw2ascii"
b) Then process the resulting files with "Prep/DemChop/demchop"
30 Arcsec Binary DEM files
==========================
These data files have world wide coverage and are available from:
3. 30-arcsec world wide data: GTOPO30 data:
http://edcwww.cr.usgs.gov/landdaac/gtopo30/gtopo30.html
To process these data files, you must first run:
a) First convert the "bin" DEM format to "ascii" DEM format using
"Prep/DemRaw2ascii/raw2ascii"
DemRaw2Ascii/raw2ascii <input_file_basename> <output_dir>
b) Then process the resulting files with "Prep/DemChop/demchop"
For example:
DemRaw2Ascii/raw2ascii /tmp/W020N90 asciidems/
4. SRTM (1 and 3-arcsec nearly world wide coverage):
This will create ASCII DEM files for each 1 degree x 1 degree area in
the specified output dir.
ftp://edcsgs9.cr.usgs.gov/pub/data/srtm/
Then, you can take these ascii dem files and feed them through the
same procedure you use with the 3 arcsec dem files.
a) Chop up the .zip files using "Prep/DemChop/hgtchop"
5. 3-arcsec ASCII DEM files:
Generally, I recommend using the SRTM data over this older data
set, however in places like Alaska, there is no SRTM coverage so
this data is better than the 30 arcsec data.
http://edcwww.cr.usgs.gov/doc/edchome/ndcdb/ndcdb.html
a) Create the .arr.gz files using the "Prep/DemChop/demchop" utility.
The result for any of these terrain sources should be a "work" tree
with a .arr.gz file for each FG tile.
6. After you create the .arr.gz files you have to create a
corresponding .fit.gz file for each of these. This is a data
reduction step which fits a set of polygons to the raw terrain with
a set of constraints on the maximum error allowed relative to the
original data set, and a max/min number of allowed nodes in the
fitted set. The provided tools use a scheme that produces an
adaptive fit which means fewer polygons in smooth flat areas, and
more polygons in complex rough areas. The end result is a *much*
better fit with fewer polygons than you could achieve by just keeping
every "nth" point from the original array.
To walk through an entire tree of .arr.gz files and produce the
corresponding .fit.gz files, use the "Prep/TerraFit/terrafit.py"
utility. Please ignore the old "ArrayFit" tools which use a stupid
algorithm and are basically useless in comparison to TerraFit.
You should now have a large tree of .arr.gz files with a corresponding
.fit.gz file for each .arr.gz file. It's worth double checking the
contents of your directory and counting all files of each type to make
sure you do have a one to one match and didn't miss anything.
Generating Airports
===================
Robin Peel maintains a world wide database of airports and navaids for
the X-Plane and FlightGear projects:
http://www.x-plane.org/users/robinp/
Robin's apt.dat needs to be run through two scripts
cat apt.dat | ./xp2simpleapt.pl > basic.dat
cat apt.dat | ./xp2runway.pl > runways.dat
Compress these and copy them to $FG_ROOT/data/Airports
Now run the runways.dat through the getapt utility:
genapts --input=runways.dat --work=$FG_WORK_DIR
Note: this creates a last_apt file which shows you the airport genapts
is currently working on.
- if genapts crashes (which is possible if you try to run through the
entire runways.dat file) you can look at last_apt to see where to start
up again.
- You can start in midstream using the --start-id=KABC option to genapts.
- If you get a consistant crash on a particular airport, you probably
found a bug in genapts, or there is some degenerate information at that
airport (40 mile long runways, 2 runways spaced miles apart, etc.)
Often you can fix the data and proceed. Sometimes you can "nudge"
things around to get past a genapts bug. For instance, if you crahs
consistantly on a valid looking runway, try nudging the heading or
position by a least significant digit. Sometimes we can get numerical
problems with the polygon cliper and this often works around it.
Other considerations:
- Airport generation pre-depends on terrain data being preped and ready
so airport surfaces can be built properly.
- If you prep new terrain data, you should probably rerun the airport
generation step.

View file

@ -50,9 +50,9 @@
#include <Geometry/poly_support.hxx>
#include <Geometry/trinodes.hxx>
#include <Output/output.hxx>
#include <Polygon/chop.hxx>
#include <Polygon/index.hxx>
#include <Polygon/polygon.hxx>
#include <Polygon/split.hxx>
#include <Polygon/superpoly.hxx>
#include <Triangulate/trieles.hxx>
@ -1210,8 +1210,8 @@ void build_airport( string airport_id, float alt_m,
string holepath = root + "/AirportArea";
// long int poly_index = poly_index_next();
// write_boundary( holepath, b, hull, poly_index );
tgSplitPolygon( holepath, HoleArea, divided_base, true );
tgSplitPolygon( holepath, AirportArea, apt_clearing, false );
tgChopPolygon( holepath, HoleArea, divided_base, true );
tgChopPolygon( holepath, AirportArea, apt_clearing, false );
}

View file

@ -1,11 +1,11 @@
noinst_LIBRARIES = libPolygon.a
libPolygon_a_SOURCES = \
chop-bin.cxx chop.hxx \
index.cxx index.hxx \
names.cxx names.hxx \
polygon.cxx polygon.hxx \
simple_clip.cxx simple_clip.hxx \
split-bin.cxx split.hxx \
superpoly.cxx superpoly.hxx
INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/Lib

View file

@ -1,8 +1,10 @@
// split.cxx -- polygon splitting utils
// chop-bin.hxx -- routine to chop a polygon up along tile boundaries and
// write the individual pieces to the TG working polygon
// file format.
//
// Written by Curtis Olson, started February 1999.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1999-2004 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
@ -20,6 +22,7 @@
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@ -39,7 +42,7 @@
#include "index.hxx"
#include "names.hxx"
#include "simple_clip.hxx"
#include "split.hxx"
#include "chop.hxx"
static void clip_and_write_poly( string root, long int p_index, AreaType area,
@ -144,8 +147,9 @@ static void clip_and_write_poly( string root, long int p_index, AreaType area,
}
// process shape (write polygon to all intersecting tiles)
void tgSplitPolygon( const string& path, AreaType area,
// process polygon shape (chop up along tile boundaries and write each
// polygon piece to a file)
void tgChopPolygon( const string& path, AreaType area,
const TGPolygon& shape, bool preserve3d )
{
Point3D min, max, p;
@ -264,7 +268,7 @@ void tgSplitPolygon( const string& path, AreaType area,
bottom_clip = horizontal_clip( shape, clip_line, Below );
}
tgSplitPolygon( path, area, bottom_clip, preserve3d );
tgChopPolygon( path, area, bottom_clip, preserve3d );
}
{
@ -293,6 +297,6 @@ void tgSplitPolygon( const string& path, AreaType area,
top_clip = horizontal_clip( shape, clip_line, Above );
}
tgSplitPolygon( path, area, top_clip, preserve3d );
tgChopPolygon( path, area, top_clip, preserve3d );
}
}

View file

@ -1,8 +1,10 @@
// split.hxx -- polygon splitting utils
// chop.hxx -- routine to chop a polygon up along tile boundaries and
// write the individual pieces to the TG working polygon
// file format.
//
// Written by Curtis Olson, started February 1999.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1999-2004 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
@ -21,19 +23,20 @@
// $Id$
#ifndef _SPLIT_HXX
#define _SPLIT_HXX
#ifndef _TG_CHOP_HXX
#define _TG_CHOP_HXX
#include "names.hxx"
#include "polygon.hxx"
// process shape (write polygon to all intersecting tiles)
void tgSplitPolygon( const string& path, AreaType area,
// process polygon shape (chop up along tile boundaries and write each
// polygon piece to a file)
void tgChopPolygon( const string& path, AreaType area,
const TGPolygon& shape, bool preserve3d );
#endif // _SPLIT_HXX
#endif // _TG_CHOP_HXX

View file

@ -44,10 +44,10 @@ SG_USING_STD(vector);
#include <Geometry/rectangle.hxx>
#include <Geometry/util.hxx>
#include <Polygon/chop.hxx>
#include <Polygon/index.hxx>
#include <Polygon/names.hxx>
#include <Polygon/polygon.hxx>
#include <Polygon/split.hxx>
#include <e00/e00.hxx>
#ifdef _MSC_VER
@ -179,7 +179,7 @@ processPoints (const E00 &data, const tg::Rectangle &bounds,
}
tg::makePolygon(p, width, shape);
tgSplitPolygon(workDir, areaType, shape, false);
tgChopPolygon(workDir, areaType, shape, false);
}
}
@ -242,7 +242,7 @@ processLines (const E00 &data, const tg::Rectangle &bounds,
cout << " Minimum angle: "
<< (shape.minangle_contour(0) * SGD_RADIANS_TO_DEGREES) << endl;
tgSplitPolygon(workDir, areaType, shape, false);
tgChopPolygon(workDir, areaType, shape, false);
}
cout << "Done lines" << endl;
}
@ -309,7 +309,7 @@ processPolygons (const E00 &data, const tg::Rectangle &bounds,
0.0));
}
}
tgSplitPolygon(workDir, areaType, shape, false);
tgChopPolygon(workDir, areaType, shape, false);
}
}

View file

@ -31,10 +31,10 @@
#include <simgear/bucket/newbucket.hxx>
#include <simgear/debug/logstream.hxx>
#include <Polygon/chop.hxx>
#include <Polygon/index.hxx>
#include <Polygon/names.hxx>
#include <Polygon/polygon.hxx>
#include <Polygon/split.hxx>
#include <Polygon/simple_clip.hxx>
#include "gshhs_split.hxx"
@ -86,13 +86,13 @@ void split_and_shift_chunk( const string& path, AreaType area,
upper_shape.shift( -360, 0 );
SG_LOG ( SG_GENERAL, SG_INFO, "Processing lower shape" );
tgSplitPolygon(path, area, lower_shape, false);
tgChopPolygon(path, area, lower_shape, false);
SG_LOG ( SG_GENERAL, SG_INFO, "Processing center shape" );
tgSplitPolygon(path, area, center_shape, false);
tgChopPolygon(path, area, center_shape, false);
SG_LOG ( SG_GENERAL, SG_INFO, "Processing upper shape" );
tgSplitPolygon(path, area, upper_shape, false);
tgChopPolygon(path, area, upper_shape, false);
}

View file

@ -38,7 +38,6 @@
#include <Polygon/index.hxx>
#include <Polygon/names.hxx>
#include <Polygon/polygon.hxx>
#include <Polygon/split.hxx>
#ifdef _MSC_VER
# include <Win32/mkdir.hpp>

View file

@ -39,8 +39,8 @@
#include <Array/array.hxx>
#include <Geometry/trinodes.hxx>
#include <Output/output.hxx>
#include <Polygon/chop.hxx>
#include <Polygon/index.hxx>
#include <Polygon/split.hxx>
#include <Polygon/polygon.hxx>
SG_USING_STD(string);
@ -329,7 +329,7 @@ int main( int argc, char **argv ) {
poly_index_init( counter_file );
string holepath = root + "/PhotoArea";
tgSplitPolygon( holepath, HoleArea, hole, false );
tgChopPolygon( holepath, HoleArea, hole, false );
return 0;
}

View file

@ -29,10 +29,10 @@
#include <simgear/debug/logstream.hxx>
#include <Polygon/chop.hxx>
#include <Polygon/index.hxx>
#include <Polygon/names.hxx>
#include <Polygon/polygon.hxx>
#include <Polygon/split.hxx>
#include <shapelib/shapefil.h>
#ifdef _MSC_VER
@ -417,7 +417,7 @@ int main( int argc, char **argv ) {
// holes are preserved
area = get_area_type( force_area_type );
tgSplitPolygon(work_dir, area, shape, false);
tgChopPolygon(work_dir, area, shape, false);
} else if ( area == OceanArea ) {
// interior of polygon is ocean, holes are islands
@ -425,7 +425,7 @@ int main( int argc, char **argv ) {
// Ocean data now comes from GSHHS so we want to ignore
// all other ocean data
// tgSplitPolygon(work_dir, area, shape, false);
// tgChopPolygon(work_dir, area, shape, false);
} else if ( area == VoidArea ) {
// interior is ????
@ -437,7 +437,7 @@ int main( int argc, char **argv ) {
// exit(-1);
}
// tgSplitPolygon(work_dir, area, shape, false);
// tgChopPolygon(work_dir, area, shape, false);
} else if ( area == NullArea ) {
// interior is ????
@ -449,9 +449,9 @@ int main( int argc, char **argv ) {
// exit(-1);
}
// tgSplitPolygon(work_dir, area, shape, false);
// tgChopPolygon(work_dir, area, shape, false);
} else {
tgSplitPolygon(work_dir, area, shape, false);
tgChopPolygon(work_dir, area, shape, false);
}
}

View file

@ -29,10 +29,10 @@
#include <simgear/debug/logstream.hxx>
#include <Polygon/chop.hxx>
#include <Polygon/index.hxx>
#include <Polygon/names.hxx>
#include <Polygon/polygon.hxx>
#include <Polygon/split.hxx>
#include <shapelib/shapefil.h>
#ifdef _MSC_VER
@ -299,7 +299,7 @@ int main( int argc, char **argv ) {
// holes are preserved
area = get_area_type( force_area_type );
tgSplitPolygon(work_dir, area, shape, false);
tgChopPolygon(work_dir, area, shape, false);
} else if ( area == OceanArea ) {
// interior of polygon is ocean, holes are islands
@ -307,7 +307,7 @@ int main( int argc, char **argv ) {
// Ocean data now comes from GSHHS so we want to ignore
// all other ocean data
// tgSplitPolygon(work_dir, area, shape, false);
// tgChopPolygon(work_dir, area, shape, false);
} else if ( area == VoidArea ) {
// interior is ????
@ -319,7 +319,7 @@ int main( int argc, char **argv ) {
// exit(-1);
}
// tgSplitPolygon(work_dir, area, shape, false);
// tgChopPolygon(work_dir, area, shape, false);
} else if ( area == NullArea ) {
// interior is ????
@ -331,9 +331,9 @@ int main( int argc, char **argv ) {
// exit(-1);
}
// tgSplitPolygon(work_dir, area, shape, false);
// tgChopPolygon(work_dir, area, shape, false);
} else {
tgSplitPolygon(work_dir, area, shape, false);
tgChopPolygon(work_dir, area, shape, false);
}
}

View file

@ -44,10 +44,10 @@ SG_USING_STD(vector);
#include <Geometry/line.hxx>
#include <Geometry/util.hxx>
#include <Polygon/chop.hxx>
#include <Polygon/index.hxx>
#include <Polygon/names.hxx>
#include <Polygon/polygon.hxx>
#include <Polygon/split.hxx>
#include <vpf/vpf.hxx>
#ifdef _MSC_VER
@ -537,7 +537,7 @@ main (int argc, const char **argv)
if ( max_segment > 1.0 ) {
shape = tgPolygonSplitLongEdges( shape, max_segment );
}
tgSplitPolygon(work_dir, material_type, shape, false);
tgChopPolygon(work_dir, material_type, shape, false);
}
}
}
@ -550,7 +550,10 @@ main (int argc, const char **argv)
if (mask.total_size() >= 3) {
cout << "Inverse polygon with " << mask.total_size() << " points in "
<< mask.contours() << " contour(s)" << endl;
tgSplitPolygon(work_dir, material_type, mask, false);
if ( max_segment > 1.0 ) {
mask = tgPolygonSplitLongEdges( mask, max_segment );
}
tgChopPolygon(work_dir, material_type, mask, false);
} else {
cout << "Inverse polygon is empty" << endl;
}

View file

@ -9,10 +9,10 @@
#include <simgear/structure/exception.hxx>
#include <Geometry/util.hxx>
#include <Polygon/chop.hxx>
#include <Polygon/index.hxx>
#include <Polygon/names.hxx>
#include <Polygon/polygon.hxx>
#include <Polygon/split.hxx>
#include <stdlib.h>
@ -65,7 +65,7 @@ add_point (SGPropertyNode_ptr node)
TGPolygon poly;
tg::makePolygon(p, node->getIntValue("width", 500), poly);
poly = tgPolygonInt(poly, bounds_poly);
tgSplitPolygon(".", material, poly, false);
tgChopPolygon(".", material, poly, false);
}
static void
@ -86,7 +86,7 @@ add_line (SGPropertyNode_ptr node)
TGPolygon poly;
tg::makePolygon(line, node->getIntValue("width", 10), poly);
poly = tgPolygonInt(poly, bounds_poly);
tgSplitPolygon(".", material, poly, false);
tgChopPolygon(".", material, poly, false);
}
static void
@ -108,7 +108,7 @@ add_polygon (SGPropertyNode_ptr node)
poly.set_hole_flag(i, contour_node->getBoolValue("hole", false));
}
poly = tgPolygonInt(poly, bounds_poly);
tgSplitPolygon(".", material, poly, false);
tgChopPolygon(".", material, poly, false);
}
void