ALMaSS Rabbit ODdox  1.1
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  g_msg->Warn(WARN_FILE, "X:", x);
105  g_msg->Warn(WARN_FILE, " Y:", y);
106  exit(1);
107  }
108  Put(x, y, i);
109  }
110  lastref = i;
111  if (m_landscape->GetPolymapping(Get(x, y)) == -1)
112  {
113  // Tripping out here means that the lsb file has a polygon that is not
114  // listed in the polygonrefs file
115  sprintf(error_num, "%d", Get(x, y));
116  g_msg->Warn(WARN_FILE, "RasterMap::RasterMap():" " Unknown polygon ref number:", error_num);
117  exit(1);
118  }
119  }
120  }
121  fclose(IFile);
122 }
123 
124 void RasterMap::Init2(const char* a_mapfile, Landscape * a_landscape)
125 {
126  m_landscape = a_landscape;
127  char error_num[20];
128 
129  ifstream IFile(a_mapfile, ios::binary);
130  if (!IFile.is_open()) {
131  g_msg->Warn(WARN_FILE, "RasterMap::RasterMap(): Unable to open file",
132  a_mapfile);
133  exit(1);
134  }
135  IFile.read(m_id,12);
136  IFile.read((char*)&m_width, sizeof (int));
137  IFile.read((char*)&m_height, sizeof (int));
138  m_map = new int[ m_width*m_height];
139  if (m_map == NULL) {
141  "RasterMap::RasterMap(): Out of memory.", "");
142  exit(1);
143  }
144  IFile.read((char*)m_map, m_width*m_height * sizeof(int));
145 
146  m_x = m_width;
147  m_y = m_height;
148  int pref = -1;
149  int lastref = 99999999;
150  for (int x = 0; x<m_x; x++)
151  {
152  for (int y = 0; y<m_y; y++)
153  {
154  pref = Get(x, y);
155  if (pref<0)
156  {
157  if (lastref>=0) Put(x, y, lastref);
158  else {
159  sprintf(error_num, "%d", Get(x, y));
160  g_msg->Warn(WARN_FILE, "RasterMap::RasterMap(): Unknown polygon map number (could be a hole):", error_num);
161  g_msg->WarnAddInfo(WARN_FILE, "X:", x);
162  g_msg->WarnAddInfo(WARN_FILE, "Y:", y);
163  exit(1);
164  }
165  }
166  lastref = pref;
167  if (m_landscape->GetPolymapping(Get(x, y)) == -1)
168  {
169  // Tripping out here means that the lsb file has a polygon that is not
170  // listed in the polygonrefs file
171  sprintf(error_num, "%d", Get(x, y));
172  g_msg->Warn(WARN_FILE, "RasterMap::RasterMap():" " Unknown polygon ref number:", error_num);
173  exit(1);
174  }
175  }
176  }
177  IFile.close();
178 }
179 
181 {
182  free( m_map );
183 }
184 
186 
187  FILE* o1;
188  FILE* o2;
189  o1=fopen("RasterDump1.lsb","wb");
190  o2=fopen("RasterDump2.lsb","wb");
191  char * l_id = m_id;
192  int new_height = m_height*2;
193  fwrite( l_id, 1, 12, o1 );
194  fwrite( & new_height, 1, sizeof( int ), o1 );
195  for (int y=0; y< m_width; y++ ) {
196  for ( int x = 0; x < m_width ; x++ ) {
197  int l_poly = Get(x,y);
198  fwrite( & l_poly, 1, sizeof( int ), o1 );
199  fwrite( & l_poly, 1, sizeof( int ), o1 );
200  }
201  for ( int x = 0; x < m_width ; x++ ) {
202  int l_poly = Get(x,y);
203  fwrite( & l_poly, 1, sizeof( int ), o1 );
204  fwrite( & l_poly, 1, sizeof( int ), o1 );
205  }
206  }
207  int multiply=cfg_rastermapmanipmultiply.value();
208  new_height = m_height*multiply;
209  fwrite( l_id, 1, 12, o2 );
210  fwrite( &new_height, 1, sizeof( int ), o2 );
211  for (int m=0; m<multiply; m++) {
212  for (int y=0; y< m_width; y++ ) {
213  for (int mm=0; mm<multiply; mm++) {
214  for ( int x = 0; x < m_width ; x++ ) {
215  int l_poly = Get(x,y);
216  fwrite( & l_poly, 1, sizeof( int ), o2 );
217  }
218  }
219  }
220  }
221  fclose( o1 );
222  fclose( o2 );
223 }
224 
225 int RasterMap::CellReplacementNeighbour(int a_x, int a_y, int a_polyref)
226 {
233  if ((a_x < 1) || (a_x > m_width - 2) || (a_y < 1) || (a_y > m_height - 2)) return -1;
234  int toreplace = Get(a_x, a_y);
235  if (toreplace != a_polyref)
236  {
237  g_msg->Warn("RasterMap::CellReplacementNeighbour: x,y pair does not match polyref ", a_polyref);
238  exit(0);
239  }
240  int surroundingcells[8];
241  surroundingcells[0] = Get(a_x - 1, a_y - 1);
242  surroundingcells[1] = Get(a_x , a_y - 1);
243  surroundingcells[2] = Get(a_x + 1, a_y - 1);
244  surroundingcells[3] = Get(a_x - 1, a_y);
245  surroundingcells[4] = Get(a_x + 1, a_y);
246  surroundingcells[5] = Get(a_x - 1, a_y + 1);
247  surroundingcells[6] = Get(a_x , a_y + 1);
248  surroundingcells[7] = Get(a_x + 1, a_y + 1);
249  // Find out how many duplicates we have
250  int count[8];
251  for (int i = 0; i < 8; i++)
252  {
253  count[i] = 0;
254  for (int j = 0; j < 8; j++)
255  {
256  if (surroundingcells[j] == surroundingcells[i]) count[i]++;
257  }
258  }
259  int found = -1;
260  int index = 0;
261  for (int i = 0; i < 8; i++)
262  {
263  if (count[i]>found) index = i;
264  found = count[i];
265  }
266  // Here we just make sure that we have not chosen another illegal. If so quietly ignore this replacement
267  if (m_landscape->SupplyPolygonArea(surroundingcells[index]) < 2) return -1;
268  // All OK so replace
269  Put(a_x, a_y, surroundingcells[index]);
270  return 1; // Signals that replacement occured
271 }
272 
273 bool RasterMap::MissingCellReplace(int a_x, int a_y, bool a_fieldsonly)
274 {
275  int surroundingcells[8];
276  surroundingcells[0] = Get(a_x - 1, a_y - 1);
277  surroundingcells[1] = Get(a_x, a_y - 1);
278  surroundingcells[2] = Get(a_x + 1, a_y - 1);
279  surroundingcells[3] = Get(a_x - 1, a_y);
280  surroundingcells[4] = Get(a_x + 1, a_y);
281  surroundingcells[5] = Get(a_x - 1, a_y + 1);
282  surroundingcells[6] = Get(a_x, a_y + 1);
283  surroundingcells[7] = Get(a_x + 1, a_y + 1);
284  // If we prefer fields then check if we have any
285  if (a_fieldsonly)
286  {
287  unsigned offset = (unsigned)(((double)rand() / RAND_MAX + 1) * 8);
288  for (unsigned i = 0; i < 8; i++)
289  {
290  if (m_landscape->IsFieldType(m_landscape->SupplyElementType(surroundingcells[(i + offset) % 8])))
291  {
292  // We have a next door field, so use this
293  Put(a_x, a_y, surroundingcells[(i + offset) % 8]);
294  return true;
295  }
296  }
297 
298  }
299  return false;
300 }
301 
302 bool RasterMap::MissingCellReplaceWrap(int a_x, int a_y, bool a_fieldsonly)
303 {
304  int surroundingcells[8];
305  if (a_x >= 1 && a_y >= 1) surroundingcells[0] = Get(a_x - 1, a_y - 1); else surroundingcells[0] = Get(a_x, a_y);
306  if (a_y >= 1) surroundingcells[1] = Get(a_x, a_y - 1); else surroundingcells[1] = Get(a_x, a_y);
307  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);
308  if (a_x >= 1) surroundingcells[3] = Get(a_x - 1, a_y); else surroundingcells[3] = Get(a_x, a_y);
309  if (a_x < m_width-1) surroundingcells[4] = Get(a_x + 1, a_y); else surroundingcells[4] = Get(a_x, a_y);
310  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);
311  if (a_y < m_height-1) surroundingcells[6] = Get(a_x, a_y + 1); else surroundingcells[6] = Get(a_x, a_y);
312  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);
313  // If we prefer fields then check if we have any
314  if (a_fieldsonly)
315  {
316  unsigned offset = (unsigned)(((double)rand() / RAND_MAX + 1) * 8);
317  for (unsigned i = 0; i < 8; i++)
318  {
319  TTypesOfLandscapeElement tole = m_landscape->SupplyElementType(surroundingcells[(i + offset) % 8]);
320  if ((tole == tole_Field) || (tole == tole_Orchard) || (tole == tole_PermanentSetaside) || (tole == tole_PermPasture) || (tole == tole_PermPastureLowYield)
321  || (tole == tole_PermPastureTussocky) || (tole == tole_PermPastureTussockyWet) || (tole == tole_Vildtager))
322  {
323  // We have a next door field, so use this
324  Put(a_x, a_y, surroundingcells[(i + offset) % 8]);
325  return true;
326  }
327  }
328 
329  }
330 /* else
331  {
332  unsigned offset = (unsigned)(((double)rand() / RAND_MAX + 1) * 8);
333  for (unsigned i = 0; i < 8; i++)
334  {
335  TTypesOfLandscapeElement tole = m_landscape->SupplyElementType(surroundingcells[(i + offset) % 8]);
336  if ((tole != tole_Missing))
337  {
338  // We have a next door useful polygon, so use this
339  Put(a_x, a_y, surroundingcells[(i + offset) % 8]);
340  return true;
341  }
342  }
343  }
344 */
345  return false;
346 }
RasterMap::Init1
void Init1(const char *a_mapfile, Landscape *m_landscape)
Definition: rastermap.cpp:66
RasterMap::Init2
void Init2(const char *a_mapfile, Landscape *m_landscape)
Definition: rastermap.cpp:124
RasterMap::Manipulation1
void Manipulation1()
Definition: rastermap.cpp:185
rastermap.h
MapErrorMsg::WarnAddInfo
void WarnAddInfo(MapErrorState a_level, std::string a_add1, std::string a_add2)
Definition: maperrormsg.cpp:149
RasterMap::~RasterMap
~RasterMap(void)
Definition: rastermap.cpp:180
g_msg
class MapErrorMsg * g_msg
Definition: maperrormsg.cpp:41
cfg_manipulation1_on
CfgBool cfg_manipulation1_on("RASTER_MANIPULATION_ONE_ON", CFG_CUSTOM, false)
Landscape
The landscape class containing all environmental and topographical data.
Definition: landscape.h:112
CfgBool
Bool configurator entry class.
Definition: configurator.h:127
tole_PermPasture
Definition: tole_declaration.h:47
tole_PermanentSetaside
Definition: tole_declaration.h:46
maperrormsg.h
MapErrorMsg::Warn
void Warn(MapErrorState a_level, std::string a_msg1, std::string a_msg2)
Definition: maperrormsg.cpp:59
RasterMap::MissingCellReplace
bool MissingCellReplace(int a_x, int a_y, bool a_fieldsonly)
A method for removing missing polygons.
Definition: rastermap.cpp:273
tole_Orchard
Definition: tole_declaration.h:71
CFG_CUSTOM
Definition: configurator.h:60
tole_PermPastureTussocky
Definition: tole_declaration.h:45
tole_Field
Definition: tole_declaration.h:43
tole_PermPastureTussockyWet
Definition: tole_declaration.h:100
WARN_FATAL
Definition: maperrormsg.h:35
tole_PermPastureLowYield
Definition: tole_declaration.h:44
WARN_FILE
Definition: maperrormsg.h:37
CfgInt
Integer configurator entry class.
Definition: configurator.h:87
TTypesOfLandscapeElement
TTypesOfLandscapeElement
Definition: tole_declaration.h:36
RasterMap::MissingCellReplaceWrap
bool MissingCellReplaceWrap(int a_x, int a_y, bool a_fieldsonly)
A method for removing missing polygons - tests for edge conditions.
Definition: rastermap.cpp:302
RasterMap::CellReplacementNeighbour
int CellReplacementNeighbour(int a_x, int a_y, int a_polyref)
A method for helping remove tiny polygons.
Definition: rastermap.cpp:225
CfgInt::value
int value(void)
Definition: configurator.h:98
configurator.h
tole_Vildtager
Definition: tole_declaration.h:99
CfgBool::value
bool value(void)
Definition: configurator.h:135
RasterMap::RasterMap
RasterMap(const char *a_mapfile, Landscape *m_landscape)
Definition: rastermap.cpp:46
cfg_rectangularmaps_on
CfgBool cfg_rectangularmaps_on("RASTER_RECTANGULARMAPS_ON", CFG_CUSTOM, true)
cfg_rastermapmanipmultiply
CfgInt cfg_rastermapmanipmultiply("RASTER_MANIPULATION_MULTIPLYFACTOR", CFG_CUSTOM, 2)