1515* @author 2020 Benedikt Hallinger <beni@hallinger.org>
1616*/
1717
18- const char VERSION[] = " 1.0.2 " ;
18+ const char VERSION[] = " 1.1.0 " ;
1919const char PROGNAME[] = " therionsurface2survex" ;
2020
2121#include < ctype.h>
@@ -204,16 +204,18 @@ int main (int argc, char **argv)
204204 std::regex parse_cs_re (" ^\\ s*(cs)\\ s+(.+)" );
205205 std::regex parse_grid_re (" ^\\ s*grid\\ s+(-?\\ d+[\\ .\\ d]*)\\ s+(-?\\ d+[\\ .\\ d]*)\\ s+(\\ d+[\\ .\\ d]*)\\ s+(\\ d+[\\ .\\ d]*)\\ s+(\\ d+)\\ s+(\\ d+)$" );
206206 std::regex parse_data_re (" ^(\\ s*\\ d+[\\ d.]*)+$" );
207+ std::regex parse_gridflip_re (" ^\\ s*grid-flip\\ s+(none|vertical|horizontal)" );
207208 std::regex parse_gdalhdr_re (" ^\\ s*(ncols|nrows|xllcorner|yllcorner|cellsize|dx|dy)\\ s+(-?[.\\ d]+)" );
208209
209210 bool in_surfacedata = false ;
210211 double origin_x, origin_y, step_x, step_y;
211212 long cols_num, rows_num;
212- long cur_col, cur_row;
213+ long cur_row; // initialized either by grid-flip or grid command
213214 bool header_valid = false ;
214215 datapoint_i gdal_ncols, gdal_nrows;
215216 datapoint_f gdal_xllcorner, gdal_yllcorner, gdal_xcellsize, gdal_ycellsize;
216217 bool gdal_detected = false ;
218+ bool flip_vertical, flip_horizontal = false ;
217219 std::vector<std::vector<double > > parsedData; // holds parsed data rows
218220 while ( std::getline (h_infile, in_line) ) {
219221 line_nr++;
@@ -234,15 +236,20 @@ int main (int argc, char **argv)
234236 if (sm_gdalhdr[1 ] == " nrows" ) {gdal_nrows.d = stol (sm_gdalhdr[2 ]); gdal_nrows.valid = (gdal_nrows.d > 0 )?true :false ;}
235237 if (sm_gdalhdr[1 ] == " xllcorner" ) {gdal_xllcorner.d = stod (sm_gdalhdr[2 ]); gdal_xllcorner.valid = true ;}
236238 if (sm_gdalhdr[1 ] == " yllcorner" ) {gdal_yllcorner.d = stod (sm_gdalhdr[2 ]); gdal_yllcorner.valid = true ;}
237- if (sm_gdalhdr[1 ] == " cellsize" ) {gdal_xcellsize.d = stod (sm_gdalhdr[2 ]); gdal_xcellsize.valid = (gdal_xcellsize. d > 0 )? true : false ;
238- gdal_ycellsize.d = stod (sm_gdalhdr[2 ]); gdal_ycellsize.valid = (gdal_ycellsize. d > 0 )? true : false ;}
239- if (sm_gdalhdr[1 ] == " dx" ) {gdal_xcellsize.d = stod (sm_gdalhdr[2 ]); gdal_xcellsize.valid = (gdal_xcellsize. d > 0 )? true : false ;}
240- if (sm_gdalhdr[1 ] == " dy" ) {gdal_ycellsize.d = stod (sm_gdalhdr[2 ]); gdal_ycellsize.valid = (gdal_ycellsize. d > 0 )? true : false ;}
239+ if (sm_gdalhdr[1 ] == " cellsize" ) {gdal_xcellsize.d = stod (sm_gdalhdr[2 ]); gdal_xcellsize.valid = true ;
240+ gdal_ycellsize.d = stod (sm_gdalhdr[2 ]); gdal_ycellsize.valid = true ;}
241+ if (sm_gdalhdr[1 ] == " dx" ) {gdal_xcellsize.d = stod (sm_gdalhdr[2 ]); gdal_xcellsize.valid = true ;}
242+ if (sm_gdalhdr[1 ] == " dy" ) {gdal_ycellsize.d = stod (sm_gdalhdr[2 ]); gdal_ycellsize.valid = true ;}
241243
242244 if (gdal_ncols.valid && gdal_nrows.valid && gdal_xllcorner.valid && gdal_yllcorner.valid && gdal_xcellsize.valid && gdal_ycellsize.valid ) {
243245 if (debug) cout << " DBG: GDAL header complete! \n " ;
244246 // once we have a full GDAL header, we can parse the data :)
245247 // simply fake grid command so the parser below can work it out
248+
249+ // if step size is negative, grid is flipped
250+ if (gdal_xcellsize.d < 0 ) { gdal_xcellsize.d *= -1 ; flip_horizontal = true ; }
251+ if (gdal_ycellsize.d < 0 ) { gdal_ycellsize.d *= -1 ; flip_vertical = true ; }
252+
246253 in_line = " grid "
247254 + to_string (gdal_xllcorner.d ) + " "
248255 + to_string (gdal_yllcorner.d ) + " "
@@ -277,6 +284,17 @@ int main (int argc, char **argv)
277284 h_outfile << command_prfx << " cs out" << " " << sm_cs[2 ] << " \n " ;
278285 }
279286
287+ // digest grid-flip command
288+ std::smatch sm_gridflip;
289+ if (std::regex_search (in_line, sm_gridflip, parse_gridflip_re)) {
290+ if (sm_gridflip[1 ] == " none" ) { flip_horizontal = false ; flip_vertical=false ; }
291+ if (sm_gridflip[1 ] == " vertical" ) { flip_vertical = true ; }
292+ if (sm_gridflip[1 ] == " horizontal" ) { flip_horizontal = true ; }
293+ cur_row = (flip_vertical)? 0 : rows_num-1 ; // may be overwritten by "grid" command
294+ if (debug) printf (" DBG: line %i: Parsed '%s' to grid-flip: flip_vertical=%d; flip_horizontal=%d\n " , line_nr, in_line.c_str (), flip_vertical, flip_horizontal);
295+ }
296+
297+
280298 // parse grid command, we need to get some values out:
281299 // grid 400080 5419750 10 10 4 5
282300 // ^x0 ^y0 ^xs ^ys ^cnum ^rnum
@@ -296,12 +314,12 @@ int main (int argc, char **argv)
296314 for (int i = 0 ; i < rows_num ; ++i) {
297315 parsedData[i].resize (cols_num);
298316 }
299- cur_row = rows_num-1 ; // need to allocate backwards, otherwise model is fipped
317+ cur_row = (flip_vertical)? 0 : rows_num-1 ; // may be overwritten by "grid-flip" command
300318 }
301319
302320 // parse raw data. These are heights at the given point in the matrix.
303321 // We note this and after parsing all of this we will generate the data out of that.
304- if (cols_num > 0 && rows_num > 0 ) {
322+ if (cols_num > 0 && rows_num > 0 && header_valid ) {
305323
306324 if (std::regex_match (in_line, parse_data_re)) {
307325 std::vector<std::string> tokens;
@@ -318,11 +336,14 @@ int main (int argc, char **argv)
318336 }
319337
320338 if (tokens.size () == cols_num) {
321- for (cur_col = 0 ; cur_col < tokens.size (); ++cur_col) { // need to allocate backwards, otherwise model is fipped
339+ long cur_col = (flip_horizontal)? cols_num-1 : 0 ;
340+ long cur_col_step = (flip_horizontal)? -1 : +1 ;
341+ long cur_col_ref = 0 ;
342+ for ( ; cur_col >= 0 && cur_col < tokens.size (); cur_col += cur_col_step) {
322343 if (debug) printf (" DBG: data stored: parsedData[%i][%i]='%f'\n " , cur_row, cur_col, stod (tokens[cur_col]) );
323- parsedData[cur_row][cur_col ] = stod (tokens[cur_col]);
324- }
325- cur_row--;
344+ parsedData[cur_row][cur_col_ref++ ] = stod (tokens[cur_col]);
345+ }
346+ (flip_vertical)? cur_row++ : cur_row--;
326347 }
327348 }
328349 }
@@ -362,7 +383,7 @@ int main (int argc, char **argv)
362383 double bbox_ur_y = origin_y + step_y * cols_num;
363384 if (debug) printf (" DBG: BBox: lowerLeft=(%f / %f); upperRight=(%f / %f)\n " , origin_x, origin_y, bbox_ur_x, bbox_ur_y);
364385 for (cur_row = 0 ; cur_row < parsedData.size (); ++cur_row) {
365- for (cur_col = 0 ; cur_col < parsedData[cur_row].size (); ++cur_col) {
386+ for (long cur_col = 0 ; cur_col < parsedData[cur_row].size (); ++cur_col) {
366387 // *fix 20 200 000 1050
367388 // name^ ^coords
368389 tgt_x = origin_x + step_x * cur_col;
@@ -379,7 +400,7 @@ int main (int argc, char **argv)
379400 /* Ok, now on to write the mesh */
380401 h_outfile << " \n " << command_prfx << " data nosurvey from to" << " \n " ;
381402 for (cur_row = 0 ; cur_row < parsedData.size (); ++cur_row) {
382- for (cur_col = 0 ; cur_col < parsedData[cur_row].size (); ++cur_col) {
403+ for (long cur_col = 0 ; cur_col < parsedData[cur_row].size (); ++cur_col) {
383404
384405 string src_name = " surface." + to_string (cur_row) + " ." + to_string (cur_col);
385406
0 commit comments