ALMaSS Rabbit ODdox  1.00
The rabbit model description following ODdox protocol
rastermap.cpp
Go to the documentation of this file.
1 //
2 // rastermap.cpp
3 //
4 /*
5 *******************************************************************************************************
6 Copyright (c) 2011, Christopher John Topping, Aarhus University
7 All rights reserved.
8 
9 Redistribution and use in source and binary forms, with or without modification, are permitted provided
10 that the following conditions are met:
11 
12 Redistributions of source code must retain the above copyright notice, this list of conditions and the
13 following disclaimer.
14 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
15 the following disclaimer in the documentation and/or other materials provided with the distribution.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
18 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
20 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 ********************************************************************************************************
26 */
27 
28 #define _CRT_SECURE_NO_DEPRECATE
29 
30 #include <cstdio>
31 #include <stdlib.h>
32 #include <string>
33 #include <iostream>
34 #include <fstream>
35 #include "maperrormsg.h"
36 #include "rastermap.h"
37 #include "configurator.h"
38 #include "../Landscape/ls.h"
39 
40 using namespace std;
41 
42 CfgBool cfg_manipulation1_on("RASTER_MANIPULATION_ONE_ON",CFG_CUSTOM,false);
43 CfgBool cfg_rectangularmaps_on("RASTER_RECTANGULARMAPS_ON",CFG_CUSTOM,true);
44 CfgInt cfg_rastermapmanipmultiply("RASTER_MANIPULATION_MULTIPLYFACTOR",CFG_CUSTOM,2);
45 
46 RasterMap::RasterMap(const char* a_mapfile, Landscape * a_landscape)
47 {
48  m_landscape = a_landscape;
49  FILE * IFile;
50 
51  IFile = fopen(a_mapfile, "rb");
52  if (!IFile) {
53  g_msg->Warn(WARN_FILE, "RasterMap::RasterMap(): Unable to open file",
54  a_mapfile);
55  exit(1);
56  }
57  fread(m_id, 1, 12, IFile);
58  fclose(IFile);
59  if (strcmp(m_id, "An LSB File") == 0 ) Init1(a_mapfile, a_landscape); else Init2(a_mapfile, a_landscape);
61  Manipulation1();
62  exit(10);
63  }
64 }
65 
66 void RasterMap::Init1(const char* a_mapfile, Landscape * a_landscape)
67 {
68  m_landscape = a_landscape;
69  FILE * IFile;
70  char error_num[20];
71  int lastref = -9999;
72 
73  IFile = fopen(a_mapfile, "rb");
74  if (!IFile) {
75  g_msg->Warn(WARN_FILE, "RasterMap::RasterMap(): Unable to open file",
76  a_mapfile);
77  exit(1);
78  }
79  fread(m_id, 1, 12, IFile);
80  fread(&m_width, 1, sizeof(int), IFile);
81  if (!cfg_rectangularmaps_on.value())m_height = m_width; else fread(&m_height, 1, sizeof(int), IFile);
82 
83  m_map = (int*)malloc(sizeof(int)* m_width*m_height);
84  if (m_map == NULL) {
86  "RasterMap::RasterMap(): Out of memory.", "");
87  exit(1);
88  }
89 
90  fread(m_map, 1, sizeof(int)*m_width*m_height, IFile);
91  m_x = m_width;
92  m_y = m_height;
93  for (int x = 0; x<m_x; x++) {
94  for (int y = 0; y<m_y; y++) {
95  int i = Get(x, y);
96  if (i<0) {
97  //if ( i<0 || i> 250000 ) { REMOVED 5/7/2013 due to problems with large maps overstepping this limit
98  // This fills in holes caused by -9999, but if two consequetive holes are found, then it will exit
99  i = lastref;
100  if (i<0) {
101  // if ( i<0 || i> 250000 ) {
102  sprintf(error_num, "%d", Get(x, y));
103  g_msg->Warn(WARN_FILE, "RasterMap::RasterMap(): Unknown polygon map number (could be a hole):", error_num);
104  exit(1);
105  }
106  Put(x, y, i);
107  }
108  lastref = i;
109  if (m_polymapping[Get(x, y)] == -1)
110  {
111  // Tripping out here means that the lsb file has a polygon that is not
112  // listed in the polygonrefs file
113  sprintf(error_num, "%d", Get(x, y));
114  g_msg->Warn(WARN_FILE, "RasterMap::RasterMap():" " Unknown polygon ref number:", error_num);
115  exit(1);
116  }
117  }
118  }
119  fclose(IFile);
120 }
121 
122 void RasterMap::Init2(const char* a_mapfile, Landscape * a_landscape)
123 {
124  m_landscape = a_landscape;
125  char error_num[20];
126 
127  ifstream IFile(a_mapfile, ios::binary);
128  if (!IFile.is_open()) {
129  g_msg->Warn(WARN_FILE, "RasterMap::RasterMap(): Unable to open file",
130  a_mapfile);
131  exit(1);
132  }
133  IFile.read(m_id,12);
134  IFile.read((char*)&m_width, sizeof (int));
135  IFile.read((char*)&m_height, sizeof (int));
136  m_map = new int[ m_width*m_height];
137  if (m_map == NULL) {
139  "RasterMap::RasterMap(): Out of memory.", "");
140  exit(1);
141  }
142  IFile.read((char*)m_map, m_width*m_height * sizeof(int));
143 
144  m_x = m_width;
145  m_y = m_height;
146  int pref = -1;
147  for (int x = 0; x<m_x; x++)
148  {
149  for (int y = 0; y<m_y; y++)
150  {
151  pref = Get(x, y);
152  if (pref<0)
153  {
154  sprintf(error_num, "%d", Get(x, y));
155  g_msg->Warn(WARN_FILE, "RasterMap::RasterMap(): Unknown polygon map number (could be a hole):", error_num);
156  exit(1);
157  }
158  if (m_polymapping[Get(x, y)] == -1)
159  {
160  // Tripping out here means that the lsb file has a polygon that is not
161  // listed in the polygonrefs file
162  sprintf(error_num, "%d", Get(x, y));
163  g_msg->Warn(WARN_FILE, "RasterMap::RasterMap():" " Unknown polygon ref number:", error_num);
164  exit(1);
165  }
166  }
167  }
168  IFile.close();
169 }
170 
172 {
173  free( m_map );
174 }
175 
177 
178  FILE* o1;
179  FILE* o2;
180  o1=fopen("RasterDump1.lsb","wb");
181  o2=fopen("RasterDump2.lsb","wb");
182  char * l_id = m_id;
183  int new_height = m_height*2;
184  fwrite( l_id, 1, 12, o1 );
185  fwrite( & new_height, 1, sizeof( int ), o1 );
186  for (int y=0; y< m_width; y++ ) {
187  for ( int x = 0; x < m_width ; x++ ) {
188  int l_poly = Get(x,y);
189  fwrite( & l_poly, 1, sizeof( int ), o1 );
190  fwrite( & l_poly, 1, sizeof( int ), o1 );
191  }
192  for ( int x = 0; x < m_width ; x++ ) {
193  int l_poly = Get(x,y);
194  fwrite( & l_poly, 1, sizeof( int ), o1 );
195  fwrite( & l_poly, 1, sizeof( int ), o1 );
196  }
197  }
198  int multiply=cfg_rastermapmanipmultiply.value();
199  new_height = m_height*multiply;
200  fwrite( l_id, 1, 12, o2 );
201  fwrite( &new_height, 1, sizeof( int ), o2 );
202  for (int m=0; m<multiply; m++) {
203  for (int y=0; y< m_width; y++ ) {
204  for (int mm=0; mm<multiply; mm++) {
205  for ( int x = 0; x < m_width ; x++ ) {
206  int l_poly = Get(x,y);
207  fwrite( & l_poly, 1, sizeof( int ), o2 );
208  }
209  }
210  }
211  }
212  fclose( o1 );
213  fclose( o2 );
214 }
215 
216 int RasterMap::CellReplacementNeighbour(int a_x, int a_y, int a_polyref)
217 {
224  if ((a_x < 1) || (a_x > m_width - 2) || (a_y < 1) || (a_y > m_height - 2)) return -1;
225  int toreplace = Get(a_x, a_y);
226  if (toreplace != a_polyref)
227  {
228  g_msg->Warn("RasterMap::CellReplacementNeighbour: x,y pair does not match polyref ", a_polyref);
229  exit(0);
230  }
231  int surroundingcells[8];
232  surroundingcells[0] = Get(a_x - 1, a_y - 1);
233  surroundingcells[1] = Get(a_x , a_y - 1);
234  surroundingcells[2] = Get(a_x + 1, a_y - 1);
235  surroundingcells[3] = Get(a_x - 1, a_y);
236  surroundingcells[4] = Get(a_x + 1, a_y);
237  surroundingcells[5] = Get(a_x - 1, a_y + 1);
238  surroundingcells[6] = Get(a_x , a_y + 1);
239  surroundingcells[7] = Get(a_x + 1, a_y + 1);
240  // Find out how many duplicates we have
241  int count[8];
242  for (int i = 0; i < 8; i++)
243  {
244  count[i] = 0;
245  for (int j = 0; j < 8; j++)
246  {
247  if (surroundingcells[j] == surroundingcells[i]) count[i]++;
248  }
249  }
250  int found = -1;
251  int index = 0;
252  for (int i = 0; i < 8; i++)
253  {
254  if (count[i]>found) index = i;
255  }
256  return surroundingcells[index];
257 }
258 
259 bool RasterMap::MissingCellReplace(int a_x, int a_y, bool a_fieldsonly)
260 {
261  int surroundingcells[8];
262  surroundingcells[0] = Get(a_x - 1, a_y - 1);
263  surroundingcells[1] = Get(a_x, a_y - 1);
264  surroundingcells[2] = Get(a_x + 1, a_y - 1);
265  surroundingcells[3] = Get(a_x - 1, a_y);
266  surroundingcells[4] = Get(a_x + 1, a_y);
267  surroundingcells[5] = Get(a_x - 1, a_y + 1);
268  surroundingcells[6] = Get(a_x, a_y + 1);
269  surroundingcells[7] = Get(a_x + 1, a_y + 1);
270  // If we prefer fields then check if we have any
271  if (a_fieldsonly)
272  {
273  unsigned offset = (unsigned)(((double)rand() / RAND_MAX + 1) * 8);
274  for (unsigned i = 0; i < 8; i++)
275  {
276  if (m_landscape->IsFieldType(m_landscape->SupplyElementType(surroundingcells[(i + offset) % 8])))
277  {
278  // We have a next door field, so use this
279  Put(a_x, a_y, surroundingcells[(i + offset) % 8]);
280  return true;
281  }
282  }
283 
284  }
285  return false;
286 }
287 
288 bool RasterMap::MissingCellReplaceWrap(int a_x, int a_y, bool a_fieldsonly)
289 {
290  int surroundingcells[8];
291  if (a_x >= 1 && a_y >= 1) surroundingcells[0] = Get(a_x - 1, a_y - 1); else surroundingcells[0] = Get(a_x, a_y);
292  if (a_y >= 1) surroundingcells[1] = Get(a_x, a_y - 1); else surroundingcells[1] = Get(a_x, a_y);
293  if (a_x < m_width-1 && a_y >= 1) surroundingcells[2] = Get(a_x + 1, a_y - 1); else surroundingcells[2] = Get(a_x, a_y);
294  if (a_x >= 1) surroundingcells[3] = Get(a_x - 1, a_y); else surroundingcells[3] = Get(a_x, a_y);
295  if (a_x < m_width-1) surroundingcells[4] = Get(a_x + 1, a_y); else surroundingcells[4] = Get(a_x, a_y);
296  if (a_x >= 1 && a_y < m_height-1) surroundingcells[5] = Get(a_x - 1, a_y + 1); else surroundingcells[5] = Get(a_x, a_y);
297  if (a_y < m_height-1) surroundingcells[6] = Get(a_x, a_y + 1); else surroundingcells[6] = Get(a_x, a_y);
298  if (a_x < m_width-1 && a_y < m_height-1) surroundingcells[7] = Get(a_x + 1, a_y + 1); else surroundingcells[7] = Get(a_x, a_y);
299  // If we prefer fields then check if we have any
300  if (a_fieldsonly)
301  {
302  unsigned offset = (unsigned)(((double)rand() / RAND_MAX + 1) * 8);
303  for (unsigned i = 0; i < 8; i++)
304  {
305  TTypesOfLandscapeElement tole = m_landscape->SupplyElementType(surroundingcells[(i + offset) % 8]);
306  if ((tole == tole_Field) || (tole == tole_Orchard) || (tole == tole_PermanentSetaside) || (tole == tole_PermPasture) || (tole == tole_PermPastureLowYield)
307  || (tole == tole_PermPastureTussocky) || (tole == tole_PermPastureTussockyWet) || (tole == tole_Vildtager))
308  {
309  // We have a next door field, so use this
310  Put(a_x, a_y, surroundingcells[(i + offset) % 8]);
311  return true;
312  }
313  }
314 
315  }
316 /* else
317  {
318  unsigned offset = (unsigned)(((double)rand() / RAND_MAX + 1) * 8);
319  for (unsigned i = 0; i < 8; i++)
320  {
321  TTypesOfLandscapeElement tole = m_landscape->SupplyElementType(surroundingcells[(i + offset) % 8]);
322  if ((tole != tole_Missing))
323  {
324  // We have a next door useful polygon, so use this
325  Put(a_x, a_y, surroundingcells[(i + offset) % 8]);
326  return true;
327  }
328  }
329  }
330 */
331  return false;
332 }
The landscape class containing all environmental and topographical data.
Definition: landscape.h:109
RasterMap(const char *a_mapfile, Landscape *m_landscape)
Definition: rastermap.cpp:46
void Manipulation1()
Definition: rastermap.cpp:176
Integer configurator entry class.
Definition: configurator.h:85
~RasterMap(void)
Definition: rastermap.cpp:171
CfgBool cfg_rectangularmaps_on("RASTER_RECTANGULARMAPS_ON", CFG_CUSTOM, true)
CfgBool cfg_manipulation1_on("RASTER_MANIPULATION_ONE_ON", CFG_CUSTOM, false)
class MapErrorMsg * g_msg
Definition: maperrormsg.cpp:38
bool value(void)
Definition: configurator.h:123
CfgInt cfg_rastermapmanipmultiply("RASTER_MANIPULATION_MULTIPLYFACTOR", CFG_CUSTOM, 2)
int * m_polymapping
m_polymapping is a mapping from polygon numbers into the list of landscape elements, m_elems. When using this it is important that it is the poly num and not the map index that is used in calling.
Definition: Landscape.cpp:237
bool MissingCellReplace(int a_x, int a_y, bool a_fieldsonly)
A method for removing missing polygons.
Definition: rastermap.cpp:259
Bool configurator entry class.
Definition: configurator.h:116
int CellReplacementNeighbour(int a_x, int a_y, int a_polyref)
A method for helping remove tiny polygons.
Definition: rastermap.cpp:216
int value(void)
Definition: configurator.h:92
void Warn(MapErrorState a_level, std::string a_msg1, std::string a_msg2)
Definition: maperrormsg.cpp:56
TTypesOfLandscapeElement
bool MissingCellReplaceWrap(int a_x, int a_y, bool a_fieldsonly)
A method for removing missing polygons - tests for edge conditions.
Definition: rastermap.cpp:288
void Init2(const char *a_mapfile, Landscape *m_landscape)
Definition: rastermap.cpp:122
void Init1(const char *a_mapfile, Landscape *m_landscape)
Definition: rastermap.cpp:66