LCOV - code coverage report
Current view: top level - ugbase/common/util - raster_impl.hpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 224 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 74 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2016:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG_raster_impl
      34              : #define __H__UG_raster_impl
      35              : 
      36              : #include <limits>
      37              : #include <cstring>
      38              : #include <algorithm>
      39              : #include <fstream>
      40              : #include "common/error.h"
      41              : #include "common/util/file_util.h"
      42              : #include "common/util/string_util.h"
      43              : #include "raster_kernels.h"
      44              : 
      45              : namespace ug{
      46              : 
      47              : ////////////////////////////////////////////////////////////////////////////////
      48              : //      Raster::MultiIndex
      49              : 
      50              : template <class T, int TDIM>
      51            0 : Raster<T, TDIM>::MultiIndex::
      52              : MultiIndex()
      53              : {}
      54              : 
      55              : template <class T, int TDIM>
      56            0 : Raster<T, TDIM>::MultiIndex::
      57              : MultiIndex(size_t i)
      58              : {
      59              :         set(i);
      60              : }
      61              : 
      62              : template <class T, int TDIM>
      63              : int Raster<T, TDIM>::MultiIndex::
      64              : dim () const                            
      65              : {
      66              :         return TDIM;
      67              : }
      68              : 
      69              : template <class T, int TDIM>
      70              : void Raster<T, TDIM>::MultiIndex::
      71              : set (size_t i)                          
      72              : {
      73            0 :         for(int d = 0; d < TDIM; ++d)
      74            0 :                 m_ind[d] = i;
      75              : }
      76              : 
      77              : template <class T, int TDIM>
      78              : size_t& Raster<T, TDIM>::MultiIndex::
      79              : operator[] (int d)                      
      80              : {
      81              :         return m_ind[d];
      82              : }
      83              : 
      84              : template <class T, int TDIM>
      85              : size_t Raster<T, TDIM>::MultiIndex::
      86              : operator[] (int d) const        
      87              : {
      88            0 :         return m_ind[d];
      89              : }
      90              : 
      91              : 
      92              : ////////////////////////////////////////////////////////////////////////////////
      93              : //      Raster::Coordinate
      94              : 
      95              : template <class T, int TDIM>
      96            0 : Raster<T, TDIM>::Coordinate::
      97              : Coordinate()
      98              : {}
      99              : 
     100              : template <class T, int TDIM>
     101            0 : Raster<T, TDIM>::Coordinate::
     102              : Coordinate(number c)
     103              : {
     104              :         set(c);
     105              : }
     106              : 
     107              : template <class T, int TDIM>
     108              : Raster<T, TDIM>::Coordinate::
     109              : Coordinate(const MathVector<TDIM, number>& v)
     110              : {
     111              :         for(int d = 0; d < TDIM; ++d)
     112              :                 m_coord[d] = v[d];
     113              : }
     114              : 
     115              : template <class T, int TDIM>
     116              : int Raster<T, TDIM>::Coordinate::
     117              : dim () const
     118              : {
     119              :         return TDIM;
     120              : }
     121              : 
     122              : template <class T, int TDIM>
     123              : void Raster<T, TDIM>::Coordinate::
     124              : set (number c)
     125              : {
     126            0 :         for(int d = 0; d < TDIM; ++d)
     127            0 :                 m_coord[d] = c;
     128              : }
     129              : 
     130              : 
     131              : template <class T, int TDIM>
     132              : number& Raster<T, TDIM>::Coordinate::
     133              : operator[] (int d)
     134              : {
     135              :         return m_coord[d];
     136              : }
     137              : 
     138              : template <class T, int TDIM>
     139              : number Raster<T, TDIM>::Coordinate::
     140              : operator[] (int d) const
     141              : {
     142            0 :         return m_coord[d];
     143              : }
     144              : 
     145              : template <class T, int TDIM>
     146              : typename Raster<T, TDIM>::Coordinate& Raster<T, TDIM>::Coordinate::
     147              : operator+= (const Coordinate& c)
     148              : {
     149              :         for(int d = 0; d < TDIM; ++d)
     150              :                 m_coord[d] += c[d];
     151              : }
     152              : 
     153              : template <class T, int TDIM>
     154              : typename Raster<T, TDIM>::Coordinate& Raster<T, TDIM>::Coordinate::
     155              : operator-= (const Coordinate& c)
     156              : {
     157              :         for(int d = 0; d < TDIM; ++d)
     158              :                 m_coord[d] -= c[d];
     159              : }
     160              : 
     161              : template <class T, int TDIM>
     162              : typename Raster<T, TDIM>::Coordinate& Raster<T, TDIM>::Coordinate::
     163              : operator*= (number s)
     164              : {
     165              :         for(int d = 0; d < TDIM; ++d)
     166              :                 m_coord[d] *= s;
     167              : }
     168              : 
     169              : 
     170              : 
     171              : ////////////////////////////////////////////////////////////////////////////////
     172              : //      Raster - public
     173              : 
     174              : template <class T, int TDIM>
     175            0 : Raster<T, TDIM>::
     176              : Raster () :
     177            0 :         m_data(NULL),
     178              :         m_numNodes(0),
     179              :         m_selNode(0),
     180              :         m_minCorner(0),
     181              :         m_extension(1),
     182              :         m_cellExtension(1),
     183              :         m_cursor(0),
     184              :         m_numNodesTotal(0),
     185            0 :         m_noDataValue(std::numeric_limits<T>::max())
     186              : {
     187              :         update_num_nodes_total();
     188              :         update_cell_extension();
     189            0 : }
     190              : 
     191              : 
     192              : template <class T, int TDIM>
     193              : Raster<T, TDIM>::
     194              : Raster (const Raster<T, TDIM>& raster) :
     195              :         m_data(NULL),
     196              :         m_numNodes(raster.m_numNodes),
     197              :         m_selNode(raster.m_selNode),
     198              :         m_minCorner(raster.m_minCorner),
     199              :         m_extension(raster.m_extension),
     200              :         m_cellExtension(raster.m_cellExtension),
     201              :         m_cursor(raster.m_cursor),
     202              :         m_numNodesTotal(raster.m_numNodesTotal),
     203              :         m_noDataValue(raster.m_noDataValue)
     204              : {
     205              :         update_num_nodes_total();
     206              :         update_cell_extension();
     207              : 
     208              :         create();
     209              : 
     210              :         memcpy(m_data, raster.m_data, num_nodes_total() * sizeof(T));
     211              : }
     212              : 
     213              : template <class T, int TDIM>
     214              : Raster<T, TDIM>::
     215              : Raster (const MultiIndex& numNodes) :
     216              :         m_data(NULL),
     217              :         m_numNodes(numNodes),
     218              :         m_selNode(0),
     219              :         m_minCorner(0),
     220              :         m_extension(1),
     221              :         m_cellExtension(1),
     222              :         m_cursor(0),
     223              :         m_numNodesTotal(0),
     224              :         m_noDataValue(std::numeric_limits<T>::max())
     225              : {
     226              :         update_num_nodes_total();
     227              : 
     228              :         for(int d = 0; d < TDIM; ++d)
     229              :                 m_extension[d] = numNodes[d] - 1;
     230              : 
     231              :         update_cell_extension();
     232              : 
     233              :         create();
     234              : }
     235              : 
     236              : template <class T, int TDIM>
     237              : Raster<T, TDIM>::
     238              : Raster (const MultiIndex& numNodes,
     239              :                 const Coordinate& extension,
     240              :                 const Coordinate& minCorner) :
     241              :         m_data(NULL),
     242              :         m_numNodes(numNodes),
     243              :         m_selNode(0),
     244              :         m_minCorner(minCorner),
     245              :         m_extension(extension),
     246              :         m_cellExtension(1),
     247              :         m_cursor(0),
     248              :         m_numNodesTotal(0),
     249              :         m_noDataValue(std::numeric_limits<T>::max())
     250              : {
     251              :         update_num_nodes_total();
     252              :         update_cell_extension();
     253              :         create();
     254              : }
     255              : 
     256              : 
     257              : template <class T, int TDIM>
     258              : Raster<T, TDIM>::
     259              : ~Raster ()
     260              : {
     261            0 :         if(m_data)
     262            0 :                 delete[] m_data;
     263            0 : }
     264              : 
     265              : template <class T, int TDIM>
     266              : Raster<T, TDIM>& Raster<T, TDIM>::
     267              : operator= (const Raster& raster)
     268              : {
     269              :         m_numNodes              = raster.m_numNodes;
     270              :         m_selNode               = raster.m_selNode;
     271              :         m_minCorner             = raster.m_minCorner;
     272              :         m_extension             = raster.m_extension;
     273              :         m_cursor                = raster.m_cursor;
     274              :         m_noDataValue   = raster.m_noDataValue;
     275              : 
     276              :         update_num_nodes_total();
     277              :         update_cell_extension();
     278              : 
     279              :         create();
     280              : 
     281              :         memcpy(m_data, raster.m_data, num_nodes_total() * sizeof(T));
     282              : 
     283              :         return *this;
     284              : }
     285              : 
     286              : template <class T, int TDIM>
     287            0 : int Raster<T, TDIM>::
     288              : dim () const
     289              : {
     290            0 :         return TDIM;
     291              : }
     292              : 
     293              : template <class T, int TDIM>
     294            0 : void Raster<T, TDIM>::
     295              : set_num_nodes (int dim, size_t num)
     296              : {
     297            0 :         m_numNodes[dim] = num;
     298              :         update_num_nodes_total();
     299              :         update_cell_extension(dim);
     300            0 : }
     301              : 
     302              : template <class T, int TDIM>
     303            0 : void Raster<T, TDIM>::
     304              : set_num_nodes (const typename Raster<T, TDIM>::MultiIndex& mi)
     305              : {
     306            0 :         m_numNodes = mi;
     307              :         update_num_nodes_total();
     308              :         update_cell_extension();
     309            0 : }
     310              : 
     311              : template <class T, int TDIM>
     312              : size_t Raster<T, TDIM>::
     313              : num_nodes_total () const
     314              : {
     315            0 :         return m_numNodesTotal;
     316              : }
     317              : 
     318              : template <class T, int TDIM>
     319            0 : size_t Raster<T, TDIM>::
     320              : num_nodes (int dim) const
     321              : {
     322            0 :         return m_numNodes[dim];
     323              : }
     324              : 
     325              : template <class T, int TDIM>
     326              : const typename Raster<T, TDIM>::MultiIndex& Raster<T, TDIM>::
     327              : num_nodes () const
     328              : {
     329              :         return m_numNodes;
     330              : }
     331              : 
     332              : 
     333              : template <class T, int TDIM>
     334            0 : void Raster<T, TDIM>::
     335              : create ()
     336              : {
     337            0 :         if(m_data){
     338            0 :                 delete[] m_data;
     339            0 :                 m_data = NULL;
     340              :         }
     341              : 
     342              :         update_num_nodes_total(); // this isn't strictly necessary if everything works right.
     343              : 
     344              :         const size_t num = num_nodes_total();
     345            0 :         if(num){
     346            0 :                 m_data = new T[num];
     347              :         }
     348            0 : }
     349              : 
     350              : 
     351              : template <class T, int TDIM>
     352              : T& Raster<T, TDIM>::
     353              : node_value (const MultiIndex& mi)
     354              : {
     355            0 :         return m_data[data_index(mi)];
     356              : }
     357              : 
     358              : template <class T, int TDIM>
     359              : T Raster<T, TDIM>::
     360              : node_value (const MultiIndex& mi) const
     361              : {
     362            0 :         return m_data[data_index(mi)];
     363              : }
     364              : 
     365              : 
     366              : template <class T, int TDIM>
     367            0 : void Raster<T, TDIM>::
     368              : set_min_corner (int dim, number coord)
     369              : {
     370            0 :         m_minCorner[dim] = coord;
     371            0 : }
     372              : 
     373              : template <class T, int TDIM>
     374              : void Raster<T, TDIM>::
     375              : set_min_corner (const Coordinate& coord)
     376              : {
     377            0 :         m_minCorner = coord;
     378              : }
     379              : 
     380              : template <class T, int TDIM>
     381              : const typename Raster<T, TDIM>::Coordinate& Raster<T, TDIM>::
     382              : min_corner () const
     383              : {
     384              :         return m_minCorner;
     385              : }
     386              : 
     387              : template <class T, int TDIM>
     388            0 : number Raster<T, TDIM>::
     389              : min_corner (int dim) const
     390              : {
     391            0 :         return m_minCorner[dim];
     392              : }
     393              : 
     394              : template <class T, int TDIM>
     395            0 : void Raster<T, TDIM>::
     396              : set_extension (int dim, number ext)
     397              : {
     398            0 :         m_extension[dim] = ext;
     399              :         update_cell_extension(dim);
     400            0 : }
     401              : 
     402              : template <class T, int TDIM>
     403            0 : void Raster<T, TDIM>::
     404              : set_extension (const Coordinate& ext)
     405              : {
     406            0 :         m_extension = ext;
     407              :         update_cell_extension();
     408            0 : }
     409              : 
     410              : template <class T, int TDIM>
     411              : const typename Raster<T, TDIM>::Coordinate& Raster<T, TDIM>::
     412              : extension () const
     413              : {
     414              :         return m_extension;
     415              : }
     416              : 
     417              : template <class T, int TDIM>
     418            0 : number Raster<T, TDIM>::
     419              : extension (int dim) const
     420              : {
     421            0 :         return m_extension[dim];
     422              : }
     423              : 
     424              : 
     425              : template <class T, int TDIM>
     426            0 : T Raster<T, TDIM>::
     427              : interpolate (const Coordinate& coord, int order) const
     428              : {
     429            0 :         switch(order){
     430              :                 case 0: {
     431              :                         MultiIndex mi;
     432            0 :                         for(size_t d = 0; d < TDIM; ++d)
     433              :                         {
     434            0 :                                 mi[d] = static_cast<int>(0.5 + (coord[d] - m_minCorner[d]) / m_cellExtension[d]);
     435              :                                 if(mi[d] < 0)                                        mi[d] = 0;
     436            0 :                                 else if(mi[d] >= num_nodes(d))       mi[d] = num_nodes(d) - 1;
     437              :                         }
     438              :                         return node_value(mi);
     439              :                 } break;
     440              : 
     441              :                 case 1: {
     442              :                         MultiIndex mi;
     443              :                         Coordinate lc;
     444            0 :                         for(size_t d = 0; d < TDIM; ++d)
     445              :                         {
     446            0 :                                 mi[d] = static_cast<int>((coord[d] - m_minCorner[d]) / m_cellExtension[d]);
     447              :                                 if(mi[d] < 0){
     448              :                                         mi[d] = 0;
     449              :                                         lc[d] = 0;
     450              :                                 }
     451            0 :                                 else if(mi[d] + 1 >= num_nodes(d)){
     452            0 :                                         mi[d] = num_nodes(d) - 2;
     453            0 :                                         lc[d] = 1;
     454              :                                 }
     455              :                                 else{
     456            0 :                                         lc[d] = ( coord[d]
     457            0 :                                                           - ((number)mi[d] * m_cellExtension[d]
     458            0 :                                                                  + m_minCorner[d]))
     459            0 :                                                         / m_cellExtension[d];
     460              :                                 }
     461              :                         }
     462              : 
     463            0 :                         return interpolate_linear(mi, lc);
     464              :                 } break;
     465              : 
     466            0 :                 default:
     467            0 :                         UG_THROW("Raster::interpolate(): Unsupported interpolation order: " << order);
     468              :         }
     469              :         return m_noDataValue;
     470              : }
     471              : 
     472              : 
     473              : template <class T, int TDIM>
     474            0 : void Raster<T, TDIM>::
     475              : set_no_data_value(T val)
     476              : {
     477            0 :         m_noDataValue = val;
     478            0 : }
     479              : 
     480              : template <class T, int TDIM>
     481            0 : T Raster<T, TDIM>::
     482              : no_data_value() const
     483              : {
     484            0 :         return m_noDataValue;
     485              : }
     486              : 
     487              : 
     488              : template <class T, int TDIM>
     489            0 : void Raster<T, TDIM>::
     490              : blur(T alpha, size_t iterations)
     491              : {
     492              :         raster_kernels::Blur<T, TDIM> blurKernel (alpha);
     493              :         const MultiIndex start(0);
     494              : 
     495            0 :         for(size_t iiter = 0; iiter < iterations; ++iiter)
     496              :                 run_on_all (blurKernel);
     497            0 : }
     498              : 
     499              : 
     500              : template <class T, int TDIM>
     501              : template <class TKernel>
     502              : typename TKernel::result_t Raster<T, TDIM>::
     503              : run_on_all()
     504              : {
     505              :         TKernel kernel;
     506              :         run_on_all (MultiIndex(0), kernel, TDIM - 1);
     507              :         return kernel.result();
     508              : }
     509              : 
     510              : template <class T, int TDIM>
     511              : template <class TKernel>
     512              : void Raster<T, TDIM>::
     513              : run_on_all(TKernel& kernel)
     514              : {
     515            0 :         run_on_all (MultiIndex(0), kernel, TDIM - 1);
     516              : }
     517              : 
     518              : 
     519              : template <class T, int TDIM>
     520              : template <class TKernel>
     521            0 : void Raster<T, TDIM>::
     522              : run_on_all(const MultiIndex& start, TKernel& kernel, int curDim)
     523              : {
     524            0 :         if(curDim > 0) {
     525              :                 const size_t numNodes = num_nodes(curDim);
     526            0 :                 for(MultiIndex cur = start; cur[curDim] < numNodes; ++cur[curDim]){
     527            0 :                         run_on_all(cur, kernel, curDim - 1);
     528              :                 }
     529              :         }
     530              :         else {
     531              :                 const size_t numNodes = num_nodes(0);
     532            0 :                 for(MultiIndex cur = start; cur[0] < numNodes; ++cur[0]){
     533            0 :                         kernel (*this, cur);
     534              :                 }
     535              :         }
     536            0 : }
     537              : 
     538              : 
     539              : template <class T, int TDIM>
     540              : template <class TKernel>
     541              : typename TKernel::result_t Raster<T, TDIM>::
     542              : run_on_nbrs(const MultiIndex& center)
     543              : {
     544              :         TKernel kernel;
     545            0 :         run_on_nbrs(center, kernel, TDIM - 1);
     546              :         return kernel.result();
     547              : }
     548              : 
     549              : 
     550              : template <class T, int TDIM>
     551              : template <class TKernel>
     552              : void Raster<T, TDIM>::
     553              : run_on_nbrs(const MultiIndex& center, TKernel& kernel)
     554              : {
     555              :         run_on_nbrs(center, kernel, TDIM - 1);
     556              : }
     557              : 
     558              : 
     559              : template <class T, int TDIM>
     560              : template <class TKernel>
     561            0 : void Raster<T, TDIM>::
     562              : run_on_nbrs(const MultiIndex& center, TKernel& kernel, int curDim)
     563              : {
     564            0 :         if(curDim > 0)
     565            0 :                 run_on_nbrs(center, kernel, curDim - 1);
     566              : 
     567            0 :         if(center[curDim] > 0){
     568            0 :                 MultiIndex c = center;
     569            0 :                 --c[curDim];
     570            0 :                 kernel(*this, c);
     571              :         }
     572              : 
     573            0 :         if(center[curDim] + 1 < num_nodes(curDim)){
     574            0 :                 MultiIndex c = center;
     575            0 :                 ++c[curDim];
     576            0 :                 kernel(*this, c);
     577              :         }
     578            0 : }
     579              : 
     580              : 
     581              : template <class T, int TDIM>
     582            0 : void Raster<T, TDIM>::
     583              : select_node (int dim, size_t index)
     584              : {
     585            0 :         m_selNode[dim] = index;
     586            0 : }
     587              : 
     588              : template <class T, int TDIM>
     589              : void Raster<T, TDIM>::
     590              : select_node (const MultiIndex& mi)
     591              : {
     592              :         m_selNode = mi;
     593              : }
     594              : 
     595              : 
     596              : template <class T, int TDIM>
     597            0 : void Raster<T, TDIM>::
     598              : set_selected_node_value (T val)
     599              : {
     600            0 :         node_value(m_selNode) = val;
     601            0 : }
     602              : 
     603              : template <class T, int TDIM>
     604            0 : T Raster<T, TDIM>::
     605              : selected_node_value () const
     606              : {
     607            0 :         return node_value(m_selNode);
     608              : }
     609              : 
     610              : 
     611              : template <class T, int TDIM>
     612            0 : void Raster<T, TDIM>::
     613              : set_cursor (int dim, number coord)
     614              : {
     615            0 :         m_cursor[dim] = coord;
     616            0 : }
     617              : 
     618              : template <class T, int TDIM>
     619              : void Raster<T, TDIM>::
     620              : set_cursor (const Coordinate& coord)
     621              : {
     622              :         m_cursor = coord;
     623              : }
     624              : 
     625              : 
     626              : template <class T, int TDIM>
     627            0 : T Raster<T, TDIM>::
     628              : interpolate_at_cursor (int order) const
     629              : {
     630            0 :         return interpolate(m_cursor, order);
     631              : }
     632              : 
     633              : 
     634              : template <class T, int TDIM>
     635            0 : void Raster<T, TDIM>::
     636              : load_from_asc (const char* filename)
     637              : {
     638              :         using namespace std;
     639              : 
     640              :         #define LFA_ERR_WHERE "Error in Raster::load_from_asc('" << filename << "'): "
     641              : //      this macro helps with error-checks for bad dimensions
     642              :         #define LFA_CHECK_DIM(d, line)\
     643              :                                 UG_COND_THROW(d >= TDIM, LFA_ERR_WHERE << "Bad dimension '" << d <<\
     644              :                                         "' in line " << line << " of file " << filename << "," <<\
     645              :                                         "while trying to read a " << TDIM << "d raster.");
     646              : 
     647            0 :         std::string fullFileName = FindFileInStandardPaths(filename);
     648            0 :         UG_COND_THROW(fullFileName.empty(),
     649              :                                   LFA_ERR_WHERE << "Couldn't find the specified file in any of the standard paths.");
     650              : 
     651            0 :         ifstream in(fullFileName.c_str());
     652            0 :         UG_COND_THROW(!in, LFA_ERR_WHERE << "Couldn't access file.");
     653              : 
     654              :         MultiIndex numNodes(0);
     655              : 
     656              : //      indicate whether minCoord was specified as cell-center
     657              :         MultiIndex minCoordIsCenter(0);
     658              : 
     659              :         Coordinate minCoord(0);
     660              :         Coordinate cellSize(0);
     661              : 
     662              :         T noDataValue = T();
     663              : 
     664              : //      parse header
     665              : //      the header lenght varies between different asc files. This depends on the
     666              : //      dimension and whether equlateral cells are specified or not, i.e., whether
     667              : //      'cellsize' or whether 'xcellsize', 'ycellsize', ... was specified.
     668              : //      We're trying to guess the correct length here.
     669              :         int headerLen = 0;
     670              :         if(TDIM == 1)           headerLen = 4;
     671              :         else if(TDIM == 2)      headerLen = 6;
     672              :         else if(TDIM == 3)      headerLen = 8;
     673              :         else{
     674              :                 UG_THROW("Raster::load_from_asc only supports 1, 2, and 3 dimensions\n");
     675              :         }
     676              :         
     677            0 :         for(int i = 0; i < headerLen; ++i){
     678              :                 string name;
     679              :                 double value;
     680            0 :                 in >> name >> value;
     681            0 :                 UG_COND_THROW(!in, LFA_ERR_WHERE <<
     682              :                                           "Couldn't parse expected name-value pair in row " << i);
     683              : 
     684            0 :                 name = ToLower(name);
     685              : 
     686            0 :                 if(name.compare("ncols") == 0){
     687              :                         LFA_CHECK_DIM(0, i);
     688            0 :                         numNodes[0] = (int)value;
     689              :                 }
     690            0 :                 else if(name.compare("nrows") == 0){
     691            0 :                         LFA_CHECK_DIM(1, i);
     692            0 :                         numNodes[1] = (int)value;
     693              :                 }
     694            0 :                 else if(name.compare("nstacks") == 0){
     695            0 :                         LFA_CHECK_DIM(2, i);
     696            0 :                         numNodes[2] = (int)value;
     697              :                 }
     698              : 
     699            0 :                 else if(name.compare("xllcenter") == 0){
     700              :                         LFA_CHECK_DIM(0, i);
     701            0 :                         minCoord[0] = value;
     702            0 :                         minCoordIsCenter[0] = 1;
     703              :                 }
     704            0 :                 else if(name.compare("yllcenter") == 0){
     705            0 :                         LFA_CHECK_DIM(1, i);
     706            0 :                         minCoord[1] = value;
     707            0 :                         minCoordIsCenter[1] = 1;
     708              :                 }
     709            0 :                 else if(name.compare("zllcenter") == 0){
     710            0 :                         LFA_CHECK_DIM(2, i);
     711            0 :                         minCoord[2] = value;
     712            0 :                         minCoordIsCenter[2] = 1;
     713              :                 }
     714            0 :                 else if(name.compare("xllcorner") == 0){
     715              :                         LFA_CHECK_DIM(0, i);
     716            0 :                         minCoord[0] = value;
     717              :                 }
     718            0 :                 else if(name.compare("yllcorner") == 0){
     719            0 :                         LFA_CHECK_DIM(1, i);
     720            0 :                         minCoord[1] = value;
     721              :                 }
     722            0 :                 else if(name.compare("zllcorner") == 0){
     723            0 :                         LFA_CHECK_DIM(2, i);
     724            0 :                         minCoord[2] = value;
     725              :                 }
     726              : 
     727            0 :                 else if(name.compare("cellsize") == 0){
     728            0 :                         for(int d = 0; d < TDIM; ++d)
     729            0 :                                 cellSize[d] = value;
     730              :                 }
     731              : 
     732            0 :                 else if(name.compare("xcellsize") == 0){
     733              :                         LFA_CHECK_DIM(0, i);
     734              :                 //      we have to read additional cell-sizes for the other dimensions
     735            0 :                         headerLen += (TDIM - 1);
     736            0 :                         cellSize[0] = value;
     737              :                 }
     738            0 :                 else if(name.compare("ycellsize") == 0){
     739            0 :                         LFA_CHECK_DIM(1, i);
     740            0 :                         cellSize[1] = value;
     741              :                 }
     742            0 :                 else if(name.compare("zcellsize") == 0){
     743            0 :                         LFA_CHECK_DIM(2, i);
     744            0 :                         cellSize[2] = value;
     745              :                 }
     746              : 
     747            0 :                 else if(name.compare("nodata_value") == 0){
     748            0 :                         noDataValue = value;
     749              :                 }
     750              : 
     751              :                 else{
     752            0 :                         UG_THROW(LFA_ERR_WHERE << "unknown identifier in header: " << name);
     753              :                 }
     754              :         }
     755              :         
     756            0 :         for(int d = 0; d < TDIM; ++d){
     757            0 :                 if(minCoordIsCenter[d])
     758            0 :                         minCoord[d] -= 0.5 * cellSize[d];
     759              :         }
     760              : 
     761              : //      check validity
     762            0 :         for(int d = 0; d < TDIM; ++d){
     763            0 :                 UG_COND_THROW(numNodes[d] == 0, LFA_ERR_WHERE << "Num nodes may not be 0 for dim " << d);
     764            0 :                 UG_COND_THROW(cellSize[d] <= 0, LFA_ERR_WHERE << "cell-size must be bigger than 0 for dim " << d);
     765              :         }
     766              : 
     767            0 :         set_num_nodes(numNodes);
     768              :         set_min_corner(minCoord);
     769            0 :         Coordinate extension = cellSize;
     770            0 :         for(int d = 0; d < TDIM; ++d)
     771            0 :                 extension[d] *= (number)(numNodes[d] - 1);
     772            0 :         set_extension(extension);
     773              :         set_no_data_value(noDataValue);
     774              : 
     775            0 :         create();
     776              : 
     777              : //      parse values
     778              : //      y and z are inverted
     779            0 :         size_t num[3] = {0, 1, 1};
     780            0 :         for(size_t i = 0; i < TDIM; ++i)
     781            0 :                 num[i] = m_numNodes[i];
     782              :                 
     783            0 :         for(size_t iz = 0; iz < num[2]; ++iz){
     784            0 :                 for(size_t iy = 0; iy < num[1]; ++iy){
     785            0 :                         for(size_t ix = 0; ix < num[0]; ++ix)
     786              :                         {
     787            0 :                                 const size_t ty = num[1] - 1 - iy;
     788            0 :                                 const size_t tz = num[2] - 1 - iz;
     789            0 :                                 in >> m_data[ix + num[0] * (ty + num[1] * tz)];
     790            0 :                                 UG_COND_THROW(!in, LFA_ERR_WHERE << "Couldn't read value for at ("
     791              :                                                           << ix << ", " << iy << ", " << iz << ")");
     792              :                         }
     793              :                 }
     794              :         }
     795            0 : }
     796              : 
     797              : template <class T, int TDIM>
     798            0 : void Raster<T, TDIM>::
     799              : save_to_asc (const char* filename) const
     800              : {
     801              :         using namespace std;
     802              :         #define STA_ERR_WHERE "Error in Raster::save_to_asc('" << filename << "'): "
     803              : 
     804            0 :         UG_COND_THROW(!m_data, STA_ERR_WHERE << "Can't write an unitinialized raster."
     805              :                                   "Please call 'create' or 'load_from_asc' first.");
     806              : 
     807            0 :         ofstream out(filename);
     808            0 :         UG_COND_THROW(!out, STA_ERR_WHERE << "Couldn't open file for writing.");
     809              : 
     810              :         out << "ncols         " << num_nodes(0) << endl;
     811              :         if(TDIM > 1)
     812              :                 out << "nrows         " << num_nodes(1) << endl;
     813              :         if(TDIM > 2)
     814              :                 out << "nstacks       " << num_nodes(2) << endl;
     815              : 
     816              :         out << "xllcorner     " << setprecision(16) << min_corner(0) << endl;
     817              :         if(TDIM > 1)
     818              :                 out << "yllcorner     " << setprecision(16) << min_corner(1) << endl;
     819              :         if(TDIM > 2)
     820              :                 out << "zllcorner     " << setprecision(16) << min_corner(2) << endl;
     821              : 
     822              :         bool equlateralCells = true;
     823            0 :         for(int d = 1; d < TDIM; ++d){
     824            0 :                 if(m_cellExtension[d] != m_cellExtension[0]){
     825              :                         equlateralCells = false;
     826              :                         break;
     827              :                 }
     828              :         }
     829              : 
     830            0 :         if(equlateralCells)
     831              :                 out << "cellsize      " << m_cellExtension[0] << endl;
     832              :         else{
     833              :                 out << "xcellsize     " << m_cellExtension[0] << endl;
     834              :                 if(TDIM > 1)
     835              :                         out << "ycellsize     " << m_cellExtension[1] << endl;
     836              :                 if(TDIM > 2)
     837              :                         out << "zcellsize     " << m_cellExtension[2] << endl;
     838              :         }
     839              : 
     840              :         out << "NODATA_value  " << no_data_value() << endl;
     841              : 
     842              : //      write values
     843              : //      y and z are inverted
     844            0 :         size_t num[3] = {0, 1, 1};
     845            0 :         for(size_t i = 0; i < TDIM; ++i)
     846            0 :                 num[i] = num_nodes(i);
     847              :                 
     848            0 :         for(size_t iz = 0; iz < num[2]; ++iz){
     849            0 :                 for(size_t iy = 0; iy < num[1]; ++iy){
     850            0 :                         for(size_t ix = 0; ix < num[0]; ++ix)
     851              :                         {
     852            0 :                                 if(ix > 0)
     853            0 :                                         out << " ";
     854            0 :                                 const size_t ty = num[1] - 1 - iy;
     855            0 :                                 const size_t tz = num[2] - 1 - iz;
     856            0 :                                 out << m_data[ix + num[0] * (ty + num[1] * tz)];
     857              :                         }
     858              :                         out << endl;
     859              :                 }
     860              :                 out << endl;
     861              :         }
     862              :         out << endl;
     863            0 : }
     864              : 
     865              : ////////////////////////////////////////////////////////////////////////////////
     866              : //      Raster - private
     867              : template <class T, int TDIM>
     868              : size_t Raster<T, TDIM>::
     869              : data_index (const MultiIndex& mi, int curDim, size_t curVal) const
     870              : {
     871            0 :         if(curDim == 0)
     872            0 :                 return curVal + mi[0];
     873              :         else{
     874            0 :                 return data_index(mi, curDim - 1, m_numNodes[curDim - 1] * (mi[curDim] + curVal));
     875              :         }
     876              : }
     877              : 
     878              : template <class T, int TDIM>
     879              : void Raster<T, TDIM>::
     880              : update_num_nodes_total()
     881              : {
     882            0 :         m_numNodesTotal = 1;
     883            0 :         for(int d = 0; d < TDIM; ++d)
     884            0 :                 m_numNodesTotal *= num_nodes(d);
     885              : }
     886              : 
     887              : template <class T, int TDIM>
     888              : void Raster<T, TDIM>::
     889              : update_cell_extension()
     890              : {
     891            0 :         for(int d = 0; d < TDIM; ++d)
     892              :                 update_cell_extension(d);
     893              : }
     894              : 
     895              : template <class T, int TDIM>
     896              : void Raster<T, TDIM>::
     897              : update_cell_extension(int dim)
     898              : {
     899            0 :         if(m_numNodes[dim] > 1 && m_extension[dim] > 0)
     900            0 :                 m_cellExtension[dim] = m_extension[dim] / (m_numNodes[dim] - 1);
     901              :         else
     902            0 :                 m_cellExtension[dim] = 1;
     903              : }
     904              : 
     905              : 
     906              : template <class T, int TDIM>
     907            0 : T Raster<T, TDIM>::
     908              : interpolate_linear (
     909              :                 const MultiIndex& minNodeInd,
     910              :                 Coordinate& localCoord,
     911              :                 int curDim) const
     912              : {
     913            0 :         if(curDim == 0)
     914            0 :                 return node_value(minNodeInd);
     915              : 
     916            0 :         MultiIndex miMax = minNodeInd;
     917            0 :         miMax[curDim - 1] += 1;
     918              : 
     919            0 :         T val0 = interpolate_linear(minNodeInd, localCoord, curDim - 1);
     920            0 :         T val1 = interpolate_linear(miMax, localCoord, curDim - 1);
     921              : 
     922              : //      perform linear interpolation
     923            0 :         val0 *= (1. - localCoord[curDim - 1]);
     924            0 :         val1 *= localCoord[curDim - 1];
     925            0 :         val0 += val1;
     926            0 :         return val0;
     927              : }
     928              : 
     929              : }//     end of namespace
     930              : 
     931              : #endif  //__H__UG_raster_impl
        

Generated by: LCOV version 2.0-1