This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Unable to create Map from a boost::int16_t array

Tags: None
(comma "," separated)
storri
Registered Member
Posts
2
Karma
0
Problem Scope: I have a project where I need to read in DTED level 1 and 2 data from files using GDAL. I have GDAL reading the data in blocks into a short array.

Goal: To create a Eigen Map that contains a N x M tiles of DTED data. For example if am reading DTED2 level 2 data (3601x3601) starting at a given coordinate (latitude,longitude) spanning two rows and two columns. The resulting Map should be able to hold the (7201x7201) elements. (NOTE: The 3601st entry is a copy of the first row of the next tile)

For example, say I have a simplified DTED tile that is 2x2 elevation points for latitude 20N and longitude 30E where I want to read for 1 degrees above 20N (2 rows) and 1 degrees to east of 30E (2 columns). The destination matrix would be a size of 4x4:

[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
[0 0 0 0]


I would like to be able to copy each DTED tile into the matrix. So the tile at 20N,30E would go into the matrix as:

[0 0 0 0]
[0 0 0 0]
[6 8 0 0]
[5 3 0 0]


and 20N,31E would go in as:

[0 0 0 0]
[0 0 0 0]
[6 8 6 6]
[5 3 4 5]



Code
:
Code: Select all
  template <unsigned int Increment>
  void DTED<Increment>::read_dted_file ( boost::filesystem::path const& file,
                                        int position_index,
                                        boost::shared_ptr<WritePosition> position_obj )
  {
    LOG_FUNCTION
    log::record_debug ( "DTED File: %1%", file );
    log::record_debug ( "Position index: %1%", position_index );
    log::record_debug ( position_obj );

    // Open the target DTED data file
    GDALDataset* dataset = (GDALDataset*) GDALOpen ( file.string().c_str(), GA_ReadOnly );
    if ( dataset == NULL )
      {
        throw MissingFileError(file.string());
      }

    // Get Band for index position                                                                                                         
    // The GDALDataSet only contains one GDALRasterBand for DTED ata                 
    GDALRasterBand* band = dataset->GetRasterBand ( 1 );
    log::record_debug ( "Raster dimension: (%1%,%2%)", band->GetXSize(), band->GetYSize() );
   
    //Calculate the number of blocks of DTED data that must be read
    //from the GDALRasterBand
    int nXSize = 0;
    int nYSize = 0;
    band->GetBlockSize ( &nXSize, &nYSize );
    log::record_debug ( "Raster block dimension: (%1%,%2%)", nXSize, nYSize );
    int nXBlocks = ( band->GetXSize() + nXSize - 1 ) / nXSize;
    int nYBlocks = ( band->GetYSize() + nYSize - 1 ) / nYSize;
    log::record_debug ( "Raster block count: (%1%,%2%)", nXBlocks, nYBlocks );
    log::record_debug ( "Raster data type: %1%", band->GetRasterDataType() );

    // Create destination array
    short* dted_data = Eigen::ei_aligned_new<short>(nXSize * nYSize);

    // Read in blocks of data
    for ( int iYBlock = 0; iYBlock < nYBlocks; iYBlock++ )
      {
        for ( int iXBlock = 0; iXBlock < nXBlocks; iXBlock++ )
          {
            log::record_debug("Reading (%1%,%2%)", iXBlock, iYBlock );
            band->ReadBlock ( iXBlock, iYBlock, dted_data );
          }
      }

    // Line of code below is at DTED_T.inl:213
    // Point of Error: See description below
    Eigen::Map<Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic> > data_map ( dted_data );

    m_elevation_data.block ( position_obj->x, position_obj->Y, position_obj->rows, position_obj->columns ).swap ( data_map );
}


Where m_elevation_data is defined as:
Code: Select all
Eigen::MatrixXi m_elevation_data;


As well as WritePosition is defined as:
Code: Select all
namespace dted {

  struct WritePosition
  {
    int X;
    int Y;
    int columns;
    int rows;
  };

} // namespace dted 

Error: The error is the user of Eigen and not Eigen itself. I am new to this set of headers and therefore I am sure I am not using it quite correctly. What I am concerned about is the conversion from a set of signed 16-bit integer values into the Eigen Map. The code above results in the following set of error messages:
[ 50%] Building CXX object CMakeFiles/dted.dir/dted/Interface.cpp.o
In file included from /home/storri/Documents/Code/dted/dted/DTED_T.hpp:89,
from /home/storri/Documents/Code/dted/dted/DTED_Level_One.hpp:4,
from /home/storri/Documents/Code/dted/dted/DTED_Factory.hpp:5,
from /home/storri/Documents/Code/dted/dted/Interface.cpp:3:
/home/storri/Documents/Code/dted/dted/DTED_T.inl: In member function ‘void dted::DTED<Increment>::read_dted_file(const boost::filesystem2::path&, int, boost::shared_ptr<dted::WritePosition>) [with unsigned int Increment = 1200u]’:
/home/storri/Documents/Code/dted/dted/DTED_T.inl:96: instantiated from ‘void dted::DTED<Increment>::init_impl(std::string, double, double, unsigned int, unsigned int) [with unsigned int Increment = 1200u]’
/home/storri/Documents/Code/dted/dted/DTED_Level_One.hpp:25: instantiated from here
/home/storri/Documents/Code/dted/dted/DTED_T.inl:213: error: no matching function for call to ‘Eigen::Map<Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, 1>::Map(short int*&)’
/usr/local/include/eigen2/Eigen/src/Core/Map.h:78: note: candidates are: Eigen::Map<MatrixType, PacketAccess>::Map(const typename Eigen::ei_traits<Eigen::Map<MatrixType, _PacketAccess> >::Scalar*, int, int) [with MatrixType = Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, int PacketAccess = 1]
/usr/local/include/eigen2/Eigen/src/Core/Map.h:76: note: Eigen::Map<MatrixType, PacketAccess>::Map(const typename Eigen::ei_traits<Eigen::Map<MatrixType, _PacketAccess> >::Scalar*, int) [with MatrixType = Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, int PacketAccess = 1]
/usr/local/include/eigen2/Eigen/src/Core/Map.h:74: note: Eigen::Map<MatrixType, PacketAccess>::Map(const typename Eigen::ei_traits<Eigen::Map<MatrixType, _PacketAccess> >::Scalar*) [with MatrixType = Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, int PacketAccess = 1]
/usr/local/include/eigen2/Eigen/src/Core/Map.h:61: note: Eigen::Map<Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, 1>::Map(const Eigen::Map<Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, 1>&)
/home/storri/Documents/Code/dted/dted/DTED_T.inl: In member function ‘void dted::DTED<Increment>::read_dted_file(const boost::filesystem2::path&, int, boost::shared_ptr<dted::WritePosition>) [with unsigned int Increment = 3600u]’:
/home/storri/Documents/Code/dted/dted/DTED_T.inl:96: instantiated from ‘void dted::DTED<Increment>::init_impl(std::string, double, double, unsigned int, unsigned int) [with unsigned int Increment = 3600u]’
/home/storri/Documents/Code/dted/dted/DTED_Level_Two.hpp:25: instantiated from here
/home/storri/Documents/Code/dted/dted/DTED_T.inl:213: error: no matching function for call to ‘Eigen::Map<Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, 1>::Map(short int*&)’
/usr/local/include/eigen2/Eigen/src/Core/Map.h:78: note: candidates are: Eigen::Map<MatrixType, PacketAccess>::Map(const typename Eigen::ei_traits<Eigen::Map<MatrixType, _PacketAccess> >::Scalar*, int, int) [with MatrixType = Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, int PacketAccess = 1]
/usr/local/include/eigen2/Eigen/src/Core/Map.h:76: note: Eigen::Map<MatrixType, PacketAccess>::Map(const typename Eigen::ei_traits<Eigen::Map<MatrixType, _PacketAccess> >::Scalar*, int) [with MatrixType = Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, int PacketAccess = 1]
/usr/local/include/eigen2/Eigen/src/Core/Map.h:74: note: Eigen::Map<MatrixType, PacketAccess>::Map(const typename Eigen::ei_traits<Eigen::Map<MatrixType, _PacketAccess> >::Scalar*) [with MatrixType = Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, int PacketAccess = 1]
/usr/local/include/eigen2/Eigen/src/Core/Map.h:61: note: Eigen::Map<Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, 1>::Map(const Eigen::Map<Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, 1>&)
make[2]: *** [CMakeFiles/dted.dir/dted/Interface.cpp.o] Error 1
make[1]: *** [CMakeFiles/dted.dir/all] Error 2
make: *** [all] Error 2
User avatar
bjacob
Registered Member
Posts
658
Karma
3
storri wrote:/home/storri/Documents/Code/dted/dted/DTED_T.inl:213: error: no matching function for call to ‘Eigen::Map<Eigen::Matrix<int, 10000, 10000, 2, 10000, 10000>, 1>::Map(short int*&)’


This error means that the Eigen::Map<MatrixXi> constructor wants a int* pointer and you're trying to pass it a short int*.

In Eigen, the type suffix 'i' means int, not short int. Eigen 2 has limited support for other integer types out of the box (but it's very easy to add support for more types). Eigen 3, on the other hand, supports every integer type out of the box, so you can without problem do:

typedef Matrix<short int, Dynamic, Dynamic> MatrixXsi;

and then use that type with Map<MatrixXsi>.


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
storri
Registered Member
Posts
2
Karma
0
bjacob wrote:In Eigen, the type suffix 'i' means int, not short int. Eigen 2 has limited support for other integer types out of the box (but it's very easy to add support for more types). Eigen 3, on the other hand, supports every integer type out of the box, so you can without problem do:

typedef Matrix<short int, Dynamic, Dynamic> MatrixXsi;

and then use that type with Map<MatrixXsi>.


I used the example you gave above with the Eigen 2 code. I now get an error with the NumTraits which is what I think you said Eigen 3 takes care of for me. Which version of Eigen was I suppose to use with the typedef for MatrixXsi you gave me?

Start of errors:
Code: Select all
In file included from /usr/local/include/eigen2/Eigen/Core:130,
                 from dted_stl_map_test.cpp:2:
/usr/local/include/eigen2/Eigen/src/Core/Matrix.h: In instantiation of ‘Eigen::ei_traits<Eigen::Matrix<short int, 10000, 10000, 2, 10000, 10000> >’:
/usr/local/include/eigen2/Eigen/src/Core/MatrixBase.h:62:   instantiated from ‘Eigen::MatrixBase<Eigen::Matrix<short int, 10000, 10000, 2, 10000, 10000> >’
/usr/local/include/eigen2/Eigen/src/Core/Matrix.h:129:   instantiated from ‘Eigen::Matrix<short int, 10000, 10000, 2, 10000, 10000>’
dted_stl_map_test.cpp:218:   instantiated from here
/usr/local/include/eigen2/Eigen/src/Core/Matrix.h:116: error: incomplete type ‘Eigen::NumTraits<short int>’ used in nested name specifier
User avatar
bjacob
Registered Member
Posts
658
Karma
3
storri wrote:
I used the example you gave above with the Eigen 2 code. I now get an error with the NumTraits which is what I think you said Eigen 3 takes care of for me. Which version of Eigen was I suppose to use with the typedef for MatrixXsi you gave me?


This was intended for eigen 3.

With Eigen 2, you'll have to add support for short ints, as explained here:
http://eigen.tuxfamily.org/dox/Customiz ... ScalarType


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!


Bookmarks



Who is online

Registered users: Bing [Bot], blue_bullet, Google [Bot], rockscient, Yahoo [Bot]