main.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. /****************************************************************************
  2. *
  3. * MODULE: v.surf.rst
  4. * AUTHOR(S): H. Mitasova, I. Kosinovsky, D. Gerdes Fall 1993
  5. * University of Illinois
  6. * I. Kosinovsky, (USA-CERL), and D.Gerdes (USA-CERL)
  7. * Michael Shapiro, U.S. Army Construction Engineering Research Laboratory
  8. * modified by McCauley in August 1995
  9. * modified by Mitasova in August 1995
  10. * modified by Mitasova in November 1999 (dmax, timestamp update)
  11. * dnorm independent tension - -t flag
  12. * cross-validation -v flag by Jaro Hofierka 2004
  13. * Parallel version: S. Zubal 2015
  14. *
  15. * PURPOSE: Surface interpolation from vector point data by splines
  16. * COPYRIGHT: (C) 2003-2009, 2013 by the GRASS Development Team
  17. *
  18. * This program is free software under the GNU General
  19. * Public License (>=v2). Read the file COPYING that
  20. * comes with GRASS for details.
  21. *
  22. *****************************************************************************/
  23. #if defined(_OPENMP)
  24. #include <omp.h>
  25. #endif
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <unistd.h>
  29. #include <math.h>
  30. #include <grass/gis.h>
  31. #include <grass/vector.h>
  32. #include <grass/dbmi.h>
  33. #include <grass/glocale.h>
  34. #include <grass/linkm.h>
  35. #include <grass/bitmap.h>
  36. #include <grass/interpf.h>
  37. #include <grass/qtree.h>
  38. #include <grass/dataquad.h>
  39. #include <grass/gmath.h>
  40. #include "surf.h"
  41. #define SCIK1 1 /*100000 */
  42. #define SCIK2 1 /*100000 */
  43. #define SCIK3 1 /*100000 */
  44. static double /* pargr */ ns_res, ew_res;
  45. static double dmin, dmax, ertre;
  46. static int KMAX2, KMIN, KMAX, totsegm, deriv, dtens, cv;
  47. static struct Map_info Map;
  48. static struct Map_info TreeMap, OverMap;
  49. static struct interp_params params;
  50. static struct tree_info *info;
  51. static void create_temp_files(void);
  52. static void clean(void);
  53. static double *az = NULL, *adx = NULL, *ady = NULL, *adxx = NULL, *adyy = NULL,
  54. *adxy = NULL;
  55. static double /* error */ ertot, ertre, zminac, zmaxac, zmult;
  56. struct multtree *root;
  57. static int NPOINT = 0;
  58. static int cond1, cond2;
  59. static char *treefile = NULL;
  60. static char *overfile = NULL;
  61. static FCELL *zero_array_cell;
  62. static char *input;
  63. static int field;
  64. static char *zcol;
  65. static char *scol;
  66. static char *wheresql;
  67. static char *elev = NULL;
  68. static char *slope = NULL;
  69. static char *aspect = NULL;
  70. static char *pcurv = NULL;
  71. static char *tcurv = NULL;
  72. static char *mcurv = NULL;
  73. static char *maskmap = NULL;
  74. static char *devi = NULL;
  75. static char *cvdev = NULL;
  76. static int sdisk, disk, ddisk, sddisk;
  77. static FILE *Tmp_fd_z = NULL;
  78. static char *Tmp_file_z = NULL;
  79. static FILE *Tmp_fd_dx = NULL;
  80. static char *Tmp_file_dx = NULL;
  81. static FILE *Tmp_fd_dy = NULL;
  82. static char *Tmp_file_dy = NULL;
  83. static FILE *Tmp_fd_xx = NULL;
  84. static char *Tmp_file_xx = NULL;
  85. static FILE *Tmp_fd_yy = NULL;
  86. static char *Tmp_file_yy = NULL;
  87. static FILE *Tmp_fd_xy = NULL;
  88. static char *Tmp_file_xy = NULL;
  89. static double gmin, gmax, c1min, c1max, c2min, c2max, fi, rsm;
  90. static double xmin, xmax, ymin, ymax, zmin, zmax;
  91. static double theta, scalex;
  92. static struct BM *bitmask;
  93. static struct Cell_head cellhd;
  94. static int n_rows, n_cols;
  95. int main(int argc, char *argv[])
  96. {
  97. int npmin;
  98. int ii;
  99. double x_orig, y_orig, dnorm, deltx, delty, xm, ym;
  100. char dmaxchar[200];
  101. char dminchar[200];
  102. struct quaddata *data;
  103. struct multfunc *functions;
  104. struct multtree *tree;
  105. int open_check, with_z;
  106. char buf[1024];
  107. int threads;
  108. struct GModule *module;
  109. struct
  110. {
  111. struct Option *input, *field, *zcol, *wheresql, *scol, *elev, *slope,
  112. *aspect, *pcurv, *tcurv, *mcurv, *treefile, *overfile, *maskmap,
  113. *dmin, *dmax, *zmult, *fi, *rsm, *segmax, *npmin, *cvdev, *devi,
  114. *theta, *scalex, *threads;
  115. } parm;
  116. struct
  117. {
  118. struct Flag *deriv, *cprght, *cv;
  119. } flag;
  120. G_gisinit(argv[0]);
  121. module = G_define_module();
  122. G_add_keyword(_("vector"));
  123. G_add_keyword(_("surface"));
  124. G_add_keyword(_("interpolation"));
  125. G_add_keyword(_("3D"));
  126. module->label = _("Performs surface interpolation from vector points map by splines.");
  127. module->description =
  128. _("Spatial approximation and topographic analysis from given "
  129. "point or isoline data in vector format to floating point "
  130. "raster format using regularized spline with tension.");
  131. flag.cv = G_define_flag();
  132. flag.cv->key = 'c';
  133. flag.cv->description =
  134. _("Perform cross-validation procedure without raster approximation");
  135. flag.cv->guisection = _("Parameters");
  136. flag.cprght = G_define_flag();
  137. flag.cprght->key = 't';
  138. flag.cprght->description = _("Use scale dependent tension");
  139. flag.cprght->guisection = _("Parameters");
  140. flag.deriv = G_define_flag();
  141. flag.deriv->key = 'd';
  142. flag.deriv->description =
  143. _("Output partial derivatives instead of topographic parameters");
  144. flag.deriv->guisection = _("Outputs");
  145. parm.input = G_define_standard_option(G_OPT_V_INPUT);
  146. parm.field = G_define_standard_option(G_OPT_V_FIELD);
  147. parm.field->answer = "1";
  148. parm.field->guisection = _("Selection");
  149. parm.zcol = G_define_standard_option(G_OPT_DB_COLUMN);
  150. parm.zcol->key = "zcolumn";
  151. parm.zcol->required = NO;
  152. parm.zcol->label =
  153. _("Name of the attribute column with values to be used for approximation");
  154. parm.zcol->description = _("If not given and input is 2D vector map then category values are used. "
  155. "If input is 3D vector map then z-coordinates are used.");
  156. parm.zcol->guisection = _("Parameters");
  157. parm.wheresql = G_define_standard_option(G_OPT_DB_WHERE);
  158. parm.wheresql->guisection = _("Selection");
  159. parm.elev = G_define_standard_option(G_OPT_R_OUTPUT);
  160. parm.elev->key = "elevation";
  161. parm.elev->required = NO;
  162. parm.elev->description = _("Name for output surface elevation raster map");
  163. parm.elev->guisection = _("Outputs");
  164. parm.slope = G_define_standard_option(G_OPT_R_OUTPUT);
  165. parm.slope->key = "slope";
  166. parm.slope->required = NO;
  167. parm.slope->description = _("Name for output slope raster map");
  168. parm.slope->guisection = _("Outputs");
  169. parm.aspect = G_define_standard_option(G_OPT_R_OUTPUT);
  170. parm.aspect->key = "aspect";
  171. parm.aspect->required = NO;
  172. parm.aspect->description = _("Name for output aspect raster map");
  173. parm.aspect->guisection = _("Outputs");
  174. parm.pcurv = G_define_standard_option(G_OPT_R_OUTPUT);
  175. parm.pcurv->key = "pcurvature";
  176. parm.pcurv->required = NO;
  177. parm.pcurv->description = _("Name for output profile curvature raster map");
  178. parm.pcurv->guisection = _("Outputs");
  179. parm.tcurv = G_define_standard_option(G_OPT_R_OUTPUT);
  180. parm.tcurv->key = "tcurvature";
  181. parm.tcurv->required = NO;
  182. parm.tcurv->description = _("Name for output tangential curvature raster map");
  183. parm.tcurv->guisection = _("Outputs");
  184. parm.mcurv = G_define_standard_option(G_OPT_R_OUTPUT);
  185. parm.mcurv->key = "mcurvature";
  186. parm.mcurv->required = NO;
  187. parm.mcurv->description = _("Name for output mean curvature raster map");
  188. parm.mcurv->guisection = _("Outputs");
  189. parm.devi = G_define_standard_option(G_OPT_V_OUTPUT);
  190. parm.devi->key = "deviations";
  191. parm.devi->required = NO;
  192. parm.devi->description = _("Name for output deviations vector point map");
  193. parm.devi->guisection = _("Outputs");
  194. parm.cvdev = G_define_standard_option(G_OPT_V_OUTPUT);
  195. parm.cvdev->key = "cvdev";
  196. parm.cvdev->required = NO;
  197. parm.cvdev->description =
  198. _("Name for output cross-validation errors vector point map");
  199. parm.cvdev->guisection = _("Outputs");
  200. parm.treefile = G_define_standard_option(G_OPT_V_OUTPUT);
  201. parm.treefile->key = "treeseg";
  202. parm.treefile->required = NO;
  203. parm.treefile->description =
  204. _("Name for output vector map showing quadtree segmentation");
  205. parm.treefile->guisection = _("Outputs");
  206. parm.overfile = G_define_standard_option(G_OPT_V_OUTPUT);
  207. parm.overfile->key = "overwin";
  208. parm.overfile->required = NO;
  209. parm.overfile->description =
  210. _("Name for output vector map showing overlapping windows");
  211. parm.overfile->guisection = _("Outputs");
  212. parm.threads = G_define_option();
  213. parm.threads->key = "nprocs";
  214. parm.threads->type = TYPE_INTEGER;
  215. parm.threads->answer = NUM_THREADS;
  216. parm.threads->required = NO;
  217. parm.threads->description =
  218. _("Number of threads for parallel computing");
  219. parm.threads->guisection = _("Parameters");
  220. parm.maskmap = G_define_standard_option(G_OPT_R_INPUT);
  221. parm.maskmap->key = "mask";
  222. parm.maskmap->required = NO;
  223. parm.maskmap->description = _("Name of raster map used as mask");
  224. parm.maskmap->guisection = _("Parameters");
  225. parm.fi = G_define_option();
  226. parm.fi->key = "tension";
  227. parm.fi->type = TYPE_DOUBLE;
  228. parm.fi->answer = TENSION;
  229. parm.fi->required = NO;
  230. parm.fi->description = _("Tension parameter");
  231. parm.fi->guisection = _("Parameters");
  232. parm.rsm = G_define_option();
  233. parm.rsm->key = "smooth";
  234. parm.rsm->type = TYPE_DOUBLE;
  235. parm.rsm->required = NO;
  236. parm.rsm->description = _("Smoothing parameter");
  237. parm.rsm->guisection = _("Parameters");
  238. parm.scol = G_define_option();
  239. parm.scol->key = "smooth_column";
  240. parm.scol->type = TYPE_STRING;
  241. parm.scol->required = NO;
  242. parm.scol->description =
  243. _("Name of the attribute column with smoothing parameters");
  244. parm.scol->guisection = _("Parameters");
  245. parm.segmax = G_define_option();
  246. parm.segmax->key = "segmax";
  247. parm.segmax->type = TYPE_INTEGER;
  248. parm.segmax->answer = MAXSEGM;
  249. parm.segmax->required = NO;
  250. parm.segmax->description = _("Maximum number of points in a segment");
  251. parm.segmax->guisection = _("Parameters");
  252. parm.npmin = G_define_option();
  253. parm.npmin->key = "npmin";
  254. parm.npmin->type = TYPE_INTEGER;
  255. parm.npmin->answer = MINPOINTS;
  256. parm.npmin->required = NO;
  257. parm.npmin->description =
  258. _("Minimum number of points for approximation in a segment (>segmax)");
  259. parm.npmin->guisection = _("Parameters");
  260. parm.dmin = G_define_option();
  261. parm.dmin->key = "dmin";
  262. parm.dmin->type = TYPE_DOUBLE;
  263. parm.dmin->required = NO;
  264. parm.dmin->description =
  265. _("Minimum distance between points (to remove almost identical points)");
  266. parm.dmin->guisection = _("Parameters");
  267. parm.dmax = G_define_option();
  268. parm.dmax->key = "dmax";
  269. parm.dmax->type = TYPE_DOUBLE;
  270. parm.dmax->required = NO;
  271. parm.dmax->description =
  272. _("Maximum distance between points on isoline (to insert additional points)");
  273. parm.dmax->guisection = _("Parameters");
  274. parm.zmult = G_define_option();
  275. parm.zmult->key = "zscale";
  276. parm.zmult->type = TYPE_DOUBLE;
  277. parm.zmult->answer = ZMULT;
  278. parm.zmult->required = NO;
  279. parm.zmult->description =
  280. _("Conversion factor for values used for approximation");
  281. parm.zmult->guisection = _("Parameters");
  282. parm.theta = G_define_option();
  283. parm.theta->key = "theta";
  284. parm.theta->type = TYPE_DOUBLE;
  285. parm.theta->required = NO;
  286. parm.theta->description =
  287. _("Anisotropy angle (in degrees counterclockwise from East)");
  288. parm.theta->guisection = _("Parameters");
  289. parm.scalex = G_define_option();
  290. parm.scalex->key = "scalex";
  291. parm.scalex->type = TYPE_DOUBLE;
  292. parm.scalex->required = NO;
  293. parm.scalex->description = _("Anisotropy scaling factor");
  294. parm.scalex->guisection = _("Parameters");
  295. if (G_parser(argc, argv))
  296. exit(EXIT_FAILURE);
  297. G_get_set_window(&cellhd);
  298. ew_res = cellhd.ew_res;
  299. ns_res = cellhd.ns_res;
  300. n_cols = cellhd.cols;
  301. n_rows = cellhd.rows;
  302. x_orig = cellhd.west;
  303. y_orig = cellhd.south;
  304. xm = cellhd.east;
  305. ym = cellhd.north;
  306. if (ew_res < ns_res)
  307. dmin = ew_res / 2;
  308. else
  309. dmin = ns_res / 2;
  310. disk = n_rows * n_cols * sizeof(int);
  311. sdisk = n_rows * n_cols * sizeof(short int);
  312. sprintf(dmaxchar, "%f", dmin * 5);
  313. sprintf(dminchar, "%f", dmin);
  314. if (!parm.dmin->answer) {
  315. parm.dmin->answer = G_store(dminchar);
  316. parm.dmin->answers = (char **) G_malloc(2 * sizeof(char *));
  317. parm.dmin->answers[0] = G_store(dminchar);
  318. parm.dmin->answers[1] = NULL;
  319. }
  320. if (!parm.dmax->answer) {
  321. parm.dmax->answer = G_store(dmaxchar);
  322. parm.dmax->answers = (char **) G_malloc(2 * sizeof(char *));
  323. parm.dmax->answers[0] = G_store(dmaxchar);
  324. parm.dmax->answers[1] = NULL;
  325. }
  326. input = parm.input->answer;
  327. zcol = parm.zcol->answer;
  328. scol = parm.scol->answer;
  329. wheresql = parm.wheresql->answer;
  330. maskmap = parm.maskmap->answer;
  331. elev = parm.elev->answer;
  332. devi = parm.devi->answer;
  333. cvdev = parm.cvdev->answer;
  334. slope = parm.slope->answer;
  335. aspect = parm.aspect->answer;
  336. pcurv = parm.pcurv->answer;
  337. tcurv = parm.tcurv->answer;
  338. mcurv = parm.mcurv->answer;
  339. treefile = parm.treefile->answer;
  340. overfile = parm.overfile->answer;
  341. sscanf(parm.threads->answer, "%d", &threads);
  342. if (threads < 1)
  343. {
  344. G_warning(_("<%d> is not valid number of threads. Number of threads will be set on <%d>"),
  345. threads, abs(threads));
  346. threads = abs(threads);
  347. }
  348. if (parm.devi->answer && threads > 1) {
  349. G_warning(_("Parallel computation disabled when deviation output is required"));
  350. threads = 1;
  351. }
  352. #if defined(_OPENMP)
  353. omp_set_num_threads(threads);
  354. #else
  355. if (threads > 1)
  356. G_warning(_("GRASS GIS is not compiled with OpenMP support, parallel computation is disabled."));
  357. #endif
  358. if (devi) {
  359. if (Vect_legal_filename(devi) == -1)
  360. G_fatal_error(_("Output vector map name <%s> is not valid map name"),
  361. devi);
  362. }
  363. if (cvdev) {
  364. if (Vect_legal_filename(cvdev) == -1)
  365. G_fatal_error(_("Output vector map name <%s> is not valid map name"),
  366. cvdev);
  367. }
  368. if (treefile) {
  369. if (Vect_legal_filename(treefile) == -1)
  370. G_fatal_error(_("Output vector map name <%s> is not valid map name"),
  371. treefile);
  372. }
  373. if (overfile) {
  374. if (Vect_legal_filename(overfile) == -1)
  375. G_fatal_error(_("Output vector map name <%s> is not valid map name"),
  376. overfile);
  377. }
  378. /* if (treefile)
  379. Vect_check_input_output_name(input, treefile, G_FATAL_EXIT);
  380. if (overfile)
  381. Vect_check_input_output_name(input, overfile, G_FATAL_EXIT);
  382. */
  383. if ((elev == NULL) && (pcurv == NULL) && (tcurv == NULL)
  384. && (mcurv == NULL)
  385. && (slope == NULL) && (aspect == NULL) && (devi == NULL)
  386. && (cvdev == NULL))
  387. G_warning(_("You are not outputting any raster or vector maps"));
  388. cond2 = ((pcurv != NULL) || (tcurv != NULL) || (mcurv != NULL));
  389. cond1 = ((slope != NULL) || (aspect != NULL) || cond2);
  390. deriv = flag.deriv->answer;
  391. dtens = flag.cprght->answer;
  392. cv = flag.cv->answer;
  393. if ((cv && cvdev == NULL) || (!(cv) && cvdev != NULL))
  394. G_fatal_error(_("Both cross-validation options (-c flag and cvdev vector output) must be specified"));
  395. if ((elev != NULL || cond1 || cond2 || devi != NULL) && cv)
  396. G_fatal_error(_("The cross-validation cannot be computed simultaneously with output raster or devi file"));
  397. ertre = 0.1;
  398. sscanf(parm.dmax->answer, "%lf", &dmax);
  399. sscanf(parm.dmin->answer, "%lf", &dmin);
  400. sscanf(parm.fi->answer, "%lf", &fi);
  401. sscanf(parm.segmax->answer, "%d", &KMAX);
  402. sscanf(parm.npmin->answer, "%d", &npmin);
  403. sscanf(parm.zmult->answer, "%lf", &zmult);
  404. /* if (fi=0.000000) G_fatal_error("Tension must be > 0.000000") */
  405. if (parm.theta->answer)
  406. sscanf(parm.theta->answer, "%lf", &theta);
  407. if (parm.scalex->answer) {
  408. sscanf(parm.scalex->answer, "%lf", &scalex);
  409. if (!parm.theta->answer)
  410. G_fatal_error(_("Using anisotropy - both theta and scalex have to be specified"));
  411. }
  412. if (parm.rsm->answer) {
  413. sscanf(parm.rsm->answer, "%lf", &rsm);
  414. if (rsm < 0.0)
  415. G_fatal_error("Smoothing must be a positive value");
  416. if (scol != NULL)
  417. G_warning(_("Both smatt and smooth options specified - using constant"));
  418. }
  419. else {
  420. sscanf(SMOOTH, "%lf", &rsm);
  421. if (scol != NULL)
  422. rsm = -1; /* used in InterpLib to indicate variable smoothing */
  423. }
  424. if (npmin > MAXPOINTS - 50) {
  425. G_warning(_("The computation will last too long - lower npmin is suggested"));
  426. KMAX2 = 2 * npmin; /* was: KMAX2 = npmin + 50; */
  427. }
  428. else
  429. KMAX2 = 2 * npmin; /* was: KMAX2 = MAXPOINTS; fixed by JH in 12/01 */
  430. /* handling of KMAX2 in GRASS4 v.surf.rst
  431. if (npmin > MAXPOINTS - 50)
  432. KMAX2 = npmin + 50;
  433. else
  434. KMAX2 = MAXPOINTS;
  435. */
  436. dmin = dmin * dmin;
  437. KMIN = npmin;
  438. az = G_alloc_vector(n_cols + 1);
  439. if (!az) {
  440. G_fatal_error(_("Not enough memory for %s"), "az");
  441. }
  442. if (cond1) {
  443. adx = G_alloc_vector(n_cols + 1);
  444. if (!adx) {
  445. G_fatal_error(_("Not enough memory for %s"), "adx");
  446. }
  447. ady = G_alloc_vector(n_cols + 1);
  448. if (!ady) {
  449. G_fatal_error(_("Not enough memory for %s"), "ady");
  450. }
  451. if (cond2) {
  452. adxx = G_alloc_vector(n_cols + 1);
  453. if (!adxx) {
  454. G_fatal_error(_("Not enough memory for %s"), "adxx");
  455. }
  456. adyy = G_alloc_vector(n_cols + 1);
  457. if (!adyy) {
  458. G_fatal_error(_("Not enough memory for %s"), "adyy");
  459. }
  460. adxy = G_alloc_vector(n_cols + 1);
  461. if (!adxy) {
  462. G_fatal_error(_("Not enough memory for %s"), "adxy");
  463. }
  464. }
  465. }
  466. if ((data =
  467. quad_data_new(x_orig, y_orig, xm, ym, n_rows, n_cols, 0,
  468. KMAX)) == NULL)
  469. G_fatal_error(_("Unable to create %s"), "quaddata");
  470. if ((functions =
  471. MT_functions_new(quad_compare, quad_divide_data, quad_add_data,
  472. quad_intersect, quad_division_check,
  473. quad_get_points)) == NULL)
  474. G_fatal_error(_("Unable to create %s"), "quadfunc");
  475. if ((tree = MT_tree_new(data, NULL, NULL, 0)) == NULL)
  476. G_fatal_error(_("Unable to create %s"), "tree");
  477. root = tree;
  478. if ((info = MT_tree_info_new(root, functions, dmin, KMAX)) == NULL)
  479. G_fatal_error(_("Unable to create %s"), "tree info");
  480. open_check = Vect_open_old2(&Map, input, "", parm.field->answer);
  481. if (open_check < 1)
  482. G_fatal_error(_("Unable to open vector map <%s>"), input);
  483. /* if (open_check < 2)
  484. G_fatal_error(_("You first need to run v.build on vector map <%s>"), input);
  485. */
  486. /* get value used for approximation */
  487. with_z = !parm.zcol->answer && Vect_is_3d(&Map);
  488. field = Vect_get_field_number(&Map, parm.field->answer);
  489. if (!with_z && field < 1)
  490. G_fatal_error(_("Layer <%s> not found"), parm.field->answer);
  491. if (Vect_is_3d(&Map)) {
  492. if (!with_z)
  493. G_verbose_message(_("Input is 3D: using attribute values instead of z-coordinates for approximation"));
  494. else
  495. G_verbose_message(_("Input is 3D: using z-coordinates for approximation"));
  496. }
  497. else { /* 2D */
  498. if (parm.zcol->answer)
  499. G_verbose_message(_("Input is 2D: using attribute values for approximation"));
  500. else
  501. G_verbose_message(_("Input is 2D: using category values for approximation"));
  502. }
  503. /* we can't read the input file's timestamp as they don't exist in */
  504. /* the new vector format. Even so, a TimeStamp structure is needed */
  505. /* for IL_init_params_2d(), so we set it to NULL. */
  506. /* If anyone is ever motivated to add it, the Plus_head struct has */
  507. /* 'long coor_mtime' and dig_head has 'char *date; char *source_date;' */
  508. /* which could be read in. */
  509. if (devi != NULL || cvdev != NULL) {
  510. Pnts = Vect_new_line_struct();
  511. Cats2 = Vect_new_cats_struct();
  512. db_init_string(&sql2);
  513. if (devi != NULL) {
  514. if (Vect_open_new(&Map2, devi, 1) < 0)
  515. G_fatal_error(_("Unable to create vector map <%s>"), devi);
  516. } else {
  517. if (Vect_open_new(&Map2, cvdev, 1) < 0)
  518. G_fatal_error(_("Unable to create vector map <%s>"), cvdev);
  519. }
  520. Vect_hist_command(&Map2);
  521. ff = Vect_default_field_info(&Map2, 1, NULL, GV_1TABLE);
  522. Vect_map_add_dblink(&Map2, 1, NULL, ff->table, GV_KEY_COLUMN, ff->database,
  523. ff->driver);
  524. /* Create new table */
  525. db_zero_string(&sql2);
  526. sprintf(buf, "create table %s ( ", ff->table);
  527. db_append_string(&sql2, buf);
  528. db_append_string(&sql2, "cat integer");
  529. db_append_string(&sql2, ", flt1 double precision");
  530. db_append_string(&sql2, ")");
  531. G_debug(1, "%s", db_get_string(&sql2));
  532. driver2 = db_start_driver_open_database(ff->driver, ff->database);
  533. if (driver2 == NULL)
  534. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  535. ff->database, ff->driver);
  536. db_set_error_handler_driver(driver2);
  537. if (db_execute_immediate(driver2, &sql2) != DB_OK) {
  538. G_fatal_error(_("Unable to create table '%s'"),
  539. db_get_string(&sql2));
  540. }
  541. db_begin_transaction(driver2);
  542. count = 1;
  543. }
  544. ertot = 0.;
  545. create_temp_files();
  546. IL_init_params_2d(&params, NULL, 1, 1, zmult, KMIN, KMAX, maskmap, n_rows,
  547. n_cols, az, adx, ady, adxx, adyy, adxy, fi, KMAX2,
  548. SCIK1, SCIK2, SCIK3, rsm, elev, slope, aspect, pcurv,
  549. tcurv, mcurv, dmin, x_orig, y_orig, deriv, theta,
  550. scalex, Tmp_fd_z, Tmp_fd_dx, Tmp_fd_dy, Tmp_fd_xx,
  551. Tmp_fd_yy, Tmp_fd_xy, devi, NULL, cv,
  552. parm.wheresql->answer);
  553. IL_init_func_2d(&params, IL_grid_calc_2d, IL_matrix_create,
  554. IL_check_at_points_2d, IL_secpar_loop_2d, IL_crst,
  555. IL_crstg, IL_write_temp_2d);
  556. totsegm =
  557. IL_vector_input_data_2d(&params, &Map, with_z ? 0 : field,
  558. zcol, scol,
  559. info, &xmin, &xmax,
  560. &ymin, &ymax, &zmin, &zmax, &NPOINT, &dmax);
  561. if (totsegm <= 0) {
  562. clean();
  563. G_fatal_error(_("Input failed"));
  564. }
  565. /*Vect_set_release_support(&Map); */
  566. Vect_close(&Map);
  567. if (treefile != NULL) {
  568. if (0 > Vect_open_new(&TreeMap, treefile, 0)) {
  569. clean();
  570. G_fatal_error(_("Unable to open vector map <%s>"), treefile);
  571. }
  572. Vect_hist_command(&TreeMap);
  573. /*
  574. sprintf (TreeMap.head.your_name, "grass");
  575. sprintf (TreeMap.head.map_name, "Quad tree for %s", input);
  576. TreeMap.head.orig_scale = 100000;
  577. TreeMap.head.plani_zone = G_zone ();
  578. */
  579. print_tree(root, x_orig, y_orig, &TreeMap);
  580. Vect_build(&TreeMap);
  581. Vect_close(&TreeMap);
  582. }
  583. disk = disk + totsegm * sizeof(int) * 4;
  584. sdisk = sdisk + totsegm * sizeof(int) * 4;
  585. if (elev != NULL)
  586. ddisk += disk;
  587. if (slope != NULL)
  588. sddisk += sdisk;
  589. if (aspect != NULL)
  590. sddisk += sdisk;
  591. if (pcurv != NULL)
  592. ddisk += disk;
  593. if (tcurv != NULL)
  594. ddisk += disk;
  595. if (mcurv != NULL)
  596. ddisk += disk;
  597. ddisk += sddisk;
  598. G_verbose_message(_("Processing all selected output files "
  599. "will require %d bytes of disk space for temp files"), ddisk);
  600. deltx = xmax - xmin;
  601. delty = ymax - ymin;
  602. dnorm = sqrt((deltx * delty * KMIN) / NPOINT);
  603. if (dtens) {
  604. params.fi = params.fi * dnorm / 1000.;
  605. G_verbose_message("dnorm = %f, rescaled tension = %f", dnorm, params.fi);
  606. }
  607. bitmask = IL_create_bitmask(&params);
  608. if (totsegm <= 0) {
  609. clean();
  610. G_fatal_error(_("Input failed"));
  611. }
  612. ertot = 0.;
  613. #if defined(_OPENMP)
  614. G_message(_("Processing segments in parallel..."));
  615. if (IL_interp_segments_2d_parallel(&params, info, info->root, bitmask,
  616. zmin, zmax, &zminac, &zmaxac, &gmin, &gmax,
  617. &c1min, &c1max, &c2min, &c2max, &ertot, totsegm,
  618. n_cols, dnorm, threads) < 0) {
  619. clean();
  620. G_fatal_error(_("Interp_segmets failed"));
  621. }
  622. #else
  623. G_message(_("Processing segments..."));
  624. if (IL_interp_segments_2d(&params, info, info->root, bitmask,
  625. zmin, zmax, &zminac, &zmaxac, &gmin, &gmax,
  626. &c1min, &c1max, &c2min, &c2max, &ertot, totsegm,
  627. n_cols, dnorm) < 0) {
  628. clean();
  629. G_fatal_error(_("Interp_segmets failed"));
  630. }
  631. #endif
  632. G_free_vector(az);
  633. if (cond1) {
  634. G_free_vector(adx);
  635. G_free_vector(ady);
  636. if (cond2) {
  637. G_free_vector(adxx);
  638. G_free_vector(adyy);
  639. G_free_vector(adxy);
  640. }
  641. }
  642. ii = IL_output_2d(&params, &cellhd, zmin, zmax, zminac, zmaxac, c1min,
  643. c1max, c2min, c2max, gmin, gmax, ertot, input, dnorm,
  644. dtens, 1, NPOINT);
  645. if (ii < 0) {
  646. clean();
  647. G_fatal_error(_("Unable to write raster maps - try to increase resolution"));
  648. }
  649. G_free(zero_array_cell);
  650. if (elev != NULL)
  651. fclose(Tmp_fd_z);
  652. if (slope != NULL)
  653. fclose(Tmp_fd_dx);
  654. if (aspect != NULL)
  655. fclose(Tmp_fd_dy);
  656. if (pcurv != NULL)
  657. fclose(Tmp_fd_xx);
  658. if (tcurv != NULL)
  659. fclose(Tmp_fd_yy);
  660. if (mcurv != NULL)
  661. fclose(Tmp_fd_xy);
  662. if (overfile != NULL) {
  663. if (0 > Vect_open_new(&OverMap, overfile, 0)) {
  664. clean();
  665. G_fatal_error(_("Unable to create vector map <%s>"), overfile);
  666. }
  667. Vect_hist_command(&OverMap);
  668. /*
  669. sprintf (OverMap.head.your_name, "grass");
  670. sprintf (OverMap.head.map_name, "Overlap segments for %s", input);
  671. OverMap.head.orig_scale = 100000;
  672. OverMap.head.plani_zone = G_zone ();
  673. */
  674. print_tree(root, x_orig, y_orig, &OverMap);
  675. Vect_build(&OverMap);
  676. Vect_close(&OverMap);
  677. }
  678. if (elev != NULL)
  679. unlink(Tmp_file_z);
  680. if (slope != NULL)
  681. unlink(Tmp_file_dx);
  682. if (aspect != NULL)
  683. unlink(Tmp_file_dy);
  684. if (pcurv != NULL)
  685. unlink(Tmp_file_xx);
  686. if (tcurv != NULL)
  687. unlink(Tmp_file_yy);
  688. if (mcurv != NULL)
  689. unlink(Tmp_file_xy);
  690. if (cvdev != NULL || devi != NULL) {
  691. db_commit_transaction(driver2);
  692. db_close_database_shutdown_driver(driver2);
  693. Vect_build(&Map2);
  694. Vect_close(&Map2);
  695. }
  696. G_done_msg(" ");
  697. exit(EXIT_SUCCESS);
  698. }
  699. int print_tree(struct multtree *tree,
  700. double x_orig, double y_orig, struct Map_info *Map)
  701. {
  702. double xarray[5], yarray[5], zarray[5];
  703. struct line_pnts *Points;
  704. struct line_cats *Cats;
  705. int j;
  706. int type = GV_LINE;
  707. if (tree == NULL)
  708. return 0;
  709. if (tree->data == NULL)
  710. return 0;
  711. if (tree->leafs != NULL) {
  712. for (j = 0; j < 4; j++) {
  713. print_tree(tree->leafs[j], x_orig, y_orig, Map);
  714. }
  715. }
  716. else {
  717. Points = Vect_new_line_struct();
  718. Cats = Vect_new_cats_struct();
  719. xarray[0] = ((struct quaddata *)(tree->data))->x_orig + x_orig;
  720. yarray[0] = ((struct quaddata *)(tree->data))->y_orig + y_orig;
  721. xarray[1] = xarray[0];
  722. yarray[3] = yarray[0];
  723. xarray[3] = ((struct quaddata *)(tree->data))->xmax + x_orig;
  724. yarray[1] = ((struct quaddata *)(tree->data))->ymax + y_orig;
  725. yarray[2] = yarray[1];
  726. xarray[2] = xarray[3];
  727. yarray[4] = yarray[0];
  728. xarray[4] = xarray[0];
  729. if (Vect_copy_xyz_to_pnts(Points, xarray, yarray, zarray, 5) < 0) {
  730. clean();
  731. G_fatal_error(_("Out of memory"));
  732. }
  733. Vect_write_line(Map, (unsigned int)type, Points, Cats);
  734. G_free(Points);
  735. }
  736. return 1;
  737. }
  738. static FILE *create_temp_file(const char *name, char **tmpname)
  739. {
  740. FILE *fp;
  741. char *tmp;
  742. int i;
  743. if (!name)
  744. return NULL;
  745. *tmpname = tmp = G_tempfile();
  746. fp = fopen(tmp, "w+");
  747. if (!fp)
  748. G_fatal_error(_("Unable to open temporary file <%s>"), *tmpname);
  749. for (i = 0; i < n_rows; i++) {
  750. if (fwrite(zero_array_cell, sizeof(FCELL), n_cols, fp) != n_cols) {
  751. clean();
  752. G_fatal_error(_("Error writing temporary file <%s>"), *tmpname);
  753. }
  754. }
  755. return fp;
  756. }
  757. static void create_temp_files(void)
  758. {
  759. zero_array_cell = (FCELL *) G_calloc(n_cols, sizeof(FCELL));
  760. Tmp_fd_z = create_temp_file(elev, &Tmp_file_z );
  761. Tmp_fd_dx = create_temp_file(slope, &Tmp_file_dx);
  762. Tmp_fd_dy = create_temp_file(aspect, &Tmp_file_dy);
  763. Tmp_fd_xx = create_temp_file(pcurv, &Tmp_file_xx);
  764. Tmp_fd_yy = create_temp_file(tcurv, &Tmp_file_yy);
  765. Tmp_fd_xy = create_temp_file(mcurv, &Tmp_file_xy);
  766. }
  767. static void clean(void)
  768. {
  769. if (Tmp_fd_z) fclose(Tmp_fd_z);
  770. if (Tmp_fd_dx) fclose(Tmp_fd_dx);
  771. if (Tmp_fd_dy) fclose(Tmp_fd_dy);
  772. if (Tmp_fd_xx) fclose(Tmp_fd_xx);
  773. if (Tmp_fd_yy) fclose(Tmp_fd_yy);
  774. if (Tmp_fd_xy) fclose(Tmp_fd_xy);
  775. if (Tmp_file_z) unlink(Tmp_file_z);
  776. if (Tmp_file_dx) unlink(Tmp_file_dx);
  777. if (Tmp_file_dy) unlink(Tmp_file_dy);
  778. if (Tmp_file_xx) unlink(Tmp_file_xx);
  779. if (Tmp_file_yy) unlink(Tmp_file_yy);
  780. if (Tmp_file_xy) unlink(Tmp_file_xy);
  781. }