00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <QtCore>
00021
00022 #include <math.h>
00023 #include <algorithm>
00024
00025 #include "Layers.h"
00026 #include "Gis.h"
00027 #include "ThreadManager.h"
00028 #include "Scheduler.h"
00029
00030 Layers::Layers(ThreadManager* MTHREAD_h, string name_h, string label_h, bool isInteger_h, bool dynamicContent_h, string fullFilename_h)
00031 {
00032 MTHREAD=MTHREAD_h;
00033 name = name_h;
00034 label = label_h;
00035 isInteger = isInteger_h;
00036 dynamicContent = dynamicContent_h;
00037 fullFileName = fullFilename_h;
00038 }
00039
00040 Layers::~Layers()
00041 {
00042 }
00043
00044 void
00045 Layers::addLegendItem(int ID_h, string label_h, int rColor_h, int gColor_h, int bColor_h, double minValue_h, double maxValue_h){
00046
00047 for (uint i=0;i<legendItems.size();i++){
00048 if (legendItems.at(i).ID == ID_h){
00049 msgOut(MSG_ERROR, "Trying to add a legend item that already exist on this layer (layer: "+label+" - legend label: "+label_h+")");
00050
00051 return;
00052 }
00053 }
00054
00055 LegendItems ITEM;
00056 ITEM.ID = ID_h;
00057 ITEM.label = label_h;
00058 ITEM.rColor = rColor_h;
00059 ITEM.gColor = gColor_h;
00060 ITEM.bColor = bColor_h;
00061 ITEM.minValue = minValue_h;
00062 ITEM.maxValue = maxValue_h;
00063 ITEM.cashedCount=0;
00064 legendItems.push_back(ITEM);
00065
00066 }
00067
00068 void
00069 Layers::addReclassificationRule(int inCode_h, int outCode_h, double p_h){
00070
00071 ReclassRules RULE;
00072 RULE.inCode=inCode_h;
00073 RULE.outCode = outCode_h;
00074 RULE.p = p_h;
00075 reclassRulesVector.push_back(RULE);
00076 }
00077
00082 double
00083 Layers::filterExogenousDataset(double code_h){
00084 bool check =false;
00085 std::vector <double> cumPVector;
00086 std::vector <double> outCodesVector;
00087 double cumP = 0;
00088 double returnCode=0;
00089
00090 for(uint i=0; i<reclassRulesVector.size(); i++){
00091 if (reclassRulesVector.at(i).inCode == code_h){
00092 check = true;
00093 cumP += reclassRulesVector.at(i).p;
00094 cumPVector.push_back(cumP);
00095 outCodesVector.push_back(reclassRulesVector.at(i).outCode);
00096 }
00097 }
00098 if (!check) {return code_h;}
00099 if (cumP <= 0.99999999 || cumP >= 1.00000001){msgOut(MSG_CRITICAL_ERROR,"the sum of land use reclassification rules is not 1 for at least one input code (input code: "+d2s(code_h)+"; cumP: "+d2s(cumP)+")");}
00100 double random;
00101
00102 random = ((double)rand() / ((double)(RAND_MAX)+(double)(1)) );
00103 for(uint i=0; i<cumPVector.size(); i++){
00104 if (random <= cumPVector.at(i)){
00105 returnCode = outCodesVector.at(i);
00106 break;
00107 }
00108 }
00109 return returnCode;
00110 };
00111
00117 QColor
00118 Layers::getColor(double ID_h){
00119 QColor nocolor(255,255,255);
00120 if (ID_h == MTHREAD->RD->getDoubleSetting("noValue")){
00121 return nocolor;
00122 }
00123 if (isInteger){
00124 for(uint i=0; i<legendItems.size(); i++){
00125 if (legendItems.at(i).ID == ((int)ID_h)){
00126 QColor color(legendItems.at(i).rColor, legendItems.at(i).gColor, legendItems.at(i).bColor);
00127 return color;
00128 }
00129 }
00130 return nocolor;
00131 }
00132 else {
00133 for(uint i=0; i<legendItems.size(); i++){
00134 if (ID_h < legendItems.at(i).maxValue && ID_h >= legendItems.at(i).minValue){
00135 QColor color(legendItems.at(i).rColor, legendItems.at(i).gColor, legendItems.at(i).bColor);
00136 return color;
00137 }
00138 }
00139 return nocolor;
00140 }
00141 }
00147 string
00148 Layers::getCategory(double ID_h){
00149 if (ID_h == MTHREAD->RD->getDoubleSetting("noValue")){
00150 return "";
00151 }
00152 if (isInteger){
00153 for(uint i=0; i<legendItems.size(); i++){
00154 if (legendItems.at(i).ID == ((int)ID_h)){
00155 return legendItems.at(i).label;
00156 }
00157 }
00158 return "";
00159 }
00160 else {
00161 for(uint i=0; i<legendItems.size(); i++){
00162 if (ID_h < legendItems.at(i).maxValue && ID_h >= legendItems.at(i).minValue){
00163 return legendItems.at(i).label;
00164 }
00165 }
00166 return "";
00167 }
00168 }
00169
00170
00171
00172
00173 void
00174 Layers::countMyPixels(bool debug){
00175
00176 for (uint i=0; i<legendItems.size(); i++){
00177 legendItems.at(i).cashedCount=0;
00178 }
00179 double totPixels = MTHREAD->GIS->getXyNPixels();
00180 double pixelValue;
00181 for (uint j=0;j<totPixels;j++){
00182 pixelValue = MTHREAD->GIS->getPixel(j)->getDoubleValue(name);
00183 if (isInteger){
00184 for(uint i=0; i<legendItems.size(); i++){
00185 if (legendItems.at(i).ID == ((int)pixelValue)){
00186 legendItems.at(i).cashedCount++;
00187 break;
00188 }
00189 }
00190 }
00191 else {
00192 for(uint i=0; i<legendItems.size(); i++){
00193 if (pixelValue < legendItems.at(i).maxValue && pixelValue >= legendItems.at(i).minValue){
00194 legendItems.at(i).cashedCount++;
00195 break;
00196 }
00197 }
00198 }
00199 }
00200 if (debug){
00201 msgOut(MSG_INFO, "Layer statistics - Count by Legend items");
00202 msgOut(MSG_INFO, "Layer name: "+label);
00203 msgOut(MSG_INFO, "Total plots: "+ d2s(totPixels));
00204 for(uint i=0;i<legendItems.size();i++){
00205 msgOut(MSG_INFO, legendItems.at(i).label+": "+i2s(legendItems.at(i).cashedCount));
00206 }
00207 }
00208 }
00209 void
00210 Layers::randomShuffle(){
00211
00212
00213 vector <double> origValues;
00214 int maskValue = -MTHREAD->GIS->getNoValue();
00215 double totPixels = MTHREAD->GIS->getXyNPixels();
00216 for (uint i=0;i<totPixels;i++){
00217 double pxValue= MTHREAD->GIS->getPixel(i)->getDoubleValue(name);
00218 if(pxValue != MTHREAD->GIS->getNoValue()){
00219 origValues.push_back(pxValue);
00220 MTHREAD->GIS->getPixel(i)->changeValue(name,maskValue);
00221 }
00222 }
00223 random_shuffle(origValues.begin(), origValues.end());
00224
00225 for (uint i=0;i<totPixels;i++){
00226 double pxValue= MTHREAD->GIS->getPixel(i)->getDoubleValue(name);
00227 if(pxValue != MTHREAD->GIS->getNoValue()){
00228 double toChangeValue = origValues.at(origValues.size()-1);
00229
00230 origValues.pop_back();
00231 MTHREAD->GIS->getPixel(i)->changeValue(name,toChangeValue);
00232 }
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 }
00264 void
00265 Layers::print(){
00266
00267 if(MTHREAD->RD->getIntSetting("outputLevel")<OUTVL_MAPS) return;
00268 string mapBaseDirectory = MTHREAD->RD->getBaseDirectory()+MTHREAD->RD->getOutputDirectory()+"maps/";
00269 string mapGridOutputDirectory = mapBaseDirectory+"asciiGrids/";
00270 string catsOutputDirectory = mapBaseDirectory+"cats/";
00271 string coloursOutputDirectory = mapBaseDirectory+"colr/";
00272
00273 string mapFilename = mapGridOutputDirectory +name+ "_" +i2s(MTHREAD->SCD->getYear()) +"_" +MTHREAD->getScenarioName();
00274 string catsFilename = catsOutputDirectory +name+ "_" +i2s(MTHREAD->SCD->getYear()) +"_" +MTHREAD->getScenarioName();
00275 string coloursFilename = coloursOutputDirectory +name+ "_" +i2s(MTHREAD->SCD->getYear()) +"_" +MTHREAD->getScenarioName();
00276 string filenameListIntLayers = mapBaseDirectory+"integerListLayers";
00277 string filenameListFloatLayers = mapBaseDirectory+"floatListLayers";
00278
00279
00280 string header;
00281 if(MTHREAD->RD->getIntSetting("mapOutputFormat") == 1){
00282 header = "north: " + d2s(MTHREAD->GIS->getGeoTopY()) + "\n"
00283 + "south: " + d2s(MTHREAD->GIS->getGeoBottomY()) + "\n"
00284 + "east: " + d2s(MTHREAD->GIS->getGeoRightX()) + "\n"
00285 + "west: " + d2s(MTHREAD->GIS->getGeoLeftX()) + "\n"
00286 + "rows: " + i2s(MTHREAD->GIS->getYNPixels()) + "\n"
00287 + "cols: " + i2s(MTHREAD->GIS->getXNPixels()) + "\n"
00288 + "null: " + d2s(MTHREAD->GIS->getNoValue()) + "\n";
00289
00290 } else if(MTHREAD->RD->getIntSetting("mapOutputFormat") == 2){
00291 header = "ncols: " + i2s(MTHREAD->GIS->getXNPixels()) + "\n"
00292 + "lrows: " + i2s(MTHREAD->GIS->getYNPixels()) + "\n"
00293 + "xllcornel: " + d2s(MTHREAD->GIS->getGeoLeftX()) + "\n"
00294 + "yllcorner: " + d2s(MTHREAD->GIS->getGeoBottomY()) + "\n"
00295 + "cellsize: " + d2s(MTHREAD->GIS->getXMetersByPixel()) + "\n"
00296 + "nodata_value: " + d2s(MTHREAD->GIS->getNoValue()) + "\n";
00297 if(MTHREAD->GIS->getXMetersByPixel() != MTHREAD->GIS->getYMetersByPixel()){
00298 msgOut(MSG_ERROR, "The X resolution is different to the Y resolution. I am exporting the map in ArcInfo ASCII Grid format using the X resolution, but be aware that it is incorrect, as this format doesn't support different X-Y resolutions.");
00299 }
00300
00301 } else {
00302 msgOut(MSG_ERROR,"Map not print for unknow output type.");
00303 }
00304
00305 ofstream outm;
00306 outm.open(mapFilename.c_str(), ios::out);
00307 if (!outm){ msgOut(MSG_ERROR,"Error in opening the file "+mapFilename+".");}
00308 outm << header << "\n";
00309
00310 for (int i=0;i<MTHREAD->GIS->getYNPixels();i++){
00311 for (int j=0;j<MTHREAD->GIS->getXNPixels();j++){
00312 outm << MTHREAD->GIS->getPixel(j, i)->getDoubleValue(name) << " ";
00313 }
00314 outm << "\n";
00315 }
00316 outm.close();
00317
00318
00319 ofstream outc;
00320 outc.open(catsFilename.c_str(), ios::out);
00321 if (!outc){ msgOut(MSG_ERROR,"Error in opening the file "+catsFilename+".");}
00322 outc << "# " << name << "_-_" << i2s(MTHREAD->SCD->getYear()) << "\n\n\n";
00323 outc << "0.00 0.00 0.00 0.00"<<"\n";
00324
00325 if (isInteger){
00326 for(uint i=0;i<legendItems.size();i++){
00327 outc << legendItems[i].ID << ":"<< legendItems[i].label << "\n";
00328 }
00329 }
00330 else {
00331 for(uint i=0;i<legendItems.size();i++){
00332 outc << legendItems[i].minValue << ":"<< legendItems[i].maxValue << ":"<< legendItems[i].label << "\n";
00333 }
00334 }
00335
00336
00337 ofstream outcl;
00338 outcl.open(coloursFilename.c_str(), ios::out);
00339 if (!outcl){ msgOut(MSG_ERROR,"Error in opening the file "+coloursFilename+".");}
00340 outcl << "% " << name << "_-_" << i2s(MTHREAD->SCD->getYear()) << "\n\n\n";
00341
00342 if (isInteger){
00343 for(uint i=0;i<legendItems.size();i++){
00344 outcl << legendItems[i].ID << ":"<< legendItems[i].rColor << ":" << legendItems[i].gColor << ":" << legendItems[i].bColor << "\n";
00345 }
00346 }
00347 else {
00348 for(uint i=0;i<legendItems.size();i++){
00349 outcl << legendItems[i].minValue << ":"<< legendItems[i].rColor << ":" << legendItems[i].gColor << ":" << legendItems[i].bColor << " "<< legendItems[i].maxValue << ":"<< legendItems[i].rColor << ":" << legendItems[i].gColor << ":" << legendItems[i].bColor << "\n";
00350 }
00351 }
00352
00353
00354 ofstream outList;
00355 if (isInteger){
00356 outList.open(filenameListIntLayers.c_str(), ios::app);
00357 outList << name << "_" << MTHREAD->SCD->getYear() << "_" << MTHREAD->getScenarioName() << "\n";
00358 }
00359 else {
00360 outList.open(filenameListFloatLayers.c_str(), ios::app);
00361 outList << name << "_" << MTHREAD->SCD->getYear() << "_" << MTHREAD->getScenarioName() << "\n";
00362 }
00363 outList.close();
00364 }
00365
00366 void
00367 Layers::printBinMap(){
00368
00369 int xNPixels = MTHREAD->GIS->getXNPixels();
00370 int subXR = MTHREAD->GIS->getSubXR();
00371 int subXL = MTHREAD->GIS->getSubXL();
00372 int subYT = MTHREAD->GIS->getSubYT();
00373 int subYB = MTHREAD->GIS->getSubYB();
00374
00375 string mapBaseDirectory = MTHREAD->RD->getBaseDirectory()+MTHREAD->RD->getOutputDirectory()+"maps/bitmaps/";
00376 string mapFilename = mapBaseDirectory +name+ "_" +i2s(MTHREAD->SCD->getYear()) +"_" +MTHREAD->getScenarioName()+".png";
00377
00378 QImage image = QImage(subXR-subXL+1, subYB-subYT+1, QImage::Format_RGB32);
00379 image.fill(qRgb(255, 255, 255));
00380 for (int countRow=subYT;countRow<subYB;countRow++){
00381 for (int countColumn=subXL;countColumn<subXR;countColumn++){
00382 double value = MTHREAD->GIS->getPixel(countRow*xNPixels+countColumn)->getDoubleValue(name);
00383 QColor color = this->getColor(value);
00384 image.setPixel(countColumn-subXL,countRow-subYT,color.rgb());
00385 }
00386 }
00387 image.save(mapFilename.c_str());
00388 }