-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLandscape.h
562 lines (498 loc) · 16.7 KB
/
Landscape.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
/*----------------------------------------------------------------------------
*
* Copyright (C) 2020 Greta Bocedi, Stephen C.F. Palmer, Justin M.J. Travis, Anne-Kathleen Malchow, Damaris Zurell
*
* This file is part of RangeShifter.
*
* RangeShifter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RangeShifter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RangeShifter. If not, see <https://www.gnu.org/licenses/>.
*
--------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
RangeShifter v2.0 Landscape
Implements the following classes:
InitDist - Initial species distribution
Landscape - Landscape grid
The Landscape is a rectangular array of Cells which are grouped together in
Patches. As far as the user is aware, the Landscape is either patch-based or
cell-based (having no Patches), but internally Patches are always present (they
each comprise only one Cell for a cell-based model). The grain of the Landscape
may be any positive integer, and is nominally in metres.
The Landscape is either input from one or more text files in ArcGIS raster export
format, or it is generated artificially as a random or fractal binary array (in
which case, it must be cell-based). An input 'real' Landscape may hold within each
Cell either discrete habitat classes, or percent cover of habitat classes, or a
continuous quality index (1 to 100%).
The Landscape may be dynamic, in which case the user specifies a set of changes
to be applied at certain years during each simulation. The changes may be to
habitat only, patches only (if a patch-based model) or habitats and patches.
Although the changes must be supplied as entire habitat / patch files (which
must match the original Landscape in terms of cell size and extent), internally
they are recorded as lists of dynamic habitat and patch changes.
The initial species distribution is a rectangular array if distribution cells
(DistCell) covering the same spatial extent at the Landscape. Its grain may be
either that of the Landscape or an integer multiple of it.
The Landscape can record a list (in the vector initcells) of Cells or Patches
to be intialised, which are specified by the user in FormSeeding. This option is
available in the GUI version only.
For full details of RangeShifter, please see:
Bocedi G., Palmer S.C.F., Pe’er G., Heikkinen R.K., Matsinos Y.G., Watts K.
and Travis J.M.J. (2014). RangeShifter: a platform for modelling spatial
eco-evolutionary dynamics and species’ responses to environmental changes.
Methods in Ecology and Evolution, 5, 388-396. doi: 10.1111/2041-210X.12162
Authors: Greta Bocedi & Steve Palmer, University of Aberdeen
Last updated: 2 December 2021 by Steve Palmer
------------------------------------------------------------------------------*/
#ifndef LandscapeH
#define LandscapeH
#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;
#include "Parameters.h"
#include "Patch.h"
#include "Cell.h"
#include "Species.h"
#include "FractalGenerator.h"
#if RS_RCPP
#include <locale>
#if !RSWIN64
#include <codecvt>
#endif
#include <Rcpp.h>
#endif
//---------------------------------------------------------------------------
// Initial species distribution
class InitDist{
public:
InitDist(Species*);
~InitDist();
int readDistribution(
string // name of species distribution file
);
void setDistribution(
int // no. of distribution cells to be initialised (0 for all cells)
);
void setDistCell( // Set a specified cell (by position in cells vector)
int, // index no. of DistCell in cells vector
bool // value to be set
);
void setDistCell( // Set a specified cell (by co-ordinates)
locn, // structure holding x (column) and y (row) co-ordinates
bool
);
bool inInitialDist( // Specified location is within the initial distribution?
locn // structure holding x (column) and y (row) co-ordinates
);
int cellCount(void);
locn getCell( // Return the co-ordinates of a specified initial distribution cell
int // index no. of DistCell in cells vector
);
locn getSelectedCell( // Return the co-ordinates of a specified initial distribution
// cell if it has been selected
// otherwise return negative co-ordinates
int // index no. of DistCell in cells vector
);
locn getDimensions(void);
void resetDistribution(void);
private:
Species *pSpecies; // pointer to species
int resol; // species distribution cell size (m)
int maxX, maxY; // dimensions
double minEast; // ) real world min co-ordinates
double minNorth; // ) read from raster file
// list of cells in the initial distribution
// cells MUST be loaded in the sequence ascending x within descending y
std::vector <DistCell*> cells;
};
//---------------------------------------------------------------------------
struct landParams {
bool patchModel; bool spDist; bool generated;
bool dynamic;
int landNum; int resol; int spResol; int nHab; int nHabMax;
int dimX,dimY,minX,minY,maxX,maxY;
short rasterType;
};
struct landData {
int resol; int dimX,dimY,minX,minY,maxX,maxY;
};
struct genLandParams {
bool fractal; bool continuous;
float minPct,maxPct; float propSuit; float hurst; int maxCells;
};
struct landPix {
int pix; float gpix;
};
struct landOrigin {
double minEast; double minNorth;
};
struct rasterHdr {
bool ok;
int errors,ncols,nrows,cellsize;
double xllcorner,yllcorner;
};
struct rasterdata {
bool ok;
int errors,ncols,nrows,cellsize;
double xllcorner,yllcorner;
#if RS_RCPP
bool utf;
#endif
};
struct patchData {
Patch *pPatch; int patchNum,nCells; int x,y;
};
struct landChange {
int chgnum,chgyear; string habfile,pchfile,costfile;
};
struct patchChange {
int chgnum, x, y, oldpatch, newpatch;
};
struct costChange {
int chgnum,x,y,oldcost,newcost;
};
class Landscape{
public:
Landscape();
~Landscape();
void resetLand(void);
// functions to set and return parameter values
void setLandParams(
landParams, // structure holding landscape parameters
bool // batch mode
);
landParams getLandParams(void);
landData getLandData(void);
void setGenLandParams(genLandParams);
genLandParams getGenLandParams(void);
void setLandLimits(
int, // minimum available X
int, // minimum available Y
int, // maximum available X
int // maximum available Y
);
void resetLandLimits(void);
void setLandPix(landPix);
landPix getLandPix(void);
void setOrigin(landOrigin);
landOrigin getOrigin(void);
// functions to handle habitat codes
bool habitatsIndexed(void);
void listHabCodes(void);
void addHabCode(int);
int findHabCode(int);
int getHabCode(int);
void clearHabitats(void);
void addColour(rgb);
void changeColour(int,rgb);
rgb getColour(int);
int colourCount(void);
// functions to handle patches and cells
void setCellArray(void);
void addPatchNum(int);
void generatePatches(void); // create an artificial landscape
void allocatePatches(Species*); // create patches for a cell-based landscape
Patch* newPatch(
int // patch sequential no. (id no. is set to equal sequential no.)
);
Patch* newPatch(
int, // patch sequential no.
int // patch id no.
);
void resetPatches(void);
void addNewCellToLand(
int, // x co-ordinate
int, // y co-ordinate
float // habitat quality value
);
void addNewCellToLand(
int, // x co-ordinate
int, // y co-ordinate
int // habitat class no.
);
void addCellToPatch(
Cell*, // pointer to Cell
Patch* // pointer to Patch
);
void addCellToPatch(
Cell*, // pointer to Cell
Patch*, // pointer to Patch
float // habitat quality value
);
void addCellToPatch(
Cell*, // pointer to Cell
Patch*, // pointer to Patch
int // habitat class no.
);
void addNewCellToPatch(
Patch*, // pointer to Patch
int, // x co-ordinate
int, // y co-ordinate
int // habitat class no.
);
void addNewCellToPatch(
Patch*, // pointer to Patch
int, // x co-ordinate
int, // y co-ordinate
float // habitat quality value
);
patchData getPatchData(
int // index no. of Patch in patches vector
);
bool existsPatch(
int // Patch id no.
);
Patch* findPatch(
int // Patch id no.
);
int checkTotalCover(void);
void resetPatchPopns(void);
void updateCarryingCapacity(
Species*, // pointer to Species
int, // year
short // landscape change index (always zero if not dynamic)
);
Cell* findCell(
int, // x co-ordinate
int // y co-ordinate
);
int patchCount(void);
void updateHabitatIndices(void);
void setEnvGradient(
Species*, // pointer to Species
bool // TRUE for initial instance that gradient is set
);
void setGlobalStoch(
int // no. of years
);
float getGlobalStoch(
int // year
);
void updateLocalStoch(void);
void resetCosts(void);
void resetEffCosts(void);
// functions to handle dynamic changes
void setDynamicLand(bool);
void addLandChange(
landChange // structure holding landscape change data
);
int numLandChanges(void);
landChange getLandChange(
short // change number
);
void deleteLandChanges(void);
#if RS_RCPP && !R_CMD
int readLandChange(
int, // change file number
bool, // change SMS costs?
wifstream&, // habitat file stream
wifstream&, // patch file stream
wifstream&, // cost file stream
int, // habnodata
int, // pchnodata
int // costnodata
);
#else
int readLandChange(
int, // change file number
bool // change SMS costs?
);
#endif
void createPatchChgMatrix(void);
void recordPatchChanges(int);
void deletePatchChgMatrix(void);
int numPatchChanges(void);
patchChange getPatchChange(
int // patch change number
);
void createCostsChgMatrix(void);
void recordCostChanges(int);
void deleteCostsChgMatrix(void);
int numCostChanges(void);
costChange getCostChange(
int // cost change number
);
// functions to handle species distributions
int newDistribution(
Species*, // pointer to Species
string // name of initial distribution file
);
void setDistribution(
Species*, // pointer to Species
int // no. of distribution squares to initialise
);
bool inInitialDist( // Specified cell matches one of the distn cells to be initialised?
Species*, // pointer to Species
locn // structure holding co-ordinates of Cell
);
void deleteDistribution(
Species* // pointer to Species
);
int distnCount(void); // Return no. of initial distributions in the Landscape
int distCellCount( // Return no. of distribution cells in an initial distribution
int // index no. of InitDist in distns vector
);
locn getDistnCell( // Get co-ordinates of a specified cell in a specified initial distn
int, // index no. of InitDist in distns vector
int // index no. of DistCell in cells vector
);
locn getSelectedDistnCell( // Get co-ordinates of a specified cell in a specified initial distn
// Returns negative co-ordinates if the cell is not selected
int, // index no. of InitDist in distns vector
int // index no. of DistCell in cells vector
);
locn getDistnDimensions( // Get the dimensions of a specified initial distribution
int // index no. of InitDist in distns vector
);
void setDistnCell( // Set a cell in a specified init distn (by posn in cells vector)
int, // index no. of InitDist in distns vector
int, // index no. of DistCell in cells vector
bool // value to be set
);
void setDistnCell( // Set a cell in a specified init distn (by given co-ordinates)
int, // index no. of InitDist in distns vector
locn, // structure holding co-ordinates of DistCell
bool // value to be set
);
void resetDistribution(
Species* // pointer to Species
);
// functions to handle initialisation cells
int initCellCount(void);
void addInitCell( // Create a new DistCell and add to the initcells vector
int, // x co-ordinate
int // y co-ordinate
);
locn getInitCell(
int // index no. of DistCell in initcells vector
);
void clearInitCells(void);
// functions to handle connectivity matrix
void createConnectMatrix(void);
void resetConnectMatrix(void);
void incrConnectMatrix(
int, // sequential no. of origin Patch
int // sequential no. of settlement Patch
);
void deleteConnectMatrix(void);
bool outConnectHeaders( // Write connectivity file headers
int // option - set to -999 to close the connectivity file
);
#if RS_RCPP
void outPathsHeaders(int, int);
#endif
void outConnect(
int, // replicate no.
int // year
);
// functions to handle input and output
int readLandscape(
int, // fileNum == 0 for (first) habitat file and optional patch file
// fileNum > 0 for subsequent habitat files under the %cover option
string, // habitat file name
string, // patch file name
string // cost file name (may be NULL)
);
void listPatches(void);
int readCosts(
string // costs file name
);
// the following four functions are implemented for the GUI version only
// in the batch version, they are defined, but empty
void setLandMap(void);
void drawLandscape(
int, // replicate no.
int, // landscape index number (always 0 if landscape is not dynamic)
int // landscape no.
);
void drawGradient(void); // Draw environmental gradient map
void drawGlobalStoch( // Draw environmental stochasticity time-series
int // no. of years
);
void resetVisits(void);
void outVisits(int,int); // save SMS path visits map to raster text file
private:
bool generated; // artificially generated?
bool patchModel; //
bool spDist; // initial species distribution loaded
bool fractal; //
bool continuous; //
bool dynamic; // landscape changes during simulation
bool habIndexed; // habitat codes have been converted to index numbers
short rasterType; // 0 = habitat codes 1 = % cover 2 = quality 9 = artificial landscape
int landNum; // landscape number
int resol; // cell size (m)
int spResol; // species distribution cell size (m)
int nHab; // no. of habitats
int nHabMax; // max. no. of habitats (used for batch input only)
int dimX,dimY; // dimensions
int minX,minY; // minimum available X and Y co-ordinates
int maxX,maxY; // maximum available X and Y co-ordinates
float minPct,maxPct; // min and max percentage of habitat in a cell
float propSuit; // proportion of suitable cells
float hurst; // Hurst exponent
int maxCells; // max. cells per patch (artificial landscapes)
int pix; // image display ratio
float gpix; // image display ratio for gradient map
double minEast; // ) real world min co-ordinates
double minNorth; // ) read from habitat raster
// list of cells in the landscape
// cells MUST be loaded in the sequence ascending x within descending y
Cell ***cells;
// list of patches in the landscape - can be in any sequence
std::vector <Patch*> patches;
// list of patch numbers in the landscape
std::vector <int> patchnums;
// list of habitat codes
std::vector <int> habCodes;
// list of colours for habitat codes
std::vector <rgb> colours;
// list of dynamic landscape changes
std::vector <landChange> landchanges;
std::vector <patchChange> patchchanges;
std::vector <costChange> costschanges;
// list of initial individual species distributions
std::vector <InitDist*> distns;
// list of cells to be initialised for ALL species
std::vector <DistCell*> initcells;
// patch connectivity matrix
// indexed by [start patch seq num][end patch seq num]
int **connectMatrix;
// global environmental stochasticity (epsilon)
float *epsGlobal; // pointer to time-series
// patch and costs change matrices (temporary - used when reading dynamic landscape)
// indexed by [descending y][x][period]
// where there are three periods, 0=original 1=previous 2=current
int ***patchChgMatrix;
int ***costsChgMatrix;
};
// NOTE: the following function is not a behaviour of Landscape, as it is run by the
// batch routine to check raster files before any Landscape has been initiated
rasterdata CheckRasterFile(string);
extern paramGrad *paramsGrad;
extern paramStoch *paramsStoch;
extern paramInit *paramsInit;
extern paramSim *paramsSim;
extern RSrandom *pRandom;
#if RSDEBUG
extern ofstream DEBUGLOG;
extern void DebugGUI(string);
#endif
extern void MemoLine(string);
#if RS_RCPP
extern rasterdata landraster,patchraster,spdistraster,costsraster;
extern void EOFerrorR(string);
extern void StreamErrorR(string);
#endif
//---------------------------------------------------------------------------
#endif