FFSM++  1.1.0
French Forest Sector Model ++
Gis.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2015 by Laboratoire d'Economie Forestière *
3  * http://ffsm-project.org *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 3 of the License, or *
8  * (at your option) any later version, given the compliance with the *
9  * exceptions listed in the file COPYING that is distribued together *
10  * with this file. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program; if not, write to the *
19  * Free Software Foundation, Inc., *
20  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  ***************************************************************************/
22 #include <algorithm> //alghoritm used to shuffle (randomize) the array
23 #include <QtCore>
24 #include <math.h>
25 
26 #include "Gis.h"
27 #include "Pixel.h"
28 
29 //#include "InputDocument.h"
30 #include "MainWindow.h"
31 #include "Scheduler.h"
32 
33 using namespace std;
34 
35 /**
36 The constructor of the GIS (unique) instance want:
37 @param RD_h Pointer to the manager of the regional data
38 @param MTHREAD_h Pointer to the main thread manager
39 */
40 Gis::Gis(ThreadManager* MTHREAD_h){
41  MTHREAD=MTHREAD_h;
42 }
43 
45 }
46 
47 /**
48 setSpace is called directly from the init system to setting the space environment in the model.
49 <br>It is responsable to:
50  - define map dimensions (from setting files)
51  - create the pixels
52  - initialize the layer @see initLayers
53  - load the layer data from their fdata-files @see loadLayersDataFromFile
54  - tell the GUI that our map will have (x,y) dimensions
55 */
56 void
58 
59 
60 
61  msgOut(MSG_INFO,"Creating the space...");
62 
63  // init basic settings....
64  geoTopY = MTHREAD->MD->getDoubleSetting("geoNorthEdge");
65  geoBottomY = MTHREAD->MD->getDoubleSetting("geoSouthEdge");
66  geoLeftX = MTHREAD->MD->getDoubleSetting("geoWestEdge");
67  geoRightX = MTHREAD->MD->getDoubleSetting("geoEastEdge");
68  xNPixels = MTHREAD->MD->getIntSetting("nCols");
69  yNPixels = MTHREAD->MD->getIntSetting("nRows");
70  noValue = MTHREAD->MD->getDoubleSetting("noValue");
71  xyNPixels = xNPixels * yNPixels;
72  xMetersByPixel = (geoRightX - geoLeftX)/xNPixels;
73  yMetersByPixel = (geoTopY - geoBottomY)/yNPixels;
74  MTHREAD->treeViewerChangeGeneralPropertyValue("total plots", d2s(getXyNPixels()));
75  MTHREAD->treeViewerChangeGeneralPropertyValue("total land", d2s(xyNPixels*getHaByPixel()));
76  // creating pixels...
77  for (int i=0;i<yNPixels;i++){
78  for (int j=0;j<xNPixels;j++){
79  Pixel myPixel(i*xNPixels+j, MTHREAD);
80  myPixel.setCoordinates(j,i);
81  pxVector.push_back(myPixel);
82  }
83  }
84  initLayers();
85  loadLayersDataFromFile();
86 
87  // Cashing the pixels owned by each region..
88  vector <ModelRegion*> regions = MTHREAD->MD->getAllRegions();
89  int nRegions = regions.size();
90  for(uint i=0;i<nRegions;i++){
91  regions[i]->setMyPixels();
92  }
93 
94  applySpatialStochasticValues(); // regional variance -> different tp in each pixel trought tp modifiers
95  applyStochasticRiskAdversion(); // risk adversion to each pixel
96  //cachePixelValues(); // For computational reasons cache some values in the constant layers directly as properties of the pixel object
97 
98  //< Print a layer of pixels id..
99  //addLayer("pxIds", "idx of the pixels", true, true, "pxIds.grd", true);
100  //resetLayer("pxIds");
101  //vector<Pixel*> allPixels = getAllPlotsByRegion(11000);
102  //for (int i=0;i<allPixels.size();i++){
103  // int pxId= allPixels[i]->getID();
104  // allPixels[i]->changeValue ("pxIds", pxId);
105  //}
106  //printLayers("pxIds");
107  //exit(1);
108 
109  MTHREAD->fitInWindow(); // tell the gui to fit the map to the widget
110 // countItems("landUse",false); // count the various records assigned to each legendItem. Do not print debug infos
111  return;
112 }
113 
114 
115 /**
116  * Apply all stochastic modifications required by the model at init time.
117  * Currently used to change time of passage devending on regional variance
118  **/
119 
120 void
122  // apply regional volume growth st.dev. -> variance to pixel based t.p.
123  // - cashing value to the pixels
124  // - apply to the tp layers with change values
125 
126  if(!MTHREAD->MD->getBoolSetting("usePixelData")) return;
127 
128  vector <int> regIds2 = MTHREAD->MD->getRegionIds(2);
129  //ModelRegion* reg = MTHREAD->MD->getRegion(regIds2[i]);
130  //vector<Pixel*> regPixels = region->getMyPixels();
131  //double sumc = 0;
132  //double nc = 0;
133  for(uint i=0;i<regIds2.size();i++){
134  int regId = regIds2[i];
135  ModelRegion* reg = MTHREAD->MD->getRegion(regId );
136  vector <Pixel*> rpx = MTHREAD->GIS->getAllPlotsByRegion(regId );
137  vector <string> fTypes = MTHREAD->MD->getForTypeIds();
138 
139  // regional variance
140  if(MTHREAD->MD->getBoolSetting("useSpatialRegionalVariance")){
141  for(uint j=0; j<fTypes.size(); j++){
142  double sStDev = MTHREAD->MD->getForData("sStDev",regId ,fTypes[j],""); // spatial standard deviation
143  double agr = MTHREAD->MD->getForData("agr",regId ,fTypes[j],""); // average growth
144  // BUG solved 20141220 To obtain a population with the same avg and st.dev of the original using moltipliers, I need to use the cv not the st.dev. !
145  // tested with excel
146  normal_distribution<double> d(1,sStDev/agr); // default any how to double
147  for (uint z=0;z<rpx.size();z++){
148  double c = d(*MTHREAD->gen);
149  double c2 = max(0.4,min(1.6,c)); /// with simmetric boundary on the cv I do not change the average, but of course I slighly reduce the stdev. See file monte_carlo_with_multipliers_sample_proof.ods
150  // TO.DO: Convert it to using normSample where instead of a min/max a loop is used to fund smaples that are within the bounds
151  //cout << regIds2[i] << ";" <<sStDev <<";"<< c <<endl
152  //rpx[z]->correctInputMultiplier("tp_multiplier",fTypes[j],c);
153  //cout << sStDev/agr << " " << c2 << endl;
154  rpx[z]->setSpModifier(c2,j);
155  //sumc += c;
156  //nc ++;
157  }
158  }
159  }
160 
161  // expectation types
162  double avgExpTypes = MTHREAD->MD->getDoubleSetting("expType",DATA_NOW,regId);
163  double avgExpTypesPrices = MTHREAD->MD->getDoubleSetting("expTypePrices",DATA_NOW,regId);
164  double expTypes_cv = MTHREAD->MD->getDoubleSetting("expType_cv",DATA_NOW,regId);
165  double expTypesPrices_cv = MTHREAD->MD->getDoubleSetting("expTypePrices_cv",DATA_NOW,regId);
166  if((avgExpTypes<0 || avgExpTypes>1) && avgExpTypes != -1){
167  msgOut(MSG_CRITICAL_ERROR, "expType parameter must be between 1 (expectations) and 0 (adaptative) or -1 (fixed).");
168  }
169  if(avgExpTypesPrices<0 || avgExpTypesPrices>1){
170  msgOut(MSG_CRITICAL_ERROR, "vgExpTypesPrices parameter must be between 1 (expectations) and 0 (adaptative).");
171  }
172  //cout << avgExpTypes << " " << expTypes_cv << endl;
173 
174  normal_distribution<double> exp_distr(avgExpTypes,expTypes_cv *avgExpTypes); // works only for double, but default any how to double
175  normal_distribution<double> expPrices_distr(avgExpTypesPrices,expTypesPrices_cv *avgExpTypesPrices);
176 
177  for (uint z=0;z<rpx.size();z++){
178  if(avgExpTypes == -1){
179  rpx[z]->expType = -1;
180  } else {
181  //double c = exp_distr(*MTHREAD->gen);
182  //double c2 = max(0.0,min(1.0,c)); /// Bounded [0,1]. With simmetric boundary on the cv I do not change the average, but of course I slighly reduce the stdev. See file monte_carlo_with_multipliers_sample_proof.ods
183  double c3 = normSample(exp_distr,*MTHREAD->gen,0.0,1.0);
184  //cout << "Sampled:\t" << c3 << endl;
185  rpx[z]->expType = c3;
186  }
187  double cPrice = normSample(expPrices_distr,*MTHREAD->gen,0.0,1.0);
188  rpx[z]->expTypePrices = cPrice;
189  }
190  }
191 }
192 
193 /**
194  * Apply to each agent a random risk-adversion coefficient
195  *
196  *For now, 1 pixel = 1 agent, and avg and st.dev. are the same in the model, but eventually this can change
197  **/
198 void
200  // apply regional volume growth st.dev. -> variance to pixel based t.p.
201  // - cashing value to the pixels
202  // - apply to the tp layers with change values
203 
204  if(!MTHREAD->MD->getBoolSetting("usePixelData")) return;
205 
206  vector <int> regIds2 = MTHREAD->MD->getRegionIds(2);
207  bool raEnabled = MTHREAD->MD->getBoolSetting("heterogeneousRiskAversion");
208  for(uint i=0;i<regIds2.size();i++){
209  int regId = regIds2[i];
210  ModelRegion* reg = MTHREAD->MD->getRegion(regId);
211  vector <Pixel*> rpx = MTHREAD->GIS->getAllPlotsByRegion(regId);
212  for (uint z=0;z<rpx.size();z++){
213  if(raEnabled){
214  double raStDev = MTHREAD->MD->getDoubleSetting("riskAversionAgentSd",DATA_NOW,regId);
215  double avg = MTHREAD->MD->getDoubleSetting("riskAversionAgentAverage",DATA_NOW,regId);
216  normal_distribution<double> d(avg,raStDev); // default any how to double
217  double c = d(*MTHREAD->gen);
218  rpx[z]->setValue ("ra", c);
219  } else {
220  rpx[z]->setValue ("ra", 0.0);
221  }
222  }
223  }
224 }
225 
226 
227 /*
228 void
229 Gis::cachePixelValues(){
230  /// Set the avalCoef (availability coefficient) from layer
231  if(!MTHREAD->MD->getBoolSetting("usePixelData")) return;
232  if(!MTHREAD->MD->getBoolSetting("applyAvalCoef")) return;
233 
234  bool applyAvalCoef = MTHREAD->MD->getBoolSetting("applyAvalCoef");
235 
236  vector <int> regIds2 = MTHREAD->MD->getRegionIds(2);
237 
238  for(uint i=0;i<regIds2.size();i++){
239  ModelRegion* reg = MTHREAD->MD->getRegion(regIds2[i]);
240  vector <Pixel*> rpx = MTHREAD->GIS->getAllPlotsByRegion(regIds2[i]);
241  for (uint p=0;p<rpx.size();p++){
242  if(applyAvalCoef){
243  rpx[p]->avalCoef = rpx[p]->getDoubleValue("avalCoef", true);
244  }
245  }
246  }
247 }
248 */
249 
250 /**
251 Called from setSpace(), initLayers() is responsable of:
252  - load each layer propriety (name, label, datafile..)
253  - add the layer to the system @see addLayer
254 <p>If the layer is to be read at start-up:
255  - adding to the layer each legend item (ID, label, min-max values..) @see addLegendItem
256  - [REMOVED, as reclassification rules are in the input ods file now, not in the gis input file] eventually adding to the layer each reclassification rules @see addReclassificationRule
257 **/
258 void
260  // setting layers...
261  //string filename_complete= MTHREAD->MD->getFilenameByType("gis");
262  string filename_complete = MTHREAD->getBaseDirectory()+MTHREAD->MD->getStringSetting("gisFilename");
263 
264  InputNode gisDocument;
265  bool test=gisDocument.setWorkingFile(filename_complete);
266  if (!test){msgOut(MSG_CRITICAL_ERROR, "Error opening the gis file "+filename_complete+".");}
267  vector<InputNode> layerNodes = gisDocument.getNodesByName("layer");
268  vector<string> ftIds = MTHREAD->MD->getForTypeIds();
269  for (uint i=0; i<layerNodes.size();i++){
270 
271  string nameOrig = layerNodes.at(i).getNodeByName("name").getStringContent();
272  string labelOrig = layerNodes.at(i).getNodeByName("label").getStringContent();
273  bool isInteger = layerNodes.at(i).getNodeByName("isInteger").getBoolContent();
274  bool dynamicContent = layerNodes.at(i).getNodeByName("dynamicContent").getBoolContent();
275  bool expandByFt = layerNodes.at(i).getNodeByName("expandByFt").getBoolContent();
276  string readAtStart = layerNodes.at(i).getNodeByName("readAtStart").getStringContent();
277  if (readAtStart != "true") continue;
278  string dirName = layerNodes.at(i).getNodeByName("dirName").getStringContent();
279  string fileName = layerNodes.at(i).getNodeByName("fileName").getStringContent();
280 
281  // Eventually expanding this input layern in as many layer as forest types exists..
282  uint endingLoop = expandByFt ? ftIds.size(): 1;
283  for(uint z=0;z<endingLoop;z++){
284  string ftExtension= expandByFt ? "_"+ftIds[z]:"";
285  string labelFtExtension= expandByFt ? " ("+ftIds[z]+")":"";
286  string name = nameOrig+ftExtension;
287  string label = labelOrig + labelFtExtension;
288 
289  string fullFileName = ((dirName == "") || (fileName==""))?"":MTHREAD->MD->getBaseDirectory()+dirName+fileName+ftExtension; // TODO: ugly: one would have to put mmyfile.grd_broadL_highF
290  addLayer(name,label,isInteger,dynamicContent,fullFileName);
291  //legend..
292  vector<InputNode> legendItemsNodes = layerNodes.at(i).getNodesByName("legendItem");
293  for (uint j=0; j<legendItemsNodes.size();j++){
294  int lID = legendItemsNodes.at(j).getIntContent();
295  string llabel = legendItemsNodes.at(j).getStringAttributeByName("label");
296  int rColor = legendItemsNodes.at(j).getIntAttributeByName("rColor");
297  int gColor = legendItemsNodes.at(j).getIntAttributeByName("gColor");
298  int bColor = legendItemsNodes.at(j).getIntAttributeByName("bColor");
299  double minValue, maxValue;
300  if (isInteger){
301  minValue = ((double)lID);
302  maxValue = ((double)lID);
303  }
304  else {
305  minValue = legendItemsNodes.at(j).getDoubleAttributeByName("minValue");
306  maxValue = legendItemsNodes.at(j).getDoubleAttributeByName("maxValue");
307  }
308  addLegendItem(name, lID, llabel, rColor, gColor, bColor, minValue, maxValue);
309  }
310  }
311  }
312  initLayersPixelData();
313  //initLayersModelData(DATA_INIT); // only the layers relative to the initial years are inserted now. All the simulation year layers will be added each year before mainSimulationyear()
314 }
315 
316 /** Init the layers of exogenous data at pixel level (e.g. time of passage, multipliers, volumes of sp. espl. ft, spread models)
317  These layers will then be read from datafile @see loadLayersDataFromFile
318 */
319 void
321  if (!MTHREAD->MD->getBoolSetting("usePixelData")){return;}
322  string dir = MTHREAD->MD->getBaseDirectory()+MTHREAD->MD->getStringSetting("spatialDataSubfolder");
323  string fileExt = MTHREAD->MD->getStringSetting("spatialDataFileExtension");
324  vector<string> files = vector<string>();
325  string fullFilename, filename, fullPath;
326  //string parName, forName, dClass, yearString;
327  //int year;
328 
329  MTHREAD->MD->getFilenamesByDir (dir,files, fileExt); // Ugly format. Files is the output (reference)
330 
331  for (unsigned int i = 0;i < files.size();i++) {
332  fullFilename = files[i];
333  fullPath = dir+"/"+fullFilename;
334  filename = fullFilename.substr(0,fullFilename.find_last_of("."));
335  addLayer(filename,filename,false,false,fullPath,false);
336  }
337 
338  // Loading volumes of forest types that are spatially known..
339  if(MTHREAD->MD->getBoolSetting("useSpExplicitForestTypes")){
340  string dir2 = MTHREAD->MD->getBaseDirectory()+MTHREAD->MD->getStringSetting("spExplicitForTypesInputDir");
341  string fileExt2 = MTHREAD->MD->getStringSetting("spExplicitForTypesFileExtension");
342  vector<string> files2 = vector<string>();
343  string fullFilename2, filename2, fullPath2;
344  MTHREAD->MD->getFilenamesByDir (dir2,files2, fileExt2); // Ugly format. Files is the output (reference)
345  for (unsigned int i = 0;i < files2.size();i++) {
346  fullFilename2 = files2[i];
347  fullPath2 = dir2+"/"+fullFilename2;
348  filename2 = fullFilename2.substr(0,fullFilename2.find_last_of("."));
349  addLayer(filename2,filename2,false,false,fullPath2,false);
350  }
351  }
352 
353  // Loading pathogens exogenous spread models...
354  if(MTHREAD->MD->getBoolSetting("usePathogenModule")){
355  string dir2 = MTHREAD->MD->getBaseDirectory()+MTHREAD->MD->getStringSetting("pathogenExogenousSpreadModelFolder");
356  string fileExt2 = MTHREAD->MD->getStringSetting("pathogenExogenousSpreadModelFileExtension");
357  vector<string> files2 = vector<string>();
358  string fullFilename2, filename2, fullPath2;
359  MTHREAD->MD->getFilenamesByDir (dir2,files2, fileExt2); // Ugly format. Files is the output (reference)
360  for (unsigned int i = 0;i < files2.size();i++) {
361  fullFilename2 = files2[i];
362  fullPath2 = dir2+"/"+fullFilename2;
363  filename2 = fullFilename2.substr(0,fullFilename2.find_last_of("."));
364  addLayer(filename2,filename2,false,false,fullPath2,false);
365  }
366  }
367 
368  // Add layer of pixel IDs
369  addLayer("pixelIds","Pixel IDs", true, false, "", true);
370  vector <Pixel*> allPx = getAllPlots(false);
371  for (unsigned int i = 0; i < allPx.size();i++) {
372  allPx[i]->changeValue("pixelIds", allPx[i]->getID());
373  }
374 
375 
376 
377 }
378 
379 /** Init the layers of exogenous data at pixel level (e.g. time of passage)
380  These layers will NOT be read by datafile, but volume for each pixel will be calculated from regional data and area map
381 */
382 /*
383 void
384 Gis::initLayersModelData(const int& year_h){
385 
386  if (!MTHREAD->MD->getBoolSetting("usePixelData")) return;
387 
388  vector <int> years;
389  if(year_h==DATA_NOW){
390  years.push_back(MTHREAD->SCD->getYear());
391  } else if (year_h==DATA_INIT){
392  int initialYear = MTHREAD->MD->getIntSetting("initialYear");
393  int initialOptYear = MTHREAD->MD->getIntSetting("initialOptYear");
394  for(int y=initialYear;y<initialOptYear;y++){
395  years.push_back(y);
396  }
397  } else {
398  years.push_back(year_h);
399  }
400 
401  vector <string> dClasses = MTHREAD->MD->getStringVectorSetting("dClasses");
402  vector <string> fTypes = MTHREAD->MD->getForTypeIds();
403  //int initialYear = MTHREAD->MD->getIntSetting("initialYear");
404  //int initialOptYear = MTHREAD->MD->getIntSetting("initialOptYear");
405  //int simYears = MTHREAD->MD->getIntSetting("simulationYears");
406  string layerName_vol,layerName_cumTp,layerName_regArea,layerName_area;
407  for(uint i=0;i< fTypes.size();i++){
408  for(int y=0;y<years.size();y++){
409  layerName_regArea = pack("regArea",fTypes[i],"",years[y]);
410  addLayer(layerName_regArea,layerName_regArea,false,true,"",false);
411  for (uint j=0;j<dClasses.size();j++){
412  layerName_vol = pack("vol",fTypes[i],dClasses[j],years[y]);
413  layerName_cumTp = pack("cumTp",fTypes[i],dClasses[j],years[y]);
414  layerName_area = pack("area",fTypes[i],dClasses[j],years[y]);
415  addLayer(layerName_vol,layerName_vol,false,true,"",false);
416  addLayer(layerName_cumTp,layerName_cumTp,false,true,"",false);
417  addLayer(layerName_area,layerName_area,false,true,"",false);
418  }
419 
420  }
421 
422  }
423  string debug = "done";
424 
425 }
426 */
427 
428 Layers*
429 Gis::getLayer(const string& layerName_h){
430  for(uint i=0;i<layerVector.size();i++){
431  if(layerVector[i].getName() == layerName_h){
432  return &layerVector[i];
433  }
434  }
435  msgOut(MSG_CRITICAL_ERROR, "Layer "+layerName_h+" not found. Aborting.");
436 }
437 
438 void
440 /*per ogni forest type:
441  - crea i layers delle forest type nuovi
442  - riempi con zero
443  - passa le info dal layerr ereditato al nuovo
444  per ogni pixel
445  */
446 
447  // caching
448  int nReclassRules = MTHREAD->MD->getNReclRules();
449  vector <reclRule*> RRs;
450  for(uint z=0;z<nReclassRules;z++){
451  RRs.push_back(MTHREAD->MD->getReclRule(z));
452  }
453 
454 
455 
456  for (uint i=0;i< MTHREAD->MD->getNForTypes();i++){
457  forType* FT = MTHREAD->MD->getForType(i);
458  if(!layerExist(FT->forLayer)){
459  addLayer(FT->forLayer, "Are layer for forest type "+FT->forTypeId, false, true);
460  resetLayer(FT->forLayer);
461  Layers* newLayer = getLayer(FT->forLayer);
462  Layers* ereditatedLayer = getLayer(MTHREAD->MD->getForType(FT->ereditatedFrom)->forLayer);
463  newLayer->addLegendItems(ereditatedLayer->getLegendItems());
464  }
465  }
466 
467 
468  for (uint i=0;i< MTHREAD->MD->getNForTypes();i++){
469  forType* FT = MTHREAD->MD->getForType(i);
470  for(uint j=0;j<xyNPixels;j++){
471  Pixel* PX = getPixel(j);
472  //int regL1 = PX->getDoubleValue ("regLev_1");
473  int regL2 = PX->getDoubleValue ("regLev_2");
474  double value = PX->getDoubleValue (FT->forLayer, true);
475  for(uint z=0;z<nReclassRules;z++){
476  reclRule* RR = RRs[z];
477  //if( (RR->regId == regL2 || RR->regId == regL1) && RR->forTypeOut == FT->forTypeId ){ // we found a reclassification rule for the region where is located this pixel and that output on the for type we are using
478  if( RR->regId == regL2 && RR->forTypeOut == FT->forTypeId ){ // we found a reclassification rule for the region where is located this pixel and that output on the for type we are using
479  string debugForTypeIn = RR->forTypeIn;
480  double inputValue = PX->getDoubleValue(MTHREAD->MD->getForType(RR->forTypeIn)->forLayer, true);
481  double reclassCoeff = RR->coeff;
482  value += inputValue * reclassCoeff ;
483  // not breaking because we may have more than one input for the same output
484  }
485  }
486  PX->changeValue(FT->forLayer, value, true);
487  }
488  updateImage(FT->forLayer);
489  }
490  //countItems("forType_B_HF", true);
491  refreshGUI();
492  /*Pixel* DP = getPixel(8386);
493  msgOut(MSG_DEBUG,"Debug info on plot 8386");
494  for (uint i=0;i< MTHREAD->MD->getNForTypes();i++){
495  forType* FT = MTHREAD->MD->getForType(i);
496  msgOut(MSG_DEBUG,FT->forTypeId+" - "+d2s(DP->getDoubleValue (FT->forLayer)));
497  }
498  */
499 }
500 
501 
502 /**
503 Called at init time from initLayers, or during model run-time, this function will add a layer to the system.
504 @param name_h ID of the layer (no spaces!)
505 @param label_h layer label
506 @param type_h type of the layer, integer or contiguous
507 @param dynamicContent_h if it change during the time (so it needs to be printed each year) or not
508 @param fullFilename_h if the layer has to be read at the beginning, the name of the associated datafile (default="")
509 <p>It:
510  - had the layer to the layerVector
511  - set all pixels with nodata for that specific layer
512  - let the GUI know we have a new layer
513 */
514 void
515 Gis::addLayer(string name_h, string label_h, bool isInteger_h, bool dynamicContent_h, string fullFileName_h, bool display_h){
516  if(name_h == "forArea_ash"){
517  bool debug = true;
518  }
519  for(uint i=0; i<layerVector.size(); i++){
520  if (layerVector.at(i).getName() == name_h){
521  msgOut(MSG_ERROR, "Layer already exist with that name");
522  return;
523  }
524  }
525  Layers LAYER (MTHREAD, name_h, label_h, isInteger_h, dynamicContent_h, fullFileName_h, display_h);
526  layerVector.push_back(LAYER);
527 
528  for (uint i=0;i<xyNPixels; i++){
529  pxVector[i].setValue(name_h,noValue);
530  }
531  if(display_h){
532  MTHREAD->addLayer(name_h,label_h);
533  }
534 
535 }
536 
537 void
538 Gis::resetLayer(string layerName_h){
539 
540  for(uint i=0; i<layerVector.size(); i++){
541  if (layerVector.at(i).getName() == layerName_h){
542  for (uint i=0;i<xyNPixels; i++){
543  pxVector.at(i).changeValue(layerName_h,noValue); // bug solved 20071022, Antonello
544  }
545  return;
546  }
547  }
548  msgOut(MSG_ERROR, "I could not reset layer "+layerName_h+" as it doesn't exist!");
549 }
550 
551 bool
552 Gis::layerExist(const string& layerName_h, bool exactMatch) const{
553 
554  if(exactMatch){
555  for(uint i=0; i<layerVector.size(); i++){
556  if (layerVector.at(i).getName() == layerName_h){
557  return true;
558  }
559  }
560  } else { // partial matching (stored layer name begin with search parameter)
561  for(uint i=0; i<layerVector.size(); i++){
562  if (layerVector.at(i).getName().compare(0, layerName_h.size(),layerName_h )){
563  return true;
564  }
565  }
566  }
567 
568  return false;
569 }
570 
571 /**
572 Search within the layerVector and call addLegendItem(...) to the appropriate one.
573 <p>Called at init time from initLayers, or during model run-time.
574 @param name_h Name of the layer
575 @param ID_h ID of the specific lagend item
576 @see Layers::addLegendItem
577 */
578 void
579 Gis::addLegendItem(string name_h, int ID_h, string label_h, int rColor_h, int gColor_h, int bColor_h, double minValue_h, double maxValue_h){
580 
581  for(uint i=0; i<layerVector.size(); i++){
582  if (layerVector.at(i).getName() == name_h){
583  layerVector.at(i).addLegendItem(ID_h, label_h, rColor_h, gColor_h, bColor_h, minValue_h, maxValue_h);
584  return;
585  }
586  }
587  msgOut(MSG_ERROR, "Trying to add a legend item to a layer that doesn't exist.");
588  return;
589 }
590 
591 /**
592 Search within the layerVector and call countMyPixels(...) to the appropriate one.
593 <p>Called at init time from initLayers, or during model run-time.
594 @param layerName_h Name of the layer
595 @param debug Print the values on the GUI
596 @see Layers::countMyPixels
597 */
598 void
599 Gis::countItems(const string &layerName_h, const bool &debug){
600 
601  for(uint i=0; i<layerVector.size(); i++){
602  if (layerVector.at(i).getName() == layerName_h){
603  layerVector.at(i).countMyPixels(debug);
604  return;
605  }
606  }
607  msgOut(MSG_ERROR, "Trying to get statistics (count pixels) of a layer that doesn't exist.");
608  return;
609 }
610 
611 
612 /**
613 Called at init time from initLayers, this function load the associated datafile to the existing layers (that if exists at this stage are all of type to be loaded at start-up).
614 <br>This function loop over layerVector and works with GRASS/ASCII (tested) or ARC/ASCII (untested) datasets, assigning to each pixel the readed value to the corresponding layer.
615 <br>The function also "compose" the initial map with the colors read by the layer (for each specific values) and send the map to the GUI.
616 
617 NOTE: It uses some Qt functions!!!
618 
619 @see Pixel::changeValue
620 @see Layers::filterExogenousDataset
621 @see Layers::getColor
622 */
623 void
625  double localNoValue = noValue;
626  double inputValue;
627  double outputValue;
628  QColor color;
629 
630  for(uint i=0;i<layerVector.size();i++){
631  string layerName =layerVector.at(i).getName();
632  string fileName=layerVector.at(i).getFilename();
633  if(fileName == "") continue; // BUGGED !!! 20121017, Antonello. It was "return", so it wasn't reading any layers following a layer with no filename
634  QFile file(fileName.c_str());
635  if (!file.open(QFile::ReadOnly)) {
636  cerr << "Cannot open file for reading: "
637  << qPrintable(file.errorString()) << endl;
638  msgOut(MSG_ERROR, "Cannot open map file "+fileName+" for reading.");
639  continue;
640  }
641  QTextStream in(&file);
642  int countRow = 0;
643  QImage image = QImage(xNPixels, yNPixels, QImage::Format_RGB32);
644  image.fill(qRgb(255, 255, 255));
645  while (!in.atEnd()) {
646  QString line = in.readLine();
647  QStringList fields = line.split(' ');
648  if (
649  (fields.at(0)== "north:" && fields.at(1).toDouble() != geoTopY)
650  || ((fields.at(0)== "south:" || fields.at(0) == "yllcorner" ) && fields.at(1).toDouble() != geoBottomY)
651  || (fields.at(0)== "east:" && fields.at(1).toDouble() != geoRightX)
652  || ((fields.at(0)== "west:" || fields.at(0) == "xllcorner" ) && fields.at(1).toDouble() != geoLeftX)
653  || ((fields.at(0)== "rows:" || fields.at(0) == "nrows" ) && fields.at(1).toInt() != yNPixels)
654  || ((fields.at(0)== "cols:" || fields.at(0) == "ncols" ) && fields.at(1).toInt() != xNPixels)
655  )
656  {
657  msgOut(MSG_ERROR, "Layer "+layerName+" has different coordinates. Aborting reading.");
658  break;
659  } else if (fields.at(0)== "null:" || fields.at(0) == "NODATA_value" || fields.at(0) == "nodata_value" ) {
660  localNoValue = fields.at(1).toDouble();
661  } else if (fields.size() > 5) {
662  for (int countColumn=0;countColumn<xNPixels;countColumn++){
663  inputValue = fields.at(countColumn).toDouble();
664  if (inputValue == localNoValue){
665  outputValue = noValue;
666  pxVector.at((countRow*xNPixels+countColumn)).changeValue(layerName,outputValue);
667  QColor nocolor(255,255,255);
668  color = nocolor;
669  }
670  else {
671  outputValue=layerVector.at(i).filterExogenousDataset(fields.at(countColumn).toDouble());
672  pxVector.at((countRow*xNPixels+countColumn)).changeValue(layerName,outputValue);
673  color = layerVector.at(i).getColor(outputValue);
674  }
675  image.setPixel(countColumn,countRow,color.rgb());
676  }
677  countRow++;
678  }
679  }
680  if (MTHREAD->MD->getBoolSetting("initialRandomShuffle") ){
681  layerVector.at(i).randomShuffle();
682  }
683  this->filterSubRegion(layerName);
684  if(layerVector.at(i).getDisplay()){
685  MTHREAD->updateImage(layerName,image);
686  //send the image to the gui...
687  refreshGUI();
688  }
689 
690 
691  }
692 }
693 
694 /**
695 Update an ALREADY EXISTING image and send the updated image to the GUI.
696 <br>It is used instead of updating the individual pixels that is much more time consuming than change the individual pixels value and then upgrade the image as a whole.
697 @param layername_h Layer from where get the image data
698 */
699 void
700 Gis::updateImage(string layerName_h){
701  msgOut (1, "Update image "+layerName_h+"...");
702 
703  // sub{X,Y}{R,L,T,B} refer to the subregion coordinates, but when this is not active they coincide with the whole region
704  QImage image = QImage(subXR-subXL+1, subYB-subYT+1, QImage::Format_RGB32);
705 
706  image.fill(qRgb(255, 255, 255));
707  int layerIndex=-1;
708  for (uint i=0;i<layerVector.size();i++){
709  if (layerVector.at(i).getName() == layerName_h){
710  layerIndex=i;
711  break;
712  }
713  }
714  if (layerIndex <0) {
715  msgOut(MSG_CRITICAL_ERROR, "Layer not found in Gis::updateImage()");
716  }
717 
718  for (int countRow=subYT;countRow<subYB;countRow++){
719  for (int countColumn=subXL;countColumn<subXR;countColumn++){
720  double value = pxVector.at((countRow*xNPixels+countColumn)).getDoubleValue(layerName_h);
721  QColor color = layerVector.at(layerIndex).getColor(value);
722  image.setPixel(countColumn-subXL,countRow-subYT,color.rgb());
723  }
724  }
725  MTHREAD->updateImage(layerName_h,image);
726  refreshGUI();
727 }
728 
729 Pixel*
730 Gis::getRandomPlotByValue(string layer_h, int layerValue_h){
731 
732  vector <Pixel* > candidates;
733  vector <uint> counts;
734  for(uint i=0;i<pxVector.size();i++) counts.push_back(i);
735  random_shuffle(counts.begin(), counts.end()); // randomize the elements of the array.
736 
737  for (uint i=0;i<counts.size();i++){
738  if(pxVector.at(counts.at(i)).getDoubleValue(layer_h) == layerValue_h ) {
739  return &pxVector.at(counts.at(i));
740  }
741  }
742 
743  msgOut(MSG_CRITICAL_ERROR,"We can't find any plot with "+d2s(layerValue_h)+" value on layer "+layer_h+".");
744  Pixel* toReturn;
745  toReturn =0;
746  return toReturn;
747 }
748 /**
749 
750 @param layer_h Name of the layer
751 @param layerValue_h Value we want the plots for
752 @param onlyFreePlots Flag to get only plots marked as free (d=false)
753 @param outputLevel Level of output in case of failure (no plots available). Default is warning, but if set as MSG_CRITICAL_ERROR it make stop the model.
754 
755 
756 */
757 vector <Pixel*>
758 Gis::getAllPlotsByValue(string layer_h, int layerValue_h, int outputLevel){
759  // this would be easier to mantain and cleaned code, but slighly slower:
760  //vector<int> layerValues;
761  //layerValues.push_back(layerValue_h);
762  //return getAllPlotsByValue(layer_h, layerValues, onlyFreePlots, outputLevel);
763 
764  vector <Pixel* > candidates;
765  for (uint i=0;i<pxVector.size();i++){
766  if(pxVector.at(i).getDoubleValue(layer_h) == layerValue_h){
767  candidates.push_back(&pxVector.at(i));
768  }
769  }
770 
771  if (candidates.size()>0){
772  random_shuffle(candidates.begin(), candidates.end()); // randomize ther elements of the array... cool !!! ;-)))
773  }
774  else {
775  msgOut(outputLevel,"We can't find any free pixel with "+d2s(layerValue_h)+" value on layer "+layer_h+".");
776  }
777  return candidates;
778 }
779 
780 /**
781 
782 @param layer_h Name of the layer
783 @param layerValues_h Values we want the plots for
784 @param onlyFreePlots Flag to get only plots marked as free (d=false)
785 @param outputLevel Level of output in case of failure (no plots available). Default is warning, but if set as MSG_CRITICAL_ERROR it make stop the model.
786 
787 
788 */
789 vector <Pixel*>
790 Gis::getAllPlotsByValue(string layer_h, vector<int> layerValues_h, int outputLevel){
791  vector <Pixel* > candidates;
792  string valuesToMatch;
793  unsigned int z;
794 
795  //string of the required land values to match;
796  for (uint j=0;j<layerValues_h.size();j++){
797  valuesToMatch = valuesToMatch + " " + i2s(layerValues_h.at(j));
798  }
799 
800  for (uint i=0;i<pxVector.size();i++){
801  z = valuesToMatch.find(d2s(pxVector.at(i).getDoubleValue(layer_h))); // search if in the string of required values is included also the value of the current plot
802  if(z!=string::npos){ //z is not at the end of the string, means found!
803  candidates.push_back(&pxVector.at(i));
804  }
805  }
806 
807  if (candidates.size()>0){
808  random_shuffle(candidates.begin(), candidates.end()); // randomize ther elements of the array... cool !!! ;-)))
809  }
810  else {
811  msgOut(outputLevel,"We can't find any free plot with the specified values ("+valuesToMatch+") on layer "+layer_h+".");
812  }
813  return candidates;
814 }
815 
816 /**
817 
818 @param onlyFreePlots Flag to get only plots marked as free (d=false)
819 @param outputLevel Level of output in case of failure (no plots available). Default is warning, but if set as MSG_CRITICAL_ERROR it make stop the model.
820 
821 */
822 vector <Pixel*>
823 Gis::getAllPlots(bool masked, int outputLevel){
824  vector <Pixel* > candidates;
825  if(masked = false){
826  for (uint i=0;i<pxVector.size();i++){
827  candidates.push_back(&pxVector.at(i));
828  }
829  if (candidates.size()>0){
830  random_shuffle(candidates.begin(), candidates.end()); // randomize ther elements of the array... cool !!! ;-)))
831  } else {
832  msgOut(outputLevel,"We can't find any free plot.");
833  }
834  } else {
835  // Only pixels within a L2 region
836  vector <int> regIds2 = MTHREAD->MD->getRegionIds(2);
837  for(uint i=0;i<regIds2.size();i++){
838  vector <Pixel*> rpx = getAllPlotsByRegion(regIds2[i]);
839  //for (uint i=0;i<rpx.size();i++){
840  // candidates.push_back(rpx.at(i));
841  //}
842  candidates.insert( candidates.end(), rpx.begin(), rpx.end() );
843  }
844  if (candidates.size()>0){
845  random_shuffle(candidates.begin(), candidates.end()); // randomize ther elements of the array... cool !!! ;-)))
846  } else {
847  msgOut(outputLevel,"We can't find any free plot.");
848  }
849  }
850  return candidates;
851 }
852 
853 /// Return the vector of all plots by a specific region (main region or subregion), optionally shuffled;
854 vector <Pixel*>
855 Gis::getAllPlotsByRegion(ModelRegion &region_h, bool shuffle){
856  vector <Pixel*> regionalPixels = region_h.getMyPixels();
857  if(shuffle){
858  random_shuffle(regionalPixels.begin(), regionalPixels.end()); // randomize the elements of the array.
859  }
860  return regionalPixels;
861 }
862 
863 vector <Pixel*>
864 Gis::getAllPlotsByRegion(int regId_h, bool shuffle){
865  ModelRegion* reg = MTHREAD->MD->getRegion(regId_h);
866  return getAllPlotsByRegion(*reg,shuffle);
867 }
868 
869 
870 
871 vector <string>
873  vector <string> toReturn;
874  for (uint i=0;i<layerVector.size();i++){
875  toReturn.push_back(layerVector[i].getName());
876  }
877  return toReturn;
878 }
879 
880 vector <Layers*>
882  vector <Layers*> toReturn;
883  for (uint i=0;i<layerVector.size();i++){
884  toReturn.push_back(&layerVector[i]);
885  }
886  return toReturn;
887 }
888 
889 void
890 Gis::printDebugValues (string layerName_h, int min_h, int max_h){
891  int min=min_h;
892  int max;
893  int ID, X, Y;
894  string out;
895  double value;
896  //double noValue = MTHREAD->MD->getDoubleSetting("noValue");
897  if (max_h==0){
898  max= pxVector.size();
899  }
900  else {
901  max = max_h;
902  }
903  msgOut(MSG_DEBUG,"Printing debug information for layer "+layerName_h+".");
904  for (int i=min;i<max;i++){
905  value = pxVector.at(i).getDoubleValue(layerName_h);
906  if (value != noValue){
907  ID = i;
908  X = pxVector.at(i).getX();
909  Y = pxVector.at(i).getY();
910  out = "Px. "+i2s(ID)+" ("+i2s(X)+","+i2s(Y)+"): "+d2s(value);
911  msgOut(MSG_DEBUG,out);
912  }
913  }
914 }
915 
916 /**
917 This function filter the region, placing noValue on the selected informative layer on pixels that are outside the subregion.
918 <br>It was thinked for speedup the development without have to run the whole model for testing each new implementation, but it can used to see what happen in the model when only a subset of the region is analysed.
919 */
920 void
921 Gis::filterSubRegion(string layerName_h){
922  subXL = 0;
923  subYT = 0;
924  subXR = xNPixels-1;
925  subYB = yNPixels-1;
926 }
927 
928 double
929 Gis::getDistance(const Pixel* px1, const Pixel* px2){
930  return sqrt (
931  pow ( (((double)px1->getX()) - ((double)px2->getX()))*xMetersByPixel,2)
932  +
933  pow ( (((double)px1->getY()) - ((double)px2->getY()))*yMetersByPixel,2)
934  );
935 }
936 
937 
938 
939 void
940 Gis::printLayers(string layerName_h){
941  msgOut(MSG_DEBUG,"Printing the layers");
942  int iteration = MTHREAD->SCD->getIteration(); // are we on the first year of the simulation ??
943  if(layerName_h == ""){
944  for (uint i=0;i<layerVector.size();i++){
945  //if(layerVector[i].getName() == "pixelIds"){
946  // cout << layerVector[i].getName() << endl;
947  //}
948  // not printing if we are in a not-0 iteration and the content of the map doesn't change
949  if (!iteration || layerVector[i].getDynamicContent()) layerVector[i].print();
950  }
951  } else {
952  for (uint i=0;i<layerVector.size();i++){
953  if(layerVector[i].getName() == layerName_h){
954  if (!iteration || layerVector[i].getDynamicContent()) layerVector[i].print();
955  return;
956  }
957  }
958  msgOut(MSG_ERROR, "Layer "+layerName_h+" unknow. No layer printed.");
959  }
960 }
961 
962 void
963 Gis::printBinMaps(string layerName_h){
964  msgOut(MSG_DEBUG,"Printing the maps as images");
965  int iteration = MTHREAD->SCD->getIteration(); // are we on the first year of the simulation ??
966  if(layerName_h == ""){
967  for (uint i=0;i<layerVector.size();i++){
968  if (!iteration || layerVector[i].getDynamicContent()) {layerVector[i].printBinMap();}
969  }
970  } else {
971  for (uint i=0;i<layerVector.size();i++){
972  if(layerVector[i].getName() == layerName_h){
973  if (!iteration || layerVector[i].getDynamicContent()) {layerVector[i].printBinMap();}
974  return;
975  }
976  }
977  msgOut(MSG_ERROR, "Layer "+layerName_h+" unknow. No layer printed.");
978  }
979 }
980 
981 int
982 Gis::sub2realID(int id_h){
983  // IMPORTANT: this function is called at refreshGUI() times, so if there are output messages, call them with the option to NOT refresh the gui, otherwise we go to an infinite loop...
984  return id_h;
985 }
986 
987 void
988 Gis::unpack(const string& key, string& parName, string& forName, string& dClass, int& year) const{
989  int parNameDelimiter = key.find("#",0);
990  int forNameDelimiter = key.find("#",parNameDelimiter+1);
991  int dClassDelimiter = key.find("#",forNameDelimiter+1);
992  int yearDelimiter = key.find("#",dClassDelimiter+1);
993  if (yearDelimiter == string::npos){
994  msgOut(MSG_CRITICAL_ERROR, "Error in unpacking the key for the layer.");
995  }
996  parName.assign(key,0,parNameDelimiter);
997  forName.assign(key,parNameDelimiter+1,forNameDelimiter-parNameDelimiter-1);
998  dClass.assign(key,forNameDelimiter+1,dClassDelimiter-forNameDelimiter-1);
999  string yearString="";
1000  yearString.assign(key,dClassDelimiter+1,yearDelimiter-dClassDelimiter-1);
1001  year = s2i(yearString);
1002 }
1003 
1004 void
1005 Gis::swap(const int& swap_what){
1006 
1007  for(uint i=0;i<pxVector.size();i++) {
1008  pxVector[i].swap(swap_what);
1009  }
1010 
1011 }
void updateImage(string layerName_h)
Add one layer to the system.
Definition: Gis.cpp:700
void filterSubRegion(string layerName_h)
If subregion mode is on, this function place noValues on the selected layer for all out-of-region pix...
Definition: Gis.cpp:921
void resetLayer(string layerName_h)
Check if a layer with a certain name is loaded in the model. Used e.g. to check if the dtm layer (opt...
Definition: Gis.cpp:538
vector< LegendItems > getLegendItems()
Definition: Layers.h:70
void addLegendItems(vector< LegendItems > legendItems_h)
Definition: Layers.cpp:72
Print an ERROR message, but don&#39;t stop the model.
Definition: BaseClass.h:61
The required data is for the current year.
Definition: BaseClass.h:73
void swap(const int &swap_what)
Definition: Gis.cpp:1005
void addLayer(string name_h, string label_h, bool isInteger_h, bool dynamicContent_h, string fullFileName_h="", bool display_h=true)
Fill a layer with empty values.
Definition: Gis.cpp:515
bool setWorkingFile(std::string filename_h)
Load the file on memory. Return false if no success.
Definition: InputNode.cpp:37
void printDebugValues(string layerName_h, int min_h=0, int max_h=0)
Definition: Gis.cpp:890
~Gis()
Definition: Gis.cpp:44
Forest types (struct)
Definition: ModelData.h:293
IO production matrix between the forest resources and the primary products (struct) ...
Definition: ModelData.h:306
Wrapper around the underlying library for reading DOM elements (nodes).
Definition: InputNode.h:51
bool layerExist(const string &layerName_h, bool exactMatch=true) const
Return a pointer to a layer given its name.
Definition: Gis.cpp:552
void changeValue(const string &layerName_h, const double &value_h, const bool &setNoValueForZero=false)
Change the value of an existing layerMTHREAD->GIS->pack(parName, forName, dClass, year)...
Definition: Pixel.cpp:135
void applyForestReclassification()
Apply the forest reclassification with the rules defined in reclRules sheet.
Definition: Gis.cpp:439
int getX() const
Definition: Pixel.h:68
double getDistance(const Pixel *px1, const Pixel *px2)
Definition: Gis.cpp:929
void loadLayersDataFromFile()
Load the data of a layer its datafile.
Definition: Gis.cpp:624
vector< Pixel * > getAllPlots(bool masked=true, int outputLevel=MSG_WARNING)
Return the vector (shuffled) of all plots. It is also possible to specify the level in case of failur...
Definition: Gis.cpp:823
string forTypeOut
Definition: ModelData.h:309
STL namespace.
void initLayers()
Init the layers.
Definition: Gis.cpp:259
Thread manager. Responsable to manage the main thread and "speak" with the GUI.
Definition: ThreadManager.h:65
void applyStochasticRiskAdversion()
Give to each agend a stochastic risk adversion. For now Pixel = Agent.
Definition: Gis.cpp:199
string forTypeIn
Definition: ModelData.h:308
string ereditatedFrom
Definition: ModelData.h:298
void addLegendItem(string name_h, int D_h, string label_h, int rColor_h, int gColor_h, int bColor_h, double minValue_h, double maxValue_h)
Definition: Gis.cpp:579
Print an error message and stop the model.
Definition: BaseClass.h:62
void printBinMaps(string layerName_h="")
Save an image in standard png format.
Definition: Gis.cpp:963
double getDoubleValue(const string &layerName_h, const bool &returnZeroForNoValue=false) const
Return the value for a specific layer.
Definition: Pixel.cpp:158
Pixel * getRandomPlotByValue(string layer_h, int layerValue__h)
Return a pointer to a plot with a specific value for the specified layer.
Definition: Gis.cpp:730
void applySpatialStochasticValues()
Apply stochastic simulation, e.g. regional volume growth s.d. -> tp multipliers.
Definition: Gis.cpp:121
Define layer objects at the regional level.
Definition: Layers.h:49
Pixel-level class.
Definition: Pixel.h:47
Print a debug message, normally filtered out.
Definition: BaseClass.h:58
Gis(ThreadManager *MTHREAD_h)
Constructor.
Definition: Gis.cpp:40
vector< Layers * > getLayerPointers()
Return a vector of pointers of existing layers.
Definition: Gis.cpp:881
string forTypeId
Definition: ModelData.h:294
vector< Pixel * > getAllPlotsByRegion(ModelRegion &region_h, bool shuffle=false)
Return the vector of all plots by a specific region (main region or subregion), optionally shuffled;...
Definition: Gis.cpp:855
void setCoordinates(int x_h, int y_h)
Definition: Pixel.h:83
void printLayers(string layerName_h="")
Print the specified layer or all layers (if param layerName_h is missing).
Definition: Gis.cpp:940
void setSpace()
Set the initial space environment, including loading data from files.
Definition: Gis.cpp:57
string forLayer
Definition: ModelData.h:297
vector< Pixel * > getAllPlotsByValue(string layer_h, int layerValue_h, int outputLevel=MSG_WARNING)
Return the vector (shuffled) of all plots with a specific value for a specified layer. It is also possible to specify the level in case of failure.
Definition: Gis.cpp:758
int sub2realID(int id_h)
Transform the ID of a pixel in subregion coordinates to the real (and model used) coordinates...
Definition: Gis.cpp:982
void countItems(const string &layerName_h, const bool &debug=false)
Count the pixels within each legend item for the selected layer.
Definition: Gis.cpp:599
vector< string > getLayerNames()
Return a vector of the layer ids (as string)
Definition: Gis.cpp:872
int regId
Definition: ModelData.h:307
vector< InputNode > getNodesByName(string nodeName_h, int debugLevel=MSG_WARNING, bool childFlag=false)
Definition: InputNode.cpp:155
double coeff
Definition: ModelData.h:310
void initLayersPixelData()
Definition: Gis.cpp:320
vector< Pixel * > getMyPixels()
Definition: ModelRegion.h:86
Print an INFO message.
Definition: BaseClass.h:59
void unpack(const string &key, string &parName, string &forName, string &dClass, int &year) const
Definition: Gis.cpp:988
int getY() const
Definition: Pixel.h:69
Layers * getLayer(const string &layerName_h)
Add a legend item to an existing layer.
Definition: Gis.cpp:429