1 // Copyright (c) 2018-2020 Robert J. Hijmans 2 // 3 // This file is part of the "spat" library. 4 // 5 // spat is free software: you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 2 of the License, or 8 // (at your option) any later version. 9 // 10 // spat is distributed in the hope that it will be useful, but 11 // WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with spat. If not, see <http://www.gnu.org/licenses/>. 17 18 #include "spatRaster.h" 19 20 21 // A collection of (perhaps non matching) SpatRasters 22 class SpatRasterCollection { 23 public: 24 SpatMessages msg; setError(std::string s)25 void setError(std::string s) { msg.setError(s); } addWarning(std::string s)26 void addWarning(std::string s) { msg.addWarning(s); } has_error()27 bool has_error() { return msg.has_error; } has_warning()28 bool has_warning() { return msg.has_warning; } getWarnings()29 std::string getWarnings() { return msg.getWarnings(); } getError()30 std::string getError() { return msg.getError(); } 31 32 std::vector<SpatRaster> ds; SpatRasterCollection()33 SpatRasterCollection() {}; SpatRasterCollection(size_t n)34 SpatRasterCollection(size_t n) { ds.resize(n); }; size()35 size_t size() { return ds.size(); } resize(size_t n)36 void resize(size_t n) { ds.resize(n); } push_back(SpatRaster r)37 void push_back(SpatRaster r) { ds.push_back(r); }; erase(size_t i)38 void erase(size_t i) { 39 if (i < ds.size()) { 40 ds.erase(ds.begin()+i); 41 } 42 } 43 SpatRaster merge(SpatOptions &opt); 44 SpatRaster mosaic(std::string fun, SpatOptions &opt); 45 SpatRaster summary(std::string fun, SpatOptions &opt); 46 47 }; 48 49 // A class for "sub-datasets" 50 class SpatRasterStack { 51 public: 52 SpatMessages msg; setError(std::string s)53 void setError(std::string s) { msg.setError(s); } addWarning(std::string s)54 void addWarning(std::string s) { msg.addWarning(s); } has_error()55 bool has_error() { return msg.has_error; } has_warning()56 bool has_warning() { return msg.has_warning; } getWarnings()57 std::string getWarnings() { return msg.getWarnings();} getError()58 std::string getError() { return msg.getError();} 59 60 std::vector<SpatRaster> ds; 61 std::vector<std::string> names; 62 std::vector<std::string> long_names; 63 std::vector<std::string> units; SpatRasterStack()64 SpatRasterStack() {}; 65 SpatRasterStack(std::string fname, std::vector<int> ids, bool useids); 66 SpatRasterStack(SpatRaster r, std::string name, std::string longname, std::string unit, bool warn=false) { 67 push_back(r, name, longname, unit, warn); 68 }; 69 70 std::vector<std::vector<std::vector<double>>> extractXY(std::vector<double> &x, std::vector<double> &y, std::string method); 71 std::vector<std::vector<std::vector<double>>> extractCell(std::vector<double> &cell); 72 std::vector<std::vector<std::vector<std::vector<double>>>> extractVector(SpatVector v, bool touches, std::string method, SpatOptions &opt); 73 get_names()74 std::vector<std::string> get_names() { 75 return names; 76 }; set_names(std::vector<std::string> nms)77 void set_names(std::vector<std::string> nms) { 78 if (nms.size() == ds.size()) { 79 names = nms; 80 } 81 } get_longnames()82 std::vector<std::string> get_longnames() { 83 return long_names; 84 }; set_longnames(std::vector<std::string> nms)85 void set_longnames(std::vector<std::string> nms) { 86 if (nms.size() == ds.size()) { 87 long_names = nms; 88 } 89 } get_units()90 std::vector<std::string> get_units() { 91 return units; 92 }; set_units(std::vector<std::string> u)93 void set_units(std::vector<std::string> u) { 94 if (u.size() == ds.size()) { 95 units = u; 96 } 97 } 98 readStart()99 bool readStart() { 100 for (auto& x : ds) { if (!x.readStart()) return false; } 101 return true; 102 } 103 readStop()104 bool readStop() { 105 for (auto& x : ds) { if (!x.readStop()) return false; } 106 return true; 107 } 108 nsds()109 unsigned nsds() { 110 return ds.size(); 111 } nrow()112 unsigned nrow() { 113 if (ds.size() > 0) { 114 return ds[0].nrow(); 115 } else { 116 return 0; 117 } 118 } ncol()119 unsigned ncol() { 120 if (ds.size() > 0) { 121 return ds[0].ncol(); 122 } else { 123 return 0; 124 } 125 } 126 nlyr()127 std::vector<unsigned> nlyr() { 128 std::vector<unsigned> out; 129 if (ds.size() > 0) { 130 out.reserve(ds.size()); 131 for (size_t i=0; i<ds.size(); i++) { 132 out.push_back(ds[i].nlyr()); 133 } 134 } 135 return out; 136 } 137 getSRS(std::string s)138 std::string getSRS(std::string s) { 139 if (ds.size() > 0) { 140 return ds[0].getSRS(s); 141 } else { 142 return ""; 143 } 144 } 145 push_back(SpatRaster r,std::string name,std::string longname,std::string unit,bool warn)146 bool push_back(SpatRaster r, std::string name, std::string longname, std::string unit, bool warn) { 147 if (ds.size() > 0) { 148 if (!r.compare_geom(ds[0], false, false, true, true, true, false)) { 149 // if (!ds[0].compare_geom(r, false, false, true, true, false, false)) { 150 if (warn) { 151 addWarning(r.msg.getError() +" (" + name + ")"); 152 return true; 153 } else { 154 setError(r.msg.getError() +" (" + name + ")"); 155 return false; 156 } 157 } 158 } 159 ds.push_back(r); 160 names.push_back(name); 161 long_names.push_back(longname); 162 units.push_back(unit); 163 return true; 164 }; 165 size()166 size_t size() { return ds.size(); } resize(size_t n)167 void resize(size_t n) { 168 if (n < ds.size()) { 169 ds.resize(n); 170 names.resize(n); 171 long_names.resize(n); 172 units.resize(n); 173 } 174 } erase(size_t i)175 void erase(size_t i) { 176 if (i < ds.size()) { 177 ds.erase(ds.begin()+i); 178 names.erase(names.begin()+i); 179 long_names.erase(long_names.begin()+i); 180 units.erase(units.begin()+i); 181 } 182 } 183 184 getsds(size_t i)185 SpatRaster getsds(size_t i) { 186 if (i < ds.size()) { 187 return(ds[i]); 188 } else { 189 SpatRaster out; 190 out.setError("invalid index"); 191 return out; 192 } 193 } subset(std::vector<unsigned> x)194 SpatRasterStack subset(std::vector<unsigned> x) { 195 SpatRasterStack out; 196 for (size_t i=0; i<x.size(); i++) { 197 if (x[i] < ds.size()) { 198 out.push_back(ds[x[i]], names[i], long_names[i], units[i], true); 199 } 200 } 201 return out; 202 } 203 replace(unsigned i,SpatRaster x)204 void replace(unsigned i, SpatRaster x) { 205 if (i > (ds.size()-1)) { 206 setError("invalid index"); 207 return; 208 } 209 if (ds.size() == 0) { 210 setError("cannot replace on empty stack"); 211 return; 212 } 213 if (!ds[0].compare_geom(x, false, false, true, true, false, false)) { 214 setError("extent does not match"); 215 return; 216 } 217 218 ds[i] = x; 219 names[i] = x.getNames()[0]; 220 long_names[i] = x.getLongSourceNames()[0]; 221 units[i] = x.getUnit()[0]; 222 } 223 collapse()224 SpatRaster collapse() { 225 SpatRaster out; 226 227 if (ds.size() > 0) { 228 out = ds[0]; 229 for (size_t i=1; i<ds.size(); i++) { 230 for (size_t j=0; j<ds[i].source.size(); j++) { 231 out.source.push_back(ds[i].source[j]); 232 } 233 } 234 } 235 return out; 236 } 237 238 SpatRaster summary_numb(std::string fun, std::vector<double> add, bool narm, SpatOptions &opt); 239 SpatRaster summary(std::string fun, bool narm, SpatOptions &opt); 240 }; 241 242 243