747 lines
29 KiB
C++
747 lines
29 KiB
C++
// ____ ______ __
|
|
// / __ \ / ____// /
|
|
// / /_/ // / / /
|
|
// / ____// /___ / /___ PixInsight Class Library
|
|
// /_/ \____//_____/ PCL 2.4.23
|
|
// ----------------------------------------------------------------------------
|
|
// pcl/StarDatabaseFile.h - Released 2022-03-12T18:59:29Z
|
|
// ----------------------------------------------------------------------------
|
|
// This file is part of the PixInsight Class Library (PCL).
|
|
// PCL is a multiplatform C++ framework for development of PixInsight modules.
|
|
//
|
|
// Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved.
|
|
//
|
|
// Redistribution and use in both source and binary forms, with or without
|
|
// modification, is permitted provided that the following conditions are met:
|
|
//
|
|
// 1. All redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
//
|
|
// 2. All redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
//
|
|
// 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
|
|
// of their contributors, may be used to endorse or promote products derived
|
|
// from this software without specific prior written permission. For written
|
|
// permission, please contact info@pixinsight.com.
|
|
//
|
|
// 4. All products derived from this software, in any form whatsoever, must
|
|
// reproduce the following acknowledgment in the end-user documentation
|
|
// and/or other materials provided with the product:
|
|
//
|
|
// "This product is based on software from the PixInsight project, developed
|
|
// by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
|
|
//
|
|
// Alternatively, if that is where third-party acknowledgments normally
|
|
// appear, this acknowledgment must be reproduced in the product itself.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
|
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
// EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
|
|
// INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
|
|
// DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#ifndef __PCL_StarDatabaseFile_h
|
|
#define __PCL_StarDatabaseFile_h
|
|
|
|
/// \file pcl/StarDatabaseFile.h
|
|
|
|
#include <pcl/Defs.h>
|
|
|
|
#include <pcl/AutoPointer.h>
|
|
#include <pcl/Compression.h>
|
|
#include <pcl/File.h>
|
|
#include <pcl/TimePoint.h>
|
|
#include <pcl/Vector.h>
|
|
|
|
namespace pcl
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \defgroup point_source_databases Star Catalogs and Point Source Databases
|
|
*/
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class PCL_CLASS StarDatabaseFile;
|
|
|
|
/*!
|
|
* \class XPSD
|
|
* \brief Base class of point source database implementations.
|
|
*
|
|
* This class defines a set of fundamental data structures, properties and
|
|
* support routines associated with point source database files (XPSD format).
|
|
*
|
|
* \ingroup point_source_databases
|
|
*/
|
|
class PCL_CLASS XPSD
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* \struct pcl::XPSD::Metadata
|
|
* \brief %Metadata items available in point source database files.
|
|
*
|
|
* This structure holds metadata items that can be stored in point source
|
|
* database files (current XPSD format version 1.0). For an existing
|
|
* database file, available metadata are extracted directly from %XML file
|
|
* headers. Currently all items are optional, so all data members of this
|
|
* structure can be empty strings.
|
|
*
|
|
* For generation of new XPSD files, the creationTime and creatorOS members
|
|
* of this structure will be ignored, since the corresponding metadata items
|
|
* will always be defined automatically by the StarDatabaseFile::Serialize()
|
|
* routine. The specified creatorApplication member, if empty, will be
|
|
* replaced in the same routine with a default value identifying the current
|
|
* PCL version.
|
|
*
|
|
* \ingroup point_source_databases
|
|
*/
|
|
struct Metadata
|
|
{
|
|
TimePoint creationTime; //!< The date this file was created.
|
|
String creatorOS; //!< The operating system on which this file was created.
|
|
String creatorApplication; //!< The software application or program that created this file.
|
|
String databaseIdentifier; //!< The unique identifier of the database this file belongs to.
|
|
String databaseVersion; //!< The version of the database this file belongs to.
|
|
String title; //!< A title that represents or identifies this XPSD file.
|
|
String briefDescription; //!< A brief (single-line) description of this XPSD file.
|
|
String description; //!< A full description of the data stored in this XPSD file.
|
|
String organizationName; //!< The name of the organization responsible for this file.
|
|
String authors; //!< The names of one or more persons or groups that have created the data in this file.
|
|
String copyright; //!< Copyright information applicable to the data stored in this XPSD file.
|
|
};
|
|
|
|
/*!
|
|
* \struct pcl::XPSD::Statistics
|
|
* \brief Structural and statistical data about an XPSD database file.
|
|
*
|
|
* This structure provides information about the number of sources included
|
|
* in an XPSD file, as well as critical data about its tree-based database
|
|
* index structure.
|
|
*
|
|
* \ingroup point_source_databases
|
|
*/
|
|
struct Statistics
|
|
{
|
|
uint64 totalSources = 0; //!< The total number of sources included in this database.
|
|
uint32 totalNodes = 0; //!< Number of quadtree index nodes, including structural and leaf nodes.
|
|
uint32 totalLeaves = 0; //!< Number of quadtree index leaf nodes.
|
|
float medianLeafLength = 0; //!< The median of quadtree leaf node lengths.
|
|
uint32 minimumLeafLength = 0; //!< Minimum quadtree leaf node length.
|
|
uint32 maximumLeafLength = 0; //!< Maximum quadtree leaf node length.
|
|
};
|
|
|
|
/*!
|
|
* \struct SearchData
|
|
* \brief Data items and parameters for catalog search operations.
|
|
*
|
|
* The StarData template parameter represents a catalog-specific structure
|
|
* to hold the data associated with a point source extracted during a
|
|
* database search operation.
|
|
*
|
|
* \ingroup point_source_databases
|
|
*/
|
|
template <class StarData>
|
|
struct SearchData
|
|
{
|
|
double centerRA = 0; //!< Field center right ascension coordinate in degrees (search parameter).
|
|
double centerDec = 0; //!< Field center declination coordinate in degrees (search parameter).
|
|
double radius = 1; //!< Field radius in degrees (search parameter).
|
|
float magnitudeLow = -1.5; /*!< Low magnitude (search parameter). Only stars of magnitude greater
|
|
than or equal to this value will be included in the stars list. */
|
|
float magnitudeHigh = 26; /*!< High magnitude (search parameter). Only stars of magnitude less
|
|
than or equal to this value will be included in the stars list. */
|
|
uint32 sourceLimit = uint32_max; /*!< The search will not include more objects than this limit
|
|
in the stars list (search parameter). */
|
|
uint32 requiredFlags = 0u; /*!< Required flags (search parameter). If non-zero, only stars with
|
|
\e all of these flags set will be included in the stars list. */
|
|
uint32 inclusionFlags = 0u; /*!< Inclusion flags (search parameter). If non-zero, only stars with
|
|
\e any of these flags set will be included in the stars list. */
|
|
uint32 exclusionFlags = 0u; /*!< Exclusion flags (search parameter). Stars with \e any of these flags
|
|
set will \e not be included in the stars list. */
|
|
|
|
Array<StarData> stars; //!< The list of stars found by the search operation (output data).
|
|
uint32 excessCount = 0u; /*!< When \a sourceLimit is exceeded, this is the number of
|
|
additional objects found but not included in the stars list (output data). */
|
|
uint32 rejectCount = 0u; /*!< Total number of rejected objects (output data). This refers to
|
|
point sources that have been tested for inclusion in the search
|
|
result, but have not matched the search criteria. */
|
|
double timeTotal = 0; //!< Total search time in seconds (output data).
|
|
double timeIO = 0; //!< Time consumed by I/O operations in seconds (output data).
|
|
uint32 countIO = 0u; //!< Total number of I/O operations performed (output data).
|
|
double timeUncompress = 0; //!< Time consumed by data uncompression in seconds (output data).
|
|
double timeDecode = 0; //!< Time consumed by data decoding in seconds (output data).
|
|
|
|
/*!
|
|
* Sets all search result data items to null values.
|
|
*/
|
|
void ResetSearchResults()
|
|
{
|
|
stars.Clear();
|
|
excessCount = rejectCount = 0u;
|
|
timeTotal = timeIO = 0;
|
|
countIO = 0u;
|
|
timeUncompress = timeDecode = 0;
|
|
}
|
|
};
|
|
|
|
protected:
|
|
|
|
struct ChildNodeData
|
|
{
|
|
// Zero-based quadtree child node positions in an index node array.
|
|
uint32 nw; // top-left child node
|
|
uint32 ne; // top-right child node
|
|
uint32 sw; // bottom-left child node
|
|
uint32 se; // bottom-right child node
|
|
};
|
|
|
|
#ifdef _MSC_VER
|
|
/*
|
|
* Our favorite brain-damaged thing does not know how to implement bit
|
|
* fields. Oh well...
|
|
*/
|
|
struct LeafNodeData
|
|
{
|
|
uint64 blockOffsetAndLeafFlag;
|
|
uint32 blockSize;
|
|
uint32 compressedBlockSize;
|
|
};
|
|
#else
|
|
struct LeafNodeData
|
|
{
|
|
uint64 blockOffset : 63; // position of source data block, byte offset
|
|
bool leafFlag : 1; // quadtree node type: 0=structural 1=leaf
|
|
uint32 blockSize; // size of point source data, in bytes
|
|
uint32 compressedBlockSize; // size of compressed data, in bytes
|
|
};
|
|
#endif
|
|
|
|
/*
|
|
* Quadtree index node (48 bytes).
|
|
*/
|
|
struct IndexNode
|
|
{
|
|
// Projected coordinates of quadtree node rectangle.
|
|
double x0; // left
|
|
double y0; // top
|
|
double x1; // right
|
|
double y1; // bottom
|
|
|
|
// Quadtree child node indexes or leaf node data.
|
|
union { ChildNodeData child;
|
|
LeafNodeData leaf; } index;
|
|
|
|
IndexNode()
|
|
{
|
|
static_assert( sizeof( *this ) == 48, "Invalid sizeof( XPSD::IndexNode )" );
|
|
static_assert( sizeof( ChildNodeData ) == 16, "Invalid sizeof( XPSD::ChildNodeData )" );
|
|
static_assert( sizeof( LeafNodeData ) == 16, "Invalid sizeof( XPSD::LeafNodeData )" );
|
|
static_assert( sizeof( index ) == 16, "Invalid sizeof( XPSD::IndexNode::index )" );
|
|
|
|
index.child.nw = index.child.ne = index.child.sw = index.child.se = 0;
|
|
}
|
|
|
|
bool IsLeaf() const
|
|
{
|
|
#ifdef _MSC_VER
|
|
return (index.leaf.blockOffsetAndLeafFlag & 0x8000000000000000) != 0;
|
|
#else
|
|
return index.leaf.leafFlag;
|
|
#endif
|
|
}
|
|
|
|
uint64 BlockOffset() const
|
|
{
|
|
#ifdef _MSC_VER
|
|
return index.leaf.blockOffsetAndLeafFlag & 0x7FFFFFFFFFFFFFFF;
|
|
#else
|
|
return index.leaf.blockOffset;
|
|
#endif
|
|
}
|
|
|
|
uint32 BlockSize() const
|
|
{
|
|
return index.leaf.blockSize;
|
|
}
|
|
|
|
uint32 CompressedBlockSize() const
|
|
{
|
|
return index.leaf.compressedBlockSize;
|
|
}
|
|
};
|
|
|
|
static double Distance( double lon1, double lat1, double lon2, double lat2 )
|
|
{
|
|
return Vector::FromSpherical( Rad( lon1 ), Rad( lat1 ) ).Angle3D( Vector::FromSpherical( Rad( lon2 ), Rad( lat2 ) ) );
|
|
}
|
|
|
|
static double CrossTrackDistance( double lon, double lat, double lon1, double lat1, double lon2, double lat2 )
|
|
{
|
|
if ( lon == lon1 )
|
|
if ( lat == lat1 )
|
|
return 0;
|
|
|
|
Vector p = Vector::FromSpherical( Rad( lon ), Rad( lat ) );
|
|
Vector c = Vector::FromSpherical( Rad( lon1 ), Rad( lat1 ) ).Cross( Vector::FromSpherical( Rad( lon2 ), Rad( lat2 ) ) );
|
|
return c.Angle3D( p ) - Pi()/2;
|
|
}
|
|
|
|
static bool WithinExtent( double lon, double lat, double lon1, double lat1, double lon2, double lat2 )
|
|
{
|
|
if ( lon1 == lon2 )
|
|
if ( lat1 == lat2 )
|
|
return lon == lon1 && lat == lat1; // null segment
|
|
|
|
Vector n0 = Vector::FromSpherical( Rad( lon ), Rad( lat ) );
|
|
Vector n1 = Vector::FromSpherical( Rad( lon1 ), Rad( lat1 ) );
|
|
Vector n2 = Vector::FromSpherical( Rad( lon2 ), Rad( lat2 ) );
|
|
|
|
// Get vectors representing p0->p1, p0->p2, p1->p2, p2->p1
|
|
Vector d10 = n0 - n1, d12 = n2 - n1;
|
|
Vector d20 = n0 - n2, d21 = n1 - n2;
|
|
|
|
// Dot product d10*d12 tells us if p0 is on p2 side of p1, similarly for d20*d21
|
|
if ( d10 * d12 >= 0 )
|
|
if ( d20 * d21 >= 0 )
|
|
return (n0 * n1) >= 0 && (n0 * n2) >= 0; // same hemisphere
|
|
|
|
return false;
|
|
}
|
|
|
|
static bool InRegion( double lon, double lat,
|
|
double lon1, double lat1, double lon2, double lat2,
|
|
double lon3, double lat3, double lon4, double lat4 )
|
|
{
|
|
Vector p = Vector::FromSpherical( Rad( lon ), Rad( lat ) );
|
|
Vector v1 = p - Vector::FromSpherical( Rad( lon1 ), Rad( lat1 ) );
|
|
Vector v2 = p - Vector::FromSpherical( Rad( lon2 ), Rad( lat2 ) );
|
|
Vector v3 = p - Vector::FromSpherical( Rad( lon3 ), Rad( lat3 ) );
|
|
Vector v4 = p - Vector::FromSpherical( Rad( lon4 ), Rad( lat4 ) );
|
|
return Abs( v1.Angle3D( v2, p ) + v2.Angle3D( v3, p ) + v3.Angle3D( v4, p ) + v4.Angle3D( v1, p ) ) > Pi();
|
|
}
|
|
|
|
enum projection_type { Equirectangular, TransverseEquirectangular, AzimuthalEquidistant };
|
|
|
|
static String ProjectionToAttributeValue( int );
|
|
static projection_type ProjectionFromAttributeValue( const String& );
|
|
|
|
class IndexTree
|
|
{
|
|
public:
|
|
|
|
IndexTree( StarDatabaseFile* parent,
|
|
projection_type projection, double centerRA, double centerDec,
|
|
const Array<IndexNode>& nodes )
|
|
: m_parent( parent )
|
|
, m_projection( projection )
|
|
, m_centerRA( centerRA )
|
|
, m_centerDec( centerDec )
|
|
, m_nodes( nodes )
|
|
{
|
|
}
|
|
|
|
IndexTree() = default;
|
|
IndexTree( const IndexTree& ) = default;
|
|
|
|
void Project( double& x, double& y, double ra, double dec ) const
|
|
{
|
|
switch( m_projection )
|
|
{
|
|
default: // ?!
|
|
case Equirectangular:
|
|
x = ra - m_centerRA;
|
|
y = dec;
|
|
break;
|
|
case AzimuthalEquidistant:
|
|
{
|
|
double sa, ca;
|
|
SinCos( Rad( ra ), sa, ca );
|
|
double r = 90 - Abs( dec );
|
|
x = r*sa;
|
|
y = r*ca;
|
|
}
|
|
break;
|
|
case TransverseEquirectangular:
|
|
{
|
|
double sa, ca;
|
|
SinCos( Rad( ra ), sa, ca );
|
|
double sd, cd;
|
|
SinCos( Rad( Abs( dec ) ), sd, cd );
|
|
x = Deg( ArcSin( cd*sa ) );
|
|
y = Deg( ArcTan( sd, cd*ca ) ) - 90;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Unproject( double& ra, double& dec, double x, double y ) const
|
|
{
|
|
switch( m_projection )
|
|
{
|
|
default: // ?!
|
|
case Equirectangular:
|
|
ra = x + m_centerRA;
|
|
dec = y;
|
|
break;
|
|
case AzimuthalEquidistant:
|
|
x = Rad( x );
|
|
y = Rad( y );
|
|
ra = Deg( ArcTan( x, y ) );
|
|
if ( ra < 0 )
|
|
ra += 360;
|
|
dec = Deg( ArcSin( Cos( Sqrt( x*x + y*y ) ) ) );
|
|
if ( m_centerDec < 0 )
|
|
dec = -dec;
|
|
break;
|
|
case TransverseEquirectangular:
|
|
{
|
|
double sx, cx;
|
|
SinCos( Rad( x ), sx, cx );
|
|
double sy, cy;
|
|
SinCos( Rad( y + 90 ), sy, cy );
|
|
ra = Deg( ArcTan( sx, cx*cy ) );
|
|
if ( ra < 0 )
|
|
ra += 360;
|
|
dec = Deg( ArcSin( sy*cx ) );
|
|
if ( m_centerDec < 0 )
|
|
dec = -dec;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Search( double ra, double dec, double r, void* searchData ) const
|
|
{
|
|
SearchRecursive( 0, ra, dec, r, searchData );
|
|
}
|
|
|
|
private:
|
|
|
|
StarDatabaseFile* m_parent = nullptr;
|
|
projection_type m_projection = Equirectangular;
|
|
double m_centerRA = 0;
|
|
double m_centerDec = 0;
|
|
Array<IndexNode> m_nodes;
|
|
|
|
void GetNodeBounds( double& ra1, double& dec1, double& ra2, double& dec2,
|
|
double& ra3, double& dec3, double& ra4, double& dec4, const IndexNode& node ) const
|
|
{
|
|
Unproject( ra1, dec1, node.x0, node.y0 );
|
|
Unproject( ra2, dec2, node.x1, node.y0 );
|
|
Unproject( ra3, dec3, node.x1, node.y1 );
|
|
Unproject( ra4, dec4, node.x0, node.y1 );
|
|
}
|
|
|
|
bool InNodeRegion( double ra, double dec, const IndexNode& node ) const
|
|
{
|
|
double ra1, dec1, ra2, dec2, ra3, dec3, ra4, dec4;
|
|
GetNodeBounds( ra1, dec1, ra2, dec2, ra3, dec3, ra4, dec4, node );
|
|
return InRegion( ra, dec, ra1, dec1, ra2, dec2, ra3, dec3, ra4, dec4 );
|
|
}
|
|
|
|
bool IntersectsNodeRegion( double ra, double dec, double r, const IndexNode& node ) const
|
|
{
|
|
double ra1, dec1, ra2, dec2, ra3, dec3, ra4, dec4;
|
|
GetNodeBounds( ra1, dec1, ra2, dec2, ra3, dec3, ra4, dec4, node );
|
|
double rr = Rad( r );
|
|
return InRegion( ra, dec, ra1, dec1, ra2, dec2, ra3, dec3, ra4, dec4 )
|
|
|| Distance( ra, dec, ra1, dec1 ) < rr
|
|
|| Distance( ra, dec, ra2, dec2 ) < rr
|
|
|| Distance( ra, dec, ra3, dec3 ) < rr
|
|
|| Distance( ra, dec, ra4, dec4 ) < rr
|
|
|| WithinExtent( ra, dec, ra1, dec1, ra2, dec2 ) && CrossTrackDistance( ra, dec, ra1, dec1, ra2, dec2 ) < rr
|
|
|| WithinExtent( ra, dec, ra2, dec2, ra3, dec3 ) && CrossTrackDistance( ra, dec, ra2, dec2, ra3, dec3 ) < rr
|
|
|| WithinExtent( ra, dec, ra3, dec3, ra4, dec4 ) && CrossTrackDistance( ra, dec, ra3, dec3, ra4, dec4 ) < rr
|
|
|| WithinExtent( ra, dec, ra4, dec4, ra1, dec1 ) && CrossTrackDistance( ra, dec, ra4, dec4, ra1, dec1 ) < rr;
|
|
}
|
|
|
|
// Defined after StarDatabaseFile declaration.
|
|
void SearchRecursive( uint32 nodeIndex, double ra, double dec, double r, void* searchData ) const;
|
|
|
|
friend class StarDatabaseFile;
|
|
};
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class StarDatabaseFile
|
|
* \brief Point source and star catalog database files (XPSD format).
|
|
*
|
|
* This class implements fast access to point source data stored in XPSD files
|
|
* (Extensible Point Source Database format). It also implements serialization
|
|
* of new XPSD files from existing point source or star catalog data.
|
|
*
|
|
* On the PixInsight/PCL platform, the XPSD file format allows for fast and
|
|
* efficient access to large star catalogs, such as Gaia (as of writing this
|
|
* documentation the Gaia DR2 and EDR3 catalogs are available) or PPMXL. The
|
|
* XPSD format allows for serialization of general purpose star catalogs, with
|
|
* special emphasis on astrometric and photometric data.
|
|
*
|
|
* \ingroup point_source_databases
|
|
*/
|
|
class PCL_CLASS StarDatabaseFile : public XPSD
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Default constructor.
|
|
*
|
|
* Constructs an invalid instance that cannot be used until initialized by
|
|
* calling the Open() member function.
|
|
*/
|
|
StarDatabaseFile() = default;
|
|
|
|
/*!
|
|
* Constructs a &StarDatabaseFile instance initialized from the specified
|
|
* point source database file in XPSD format.
|
|
*
|
|
* In the event of errors or invalid data, this constructor will throw the
|
|
* appropriate Error exception.
|
|
*/
|
|
StarDatabaseFile( const String& filePath )
|
|
{
|
|
Open( filePath );
|
|
}
|
|
|
|
/*!
|
|
* Move constructor.
|
|
*/
|
|
StarDatabaseFile( StarDatabaseFile&& ) = default;
|
|
|
|
/*!
|
|
* Move assignment operator. Returns a reference to this object.
|
|
*/
|
|
StarDatabaseFile& operator =( StarDatabaseFile&& ) = default;
|
|
|
|
/*!
|
|
* Deleted copy constructor. %StarDatabaseFile instances are unique, hence
|
|
* cannot be copied.
|
|
*/
|
|
StarDatabaseFile( const StarDatabaseFile& ) = delete;
|
|
|
|
/*!
|
|
* Deleted copy assignment operator. %StarDatabaseFile instances are unique,
|
|
* hence cannot be copied.
|
|
*/
|
|
StarDatabaseFile& operator =( const StarDatabaseFile& ) = delete;
|
|
|
|
/*!
|
|
* Virtual destructor.
|
|
*/
|
|
virtual ~StarDatabaseFile() noexcept( false )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Initializes this object to provide access to the specified point source
|
|
* database file in XPSD format.
|
|
*
|
|
* This member function opens an existing file at the specified \a filePath,
|
|
* loads and parses its XML header, and loads the file indexes ready for
|
|
* fast access to point source data. The file will remain open until this
|
|
* object is destroyed, or until a new call to this function is made.
|
|
*
|
|
* If a previous file was already opened by this instance, it will be closed
|
|
* and all associated control and file indexing structures will be destroyed
|
|
* and deallocated, before accessing the new file.
|
|
*/
|
|
void Open( const String& filePath );
|
|
|
|
/*!
|
|
* Closes the point source database file represented by this object and
|
|
* resets all internal structures to a default, uninitialized state.
|
|
*
|
|
* If a previous file was already opened by this instance, it will be closed
|
|
* and all associated control and file indexing structures will be destroyed
|
|
* and deallocated. If no file is currently open, calling this member has no
|
|
* effect.
|
|
*/
|
|
void Close();
|
|
|
|
/*!
|
|
* Returns true iff this object has an open database file and is ready for
|
|
* point source data retrieval.
|
|
*/
|
|
bool IsOpen() const
|
|
{
|
|
return m_file.IsOpen();
|
|
}
|
|
|
|
/*!
|
|
* Returns the path of the point source database file represented by this
|
|
* object. Returned file paths are always absolute, full file paths.
|
|
*/
|
|
const String& FilePath() const
|
|
{
|
|
return m_file.FilePath();
|
|
}
|
|
|
|
/*!
|
|
* Returns the low limiting magnitude of this database file. All contained
|
|
* sources should have magnitudes greater than the value returned by this
|
|
* function.
|
|
*/
|
|
float MagnitudeLow() const
|
|
{
|
|
return m_magnitudeLow;
|
|
}
|
|
|
|
/*!
|
|
* Returns the high limiting magnitude of this database file. All contained
|
|
* sources should have magnitudes less than or equal to the value returned
|
|
* by this function.
|
|
*/
|
|
float MagnitudeHigh() const
|
|
{
|
|
return m_magnitudeHigh;
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) set of metadata items available in
|
|
* the point source database file loaded by this object.
|
|
*/
|
|
const XPSD::Metadata& Metadata() const
|
|
{
|
|
return m_metadata;
|
|
}
|
|
|
|
/*!
|
|
* Returns a reference to the (immutable) set of statistical and structural
|
|
* information items available in the point source database file loaded by
|
|
* this object.
|
|
*/
|
|
const XPSD::Statistics& Statistics() const
|
|
{
|
|
return m_statistics;
|
|
}
|
|
|
|
/*!
|
|
* Generates a file to store a point source database in XPSD format.
|
|
*
|
|
* \param filePath Path to the file that will be generated in the local
|
|
* filesystem. The file name should carry the '.xpsd'
|
|
* suffix.
|
|
*
|
|
* \param metadata Reference to an XPSD::Metadata structure with
|
|
* optional metadata information that will be included
|
|
* in the generated XPSD file.
|
|
*
|
|
* \param statistics Reference to an XPSD::Statistics structure with
|
|
* statistical and structural information about the
|
|
* XPSD database, which will be included in the
|
|
* generated XPSD file.
|
|
*
|
|
* \param magnitudeLow Low limiting magnitude. All point sources serialized
|
|
* in the \a data array should have magnitudes greater
|
|
* than the value of this parameter.
|
|
*
|
|
* \param magnitudeHigh High limiting magnitude. All point sources
|
|
* serialized in the \a data array should have
|
|
* magnitudes less than or equal to the value of this
|
|
* parameter.
|
|
*
|
|
* \param index Array of quadtree index structures.
|
|
*
|
|
* \param data Serialized point source data.
|
|
*
|
|
* \param compression Pointer to a Compression object used to compress
|
|
* point source data blocks (leaf node data), or
|
|
* nullptr if no compression has been applied. If
|
|
* specified, this object will be used exclusively to
|
|
* gather information about the compression algorithm
|
|
* and parameters used, \e not to compress any data.
|
|
*
|
|
* In the event of invalid, incongruent or malformed data, or if an I/O
|
|
* error occurs, this function will throw an Error exception.
|
|
*
|
|
* \warning If a file already exists at the specified path, its previous
|
|
* contents will be lost after calling this function.
|
|
*/
|
|
static void Serialize( const String& filePath,
|
|
const XPSD::Metadata& metadata,
|
|
const XPSD::Statistics& statistics,
|
|
float magnitudeLow, float magnitudeHigh,
|
|
const Array<XPSD::IndexTree>& index,
|
|
const ByteArray& data,
|
|
const Compression* compression = nullptr );
|
|
|
|
protected:
|
|
|
|
mutable File m_file;
|
|
XPSD::Metadata m_metadata;
|
|
XPSD::Statistics m_statistics;
|
|
float m_magnitudeLow = 0;
|
|
float m_magnitudeHigh = 0;
|
|
Array<XPSD::IndexTree> m_index;
|
|
uint64 m_dataPosition = 0;
|
|
AutoPointer<Compression> m_compression;
|
|
|
|
virtual void LoadData( void* block, uint64 offset, uint32 size, void* ) const
|
|
{
|
|
m_file.SetPosition( m_dataPosition + offset );
|
|
m_file.Read( block, size );
|
|
}
|
|
|
|
virtual void Uncompress( ByteArray& block, uint32 uncompressedSize, void* ) const
|
|
{
|
|
if ( m_compression )
|
|
block = m_compression->Uncompress( block, uncompressedSize );
|
|
}
|
|
|
|
virtual void GetEncodedData( const ByteArray&, const XPSD::IndexTree&, const XPSD::IndexNode&, void* ) const = 0;
|
|
|
|
friend class XPSD::IndexTree;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
inline void
|
|
XPSD::IndexTree::SearchRecursive( uint32 nodeIndex, double ra, double dec, double r, void* searchData ) const
|
|
{
|
|
const IndexNode& node = m_nodes[nodeIndex];
|
|
if ( IntersectsNodeRegion( ra, dec, r, node ) )
|
|
{
|
|
if ( node.IsLeaf() )
|
|
{
|
|
ByteArray block( size_type( node.CompressedBlockSize() ) );
|
|
m_parent->LoadData( block.Begin(), node.BlockOffset(), node.CompressedBlockSize(), searchData );
|
|
if ( node.CompressedBlockSize() != node.BlockSize() )
|
|
m_parent->Uncompress( block, node.BlockSize(), searchData );
|
|
m_parent->GetEncodedData( block, *this, node, searchData );
|
|
}
|
|
else
|
|
{
|
|
if ( node.index.child.nw != 0 )
|
|
SearchRecursive( node.index.child.nw, ra, dec, r, searchData );
|
|
if ( node.index.child.ne != 0 )
|
|
SearchRecursive( node.index.child.ne, ra, dec, r, searchData );
|
|
if ( node.index.child.sw != 0 )
|
|
SearchRecursive( node.index.child.sw, ra, dec, r, searchData );
|
|
if ( node.index.child.se != 0 )
|
|
SearchRecursive( node.index.child.se, ra, dec, r, searchData );
|
|
}
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
} // pcl
|
|
|
|
#endif // __PCL_StarDatabaseFile_h
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// EOF pcl/StarDatabaseFile.h - Released 2022-03-12T18:59:29Z
|