1
0
Fork 0

library reorg step 1

- no more Geometry
- delete unused files
This commit is contained in:
Peter Sadrozinski 2012-12-14 22:20:24 -05:00
parent 4b97381559
commit ce1f89f832
60 changed files with 209 additions and 6338 deletions

View file

@ -26,7 +26,7 @@ add_executable(genapts850
)
target_link_libraries(genapts850
Polygon Geometry
Polygon
Array
${GDAL_LIBRARY}
${SIMGEAR_CORE_LIBRARIES}

View file

@ -288,8 +288,6 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
// runway lights
tglightcontour_list rwy_lights;
//Point3D p;
bool make_shapefiles = false;
// parse main airport information
@ -1064,114 +1062,6 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
TGAptSurface apt_surf( root, elev_src, aptBounds, average );
GENAPT_LOG(SG_GENERAL, SG_DEBUG, "Airport surface created");
// add base skirt (to hide potential cracks)
// this has to happen after we've calculated the node elevations
// but before we convert to wgs84 coordinates
#if 0 // do we still need a skirt?
int uindex, lindex;
for ( unsigned int i = 0; i < divided_base.Contours(); ++i )
{
strip_v.clear();
strip_n.clear();
strip_tc.clear();
// prime the pump ...
uindex = nodes.find( divided_base.GetNode( i, 0 ) );
if ( uindex >= 0 )
{
Point3D lower = geod_nodes[uindex] - Point3D(0, 0, 20);
GENAPT_LOG(SG_GENERAL, SG_DEBUG, geod_nodes[uindex] << " <-> " << lower);
lindex = nodes.simple_add( lower );
geod_nodes.push_back( lower );
strip_v.push_back( uindex );
strip_v.push_back( lindex );
// use 'the' normal. We are pushing on two nodes so we
// need to push on two normals.
index = normals.unique_add( vn );
strip_n.push_back( index );
strip_n.push_back( index );
}
else
{
string message = "Ooops missing node when building skirt (in init)";
GENAPT_LOG( SG_GENERAL, SG_ALERT, message << " " << p );
throw sg_exception( message );
}
// loop through the list
for ( unsigned int j = 1; j < divided_base.ContourSize(i); ++j )
{
p = Point3D::fromSGGeod( divided_base.GetNode( i, j ) );
uindex = nodes.find( p );
if ( uindex >= 0 )
{
Point3D lower = geod_nodes[uindex] - Point3D(0, 0, 20);
GENAPT_LOG(SG_GENERAL, SG_DEBUG, geod_nodes[uindex] << " <-> " << lower);
lindex = nodes.simple_add( lower );
geod_nodes.push_back( lower );
strip_v.push_back( uindex );
strip_v.push_back( lindex );
index = normals.unique_add( vn );
strip_n.push_back( index );
strip_n.push_back( index );
}
else
{
string message = "Ooops missing node when building skirt (in loop)";
GENAPT_LOG( SG_GENERAL, SG_ALERT, message << " " << p );
throw sg_exception( message );
}
}
// close off the loop
p = Point3D::fromSGGeod( divided_base.GetNode( i, 0 ) );
uindex = nodes.find( p );
if ( uindex >= 0 )
{
Point3D lower = geod_nodes[uindex] - Point3D(0, 0, 20);
GENAPT_LOG(SG_GENERAL, SG_DEBUG, geod_nodes[uindex] << " <-> " << lower);
lindex = nodes.simple_add( lower );
geod_nodes.push_back( lower );
strip_v.push_back( uindex );
strip_v.push_back( lindex );
index = normals.unique_add( vn );
strip_n.push_back( index );
strip_n.push_back( index );
}
else
{
string message = "Ooops missing node when building skirt (at end)";
GENAPT_LOG( SG_GENERAL, SG_ALERT, message << " " << p );
throw sg_exception( message );
}
strips_v.push_back( strip_v );
strips_n.push_back( strip_n );
strip_materials.push_back( "Grass" );
std::vector < SGGeod > geodNodes;
for ( unsigned int j = 0; j < nodes.get_node_list().size(); j++ )
{
Point3D node = nodes.get_node_list()[j];
geodNodes.push_back( SGGeod::fromDegM( node.x(), node.y(), node.z() ) );
}
base_txs.clear();
base_txs = sgCalcTexCoords( b, geodNodes, strip_v );
base_tc.clear();
for ( unsigned int j = 0; j < base_txs.size(); ++j )
{
index = texcoords.simple_add( base_txs[j] );
base_tc.push_back( index );
}
strips_tc.push_back( base_tc );
}
#endif
// add light points
// pass one, calculate raw elevations from Array
for ( unsigned int i = 0; i < rwy_lights.size(); ++i ) {
@ -1179,28 +1069,6 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
double light_elevation = calc_elevation( apt_surf, rwy_lights[i].GetNode(j), 0.0 );
rwy_lights[i].SetElevation(j, light_elevation);
}
// TODO : It doesn't look like this does anything... got back in history and make sure...
//string flag = rwy_lights[i].GetFlag();
//if ( flag != (string)"" )
//{
// GENAPT_LOG(SG_GENERAL, SG_INFO, " flag " << flag);
// double max = -9999;
// const_elev_map_iterator it = elevation_map.find( flag );
// if ( it != elevation_map.end() )
// {
// max = elevation_map[flag];
// }
// for ( unsigned int j = 0; j < geod_light_nodes.size(); ++j )
// {
// if ( geod_light_nodes[j].z() > max )
// {
// max = geod_light_nodes[j].z();
// }
// }
// elevation_map[flag] = max;
// GENAPT_LOG( SG_GENERAL, SG_INFO, " " << flag << " max = " << max );
//}
}
GENAPT_LOG(SG_GENERAL, SG_INFO, "Done with lighting calc_elevations() num light polys is " << rwy_lights.size() );

View file

@ -24,7 +24,7 @@
# include <config.h>
#endif
#include <Lib/Geometry/TNT/jama_qr.h>
#include <Lib/Polygon/TNT/jama_qr.h>
#include <simgear/compiler.h>
#include <simgear/constants.h>

View file

@ -26,7 +26,7 @@
#include <string>
#include <Lib/Geometry/TNT/tnt_array2d.h>
#include <Lib/Polygon/TNT/tnt_array2d.h>
#include <simgear/debug/logstream.hxx>
#include <Lib/Polygon/polygon.hxx>

View file

@ -3,7 +3,6 @@
#include <simgear/debug/logstream.hxx>
#include <Polygon/polygon.hxx>
#include <Geometry/poly_support.hxx>
#include "global.hxx"
#include "beznode.hxx"

View file

@ -17,8 +17,6 @@
#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include <Geometry/poly_support.hxx>
#include "global.hxx"
#include "apt_math.hxx"
#include "helipad.hxx"

View file

@ -1,7 +1,5 @@
#include <stdlib.h>
#include <Geometry/poly_support.hxx>
#include "global.hxx"
#include "beznode.hxx"
#include "linearfeature.hxx"

View file

@ -22,7 +22,6 @@
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sgstream.hxx>
#include <Geometry/poly_support.hxx>
#include <Include/version.h>
#include "scheduler.hxx"
@ -306,7 +305,7 @@ int main(int argc, char **argv)
}
// Initialize shapefile support (for debugging)
tgShapefileInit();
tgShapefile::Init();
sg_gzifstream in( input_file );
if ( !in.is_open() )

View file

@ -5,7 +5,6 @@
#include <simgear/bucket/newbucket.hxx>
#include <simgear/math/SGGeodesy.hxx>
#include <Geometry/poly_support.hxx>
#include <Polygon/polygon.hxx>
#include "global.hxx"

View file

@ -26,8 +26,6 @@
#include <boost/lexical_cast.hpp>
#include <Geometry/poly_support.hxx>
#include "global.hxx"
#include "beznode.hxx"
#include "runway.hxx"

View file

@ -10,7 +10,7 @@
#include <simgear/timing/timestamp.hxx>
#include <simgear/threads/SGThread.hxx>
#include <simgear/threads/SGQueue.hxx>
#include <Geometry/rectangle.hxx>
#include <Polygon/rectangle.hxx>
#include "airport.hxx"
#define P_STATE_INIT (0)

View file

@ -27,7 +27,7 @@ set_target_properties(tg-construct PROPERTIES
"DEFAULT_USGS_MAPFILE=\"${PKGDATADIR}/usgsmap.txt\";DEFAULT_PRIORITIES_FILE=\"${PKGDATADIR}/default_priorities.txt\"" )
target_link_libraries(tg-construct
Polygon Geometry
Polygon
Array landcover
${Boost_LIBRARIES}
${GDAL_LIBRARY}
@ -43,7 +43,7 @@ add_executable(cliptst
cliptst.cxx)
target_link_libraries(cliptst
Polygon Geometry
Polygon
${GDAL_LIBRARY}
${SIMGEAR_CORE_LIBRARIES}
${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}

View file

@ -14,10 +14,6 @@
#include <Polygon/clipper.hpp>
#include <Polygon/polygon.hxx>
#include <Geometry/poly_support.hxx>
//#include "windows.h"
//#include <conio.h>
//---------------------------------------------------------------------------
@ -263,7 +259,7 @@ int main(int argc, char* argv[])
}
if (show_svg) {
tgShapefileInit();
tgShapefile::Init();
clipper_to_shapefile( subject, "./clptst_subject" );
clipper_to_shapefile( clip, "./clptst_clip" );
}

View file

@ -24,7 +24,6 @@
#include <simgear/debug/logstream.hxx>
#include <Include/version.h>
#include <Geometry/poly_support.hxx>
#include "tgconstruct.hxx"
#include "usgs.hxx"
@ -73,7 +72,7 @@ int main(int argc, char **argv) {
sglog().setLogLevels( SG_ALL, SG_INFO );
// Initialize shapefile support (for debugging)
tgShapefileInit();
tgShapefile::Init();
//
// Parse the command-line arguments.

View file

@ -34,7 +34,7 @@
#define TG_MAX_AREA_TYPES 128
#include <Array/array.hxx>
#include <Geometry/tg_nodes.hxx>
#include <Polygon/tg_nodes.hxx>
#include <landcover/landcover.hxx>
#include "tglandclass.hxx"

View file

@ -30,9 +30,6 @@
//#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
#include <Geometry/poly_support.hxx>
#include <Geometry/poly_extra.hxx>
#include "tgconstruct.hxx"
using std::string;

View file

@ -27,7 +27,6 @@
#include <sstream>
#include <simgear/debug/logstream.hxx>
#include <Geometry/poly_support.hxx>
#include "tgconstruct.hxx"

View file

@ -25,7 +25,6 @@
#endif
#include <simgear/debug/logstream.hxx>
#include <Geometry/poly_support.hxx>
#include "tgconstruct.hxx"
@ -81,7 +80,7 @@ void TGConstruct::calc_normals( std::vector<SGGeod>& geod_nodes, std::vector<SGV
SGVec3d v2 = wgs84_nodes[ poly.GetTriIdx( tri, 1 ) ];
SGVec3d v3 = wgs84_nodes[ poly.GetTriIdx( tri, 2 ) ];
area = triangle_area( g1, g2, g3 );
area = tgTriangle::area( g1, g2, g3 );
normal = calc_normal( area, v1, v2, v3 );
poly.SetTriFaceArea( tri, area );

View file

@ -29,8 +29,6 @@
#include <simgear/misc/sg_dir.hxx>
#include <simgear/debug/logstream.hxx>
#include <Geometry/poly_support.hxx>
#include "tgconstruct.hxx"
using std::string;

View file

@ -30,8 +30,6 @@
#include <simgear/debug/logstream.hxx>
#include <simgear/io/lowlevel.hxx>
#include <Geometry/poly_support.hxx>
#include "tgconstruct.hxx"
using std::string;
@ -134,7 +132,7 @@ void TGConstruct::WriteNeighborFaces( gzFile& fp, const SGGeod& pt ) const
SGVec3d const& wgs_p2 = nodes[ poly.GetTriIdx( tri, 0) ].GetWgs84();
SGVec3d const& wgs_p3 = nodes[ poly.GetTriIdx( tri, 0) ].GetWgs84();
double face_area = triangle_area( p1, p2, p3 );
double face_area = tgTriangle::area( p1, p2, p3 );
SGVec3f face_normal = calc_normal( face_area, wgs_p1, wgs_p2, wgs_p3 );
sgWriteDouble( fp, face_area );

View file

@ -28,7 +28,7 @@
#include <simgear/math/sg_types.hxx>
#include <simgear/misc/sgstream.hxx>
#include <Lib/Geometry/point3d.hxx>
#include <Lib/Polygon/point3d.hxx>
class TGArray {

View file

@ -2,7 +2,6 @@ include_directories(${PROJECT_SOURCE_DIR}/src/Lib)
add_subdirectory(Array)
add_subdirectory(DEM)
add_subdirectory(Geometry)
add_subdirectory(HGT)
add_subdirectory(Polygon)
add_subdirectory(landcover)

View file

@ -1,22 +0,0 @@
include_directories(${GDAL_INCLUDE_DIR})
add_library(Geometry STATIC
contour_tree.cxx
line.cxx
poly_support.cxx
poly_extra.cxx
poly_cgal.cxx
rectangle.cxx
tg_nodes.cxx
trinodes.cxx
trisegs.cxx
contour_tree.hxx
line.hxx
point3d.hxx
poly_support.hxx
poly_extra.hxx
rectangle.hxx
tg_nodes.hxx
trinodes.hxx
trisegs.hxx
)

View file

@ -1,326 +0,0 @@
#ifndef JAMA_QR_H
#define JAMA_QR_H
#include "tnt_array1d.h"
#include "tnt_array2d.h"
#include "tnt_math_utils.h"
namespace JAMA
{
/**
<p>
Classical QR Decompisition:
for an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n
orthogonal matrix Q and an n-by-n upper triangular matrix R so that
A = Q*R.
<P>
The QR decompostion always exists, even if the matrix does not have
full rank, so the constructor will never fail. The primary use of the
QR decomposition is in the least squares solution of nonsquare systems
of simultaneous linear equations. This will fail if isFullRank()
returns 0 (false).
<p>
The Q and R factors can be retrived via the getQ() and getR()
methods. Furthermore, a solve() method is provided to find the
least squares solution of Ax=b using the QR factors.
<p>
(Adapted from JAMA, a Java Matrix Library, developed by jointly
by the Mathworks and NIST; see http://math.nist.gov/javanumerics/jama).
*/
template <class Real>
class QR {
/** Array for internal storage of decomposition.
@serial internal array storage.
*/
TNT::Array2D<Real> QR_;
/** Row and column dimensions.
@serial column dimension.
@serial row dimension.
*/
int m, n;
/** Array for internal storage of diagonal of R.
@serial diagonal of R.
*/
TNT::Array1D<Real> Rdiag;
public:
/**
Create a QR factorization object for A.
@param A rectangular (m>=n) matrix.
*/
QR(const TNT::Array2D<Real> &A) /* constructor */
{
QR_ = A.copy();
m = A.dim1();
n = A.dim2();
Rdiag = TNT::Array1D<Real>(n);
int i=0, j=0, k=0;
// Main loop.
for (k = 0; k < n; k++) {
// Compute 2-norm of k-th column without under/overflow.
Real nrm = 0;
for (i = k; i < m; i++) {
nrm = TNT::hypot(nrm,QR_[i][k]);
}
if (nrm != 0.0) {
// Form k-th Householder vector.
if (QR_[k][k] < 0) {
nrm = -nrm;
}
for (i = k; i < m; i++) {
QR_[i][k] /= nrm;
}
QR_[k][k] += 1.0;
// Apply transformation to remaining columns.
for (j = k+1; j < n; j++) {
Real s = 0.0;
for (i = k; i < m; i++) {
s += QR_[i][k]*QR_[i][j];
}
s = -s/QR_[k][k];
for (i = k; i < m; i++) {
QR_[i][j] += s*QR_[i][k];
}
}
}
Rdiag[k] = -nrm;
}
}
/**
Flag to denote the matrix is of full rank.
@return 1 if matrix is full rank, 0 otherwise.
*/
int isFullRank() const
{
for (int j = 0; j < n; j++)
{
if (Rdiag[j] == 0)
return 0;
}
return 1;
}
/**
Retreive the Householder vectors from QR factorization
@returns lower trapezoidal matrix whose columns define the reflections
*/
TNT::Array2D<Real> getHouseholder (void) const
{
TNT::Array2D<Real> H(m,n);
/* note: H is completely filled in by algorithm, so
initializaiton of H is not necessary.
*/
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (i >= j) {
H[i][j] = QR_[i][j];
} else {
H[i][j] = 0.0;
}
}
}
return H;
}
/** Return the upper triangular factor, R, of the QR factorization
@return R
*/
TNT::Array2D<Real> getR() const
{
TNT::Array2D<Real> R(n,n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i < j) {
R[i][j] = QR_[i][j];
} else if (i == j) {
R[i][j] = Rdiag[i];
} else {
R[i][j] = 0.0;
}
}
}
return R;
}
/**
Generate and return the (economy-sized) orthogonal factor
@param Q the (ecnomy-sized) orthogonal factor (Q*R=A).
*/
TNT::Array2D<Real> getQ() const
{
int i=0, j=0, k=0;
TNT::Array2D<Real> Q(m,n);
for (k = n-1; k >= 0; k--) {
for (i = 0; i < m; i++) {
Q[i][k] = 0.0;
}
Q[k][k] = 1.0;
for (j = k; j < n; j++) {
if (QR_[k][k] != 0) {
Real s = 0.0;
for (i = k; i < m; i++) {
s += QR_[i][k]*Q[i][j];
}
s = -s/QR_[k][k];
for (i = k; i < m; i++) {
Q[i][j] += s*QR_[i][k];
}
}
}
}
return Q;
}
/** Least squares solution of A*x = b
@param B m-length array (vector).
@return x n-length array (vector) that minimizes the two norm of Q*R*X-B.
If B is non-conformant, or if QR.isFullRank() is false,
the routine returns a null (0-length) vector.
*/
TNT::Array1D<Real> solve(const TNT::Array1D<Real> &b) const
{
if (b.dim1() != m) /* arrays must be conformant */
return TNT::Array1D<Real>();
if ( !isFullRank() ) /* matrix is rank deficient */
{
return TNT::Array1D<Real>();
}
TNT::Array1D<Real> x = b.copy();
// Compute Y = transpose(Q)*b
for (int k = 0; k < n; k++)
{
Real s = 0.0;
for (int i = k; i < m; i++)
{
s += QR_[i][k]*x[i];
}
s = -s/QR_[k][k];
for (int i = k; i < m; i++)
{
x[i] += s*QR_[i][k];
}
}
// Solve R*X = Y;
for (int k = n-1; k >= 0; k--)
{
x[k] /= Rdiag[k];
for (int i = 0; i < k; i++) {
x[i] -= x[k]*QR_[i][k];
}
}
/* return n x nx portion of X */
TNT::Array1D<Real> x_(n);
for (int i=0; i<n; i++)
x_[i] = x[i];
return x_;
}
/** Least squares solution of A*X = B
@param B m x k Array (must conform).
@return X n x k Array that minimizes the two norm of Q*R*X-B. If
B is non-conformant, or if QR.isFullRank() is false,
the routine returns a null (0x0) array.
*/
TNT::Array2D<Real> solve(const TNT::Array2D<Real> &B) const
{
if (B.dim1() != m) /* arrays must be conformant */
return TNT::Array2D<Real>(0,0);
if ( !isFullRank() ) /* matrix is rank deficient */
{
return TNT::Array2D<Real>(0,0);
}
int nx = B.dim2();
TNT::Array2D<Real> X = B.copy();
int i=0, j=0, k=0;
// Compute Y = transpose(Q)*B
for (k = 0; k < n; k++) {
for (j = 0; j < nx; j++) {
Real s = 0.0;
for (i = k; i < m; i++) {
s += QR_[i][k]*X[i][j];
}
s = -s/QR_[k][k];
for (i = k; i < m; i++) {
X[i][j] += s*QR_[i][k];
}
}
}
// Solve R*X = Y;
for (k = n-1; k >= 0; k--) {
for (j = 0; j < nx; j++) {
X[k][j] /= Rdiag[k];
}
for (i = 0; i < k; i++) {
for (j = 0; j < nx; j++) {
X[i][j] -= X[k][j]*QR_[i][k];
}
}
}
/* return n x nx portion of X */
TNT::Array2D<Real> X_(n,nx);
for (i=0; i<n; i++)
for (j=0; j<nx; j++)
X_[i][j] = X[i][j];
return X_;
}
};
}
// namespace JAMA
#endif
// JAMA_QR__H

View file

@ -1,301 +0,0 @@
/*
*
* Template Numerical Toolkit (TNT)
*
* Mathematical and Computational Sciences Division
* National Institute of Technology,
* Gaithersburg, MD USA
*
*
* This software was developed at the National Institute of Standards and
* Technology (NIST) by employees of the Federal Government in the course
* of their official duties. Pursuant to title 17 Section 105 of the
* United States Code, this software is not subject to copyright protection
* and is in the public domain. NIST assumes no responsibility whatsoever for
* its use by other parties, and makes no guarantees, expressed or implied,
* about its quality, reliability, or any other characteristic.
*
*/
#ifndef TNT_ARRAY1D_H
#define TNT_ARRAY1D_H
//#include <cstdlib>
#include <iostream>
#ifdef TNT_BOUNDS_CHECK
#include <assert.h>
#endif
#include "tnt_i_refvec.h"
namespace TNT
{
template <class T>
class Array1D
{
private:
/* ... */
i_refvec<T> v_;
int n_;
T* data_; /* this normally points to v_.begin(), but
* could also point to a portion (subvector)
* of v_.
*/
void copy_(T* p, const T* q, int len) const;
void set_(T* begin, T* end, const T& val);
public:
typedef T value_type;
Array1D();
explicit Array1D(int n);
Array1D(int n, const T &a);
Array1D(int n, T *a);
inline Array1D(const Array1D &A);
inline operator T*();
inline operator const T*();
inline Array1D & operator=(const T &a);
inline Array1D & operator=(const Array1D &A);
inline Array1D & ref(const Array1D &A);
Array1D copy() const;
Array1D & inject(const Array1D & A);
inline T& operator[](int i);
inline T& operator()(int i);
inline const T& operator[](int i) const;
inline const T& operator()(int i) const;
inline int dim1() const;
inline int dim() const;
~Array1D();
/* ... extended interface ... */
inline int ref_count() const;
inline Array1D<T> subarray(int i0, int i1);
};
template <class T>
Array1D<T>::Array1D() : v_(), n_(0), data_(0) {}
template <class T>
Array1D<T>::Array1D(const Array1D<T> &A) : v_(A.v_), n_(A.n_),
data_(A.data_)
{
#ifdef TNT_DEBUG
std::cout << "Created Array1D(const Array1D<T> &A) \n";
#endif
}
template <class T>
Array1D<T>::Array1D(int n) : v_(n), n_(n), data_(v_.begin())
{
#ifdef TNT_DEBUG
std::cout << "Created Array1D(int n) \n";
#endif
}
template <class T>
Array1D<T>::Array1D(int n, const T &val) : v_(n), n_(n), data_(v_.begin())
{
#ifdef TNT_DEBUG
std::cout << "Created Array1D(int n, const T& val) \n";
#endif
set_(data_, data_+ n, val);
}
template <class T>
Array1D<T>::Array1D(int n, T *a) : v_(a), n_(n) , data_(v_.begin())
{
#ifdef TNT_DEBUG
std::cout << "Created Array1D(int n, T* a) \n";
#endif
}
template <class T>
inline Array1D<T>::operator T*()
{
return &(v_[0]);
}
template <class T>
inline Array1D<T>::operator const T*()
{
return &(v_[0]);
}
template <class T>
inline T& Array1D<T>::operator[](int i)
{
#ifdef TNT_BOUNDS_CHECK
assert(i>= 0);
assert(i < n_);
#endif
return data_[i];
}
template <class T>
inline const T& Array1D<T>::operator[](int i) const
{
#ifdef TNT_BOUNDS_CHECK
assert(i>= 0);
assert(i < n_);
#endif
return data_[i];
}
template <class T>
inline T& Array1D<T>::operator()(int i)
{
#ifdef TNT_BOUNDS_CHECK
assert(i>= 0);
assert(i < n_);
#endif
return data_[i-1];
}
template <class T>
inline const T& Array1D<T>::operator()(int i) const
{
#ifdef TNT_BOUNDS_CHECK
assert(i>= 0);
assert(i < n_);
#endif
return data_[i-1];
}
template <class T>
Array1D<T> & Array1D<T>::operator=(const T &a)
{
set_(data_, data_+n_, a);
return *this;
}
template <class T>
Array1D<T> Array1D<T>::copy() const
{
Array1D A( n_);
copy_(A.data_, data_, n_);
return A;
}
template <class T>
Array1D<T> & Array1D<T>::inject(const Array1D &A)
{
if (A.n_ == n_)
copy_(data_, A.data_, n_);
return *this;
}
template <class T>
Array1D<T> & Array1D<T>::ref(const Array1D<T> &A)
{
if (this != &A)
{
v_ = A.v_; /* operator= handles the reference counting. */
n_ = A.n_;
data_ = A.data_;
}
return *this;
}
template <class T>
Array1D<T> & Array1D<T>::operator=(const Array1D<T> &A)
{
return ref(A);
}
template <class T>
inline int Array1D<T>::dim1() const { return n_; }
template <class T>
inline int Array1D<T>::dim() const { return n_; }
template <class T>
Array1D<T>::~Array1D() {}
/* ............................ exented interface ......................*/
template <class T>
inline int Array1D<T>::ref_count() const
{
return v_.ref_count();
}
template <class T>
inline Array1D<T> Array1D<T>::subarray(int i0, int i1)
{
if (((i0 >= 0) && (i1 < n_)) || (i0 <= i1))
{
Array1D<T> X(*this); /* create a new instance of this array. */
X.n_ = i1-i0+1;
X.data_ += i0;
return X;
}
else
{
return Array1D<T>();
}
}
/* private internal functions */
template <class T>
void Array1D<T>::set_(T* begin, T* end, const T& a)
{
for (T* p=begin; p<end; p++)
*p = a;
}
template <class T>
void Array1D<T>::copy_(T* p, const T* q, int len) const
{
T *end = p + len;
while (p<end )
*p++ = *q++;
}
} /* namespace TNT */
#endif
/* TNT_ARRAY1D_H */

View file

@ -1,451 +0,0 @@
/*
*
* Template Numerical Toolkit (TNT)
*
* Mathematical and Computational Sciences Division
* National Institute of Technology,
* Gaithersburg, MD USA
*
*
* This software was developed at the National Institute of Standards and
* Technology (NIST) by employees of the Federal Government in the course
* of their official duties. Pursuant to title 17 Section 105 of the
* United States Code, this software is not subject to copyright protection
* and is in the public domain. NIST assumes no responsibility whatsoever for
* its use by other parties, and makes no guarantees, expressed or implied,
* about its quality, reliability, or any other characteristic.
*
*/
#ifndef TNT_ARRAY2D_H
#define TNT_ARRAY2D_H
#include <cstdlib>
#include <iostream>
#ifdef TNT_BOUNDS_CHECK
#include <assert.h>
#endif
#include "tnt_array1d.h"
namespace TNT
{
/**
Ttwo-dimensional numerical array which
looks like a conventional C multiarray.
Storage corresponds to C (row-major) ordering.
Elements are accessed via A[i][j] notation for 0-based indexing,
and A(i,j) for 1-based indexing..
<p>
Array assignment is by reference (i.e. shallow assignment).
That is, B=A implies that the A and B point to the
same array, so modifications to the elements of A
will be reflected in B. If an independent copy
is required, then B = A.copy() can be used. Note
that this facilitates returning arrays from functions
without relying on compiler optimizations to eliminate
extensive data copying.
<p>
The indexing and layout of this array object makes
it compatible with C and C++ algorithms that utilize
the familiar C[i][j] notation. This includes numerous
textbooks, such as Numercial Recipes, and various
public domain codes.
*/
template <class T>
class Array2D
{
private:
Array1D<T> data_;
Array1D<T*> v_;
int m_;
int n_;
public:
/**
Used to determined the data type of array entries. This is most
commonly used when requiring scalar temporaries in templated algorithms
that have TNT arrays as input. For example,
<pre>
template &lt class ArrayTwoD &gt
void foo(ArrayTwoD &A)
{
A::value_type first_entry = A[0][0];
...
}
</pre>
*/
typedef T value_type;
/**
Create a null array. This is <b>not</b> the same
as Array2D(0,0), which consumes some memory overhead.
*/
Array2D();
/**
Create a new (m x n) array, without initalizing elements. (This
encurs an O(1) operation cost, rather than a O(m*n) cost.)
@param m the first (row) dimension of the new matrix.
@param n the second (column) dimension of the new matrix.
*/
Array2D(int m, int n);
/**
Create a new (m x n) array, as a view of an existing one-dimensional
array stored in row-major order, i.e. right-most dimension varying fastest.
Note that the storage for this pre-existing array will
never be destroyed by TNT.
@param m the first (row) dimension of the new matrix.
@param n the second (column) dimension of the new matrix.
@param a the one dimensional C array to use as data storage for
the array.
*/
Array2D(int m, int n, T *a);
/**
Create a new (m x n) array, initializing array elements to
constant specified by argument. Most often used to
create an array of zeros, as in A(m, n, 0.0).
@param m the first (row) dimension of the new matrix.
@param n the second (column) dimension of the new matrix.
@param val the constant value to set all elements of the new array to.
*/
Array2D(int m, int n, const T &val);
/**
Copy constructor. Array data is NOT copied, but shared.
Thus, in Array2D B(A), subsequent changes to A will
be reflected in B. For an indepent copy of A, use
Array2D B(A.copy()), or B = A.copy(), instead.
*/
inline Array2D(const Array2D &A);
/**
Convert 2D array into a regular multidimensional C pointer. Most often
called automatically when calling C interfaces that expect things like
double** rather than Array2D<dobule>.
*/
inline operator T**();
/**
Convert a const 2D array into a const multidimensional C pointer.
Most often called automatically when calling C interfaces that expect
things like "const double**" rather than "const Array2D<dobule>&".
*/
inline operator const T**() const;
/**
Assign all elements of array the same value.
@param val the value to assign each element.
*/
inline Array2D & operator=(const T &val);
/**
Assign one Array2D to another. (This is a shallow-assignement operation,
and it is the identical semantics to ref(A).
@param A the array to assign this one to.
*/
inline Array2D & operator=(const Array2D &A);
inline Array2D & ref(const Array2D &A);
Array2D copy() const;
Array2D & inject(const Array2D & A);
inline T* operator[](int i);
inline const T* operator[](int i) const;
inline int dim1() const;
inline int dim2() const;
~Array2D();
/* extended interface (not part of the standard) */
inline int ref_count();
inline int ref_count_data();
inline int ref_count_dim1();
Array2D subarray(int i0, int i1, int j0, int j1);
};
/**
Create a new (m x n) array, WIHOUT initializing array elements.
To create an initialized array of constants, see Array2D(m,n,value).
<p>
This version avoids the O(m*n) initialization overhead and
is used just before manual assignment.
@param m the first (row) dimension of the new matrix.
@param n the second (column) dimension of the new matrix.
*/
template <class T>
Array2D<T>::Array2D() : data_(), v_(), m_(0), n_(0) {}
template <class T>
Array2D<T>::Array2D(const Array2D<T> &A) : data_(A.data_), v_(A.v_),
m_(A.m_), n_(A.n_) {}
template <class T>
Array2D<T>::Array2D(int m, int n) : data_(m*n), v_(m), m_(m), n_(n)
{
if (m>0 && n>0)
{
T* p = &(data_[0]);
for (int i=0; i<m; i++)
{
v_[i] = p;
p += n;
}
}
}
template <class T>
Array2D<T>::Array2D(int m, int n, const T &val) : data_(m*n), v_(m),
m_(m), n_(n)
{
if (m>0 && n>0)
{
data_ = val;
T* p = &(data_[0]);
for (int i=0; i<m; i++)
{
v_[i] = p;
p += n;
}
}
}
template <class T>
Array2D<T>::Array2D(int m, int n, T *a) : data_(m*n, a), v_(m), m_(m), n_(n)
{
if (m>0 && n>0)
{
T* p = &(data_[0]);
for (int i=0; i<m; i++)
{
v_[i] = p;
p += n;
}
}
}
template <class T>
inline T* Array2D<T>::operator[](int i)
{
#ifdef TNT_BOUNDS_CHECK
assert(i >= 0);
assert(i < m_);
#endif
return v_[i];
}
template <class T>
inline const T* Array2D<T>::operator[](int i) const
{
#ifdef TNT_BOUNDS_CHECK
assert(i >= 0);
assert(i < m_);
#endif
return v_[i];
}
template <class T>
Array2D<T> & Array2D<T>::operator=(const T &a)
{
/* non-optimzied, but will work with subarrays in future verions */
for (int i=0; i<m_; i++)
for (int j=0; j<n_; j++)
v_[i][j] = a;
return *this;
}
template <class T>
Array2D<T> Array2D<T>::copy() const
{
Array2D A(m_, n_);
for (int i=0; i<m_; i++)
for (int j=0; j<n_; j++)
A[i][j] = v_[i][j];
return A;
}
template <class T>
Array2D<T> & Array2D<T>::inject(const Array2D &A)
{
if (A.m_ == m_ && A.n_ == n_)
{
for (int i=0; i<m_; i++)
for (int j=0; j<n_; j++)
v_[i][j] = A[i][j];
}
return *this;
}
template <class T>
Array2D<T> & Array2D<T>::ref(const Array2D<T> &A)
{
if (this != &A)
{
v_ = A.v_;
data_ = A.data_;
m_ = A.m_;
n_ = A.n_;
}
return *this;
}
template <class T>
Array2D<T> & Array2D<T>::operator=(const Array2D<T> &A)
{
return ref(A);
}
template <class T>
inline int Array2D<T>::dim1() const { return m_; }
template <class T>
inline int Array2D<T>::dim2() const { return n_; }
template <class T>
Array2D<T>::~Array2D() {}
template <class T>
inline Array2D<T>::operator T**()
{
return &(v_[0]);
}
template <class T>
inline Array2D<T>::operator const T**() const
{
return static_cast<const T**>(&(v_[0]));
}
/* ............... extended interface ............... */
/**
Create a new view to a subarray defined by the boundaries
[i0][i0] and [i1][j1]. The size of the subarray is
(i1-i0) by (j1-j0). If either of these lengths are zero
or negative, the subarray view is null.
*/
template <class T>
Array2D<T> Array2D<T>::subarray(int i0, int i1, int j0, int j1)
{
Array2D<T> A;
int m = i1-i0+1;
int n = j1-j0+1;
/* if either length is zero or negative, this is an invalide
subarray. return a null view.
*/
if (m<1 || n<1)
return A;
A.data_ = data_;
A.m_ = m;
A.n_ = n;
A.v_ = Array1D<T*>(m);
T* p = &(data_[0]) + i0 * n_ + j0;
for (int i=0; i<m; i++)
{
A.v_[i] = p + i*n_;
}
return A;
}
template <class T>
inline int Array2D<T>::ref_count()
{
return ref_count_data();
}
template <class T>
inline int Array2D<T>::ref_count_data()
{
return data_.ref_count();
}
template <class T>
inline int Array2D<T>::ref_count_dim1()
{
return v_.ref_count();
}
} /* namespace TNT */
#endif
/* TNT_ARRAY2D_H */

View file

@ -1,243 +0,0 @@
/*
*
* Template Numerical Toolkit (TNT)
*
* Mathematical and Computational Sciences Division
* National Institute of Technology,
* Gaithersburg, MD USA
*
*
* This software was developed at the National Institute of Standards and
* Technology (NIST) by employees of the Federal Government in the course
* of their official duties. Pursuant to title 17 Section 105 of the
* United States Code, this software is not subject to copyright protection
* and is in the public domain. NIST assumes no responsibility whatsoever for
* its use by other parties, and makes no guarantees, expressed or implied,
* about its quality, reliability, or any other characteristic.
*
*/
#ifndef TNT_I_REFVEC_H
#define TNT_I_REFVEC_H
#include <cstdlib>
#include <iostream>
#ifdef TNT_BOUNDS_CHECK
#include <assert.h>
#endif
#ifndef NULL
#define NULL 0
#endif
namespace TNT
{
/*
Internal representation of ref-counted array. The TNT
arrays all use this building block.
<p>
If an array block is created by TNT, then every time
an assignment is made, the left-hand-side reference
is decreased by one, and the right-hand-side refernce
count is increased by one. If the array block was
external to TNT, the refernce count is a NULL pointer
regardless of how many references are made, since the
memory is not freed by TNT.
*/
template <class T>
class i_refvec
{
private:
T* data_;
int *ref_count_;
public:
i_refvec();
explicit i_refvec(int n);
inline i_refvec(T* data);
inline i_refvec(const i_refvec &v);
inline T* begin();
inline const T* begin() const;
inline T& operator[](int i);
inline const T& operator[](int i) const;
inline i_refvec<T> & operator=(const i_refvec<T> &V);
void copy_(T* p, const T* q, const T* e);
void set_(T* p, const T* b, const T* e);
inline int ref_count() const;
inline int is_null() const;
inline void destroy();
~i_refvec();
};
template <class T>
void i_refvec<T>::copy_(T* p, const T* q, const T* e)
{
for (T* t=p; q<e; t++, q++)
*t= *q;
}
template <class T>
i_refvec<T>::i_refvec() : data_(NULL), ref_count_(NULL) {}
/**
In case n is 0 or negative, it does NOT call new.
*/
template <class T>
i_refvec<T>::i_refvec(int n) : data_(NULL), ref_count_(NULL)
{
if (n >= 1)
{
#ifdef TNT_DEBUG
std::cout << "new data storage.\n";
#endif
data_ = new T[n];
ref_count_ = new int;
*ref_count_ = 1;
}
}
template <class T>
inline i_refvec<T>::i_refvec(const i_refvec<T> &V): data_(V.data_),
ref_count_(V.ref_count_)
{
if (V.ref_count_ != NULL)
(*(V.ref_count_))++;
}
template <class T>
i_refvec<T>::i_refvec(T* data) : data_(data), ref_count_(NULL) {}
template <class T>
inline T* i_refvec<T>::begin()
{
return data_;
}
template <class T>
inline const T& i_refvec<T>::operator[](int i) const
{
return data_[i];
}
template <class T>
inline T& i_refvec<T>::operator[](int i)
{
return data_[i];
}
template <class T>
inline const T* i_refvec<T>::begin() const
{
return data_;
}
template <class T>
i_refvec<T> & i_refvec<T>::operator=(const i_refvec<T> &V)
{
if (this == &V)
return *this;
if (ref_count_ != NULL)
{
(*ref_count_) --;
if ((*ref_count_) == 0)
destroy();
}
data_ = V.data_;
ref_count_ = V.ref_count_;
if (V.ref_count_ != NULL)
(*(V.ref_count_))++;
return *this;
}
template <class T>
void i_refvec<T>::destroy()
{
if (ref_count_ != NULL)
{
#ifdef TNT_DEBUG
std::cout << "destorying data... \n";
#endif
delete ref_count_;
#ifdef TNT_DEBUG
std::cout << "deleted ref_count_ ...\n";
#endif
if (data_ != NULL)
delete []data_;
#ifdef TNT_DEBUG
std::cout << "deleted data_[] ...\n";
#endif
data_ = NULL;
}
}
/*
* return 1 is vector is empty, 0 otherwise
*
* if is_null() is false and ref_count() is 0, then
*
*/
template<class T>
int i_refvec<T>::is_null() const
{
return (data_ == NULL ? 1 : 0);
}
/*
* returns -1 if data is external,
* returns 0 if a is NULL array,
* otherwise returns the positive number of vectors sharing
* this data space.
*/
template <class T>
int i_refvec<T>::ref_count() const
{
if (data_ == NULL)
return 0;
else
return (ref_count_ != NULL ? *ref_count_ : -1) ;
}
template <class T>
i_refvec<T>::~i_refvec()
{
if (ref_count_ != NULL)
{
(*ref_count_)--;
if (*ref_count_ == 0)
destroy();
}
}
} /* namespace TNT */
#endif
/* TNT_I_REFVEC_H */

View file

@ -1,37 +0,0 @@
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
/* needed for abs(), sqrt() below */
#include <cmath>
namespace TNT
{
using namespace std;
/**
@returns hypotenuse of real (non-complex) scalars a and b by
avoiding underflow/overflow
using (a * sqrt( 1 + (b/a) * (b/a))), rather than
sqrt(a*a + b*b).
*/
template <class Real>
Real hypot(const Real &a, const Real &b)
{
if (a== 0)
return abs(b);
else
{
Real c = b/a;
return abs(a) * sqrt(1 + c*c);
}
}
} /* TNT namespace */
#endif
/* MATH_UTILS_H */

View file

@ -1,49 +0,0 @@
// contour_tree.cxx -- routines for building a contour tree showing
// which contours are inside if which contours
//
// Written by Curtis Olson, started June 2000.
//
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: contour_tree.cxx,v 1.3 2004-11-19 22:25:50 curt Exp $
#include "contour_tree.hxx"
// Constructor
TGContourNode::TGContourNode() {
kids.clear();
}
// Constructor
TGContourNode::TGContourNode( int n ) {
contour_num = n;
kids.clear();
}
// Destructor
TGContourNode::~TGContourNode() {
for ( unsigned int i = 0; i < kids.size(); ++i ) {
if ( kids[i] != NULL ) {
delete kids[i];
}
}
}

View file

@ -1,81 +0,0 @@
// contour_tree.hxx -- routines for building a contour tree showing
// which contours are inside if which contours
//
// Written by Curtis Olson, started June 2000.
//
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: contour_tree.hxx,v 1.5 2004-11-19 22:25:50 curt Exp $
#ifndef _CONTOUR_TREE_HXX
#define _CONTOUR_TREE_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include <vector>
#include <cstddef>
// forward declaration
class TGContourNode;
typedef std::vector < TGContourNode * > contour_kids;
typedef contour_kids::iterator contour_kids_iterator;
typedef contour_kids::const_iterator const_contour_kids_iterator;
// a simple class for building a contour tree for a polygon. The
// contour tree shows the hierarchy of which contour is inside which
// contour.
class TGContourNode {
private:
int contour_num; // -1 for the root node
contour_kids kids;
public:
TGContourNode();
TGContourNode( int n );
~TGContourNode();
inline int get_contour_num() const { return contour_num; }
inline void set_contour_num( int n ) { contour_num = n; }
inline int get_num_kids() const { return kids.size(); }
inline TGContourNode *get_kid( int n ) const { return kids[n]; }
inline void add_kid( TGContourNode *kid ) { kids.push_back( kid ); }
inline void remove_kid( int n ) {
// cout << "kids[" << n << "] = " << kids[n] << endl;
delete kids[n];
kids[n] = NULL;
}
};
#endif // _CONTOUR_TREE_HXX

View file

@ -1,78 +0,0 @@
// line.cxx - a simple multi-segment line class.
//
// Started by David Megginson, July 2002
//
// This file is in the Public Domain and comes with NO WARRANTY OF ANY KIND.
#include "line.hxx"
namespace tg {
Line::Line ()
{
}
Line::Line (const Line &l)
{
int nPoints = l.getPointCount();
for (int i = 0; i < nPoints; i++)
addPoint(l.getPoint(i));
}
Line::~Line ()
{
}
int
Line::getPointCount () const
{
return _points.size();
}
const Point3D &
Line::getPoint (int index) const
{
return _points[index];
}
Point3D &
Line::getPoint (int index)
{
return _points[index];
}
void
Line::addPoint (const Point3D &point)
{
_points.push_back(point);
}
Rectangle
Line::getBounds () const
{
SGGeod min;
SGGeod max;
int nPoints = _points.size();
for (int i = 0; i < nPoints; i++) {
if (i == 0) {
min = max = _points[i].toSGGeod();
} else {
if (_points[i].x() < min.getLongitudeDeg())
min.setLongitudeDeg(_points[i].x());
if (_points[i].x() > max.getLongitudeDeg())
max.setLongitudeDeg(_points[i].x());
if (_points[i].y() < min.getLatitudeDeg())
min.setLatitudeDeg(_points[i].y());
if (_points[i].y() > max.getLatitudeDeg())
max.setLatitudeDeg(_points[i].y());
}
}
return Rectangle(min, max);
}
};
// end of line.cxx

View file

@ -1,92 +0,0 @@
// line.hxx - a simple multi-segment line class.
//
// Started by David Megginson, July 2002
//
// This file is in the Public Domain and comes with NO WARRANTY OF ANY KIND.
#ifndef __LINE_HXX
#define __LINE_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include <Geometry/point3d.hxx>
#include <vector>
#include "rectangle.hxx"
namespace tg {
/**
* A simple multi-segment line class.
*
* A line segment is a growable list of points. I will add more
* functionality if or when it is needed.
*/
class Line
{
public:
/**
* Create a new line with no points.
*/
Line ();
/**
* Copy an existing line.
*
* @param l The line to copy.
*/
Line (const Line &l);
/**
* Destructor.
*/
virtual ~Line ();
/**
* Get the number of points currently in the line.
*
* @return The point count.
*/
virtual int getPointCount () const;
/**
* Get a point in the line (const).
*
* @param index The index of the point, zero-based.
* @return The point at the index specified.
*/
virtual const Point3D &getPoint (int index) const;
/**
* Get a point in the line (non-const).
*
* @param index The index of the point, zero-based.
* @return The point at the index specified.
*/
virtual Point3D &getPoint (int index);
/**
* Add a new point to the end of the line.
*
* @param point The point to add.
*/
virtual void addPoint (const Point3D &point);
/**
* Get the bounding rectangle for the line.
*
* @return The bounding rectangle.
*/
virtual Rectangle getBounds () const;
private:
std::vector<Point3D> _points;
};
};
#endif // __LINE_HXX

View file

@ -1,165 +0,0 @@
#include <float.h>
#include <stdio.h>
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <Geometry/point3d.hxx>
#include <simgear/math/sg_types.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
#include <Polygon/polygon.hxx>
#include "poly_support.hxx"
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_face_base_with_info_2.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Triangle_2.h>
#include <iostream>
/* determining if a face is within the reulting poly */
struct FaceInfo2
{
FaceInfo2() {}
int nesting_level;
bool in_domain(){
return nesting_level%2 == 1;
}
};
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_vertex_base_2<K> Vb;
typedef CGAL::Triangulation_face_base_with_info_2<FaceInfo2,K> Fbb;
typedef CGAL::Constrained_triangulation_face_base_2<K,Fbb> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
typedef CGAL::Exact_predicates_tag Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, TDS, Itag> CDT;
typedef CDT::Point Point;
typedef CGAL::Polygon_2<K> Polygon_2;
typedef CGAL::Triangle_2<K> Triangle_2;
void mark_domains(CDT& ct, CDT::Face_handle start, int index, std::list<CDT::Edge>& border )
{
if(start->info().nesting_level != -1) {
return;
}
std::list<CDT::Face_handle> queue;
queue.push_back(start);
while( !queue.empty() ){
CDT::Face_handle fh = queue.front();
queue.pop_front();
if(fh->info().nesting_level == -1) {
fh->info().nesting_level = index;
for(int i = 0; i < 3; i++) {
CDT::Edge e(fh,i);
CDT::Face_handle n = fh->neighbor(i);
if(n->info().nesting_level == -1) {
if(ct.is_constrained(e)) border.push_back(e);
else queue.push_back(n);
}
}
}
}
}
//explore set of facets connected with non constrained edges,
//and attribute to each such set a nesting level.
//We start from facets incident to the infinite vertex, with a nesting
//level of 0. Then we recursively consider the non-explored facets incident
//to constrained edges bounding the former set and increase the nesting level by 1.
//Facets in the domain are those with an odd nesting level.
void mark_domains(CDT& cdt)
{
for(CDT::All_faces_iterator it = cdt.all_faces_begin(); it != cdt.all_faces_end(); ++it){
it->info().nesting_level = -1;
}
int index = 0;
std::list<CDT::Edge> border;
mark_domains(cdt, cdt.infinite_face(), index++, border);
while(! border.empty()) {
CDT::Edge e = border.front();
border.pop_front();
CDT::Face_handle n = e.first->neighbor(e.second);
if(n->info().nesting_level == -1) {
mark_domains(cdt, n, e.first->info().nesting_level+1, border);
}
}
}
void insert_polygon(CDT& cdt,const Polygon_2& polygon)
{
if ( polygon.is_empty() ) return;
CDT::Vertex_handle v_prev=cdt.insert(*CGAL::cpp0x::prev(polygon.vertices_end()));
for (Polygon_2::Vertex_iterator vit=polygon.vertices_begin(); vit!=polygon.vertices_end();++vit) {
CDT::Vertex_handle vh=cdt.insert(*vit);
cdt.insert_constraint(vh,v_prev);
v_prev=vh;
}
}
TGPolygon polygon_tesselate_alt_with_extra_cgal( TGPolygon &p, const std::vector<SGGeod>& extra_nodes, bool verbose ) {
TGPolygon result;
CDT cdt;
result.erase();
// Bail right away if polygon is empty
if ( p.contours() == 0 ) {
return result;
}
// First, insert the extra points
std::vector<Point> points;
points.reserve(extra_nodes.size());
for (unsigned int n = 0; n < extra_nodes.size(); n++) {
points.push_back( Point(extra_nodes[n].getLongitudeDeg(), extra_nodes[n].getLatitudeDeg()) );
}
cdt.insert(points.begin(), points.end());
// then insert each polygon as a constraint into the triangulation
for (int c = 0; c < p.contours(); c++) {
point_list contour = p.get_contour( c );
Polygon_2 poly;
for (unsigned int n = 0; n < contour.size(); n++ ) {
Point3D node = contour[n];
poly.push_back( Point( node.x(), node.y()) );
}
insert_polygon(cdt, poly);
}
mark_domains( cdt );
int count=0;
for (CDT::Finite_faces_iterator fit=cdt.finite_faces_begin(); fit!=cdt.finite_faces_end();++fit) {
if ( fit->info().in_domain() ) {
Triangle_2 tri = cdt.triangle(fit);
Point3D p0 = Point3D( tri.vertex(0).x(), tri.vertex(0).y(), 0.0f );
Point3D p1 = Point3D( tri.vertex(1).x(), tri.vertex(1).y(), 0.0f );
Point3D p2 = Point3D( tri.vertex(2).x(), tri.vertex(2).y(), 0.0f );
result.add_node( count, p0 );
result.add_node( count, p1 );
result.add_node( count, p2 );
++count;
// create a contour in result with this face
}
}
return result;
}
TGPolygon polygon_tesselate_alt_cgal( TGPolygon &p, bool verbose ) {
std::vector<SGGeod> pl; pl.clear();
return ( polygon_tesselate_alt_with_extra_cgal(p, pl, verbose) );
}

View file

@ -1,177 +0,0 @@
// poly_extra.cxx -- Extra polygon manipulation routines
//
// Written by Curtis Olson, started February 2002.
//
// Copyright (C) 2002 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: poly_extra.cxx,v 1.9 2004-11-19 22:25:49 curt Exp $
//
#include <stdio.h>
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
#include <Geometry/poly_support.hxx>
#include "poly_extra.hxx"
// Divide segment if there are other existing points on it, return the
// new polygon
void add_intermediate_nodes( int contour, const Point3D& start,
const Point3D& end, point_list& tmp_nodes,
TGPolygon *result,
const double bbEpsilon,
const double errEpsilon
)
{
Point3D new_pt;
SG_LOG(SG_GENERAL, SG_BULK, " " << start << " <==> " << end );
bool found_extra = find_intermediate_node( start, end, tmp_nodes, &new_pt, bbEpsilon, errEpsilon );
if ( found_extra ) {
// recurse with two sub segments
// SG_LOG(SG_GENERAL, SG_DEBUG, "dividing " << p0 << " " << nodes[extra_index]
// << " " << p1);
add_intermediate_nodes( contour, start, new_pt, tmp_nodes, result, bbEpsilon, errEpsilon );
result->add_node( contour, new_pt );
SG_LOG(SG_GENERAL, SG_BULK, " adding = " << new_pt);
add_intermediate_nodes( contour, new_pt, end, tmp_nodes, result, bbEpsilon, errEpsilon );
}
}
void add_intermediate_nodes( int contour, const Point3D& start,
const Point3D& end, std::vector<SGGeod>&tmp_nodes,
TGPolygon *result,
const double bbEpsilon,
const double errEpsilon
)
{
Point3D new_pt;
SG_LOG(SG_GENERAL, SG_BULK, " " << start << " <==> " << end );
bool found_extra = find_intermediate_node( start, end, tmp_nodes, &new_pt, bbEpsilon, errEpsilon );
if ( found_extra ) {
// recurse with two sub segments
// SG_LOG(SG_GENERAL, SG_DEBUG, "dividing " << p0 << " " << nodes[extra_index]
// << " " << p1);
add_intermediate_nodes( contour, start, new_pt, tmp_nodes, result, bbEpsilon, errEpsilon );
result->add_node( contour, new_pt );
SG_LOG(SG_GENERAL, SG_BULK, " adding = " << new_pt);
add_intermediate_nodes( contour, new_pt, end, tmp_nodes, result, bbEpsilon, errEpsilon );
}
}
// Search each segment for additional vertex points that may have been
// created elsewhere that lie on the segment and split it there to
// avoid "T" intersections.
TGPolygon add_nodes_to_poly( const TGPolygon& poly,
const TGTriNodes& nodes ) {
int i, j;
TGPolygon result; result.erase();
point_list tmp_nodes = nodes.get_node_list();
Point3D p0, p1;
// SG_LOG(SG_GENERAL, SG_DEBUG, "add_nodes_to_poly");
for ( i = 0; i < poly.contours(); ++i ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, "contour = " << i);
for ( j = 0; j < poly.contour_size(i) - 1; ++j ) {
p0 = poly.get_pt( i, j );
p1 = poly.get_pt( i, j + 1 );
// add start of segment
result.add_node( i, p0 );
// add intermediate points
add_intermediate_nodes( i, p0, p1, tmp_nodes, &result, SG_EPSILON*10, SG_EPSILON*4 );
// end of segment is beginning of next segment
}
p0 = poly.get_pt( i, poly.contour_size(i) - 1 );
p1 = poly.get_pt( i, 0 );
// add start of segment
result.add_node( i, p0 );
// add intermediate points
add_intermediate_nodes( i, p0, p1, tmp_nodes, &result, SG_EPSILON*10, SG_EPSILON*4 );
// end of segment is beginning of next segment
// 5/9/2000 CLO - this results in duplicating the last point
// of a contour so I have removed this line.
// result.add_node( i, p1 );
// maintain original hole flag setting
result.set_hole_flag( i, poly.get_hole_flag( i ) );
}
return result;
}
TGPolygon add_tgnodes_to_poly( const TGPolygon& poly,
const TGNodes* nodes ) {
TGPolygon result; result.erase();
SGGeod min, max;
Point3D p0, p1;
std::vector<SGGeod> poly_points;
poly.get_bounding_box(min, max);
SG_LOG(SG_GENERAL, SG_DEBUG, "add_tgnodes_to_poly : min " << min << " max " << max );
nodes->get_geod_inside( min, max, poly_points );
for ( int i = 0; i < poly.contours(); ++i ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "contour = " << i);
for ( int j = 0; j < poly.contour_size(i) - 1; ++j ) {
p0 = poly.get_pt( i, j );
p1 = poly.get_pt( i, j + 1 );
// add start of segment
result.add_node( i, p0 );
// add intermediate points
add_intermediate_nodes( i, p0, p1, poly_points, &result, SG_EPSILON*10, SG_EPSILON*4 );
// end of segment is beginning of next segment
}
p0 = poly.get_pt( i, poly.contour_size(i) - 1 );
p1 = poly.get_pt( i, 0 );
// add start of segment
result.add_node( i, p0 );
// add intermediate points
add_intermediate_nodes( i, p0, p1, poly_points, &result, SG_EPSILON*10, SG_EPSILON*4 );
// maintain original hole flag setting
result.set_hole_flag( i, poly.get_hole_flag( i ) );
}
return result;
}

View file

@ -1,66 +0,0 @@
// poly_extra.hxx -- Extra polygon manipulation routines
//
// Written by Curtis Olson, started February 2002.
//
// Copyright (C) 2002 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: poly_extra.hxx,v 1.5 2004-11-19 22:25:49 curt Exp $
//
#ifndef _POLY_EXTRA_HXX
#define _POLY_EXTRA_HXX
#include <Geometry/point3d.hxx>
#include <Geometry/trinodes.hxx>
#include <Geometry/tg_nodes.hxx>
#include <Polygon/polygon.hxx>
// Divide segment if there are other existing points on it, return the
// new polygon
void add_intermediate_nodes( int contour, const Point3D& start,
const Point3D& end, const point_list& tmp_nodes,
TGPolygon *result,
const double bbEpsilon = SG_EPSILON*10,
const double errEpsilon = SG_EPSILON*4
);
// TEMP - converting tgnodes to SGGeod/SGVec3d
void add_intermediate_nodes( int contour, const Point3D& start,
const Point3D& end, const std::vector<SGGeod>& tmp_nodes,
TGPolygon *result,
const double bbEpsilon = SG_EPSILON*10,
const double errEpsilon = SG_EPSILON*4
);
// Search each segment for additional vertex points that may have been
// created elsewhere that lie on the segment and split it there to
// avoid "T" intersections.
TGPolygon add_nodes_to_poly( const TGPolygon& poly,
const TGTriNodes& tmp_nodes );
TGPolygon add_tgnodes_to_poly( const TGPolygon& poly,
const TGNodes* nodes );
#endif // _POLY_EXTRA_HXX

File diff suppressed because it is too large Load diff

View file

@ -1,122 +0,0 @@
// poly_support.hxx -- additional supporting routines for the TGPolygon class
// specific to the object building process.
//
// Written by Curtis Olson, started October 1999.
//
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: poly_support.hxx,v 1.14 2004-11-19 22:25:50 curt Exp $
#ifndef _POLY_SUPPORT_HXX
#define _POLY_SUPPORT_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include <simgear/math/sg_types.hxx>
#include <Polygon/polygon.hxx>
#include "trieles.hxx"
#include "trinodes.hxx"
// Calculate the area of a triangle
inline double triangle_area( const SGGeod& p1, const SGGeod& p2, const SGGeod& p3 )
{
return fabs(0.5 * ( p1.getLongitudeDeg() * p2.getLatitudeDeg() - p2.getLongitudeDeg() * p1.getLatitudeDeg() +
p2.getLongitudeDeg() * p3.getLatitudeDeg() - p3.getLongitudeDeg() * p2.getLatitudeDeg() +
p3.getLongitudeDeg() * p1.getLatitudeDeg() - p1.getLongitudeDeg() * p3.getLatitudeDeg() ));
}
// Alternate basic triangulation of a polygon with out adding points
// or splitting edges and without regard for holes. Returns a polygon
// with one contour per tesselated triangle.
TGPolygon polygon_tesselate_alt_with_extra_cgal( TGPolygon &p,
const std::vector<SGGeod>& extra_nodes, bool verbose );
TGPolygon polygon_tesselate_alt_cgal( TGPolygon &p, bool verbose );
// calculate some "arbitrary" point inside each of the polygons contours
void calc_points_inside( TGPolygon& p );
// snap all points to a grid
TGPolygon snap( const TGPolygon &poly, double grid_size );
// remove duplicate nodes in a polygon should they exist. Returns the
// fixed polygon
TGPolygon remove_dups( const TGPolygon &poly );
// Search each segment of each contour for degenerate points (i.e. out
// of order points that lie coincident on other segments
TGPolygon reduce_degeneracy( const TGPolygon& poly );
// Occasionally the outline of the clipped polygon can take a side
// track, then double back on return to the start of the side track
// branch and continue normally. Attempt to detect and clear this
// extraneous nonsense.
TGPolygon remove_cycles( const TGPolygon& poly );
// Occasionally the outline of the clipped polygon can have long spikes
// that come close to doubling back on the same segment - this kills
// triangulation
TGPolygon remove_spikes( const TGPolygon& poly );
// Find a point in the given node list that lies between start and
// end, return true if something found, false if nothing found.
bool find_intermediate_node( const Point3D& start, const Point3D& end,
const point_list& nodes, Point3D *result,
const double bbEpsilon = SG_EPSILON*10,
const double errEpsilon = SG_EPSILON*4
);
// TEMP
bool find_intermediate_node( const Point3D& start, const Point3D& end,
const std::vector<SGGeod>& nodes, Point3D *result,
const double bbEpsilon = SG_EPSILON*10,
const double errEpsilon = SG_EPSILON*4
);
// remove any degenerate contours
TGPolygon remove_bad_contours( const TGPolygon &poly );
// remove any too small contours
TGPolygon remove_tiny_contours( const TGPolygon &poly );
TGPolygon remove_small_contours( const TGPolygon &poly );
// Write Polygons to Shapefile Support
void tgShapefileInit( void );
void* tgShapefileOpenDatasource( const char* datasource_name );
void* tgShapefileOpenLayer( void* ds_id, const char* layer_name );
void tgShapefileCreateFeature( void* ds_id, void* l_id, const TGPolygon &poly, const char* feature_name, bool has_point_inside = false );
void tgShapefileCloseLayer( void* l_id );
void* tgShapefileCloseDatasource( void* ds_id );
#endif // _POLY_SUPPORT_HXX

View file

@ -1,72 +0,0 @@
// trieles.hxx -- "Triangle" element management class
//
// Written by Curtis Olson, started March 1999.
//
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: trieles.hxx,v 1.4 2004-11-19 22:25:50 curt Exp $
#ifndef _TRIELES_HXX
#define _TRIELES_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include <vector>
// a segment is two integer pointers into the node list
class TGTriEle {
int n1, n2, n3;
double attribute;
public:
// Constructor and destructor
inline TGTriEle( void ) { };
inline TGTriEle( int i1, int i2, int i3, double a ) {
n1 = i1; n2 = i2; n3 = i3; attribute = a;
}
inline ~TGTriEle( void ) { };
inline int get_n1() const { return n1; }
inline void set_n1( int i ) { n1 = i; }
inline int get_n2() const { return n2; }
inline void set_n2( int i ) { n2 = i; }
inline int get_n3() const { return n3; }
inline void set_n3( int i ) { n3 = i; }
inline double get_attribute() const { return attribute; }
inline void set_attribute( double a ) { attribute = a; }
};
typedef std::vector < TGTriEle > triele_list;
typedef triele_list::iterator triele_list_iterator;
typedef triele_list::const_iterator const_triele_list_iterator;
#endif // _TRIELES_HXX

View file

@ -1,209 +0,0 @@
// trisegs.cxx -- "Triangle" segment management class
//
// Written by Curtis Olson, started March 1999.
//
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: trisegs.cxx,v 1.10 2004-11-19 22:25:50 curt Exp $
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <Geometry/point3d.hxx>
#include <iostream>
#include "trinodes.hxx"
#include "trisegs.hxx"
// Constructor
TGTriSegments::TGTriSegments( void ) {
}
// Destructor
TGTriSegments::~TGTriSegments( void ) {
}
// Add a segment to the segment list if it doesn't already exist.
// Returns the index (starting at zero) of the segment in the list.
int TGTriSegments::unique_add( const TGTriSeg& s )
{
triseg_list_iterator current, last;
int counter = 0;
// SG_LOG(SG_GENERAL, SG_DEBUG, s.get_n1() << "," << s.get_n2() );
// check if segment has duplicated endpoints
if ( s.get_n1() == s.get_n2() ) {
SG_LOG(SG_GENERAL, SG_ALERT, "WARNING: ignoring null segment with the same point for both endpoints" );
return -1;
}
// check if segment already exists
current = seg_list.begin();
last = seg_list.end();
for ( ; current != last; ++current ) {
if ( s == *current ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, "found an existing segment match" );
return counter;
}
++counter;
}
// add to list
seg_list.push_back( s );
return counter;
}
// Divide segment if there are other points on it, return the divided
// list of segments
void TGTriSegments::unique_divide_and_add( const point_list& nodes,
const TGTriSeg& s )
{
Point3D p0 = nodes[ s.get_n1() ];
Point3D p1 = nodes[ s.get_n2() ];
bool found_extra = false;
int extra_index = 0;
int counter;
double m, m1, b, b1, y_err, x_err, y_err_min, x_err_min;
const_point_list_iterator current, last;
// bool temp = false;
// if ( s == TGTriSeg( 170, 206 ) ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, "this is it!" );
// temp = true;
// }
double xdist = fabs(p0.x() - p1.x());
double ydist = fabs(p0.y() - p1.y());
x_err_min = xdist + 1.0;
y_err_min = ydist + 1.0;
if ( xdist > ydist ) {
// use y = mx + b
// sort these in a sensible order
if ( p0.x() > p1.x() ) {
Point3D tmp = p0;
p0 = p1;
p1 = tmp;
}
m = (p0.y() - p1.y()) / (p0.x() - p1.x());
b = p1.y() - m * p1.x();
// if ( temp ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, "m = " << m << " b = " << b );
// }
current = nodes.begin();
last = nodes.end();
counter = 0;
for ( ; current != last; ++current ) {
if ( (current->x() > (p0.x() + SG_EPSILON))
&& (current->x() < (p1.x() - SG_EPSILON)) ) {
// if ( temp ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, counter );
// }
y_err = fabs(current->y() - (m * current->x() + b));
if ( y_err < FG_PROXIMITY_EPSILON ) {
//SG_LOG(SG_GENERAL, SG_DEBUG, "FOUND EXTRA SEGMENT NODE (Y)" );
//SG_LOG(SG_GENERAL, SG_DEBUG, p0 << " < " << *current << " < " << p1 );
found_extra = true;
if ( y_err < y_err_min ) {
extra_index = counter;
y_err_min = y_err;
}
}
}
++counter;
}
} else {
// use x = m1 * y + b1
// sort these in a sensible order
if ( p0.y() > p1.y() ) {
Point3D tmp = p0;
p0 = p1;
p1 = tmp;
}
m1 = (p0.x() - p1.x()) / (p0.y() - p1.y());
b1 = p1.x() - m1 * p1.y();
// bool temp = true;
// if ( temp ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, "xdist = " << xdist << " ydist = " << ydist );
// SG_LOG(SG_GENERAL, SG_DEBUG, " p0 = " << p0 << " p1 = " << p1 );
// SG_LOG(SG_GENERAL, SG_DEBUG, " m1 = " << m1 << " b1 = " << b1 );
// }
// SG_LOG(SG_GENERAL, SG_DEBUG, " should = 0 = " << fabs(p0.x() - (m1 * p0.y() + b1)) );
// SG_LOG(SG_GENERAL, SG_DEBUG, " should = 0 = " << fabs(p1.x() - (m1 * p1.y() + b1)) );
current = nodes.begin();
last = nodes.end();
counter = 0;
for ( ; current != last; ++current ) {
if ( (current->y() > (p0.y() + SG_EPSILON))
&& (current->y() < (p1.y() - SG_EPSILON)) ) {
x_err = fabs(current->x() - (m1 * current->y() + b1));
// if ( temp ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, " (" << counter << ") x_err = " << x_err );
// }
if ( x_err < FG_PROXIMITY_EPSILON ) {
//SG_LOG(SG_GENERAL, SG_DEBUG, "FOUND EXTRA SEGMENT NODE (X)" );
//SG_LOG(SG_GENERAL, SG_DEBUG, p0 << " < " << *current << " < " << p1 );
found_extra = true;
if ( x_err < x_err_min ) {
extra_index = counter;
x_err_min = x_err;
}
}
}
++counter;
}
}
if ( found_extra ) {
// recurse with two sub segments
SG_LOG(SG_GENERAL, SG_DEBUG, "dividing " << s.get_n1() << " " << extra_index << " " << s.get_n2() );
unique_divide_and_add( nodes, TGTriSeg( s.get_n1(), extra_index,
s.get_boundary_marker() ) );
unique_divide_and_add( nodes, TGTriSeg( extra_index, s.get_n2(),
s.get_boundary_marker() ) );
} else {
// this segment does not need to be divided, lets add it
unique_add( s );
}
}

View file

@ -1,122 +0,0 @@
// trisegs.hxx -- "Triangle" segment management class
//
// Written by Curtis Olson, started March 1999.
//
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: trisegs.hxx,v 1.4 2004/11/19 22:25:50 curt Exp $
#ifndef _TRISEGS_HXX
#define _TRISEGS_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include <vector>
#include "trinodes.hxx"
// a segment is two integer pointers into the node list
class TGTriSeg {
int n1, n2; // indices into point list
int boundary_marker; // flag if segment is a boundary
// (i.e. shouldn't get split)
public:
// Constructor and destructor
inline TGTriSeg( void ) { };
inline TGTriSeg( int i1, int i2, int b ) {
n1 = i1;
n2 = i2;
boundary_marker = b;
}
inline ~TGTriSeg( void ) { };
inline int get_n1() const { return n1; }
inline void set_n1( int i ) { n1 = i; }
inline int get_n2() const { return n2; }
inline void set_n2( int i ) { n2 = i; }
inline int get_boundary_marker() const { return boundary_marker; }
inline void set_boundary_marker( int b ) { boundary_marker = b; }
friend bool operator == (const TGTriSeg& a, const TGTriSeg& b);
};
inline bool operator == (const TGTriSeg& a, const TGTriSeg& b)
{
return ((a.n1 == b.n1) && (a.n2 == b.n2))
|| ((a.n1 == b.n2) && (a.n2 == b.n1));
}
typedef std::vector < TGTriSeg > triseg_list;
typedef triseg_list::iterator triseg_list_iterator;
typedef triseg_list::const_iterator const_triseg_list_iterator;
class TGTriSegments {
private:
triseg_list seg_list;
// Divide segment if there are other points on it, return the
// divided list of segments
triseg_list divide_segment( const point_list& nodes,
const TGTriSeg& s );
public:
// Constructor and destructor
TGTriSegments( void );
~TGTriSegments( void );
// delete all the data out of seg_list
inline void clear() { seg_list.clear(); }
// Add a segment to the segment list if it doesn't already exist.
// Returns the index (starting at zero) of the segment in the
// list.
int unique_add( const TGTriSeg& s );
// Add a segment to the segment list if it doesn't already exist.
// Returns the index (starting at zero) of the segment in the list.
void unique_divide_and_add( const point_list& node_list,
const TGTriSeg& s );
// return the master segment list
inline triseg_list& get_seg_list() { return seg_list; }
inline const triseg_list& get_seg_list() const { return seg_list; }
// return the ith segment
inline TGTriSeg& get_seg( int i ) { return seg_list[i]; }
inline const TGTriSeg& get_seg( int i ) const { return seg_list[i]; }
};
#endif // _TRISEGS_HXX

View file

@ -3,15 +3,25 @@ include_directories(${GDAL_INCLUDE_DIR})
include( ${CGAL_USE_FILE} )
add_library(Polygon STATIC
chop-bin.cxx
index.cxx
polygon.cxx
simple_clip.cxx
chop.hxx
index.hxx
names.hxx
polygon.hxx
simple_clip.hxx
clipper.cpp
clipper.hpp
)
polygon.cxx
polygon.hxx
rectangle.cxx
rectangle.hxx
tg_nodes.cxx
tg_nodes.hxx
tg_unique_geod.hxx
tg_unique_tgnode.hxx
tg_unique_vec2f.hxx
tg_unique_vec3d.hxx
tg_unique_vec3f.hxx
trinodes.cxx
trinodes.hxx
TNT/jama_qr.h
TNT/tnt_array1d.h
TNT/tnt_array2d.h
TNT/tnt_i_refvec.h
TNT/tnt_math_utils.h
point3d.hxx
)

File diff suppressed because it is too large Load diff

View file

@ -1,50 +0,0 @@
// 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-2004 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: chop.hxx,v 1.3 2004-11-19 22:25:50 curt Exp $
#ifndef _TG_CHOP_HXX
#define _TG_CHOP_HXX
#include <string>
#include "polygon.hxx"
// process polygon shape (chop up along tile boundaries and write each
// polygon piece to a file)
void tgChopNormalPolygon( const std::string& path, const std::string& poly_type,
const TGPolygon& shape, bool preserve3d );
void tgChopNormalPolygonsWithMask(const std::string& path, const std::string& poly_type,
const poly_list& segments, bool preserve3d );
// process polygon shape (chop up along tile boundaries and write each
// polygon piece to a file) This has a front end to a crude clipper
// that doesn't handle holes so beware. This routine is appropriate
// for breaking down really huge structures if needed.
void tgChopBigSimplePolygon( const std::string& path, const std::string& poly_type,
const TGPolygon& shape, bool preserve3d );
#endif // _TG_CHOP_HXX

View file

@ -1,76 +0,0 @@
// index.cxx -- routines to handle a unique/persistant integer polygon index
//
// Written by Curtis Olson, started February 1999.
//
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: index.cxx,v 1.7 2004-11-19 22:25:50 curt Exp $
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
#include <string>
#include <stdio.h>
#include "index.hxx"
using std::string;
static long int poly_index;
static string poly_path;
// initialize the unique polygon index counter stored in path
bool poly_index_init( string path )
{
poly_path = path;
FILE *fp = fopen( poly_path.c_str(), "r" );
if ( fp == NULL ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "Warning: cannot open " << poly_path);
poly_index = 0;
return false;
}
fscanf( fp, "%ld", &poly_index );
fclose( fp );
return true;
}
// increment the persistant counter and return the next poly_index
long int poly_index_next()
{
++poly_index;
FILE *fp = fopen( poly_path.c_str(), "w" );
if ( fp == NULL )
SG_LOG(SG_GENERAL, SG_ALERT,
"Error cannot open " << poly_path << " for writing");
fprintf( fp, "%ld\n", poly_index );
fclose( fp );
return poly_index;
}

View file

@ -1,42 +0,0 @@
// index.cxx -- routines to handle a unique/persistant integer polygon index
//
// Written by Curtis Olson, started February 1999.
//
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: index.hxx,v 1.4 2004-11-19 22:25:50 curt Exp $
#ifndef _INDEX_HXX
#define _INDEX_HXX
#include <simgear/compiler.h>
#include <string>
// initialize the unique polygon index counter stored in path
bool poly_index_init( std::string path );
// increment the persistant counter and return the next poly_index
long int poly_index_next();
#endif // _INDEX_HXX

View file

@ -1 +0,0 @@

View file

@ -1,48 +0,0 @@
// names.hxx -- process shapefiles names
//
// Written by Curtis Olson, started February 1999.
//
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: names.hxx,v 1.16 2007-10-31 15:05:13 curt Exp $
#ifndef _NAMES_HXX
#define _NAMES_HXX
#include <simgear/compiler.h>
#include <string>
inline static bool is_ocean_area( const std::string &area )
{
return area == "Ocean" || area == "Bay Estuary or Ocean";
}
inline static bool is_void_area( const std::string &area )
{
return area == "Void Area";
}
inline static bool is_null_area( const std::string& area )
{
return area == "Null";
}
#endif // _NAMES_HXX

View file

@ -30,10 +30,9 @@
#include <simgear/misc/texcoord.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/debug/logstream.hxx>
#include <Geometry/point3d.hxx>
#include <Geometry/poly_support.hxx>
#include <Geometry/trinodes.hxx>
#include <Polygon/point3d.hxx>
#include <Polygon/trinodes.hxx>
#include "polygon.hxx"
@ -76,7 +75,7 @@ void TGPolygon::get_bounding_box( SGGeod& min, SGGeod& max ) const
max = SGGeod::fromDeg( maxx, maxy );
}
#if 0
// Set the elevations of points in the current polgyon based on the
// elevations of points in source. For points that are not found in
// source, propogate the value from the nearest matching point.
@ -142,7 +141,7 @@ void TGPolygon::inherit_elevations( const TGPolygon &source ) {
}
}
}
#endif
// Set the elevations of all points to the specified values
void TGPolygon::set_elevations( double elev ) {
@ -532,7 +531,7 @@ void clipper_to_shapefile( ClipperLib::Polygons polys, char* ds )
TGPolygon tgcontour;
char layer[32];
void* ds_id = tgShapefileOpenDatasource( ds );
void* ds_id = tgShapefile::OpenDatasource( ds );
for (unsigned int i = 0; i < polys.size(); ++i) {
if ( Orientation( polys[i] ) ) {
@ -541,18 +540,18 @@ void clipper_to_shapefile( ClipperLib::Polygons polys, char* ds )
sprintf( layer, "%04d_hole", i );
}
void* l_id = tgShapefileOpenLayer( ds_id, layer );
void* l_id = tgShapefile::OpenLayer( ds_id, layer );
contour.clear();
contour.push_back( polys[i] );
tgcontour.erase();
make_tg_poly_from_clipper( contour, &tgcontour );
tgShapefileCreateFeature( ds_id, l_id, tgcontour, "contour" );
tgShapefile::CreateFeature( ds_id, l_id, tgcontour, "contour" );
}
// close after each write
ds_id = tgShapefileCloseDatasource( ds_id );
ds_id = tgShapefile::CloseDatasource( ds_id );
}
TGPolygon polygon_clip_clipper( clip_op poly_op, const TGPolygon& subject, const TGPolygon& clip )
@ -652,17 +651,17 @@ void tgPolygonFreeClipperAccumulator( void )
void tgPolygonDumpAccumulator( char* ds, char* layer, char* name )
{
void* ds_id = tgShapefileOpenDatasource( ds );
void* l_id = tgShapefileOpenLayer( ds_id, layer );
void* ds_id = tgShapefile::OpenDatasource( ds );
void* l_id = tgShapefile::OpenLayer( ds_id, layer );
TGPolygon accum;
for (unsigned int i=0; i<clipper_accumulator.size(); i++) {
make_tg_poly_from_clipper( clipper_accumulator[i], &accum );
tgShapefileCreateFeature( ds_id, l_id, accum, name );
tgShapefile::CreateFeature( ds_id, l_id, accum, name );
}
// close after each write
ds_id = tgShapefileCloseDatasource( ds_id );
ds_id = tgShapefile::CloseDatasource( ds_id );
}
void tgPolygonAddToClipperAccumulator( const TGPolygon& subject, bool dump )
@ -3053,11 +3052,11 @@ void tgPolygon::Texture( void )
void tgPolygon::ToShapefile( const tgPolygon& subject, const std::string& datasource, const std::string& layer, const std::string& description )
{
void* ds_id = tgShapefileOpenDatasource( datasource.c_str() );
SG_LOG(SG_GENERAL, SG_DEBUG, "tgShapefileOpenDatasource returned " << (unsigned long)ds_id);
void* ds_id = tgShapefile::OpenDatasource( datasource.c_str() );
SG_LOG(SG_GENERAL, SG_DEBUG, "tgShapefile::OpenDatasource returned " << (unsigned long)ds_id);
OGRLayer* l_id = (OGRLayer *)tgShapefileOpenLayer( ds_id, layer.c_str() );
SG_LOG(SG_GENERAL, SG_DEBUG, "tgShapefileOpenLayer returned " << (unsigned long)l_id);
OGRLayer* l_id = (OGRLayer *)tgShapefile::OpenLayer( ds_id, layer.c_str() );
SG_LOG(SG_GENERAL, SG_DEBUG, "tgShapefile::OpenLayer returned " << (unsigned long)l_id);
OGRPolygon* polygon = new OGRPolygon();
@ -3102,7 +3101,7 @@ void tgPolygon::ToShapefile( const tgPolygon& subject, const std::string& dataso
}
// close after each write
ds_id = tgShapefileCloseDatasource( ds_id );
ds_id = tgShapefile::CloseDatasource( ds_id );
}
tgPolygon tgPolygon::FromOGR( const OGRPolygon* subject )
@ -3224,25 +3223,6 @@ bool tgPolygon::ChopIdxInit( const std::string& path )
return true;
}
SGMutex index_next_mutex;
static long int tgPolygon_index_next()
{
SGGuard<SGMutex> g(index_next_mutex);
++poly_index;
FILE *fp = fopen( poly_path.c_str(), "w" );
if ( fp == NULL ) {
SG_LOG(SG_GENERAL, SG_ALERT, "Error cannot open BLAH BLAG BLAH " << poly_path << " for writing");
}
fprintf( fp, "%ld\n", poly_index );
fclose( fp );
return poly_index;
}
/************************ TESSELATION ***********************************/
void tg_mark_domains(CDT& ct, CDT::Face_handle start, int index, std::list<CDT::Edge>& border )
@ -3993,3 +3973,121 @@ void tgChopper::Save( void )
gzclose( fp );
}
}
const char* format_name="ESRI Shapefile";
void tgShapefile::Init( void )
{
OGRRegisterAll();
}
void* tgShapefile::OpenDatasource( const char* datasource_name )
{
OGRDataSource *datasource;
OGRSFDriver *ogrdriver;
ogrdriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(format_name);
if (!ogrdriver) {
SG_LOG(SG_GENERAL, SG_ALERT, "Unknown datasource format driver: " << format_name);
exit(1);
}
datasource = ogrdriver->Open(datasource_name, TRUE);
if (!datasource) {
datasource = ogrdriver->CreateDataSource(datasource_name, NULL);
}
if (!datasource) {
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to open or create datasource: " << datasource_name);
exit(1);
}
return (void*)datasource;
}
void* tgShapefile::OpenLayer( void* ds_id, const char* layer_name ) {
OGRDataSource* datasource = (OGRDataSource *)ds_id;
OGRLayer* layer;
OGRSpatialReference srs;
srs.SetWellKnownGeogCS("WGS84");
layer = datasource->GetLayerByName(layer_name);
if (!layer) {
layer = datasource->CreateLayer( layer_name, &srs, wkbPolygon25D, NULL);
OGRFieldDefn descriptionField("ID", OFTString);
descriptionField.SetWidth(128);
if( layer->CreateField( &descriptionField ) != OGRERR_NONE ) {
SG_LOG(SG_GENERAL, SG_ALERT, "Creation of field 'Description' failed");
}
}
if (!layer) {
SG_LOG(SG_GENERAL, SG_ALERT, "Creation of layer '" << layer_name << "' failed");
return NULL;
}
return (void*)layer;
}
void tgShapefile::CreateFeature( void* ds_id, void* l_id, const TGPolygon &poly, const char* description )
{
OGRLayer* layer = (OGRLayer*)l_id;
OGRPolygon* polygon = new OGRPolygon();
for ( int i = 0; i < poly.contours(); i++ ) {
bool skip_ring=false;
point_list contour = poly.get_contour( i );
if (contour.size()<3) {
SG_LOG(SG_GENERAL, SG_DEBUG, "Polygon with less than 3 points");
skip_ring=true;
}
// FIXME: Current we ignore the hole-flag and instead assume
// that the first ring is not a hole and the rest
// are holes
OGRLinearRing *ring=new OGRLinearRing();
for (unsigned int pt = 0; pt < contour.size(); pt++) {
OGRPoint *point=new OGRPoint();
point->setX( contour[pt].x() );
point->setY( contour[pt].y() );
point->setZ( 0.0 );
ring->addPoint(point);
}
ring->closeRings();
if (!skip_ring) {
polygon->addRingDirectly(ring);
}
OGRFeature* feature = NULL;
feature = new OGRFeature( layer->GetLayerDefn() );
feature->SetField("ID", description);
feature->SetGeometry(polygon);
if( layer->CreateFeature( feature ) != OGRERR_NONE )
{
SG_LOG(SG_GENERAL, SG_ALERT, "Failed to create feature in shapefile");
}
OGRFeature::DestroyFeature(feature);
}
}
void tgShapefile::CloseLayer( void* l_id )
{
//OGRLayer::DestroyLayer( layer );
}
void* tgShapefile::CloseDatasource( void* ds_id )
{
OGRDataSource* datasource = (OGRDataSource *)ds_id;
OGRDataSource::DestroyDataSource( datasource );
return (void *)-1;
}

View file

@ -29,16 +29,15 @@
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include <simgear/math/sg_types.hxx>
#include <Geometry/point3d.hxx>
#include <iostream>
#include <string>
#include <vector>
#include <simgear/compiler.h>
#include <simgear/math/sg_types.hxx>
#include <Polygon/point3d.hxx>
// forward declaration
class TGPolygon;
@ -316,8 +315,8 @@ std::ostream &operator<<(std::ostream &output, const TGPolygon &poly);
#include <simgear/bucket/newbucket.hxx>
#include <simgear/threads/SGThread.hxx>
#include <Geometry/trinodes.hxx>
#include <Geometry/rectangle.hxx>
#include <Polygon/trinodes.hxx>
#include <Polygon/rectangle.hxx>
#include "tg_unique_geod.hxx"
@ -486,6 +485,12 @@ public:
return face_area;
}
static double area( const SGGeod& p1, const SGGeod& p2, const SGGeod& p3 ) {
return fabs(0.5 * ( p1.getLongitudeDeg() * p2.getLatitudeDeg() - p2.getLongitudeDeg() * p1.getLatitudeDeg() +
p2.getLongitudeDeg() * p3.getLatitudeDeg() - p3.getLongitudeDeg() * p2.getLatitudeDeg() +
p3.getLongitudeDeg() * p1.getLatitudeDeg() - p1.getLongitudeDeg() * p3.getLatitudeDeg() ));
}
void SaveToGzFile( gzFile& fp ) const;
void LoadFromGzFile( gzFile& fp );
@ -917,6 +922,17 @@ private:
clipper_polygons_list accum;
};
class tgShapefile
{
public:
static void Init( void );
static void* OpenDatasource( const char* datasource_name );
static void* OpenLayer( void* ds_id, const char* layer_name );
static void CreateFeature( void* ds_id, void* l_id, const TGPolygon &poly, const char* description );
static void CloseLayer( void* l_id );
static void* CloseDatasource( void* ds_id );
};
#endif // _POLYGON_HXX

View file

@ -1,550 +0,0 @@
// simple_clip.cxx -- simplistic polygon clipping routine. Returns
// the portion of a polygon that is above or below
// a horizontal line of y = a. Only works with
// single contour polygons (no holes.)
//
// Written by Curtis Olson, started August 1999.
//
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: simple_clip.cxx,v 1.7 2004-11-19 22:25:50 curt Exp $
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
#include "simple_clip.hxx"
#define CLIP_EPSILON 0.000000000001
// Given a line segment specified by two endpoints p1 and p2, return
// the x value of a point on the line that intersects with the
// horizontal line through y. Return true if an intersection is found,
// false otherwise.
static bool intersects_y( Point3D p0, Point3D p1, double y, Point3D *result )
{
// sort the end points
if ( p0.y() > p1.y() ) {
Point3D tmp = p0;
p0 = p1;
p1 = tmp;
}
if ( (y < p0.y()) || (y > p1.y()) )
// out of range of line segment, bail right away
return false;
// equation of a line through (x0,y0) and (x1,y1):
//
// y = y1 + (x - x1) * (y0 - y1) / (x0 - x1)
// x = x1 + (y - y1) * (x0 - x1) / (y0 - y1)
double x;
if ( fabs(p0.y() - p1.y()) > CLIP_EPSILON )
x = p1.x() + (y - p1.y()) * (p0.x() - p1.x()) / (p0.y() - p1.y());
else
return false;
result->setx(x);
result->sety(y);
if ( p0.x() <= p1.x() ) {
if ( (p0.x() <= x) && (x <= p1.x()) )
return true;
} else if ( (p0.x() >= x) && (x >= p1.x()) )
return true;
return false;
}
// find the smallest point in contour 0 of poly such that x > min_x
// and y = y. Returns index of the found point, -1 if no match found.
static int find_point( const TGPolygon& poly, double min_x, double y )
{
Point3D p, save;
int index = -1;
save.setx( 361.0 );
for ( int i = 0; i < poly.contour_size( 0 ); ++i ) {
p = poly.get_pt( 0, i );
if ( p.y() == y ) {
// printf("(%d) p.y() = %.12f y = %.12f\n", i, p.y(), y);
// SG_LOG(SG_GENERAL, SG_DEBUG, " " << p);
if ( p.x() > min_x ) {
if ( p.x() < save.x() ) {
save = p;
index = i;
}
}
}
}
return index;
}
// return if interesection is valid (not in the ignore list)
static bool valid_intersection( int intersection, const int_list& ignore_ints )
{
for ( int i = 0; i < (int)ignore_ints.size(); ++i )
if ( intersection == ignore_ints[i] )
return false;
return true;
}
// return index of next valid intersection
static int next_intersection( const int_list& keep_ints,
const int_list& ignore_ints,
const int beginning_at )
{
// SG_LOG(SG_GENERAL, SG_DEBUG, "[ni] start_int = " << beginning_at);
int i = beginning_at;
if ( i < 0 ) i = 0; while ( i < (int)keep_ints.size() ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, " i = " << i);
if ( keep_ints[i] != -1 )
if ( valid_intersection(keep_ints[i], ignore_ints) )
return i;
++i;
}
return -1;
}
// return true if point.y() touches or is inside of line, else return false
inline bool is_on_or_inside( double line, Point3D p, fgSideType side )
{
if ( side == Above ) {
if ( p.y() >= line )
return true;
} else if ( side == Below )
if ( p.y() <= line )
return true;
return false;
}
// return true if point.y() is inside of line, else return false
inline bool is_inside( double line, Point3D p, fgSideType side )
{
if ( side == Above ) {
if ( p.y() > line )
return true;
} else if ( side == Below )
if ( p.y() < line )
return true;
return false;
}
// Walk through the input polygon and split it into the
// portion that is inside the clip region
static bool simple_clip( const TGPolygon& in, const double y,
const fgSideType side,
TGPolygon& result )
{
Point3D p, p_last, p_int;
int i;
result.erase();
SG_LOG(SG_GENERAL, SG_DEBUG, "input poly size = " << in.total_size());
p_last = in.get_pt( 0, in.contour_size(0) - 1 );
for ( i = 0; i < (int)in.contour_size(0); ++i ) {
p = in.get_pt( 0, i );
if ( (fabs(p.x() - p_last.x()) < CLIP_EPSILON) &&
(fabs(p.y() - p_last.y()) < CLIP_EPSILON) &&
(i > 0) ) {
// SG_LOG(SG_GENERAL, SG_WARN,
// "WARNING: p and p_last are identical at index = " << i);
}
if ( is_on_or_inside(y, p, side) ) {
if ( is_on_or_inside(y, p_last, side) )
// SG_LOG(SG_GENERAL, SG_DEBUG, "inside & inside " << i << " " << p);
result.add_node( 0, p );
else {
if ( !intersects_y(p, p_last, y, &p_int) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "Huh, this should have intersected!");
return false;
} else {
// SG_LOG(SG_GENERAL, SG_DEBUG,
// "intersection outside to inside " << i << " "
// << p_int " i - 1 = " << in.get_pt( 0, i-1 ));
// SG_LOG(SG_GENERAL, SG_DEBUG, " i = " << in.get_pt( 0, i ));
// SG_LOG(SG_GENERAL, SG_DEBUG, " i + 1 = " << in.get_pt( 0, i+1 ));
result.add_node( 0, p_int );
if ( (fabs(p.x() - p_int.x()) < CLIP_EPSILON) &&
(fabs(p.y() - p_int.y()) < CLIP_EPSILON) ) {
// SG_LOG(SG_GENERAL, SG_DEBUG,
// "WARNING: p and p_int are identical, "
// << "omitting p");
} else {
SG_LOG(SG_GENERAL, SG_DEBUG, "adding intersection" << i << " " << p);
result.add_node( 0, p );
}
}
}
} else {
if ( is_inside(y, p_last, side) ) {
if ( !intersects_y(p, p_last, y, &p_int) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "Huh, this should have intersected!");
return false;
} else {
// SG_LOG(SG_GENERAL, SG_DEBUG,
// "intersection inside to outside " << i << " "
// << p_int);
if ( (fabs(p.x() - p_int.x()) < CLIP_EPSILON) &&
(fabs(p.y() - p_int.y()) < CLIP_EPSILON) ) {
SG_LOG(SG_GENERAL, SG_DEBUG,
"WARNING: p and p_int are identical, "
<< "omitting p");
} else
result.add_node( 0, p_int );
}
}
}
p_last = p;
}
return true;
}
// build the list of intersections
static bool build_intersections( const TGPolygon& arcs, double line,
fgSideType side,
int_list& keep_ints,
int_list& ignore_ints )
{
keep_ints.clear();
ignore_ints.clear();
int index = 0;
double current_x = -181.0;
while ( index >= 0 ) {
index = find_point( arcs, current_x, line );
if ( index >= 0 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "intersection at " << index << " = "
<< arcs.get_pt( 0, index ));
keep_ints.push_back( index );
current_x = arcs.get_pt( 0, index ).x();
int before = index - 1;
if ( before < 0 ) before += arcs.contour_size(0); int after = (index + 1) % arcs.contour_size(0);
SG_LOG(SG_GENERAL, SG_DEBUG, " before = "
<< arcs.get_pt(0, before));
SG_LOG(SG_GENERAL, SG_DEBUG, " int = "
<< arcs.get_pt(0, index));
SG_LOG(SG_GENERAL, SG_DEBUG, " after = "
<< arcs.get_pt(0, after));
if ( side == Above ) {
if ( (arcs.get_pt(0, before).y() > line) &&
(arcs.get_pt(0, after).y() > line) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "side = above");
SG_LOG(SG_GENERAL, SG_DEBUG,
"V intersection with clip line from above");
SG_LOG(SG_GENERAL, SG_DEBUG,
"Adding intersection to ignore_ints");
ignore_ints.push_back( index );
}
if ( (arcs.get_pt(0, before).y() <= line) &&
(arcs.get_pt(0, after).y() <= line) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "side = above");
SG_LOG(SG_GENERAL, SG_DEBUG,
"V intersection with clip line from BELOW\n"
<< "or an extra in-clip-line intersection.\n"
<< "Adding intersection to ignore_ints");
ignore_ints.push_back( index );
}
} else if ( side == Below ) {
if ( (arcs.get_pt(0, before).y() >= line) &&
(arcs.get_pt(0, after).y() >= line) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "side = below");
SG_LOG(SG_GENERAL, SG_DEBUG, "V intersection with clip line from above");
SG_LOG(SG_GENERAL, SG_DEBUG, "Adding intersection to ignore_ints");
ignore_ints.push_back( index );
}
if ( (arcs.get_pt(0, before).y() < line) &&
(arcs.get_pt(0, after).y() < line) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "side = below");
SG_LOG(SG_GENERAL, SG_DEBUG, "V intersection with clip line from BELOW");
SG_LOG(SG_GENERAL, SG_DEBUG, "or an extra in-clip-line intersection.");
SG_LOG(SG_GENERAL, SG_DEBUG, "Adding intersection to ignore_ints");
ignore_ints.push_back( index );
}
}
}
}
return true;
}
// test for duplicate nodes
TGPolygon fix_dups( TGPolygon& in )
{
TGPolygon result;
double x_last = -20000.0;
double y_last = -20000.0;
double x, y;
for ( int i = 0; i < (int)in.contour_size(0); ++i ) {
x = in.get_pt(0, i).x();
y = in.get_pt(0, i).y();
if ( (x == x_last) && (y == y_last) ) {
// ignore
} else
result.add_node(0, in.get_pt(0, i));
x_last = x;
y_last = y;
}
return result;
}
// simple polygon clipping routine. Returns the portion of a polygon
// that is above and below a horizontal line of y = a. Only works
// with single contour polygons (no holes.) Returns true if routine
// thinks it was successful.
static bool clip_contour( const TGPolygon& in, const double y,
const fgSideType side,
TGPolygon& result )
{
TGPolygon result_arcs, arcs;
int i, i1, i2, index;
// Step 1: sanity checks
if ( (int)in.contours() != 1 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "we only handle single contour polygons");
return false;
}
if ( (int)in.contour_size( 0 ) < 3 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "we must have at least three vertices to work");
return false;
}
// Step 2: walk through the input polygon and split it into the
// portion that is on or inside the clip line
if ( simple_clip( in, y, side, result_arcs ) ) {
if ( result_arcs.contours() > 0 )
SG_LOG(SG_GENERAL, SG_DEBUG, "result_arcs size = "
<< result_arcs.total_size());
else
SG_LOG(SG_GENERAL, SG_DEBUG, "empty result");
} else
throw sg_exception("simple_clip_above() failed!");
// Step 3: check for trivial cases
result.erase();
// trivial -- nothing inside of clip line
if ( result_arcs.contours() == 0 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "trivially empty");
return true;
}
// trivial -- everything inside of clip line
i1 = find_point( result_arcs, -181.0, y );
if ( i1 < 0 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "trivially full");
result = result_arcs;
return true;
}
// trivial -- single clip line intersection (polygon just nicks
// it) -- everything inside
i2 = find_point( result_arcs, result_arcs.get_pt(0, i1).x(), y );
if ( i2 < 0 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "trivially full (clip line nicks edge)");
result = result_arcs;
return true;
}
// Step 4: If we are finding the "below" clip, reverse the points
// before extracting the cycles. (and remove duplicates)
TGPolygon tmp;
tmp.erase();
if ( side == Below ) {
for ( i = result_arcs.contour_size(0) - 1; i >= 0; --i ) {
Point3D p = result_arcs.get_pt( 0, i );
tmp.add_node( 0, p );
}
} else
tmp = result_arcs;
arcs = fix_dups( tmp );
// Step 5: Build the intersections lists
int_list keep_ints, ignore_ints;
build_intersections( arcs, y, side, keep_ints, ignore_ints );
SG_LOG(SG_GENERAL, SG_DEBUG, "total keep_ints = " << keep_ints.size());
SG_LOG(SG_GENERAL, SG_DEBUG, "total ignore_ints = " << ignore_ints.size());
// Step 6: Walk through the result_arcs and extract the cycles (or
// individual contours.)
int start_int = next_intersection( keep_ints, ignore_ints, 0 );
int next_int = next_intersection( keep_ints, ignore_ints, start_int + 1 );
SG_LOG(SG_GENERAL, SG_DEBUG, "start_int = " << start_int);
SG_LOG(SG_GENERAL, SG_DEBUG, "next_int = " << next_int);
int count = 0;
// while we have keep_ints left to process
while ( start_int >= 0 ) {
point_list contour;
contour.clear();
index = keep_ints[next_int];
keep_ints[next_int] = -1;
SG_LOG(SG_GENERAL, SG_DEBUG, "\nstarting at point = "
<< arcs.get_pt(0, index));
while ( index != keep_ints[start_int] ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "index = " << index
<< " start_int = " << start_int
<< " keep_ints[start_int] = " << keep_ints[start_int]);
// start with the 2nd item in the intersection list and
// traverse until we find another intersection
contour.push_back( arcs.get_pt(0, index) );
index = (index + 1) % arcs.contour_size(0);
while ( (arcs.get_pt(0, index).y() != y) ||
!valid_intersection(index, ignore_ints) ) {
contour.push_back( arcs.get_pt(0, index) );
index = (index + 1) % arcs.contour_size(0);
}
contour.push_back( arcs.get_pt(0, index) );
SG_LOG(SG_GENERAL, SG_WARN, "exited at poly index = "
<< index << " " << arcs.get_pt(0, index));
// find which intersection we came out on in our list
SG_LOG(SG_GENERAL, SG_DEBUG, "finding exit intersection for " << index);
i = 0;
while ( i < (int)keep_ints.size() ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, " keep_int[" << i << "] = " << keep_ints[i]);
if ( index == keep_ints[i] ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " intersection index = " << i);
if ( index != keep_ints[start_int] ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " not start index so keep going");
keep_ints[i] = -1;
next_int = next_intersection( keep_ints, ignore_ints,
i + 1 );
index = keep_ints[next_int];
keep_ints[next_int] = -1;
SG_LOG(SG_GENERAL, SG_DEBUG,
" next_int = " << next_int << " index = "
<< index);
}
break;
}
++i;
}
if ( i == (int)keep_ints.size() )
throw sg_exception("oops, didn't find that intersection, you are screwed");
}
keep_ints[start_int] = -1;
result.add_contour( contour, count );
count++;
// find next keep_ints
start_int = next_intersection( keep_ints, ignore_ints, -1 );
next_int = next_intersection( keep_ints, ignore_ints, start_int + 1 );
SG_LOG(SG_GENERAL, SG_DEBUG, "start_int = " << start_int);
SG_LOG(SG_GENERAL, SG_DEBUG, "next_int = " << next_int);
}
return true;
}
// simple polygon clipping routine. Returns the portion of a polygon
// that is above and below a horizontal line of y = a. Clips
// multi-contour polygons individually and then reassembles the
// results. Doesn't work with holes. Returns true if routine thinks
// it was successful.
TGPolygon horizontal_clip( const TGPolygon& in, const double y,
const fgSideType side )
{
TGPolygon result;
result.erase();
// Step 1: sanity checks
if ( (int)in.contours() == 0 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "Error: 0 contour polygon");
return result;
}
// clip each contour individually
TGPolygon tmp_poly, clip_poly;
point_list contour;
for ( int i = 0; i < in.contours(); ++i ) {
if ( (int)in.contour_size( i ) < 3 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "we must have at least three vertices to work");
return result;
}
tmp_poly.erase();
contour = in.get_contour( i );
tmp_poly.add_contour( contour, 0 );
clip_contour( tmp_poly, y, side, clip_poly );
// add each clip_poly contour to the result poly
for ( int j = 0; j < clip_poly.contours(); ++j ) {
contour = clip_poly.get_contour( j );
result.add_contour( contour, 0 );
}
}
return result;
}

View file

@ -1,53 +0,0 @@
// simple_clip.hxx -- simplistic polygon clipping routine. Returns
// the portion of a polygon that is above or below
// a horizontal line of y = a. Only works with
// single contour polygons (no holes.)
//
// Written by Curtis Olson, started August 1999.
//
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: simple_clip.hxx,v 1.4 2004-11-19 22:25:50 curt Exp $
#ifndef _SIMPLE_CLIP_HXX
#define _SIMPLE_CLIP_HXX
#include "polygon.hxx"
// side type
enum fgSideType {
Above = 0,
Below = 1
};
// simple polygon clipping routine. Returns the portion of a polygon
// that is above and below a horizontal line of y = a. Clips
// multi-contour polygons individually and then reassembles the
// results. Doesn't work with holes. Returns true if routine thinks
// it was successful.
TGPolygon horizontal_clip( const TGPolygon& in, const double y,
const fgSideType side );
#endif // _SIMPLE_CLIP_HXX

View file

@ -31,9 +31,9 @@
#include <simgear/compiler.h>
#include <Geometry/point3d.hxx>
#include <simgear/math/sg_types.hxx>
#include <Polygon/point3d.hxx>
#define FG_PROXIMITY_EPSILON 0.000001
//#define FG_COURSE_EPSILON 0.0003

View file

@ -3,9 +3,9 @@ add_executable(ogr-decode ogr-decode.cxx)
target_link_libraries(ogr-decode
${GDAL_LIBRARY}
Polygon Geometry
${SIMGEAR_CORE_LIBRARIES}
${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
Polygon
${SIMGEAR_CORE_LIBRARIES}
${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
)
install(TARGETS ogr-decode RUNTIME DESTINATION bin)

View file

@ -38,9 +38,6 @@
#include <simgear/misc/sg_path.hxx>
#include <Include/version.h>
#include <Polygon/chop.hxx>
#include <Polygon/index.hxx>
#include <Polygon/names.hxx>
#include <Polygon/polygon.hxx>
/* stretch endpoints to reduce slivers in linear data ~.1 meters */
@ -68,6 +65,19 @@ int num_threads = 1;
SGLockedQueue<OGRFeature *> global_workQueue;
/* very GDAL specific here... */
inline static bool is_ocean_area( const std::string &area ) {
return area == "Ocean" || area == "Bay Estuary or Ocean";
}
inline static bool is_void_area( const std::string &area ) {
return area == "Void Area";
}
inline static bool is_null_area( const std::string& area ) {
return area == "Null";
}
class Decoder : public SGThread
{
public: