GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
raster/open.c
Go to the documentation of this file.
1/*!
2 * \file lib/raster/open.c
3 *
4 * \brief Raster Library - Open raster file
5 *
6 * (C) 1999-2009 by the GRASS Development Team
7 *
8 * This program is free software under the GNU General Public
9 * License (>=v2). Read the file COPYING that comes with GRASS
10 * for details.
11 *
12 * \author USACERL and many others
13 */
14
15#include <unistd.h>
16#include <string.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <fcntl.h>
20#include <errno.h>
21
22#include <grass/config.h>
23#include <grass/gis.h>
24#include <grass/raster.h>
25#include <grass/glocale.h>
26
27#include "R.h"
28#define FORMAT_FILE "f_format"
29#define NULL_FILE "null"
30/* cmpressed null file */
31#define NULLC_FILE "nullcmpr"
32
33static int new_fileinfo(void)
34{
36 int newsize = oldsize;
37 int i;
38
39 for (i = 0; i < oldsize; i++)
40 if (R__.fileinfo[i].open_mode <= 0) {
41 memset(&R__.fileinfo[i], 0, sizeof(struct fileinfo));
42 R__.fileinfo[i].open_mode = -1;
43 return i;
44 }
45
46 if (newsize < 20)
47 newsize += 20;
48 else
49 newsize *= 2;
50
51 R__.fileinfo = G_realloc(R__.fileinfo, newsize * sizeof(struct fileinfo));
52
53 /* Mark all cell files as closed */
54 for (i = oldsize; i < newsize; i++) {
55 memset(&R__.fileinfo[i], 0, sizeof(struct fileinfo));
56 R__.fileinfo[i].open_mode = -1;
57 }
58
60
61 return oldsize;
62}
63
64/*!
65 * \brief Open raster file
66 *
67 * Arrange for the NULL-value bitmap to be read as well as the raster
68 * map. If no NULL-value bitmap exists, arrange for the production of
69 * NULL-values based on zeros in the raster map. If the map is
70 * floating-point, arrange for quantization to integer for
71 * Rast_get_c_row(), et. al., by reading the quantization rules
72 * for the map using Rast_read_quant(). If the programmer wants to read
73 * the floating point map using uing quant rules other than the ones
74 * stored in map's quant file, he/she should call Rast_set_quant_rules()
75 * after the call to Rast_open_old().
76 *
77 * \param name map name
78 * \param open_mode mode
79 * \param map_type map type (CELL, FCELL, DCELL)
80 *
81 * \return open file descriptor ( >= 0) if successful
82 */
83static int open_raster_new(const char *name, int open_mode,
84 RASTER_MAP_TYPE map_type);
85
86/*!
87 \brief Open an existing integer raster map (cell)
88
89 Opens the existing cell file <i>name</i> in the <i>mapset</i> for
90 reading by Rast_get_row() with mapping into the current window.
91
92 This routine opens the raster map <i>name</i> in <i>mapset</i> for
93 reading. A nonnegative file descriptor is returned if the open is
94 successful. Otherwise a diagnostic message is printed and a negative
95 value is returned. This routine does quite a bit of work. Since
96 GRASS users expect that all raster maps will be resampled into the
97 current region, the resampling index for the raster map is prepared
98 by this routine after the file is opened. The resampling is based on
99 the active module region (see also \ref The_Region}. Preparation
100 required for reading the various raster file formats (see \ref
101 Raster_File_Format for an explanation of the various raster file
102 formats) is also done.
103
104 Diagnostics: warning message printed if open fails.
105
106 \param name map name
107 \param mapset mapset name where raster map <i>name</i> lives
108
109 \return nonnegative file descriptor (int)
110 */
111int Rast_open_old(const char *name, const char *mapset)
112{
113 int fd = Rast__open_old(name, mapset);
114
115 /* turn on auto masking, if not already on */
117 /*
118 if(R__.auto_mask <= 0)
119 R__.mask_buf = Rast_allocate_c_buf();
120 now we don't ever free it!, so no need to allocate it (Olga)
121 */
122 /* mask_buf is used for reading mask file when mask is set and
123 for reading map rows when the null file doesn't exist */
124
125 return fd;
126}
127
128/*! \brief Lower level function, open cell files, supercell files,
129 and the mask file.
130
131 Actions:
132 - opens the named cell file, following reclass reference if
133 named layer is a reclass layer.
134 - creates the required mapping between the data and the window
135 for use by the get_map_row family of routines.
136
137 Diagnostics: Errors other than actual open failure will cause a
138 diagnostic to be delivered through G_warning() open failure messages
139 are left to the calling routine since the masking logic will want to
140 issue a different warning.
141
142 Note: This routine does NOT open the mask layer. If it did we would
143 get infinite recursion. This routine is called to open the mask by
144 Rast__check_for_auto_masking() which is called by Rast_open_old().
145
146 \param name map name
147 \param mapset mapset of cell file to be opened
148
149 \return open file descriptor
150 */
151int Rast__open_old(const char *name, const char *mapset)
152{
153 struct fileinfo *fcb;
154 int cell_fd, fd;
155 char *cell_dir;
156 const char *r_name;
157 const char *r_mapset;
158 struct Cell_head cellhd;
159 int CELL_nbytes = 0; /* bytes per cell in CELL map */
160 int reclass_flag;
161 int MAP_NBYTES;
163 struct Reclass reclass;
165 struct GDAL_link *gdal;
166 struct R_vrt *vrt;
167
168 Rast__init();
169
171 name = xname;
172 mapset = xmapset;
173
174 if (!G_find_raster2(name, mapset))
175 G_fatal_error(_("Raster map <%s> not found"),
177
178 /* Check for reclassification */
179 reclass_flag = Rast_get_reclass(name, mapset, &reclass);
180
181 switch (reclass_flag) {
182 case 0:
183 r_name = name;
184 r_mapset = mapset;
185 break;
186 case 1:
187 r_name = reclass.name;
188 r_mapset = reclass.mapset;
191 _("Unable to open raster map <%s@%s> since it is a reclass "
192 "of raster map <%s@%s> which does not exist"),
193 name, mapset, r_name, r_mapset);
194 break;
195 default: /* Error reading cellhd/reclass file */
196 G_fatal_error(_("Error reading reclass file for raster map <%s>"),
198 break;
199 }
200
201 /* read the cell header */
203
204 /* now check the type */
206 if (MAP_TYPE < 0)
207 G_fatal_error(_("Error reading map type for raster map <%s>"),
209
210 if (MAP_TYPE == CELL_TYPE)
211 /* set the number of bytes for CELL map */
212 {
213 CELL_nbytes = cellhd.format + 1;
214 if (CELL_nbytes < 1)
216 _("Raster map <%s@%s>: format field in header file invalid"),
218 }
219
220 /* compressor */
221 if (MAP_TYPE != CELL_TYPE) {
222 /* fp maps do not use RLE */
223 /* previously, compressed simply meant yes (ZLIB) or no
224 * now compressed encodes compressor type
225 * 0: not compressed
226 * 1, 2: ZLIB
227 * 3: LZ4
228 * 4: BZIP2
229 * etc */
230 if (cellhd.compressed == 1)
231 cellhd.compressed = 2;
232 }
233 /* test if compressor type is supported */
234 if (!G_check_compressor(cellhd.compressed)) {
235 G_fatal_error(_("Compression with %s is not supported in this GRASS "
236 "GIS installation"),
238 }
239
240 if (cellhd.proj != R__.rd_window.proj)
242 _("Raster map <%s> is in different projection than current region. "
243 "Found <%s>, should be <%s>."),
245 G_projection_name(cellhd.proj),
247
248 if (cellhd.zone != R__.rd_window.zone)
249 G_fatal_error(_("Raster map <%s> is in different zone (%d) than "
250 "current region (%d)"),
251 G_fully_qualified_name(name, mapset), cellhd.zone,
252 R__.rd_window.zone);
253
254 /* when map is int warn if too large cell size */
255 if (MAP_TYPE == CELL_TYPE && (unsigned int)CELL_nbytes > sizeof(CELL))
256 G_fatal_error(_("Raster map <%s>: bytes per cell (%d) too large"),
258
259 /* record number of bytes per cell */
260 if (MAP_TYPE == FCELL_TYPE) {
261 cell_dir = "fcell";
263 }
264 else if (MAP_TYPE == DCELL_TYPE) {
265 cell_dir = "fcell";
267 }
268 else { /* integer */
269 cell_dir = "cell";
271 }
272
275 cell_fd = -1;
276 if (gdal) {
277 cell_fd = -1;
278 }
279 else if (vrt) {
280 cell_fd = -1;
281 }
282 else {
283 /* now actually open file for reading */
285 if (cell_fd < 0)
286 G_fatal_error(_("Unable to open %s file for raster map <%s@%s>"),
288 }
289
290 fd = new_fileinfo();
291 fcb = &R__.fileinfo[fd];
292 fcb->data_fd = cell_fd;
293
294 fcb->map_type = MAP_TYPE;
295
296 /* Save cell header */
297 fcb->cellhd = cellhd;
298
299 /* allocate null bitstream buffers for reading null rows */
300 fcb->null_fd = -1;
301 fcb->null_cur_row = -1;
302 fcb->null_bits = Rast__allocate_null_bits(cellhd.cols);
303
304 /* mark closed */
305 fcb->open_mode = -1;
306
307 /* save name and mapset */
308 fcb->name = G_store(name);
309 fcb->mapset = G_store(mapset);
310
311 /* mark no data row in memory */
312 fcb->cur_row = -1;
313
314 /* if reclass, copy reclass structure */
315 if ((fcb->reclass_flag = reclass_flag))
316 fcb->reclass = reclass;
317
318 fcb->gdal = gdal;
319 fcb->vrt = vrt;
320 if (!gdal && !vrt) {
321 /* check for compressed data format, making initial reads if necessary
322 */
323 if (Rast__check_format(fd) < 0) {
324 close(cell_fd); /* warning issued by check_format() */
325 G_fatal_error(_("Error reading format for <%s@%s>"), r_name,
326 r_mapset);
327 }
328 }
329
330 if (!vrt) {
331 /* create the mapping from cell file to window */
333 }
334
335 /*
336 * allocate the data buffer
337 * number of bytes per cell is cellhd.format+1
338 */
339
340 /* for reading fcb->data is allocated to be fcb->cellhd.cols * fcb->nbytes
341 (= XDR_FLOAT/DOUBLE_NBYTES) */
342 fcb->data = (unsigned char *)G_calloc(fcb->cellhd.cols, MAP_NBYTES);
343
344 /* initialize/read in quant rules for float point maps */
345 if (fcb->map_type != CELL_TYPE) {
346 if (fcb->reclass_flag)
347 Rast_read_quant(fcb->reclass.name, fcb->reclass.mapset,
348 &(fcb->quant));
349 else
350 Rast_read_quant(fcb->name, fcb->mapset, &(fcb->quant));
351 }
352
353 /* now mark open for read: this must follow create_window_mapping() */
354 fcb->open_mode = OPEN_OLD;
355 fcb->io_error = 0;
356 fcb->map_type = MAP_TYPE;
357 fcb->nbytes = MAP_NBYTES;
358 fcb->null_row_ptr = NULL;
359
360 if (!gdal && !vrt) {
361 /* First, check for compressed null file */
362 fcb->null_fd =
364 if (fcb->null_fd < 0) {
365 fcb->null_fd =
367 if (fcb->null_fd >= 0) {
368 fcb->null_row_ptr =
369 G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
370 if (Rast__read_null_row_ptrs(fd, fcb->null_fd) < 0) {
371 close(fcb->null_fd);
372 fcb->null_fd = -1;
373 G_free(fcb->null_row_ptr);
374 fcb->null_row_ptr = NULL;
375 }
376 }
377 }
378 fcb->null_file_exists = fcb->null_fd >= 0;
379 }
380
381 return fd;
382}
383
384/*!
385 \brief Opens a new cell file in a database (compressed)
386
387 Opens a new cell file <i>name</i> in the current mapset for writing
388 by Rast_put_row().
389
390 The file is created and filled with no data it is assumed that the
391 new cell file is to conform to the current window.
392
393 The file must be written sequentially. Use Rast_open_new_random()
394 for non sequential writes.
395
396 Note: the open actually creates a temporary file Rast_close() will
397 move the temporary file to the cell file and write out the necessary
398 support files (cellhd, cats, hist, etc.).
399
400 Diagnostics: warning message printed if open fails
401
402 Warning: calls to Rast_set_window() made after opening a new cell file
403 may create confusion and should be avoided the new cell file will be
404 created to conform to the window at the time of the open.
405
406 \param name map name
407
408 \return open file descriptor ( >= 0) if successful
409 \return negative integer if error
410 */
411int Rast_open_c_new(const char *name)
412{
413 return open_raster_new(name, OPEN_NEW_COMPRESSED, CELL_TYPE);
414}
415
416/*!
417 \brief Opens a new cell file in a database (uncompressed)
418
419 See also Rast_open_new().
420
421 \param name map name
422
423 \return open file descriptor ( >= 0) if successful
424 \return negative integer if error
425 */
427{
428 return open_raster_new(name, OPEN_NEW_UNCOMPRESSED, CELL_TYPE);
429}
430
431/*!
432 \brief Save histogram for newly create raster map (cell)
433
434 If newly created cell files should have histograms, set flag=1
435 otherwise set flag=0. Applies to subsequent opens.
436
437 \param flag flag indicator
438 */
440{
442}
443
444/*!
445 \brief Sets the format for subsequent opens on new integer cell files
446 (uncompressed and random only).
447
448 Warning: subsequent put_row calls will only write n+1 bytes per
449 cell. If the data requires more, the cell file will be written
450 incorrectly (but with n+1 bytes per cell)
451
452 When writing float map: format is -1
453
454 \param n format
455 */
457/* sets the format for integer raster map */
458{
459 R__.nbytes = n + 1;
460 if (R__.nbytes <= 0)
461 R__.nbytes = 1;
462 if (R__.nbytes > (int)sizeof(CELL))
463 R__.nbytes = sizeof(CELL);
464}
465
466/*!
467 \brief Get cell value format
468
469 \param v cell
470
471 \return cell format
472 */
474{
475 unsigned int i;
476
477 if (v >= 0)
478 for (i = 0; i < sizeof(CELL); i++)
479 if (!(v /= 256))
480 return i;
481 return sizeof(CELL) - 1;
482}
483
484/*!
485 \brief Opens new fcell file in a database
486
487 Opens a new floating-point map <i>name</i> in the current mapset for
488 writing. The type of the file (i.e. either double or float) is
489 determined and fixed at this point. The default is FCELL_TYPE. In
490 order to change this default
491
492 Use Rast_set_fp_type() where type is one of DCELL_TYPE or FCELL_TYPE.
493
494 See warnings and notes for Rast_open_new().
495
496 \param name map name
497
498 \return nonnegative file descriptor (int)
499 */
500int Rast_open_fp_new(const char *name)
501{
502 return open_raster_new(name, OPEN_NEW_COMPRESSED, R__.fp_type);
503}
504
505/*!
506 \brief Opens new fcell file in a database (uncompressed)
507
508 See Rast_open_fp_new() for details.
509
510 \param name map name
511
512 \return nonnegative file descriptor (int)
513 */
515{
516 return open_raster_new(name, OPEN_NEW_UNCOMPRESSED, R__.fp_type);
517}
518
519static int open_raster_new_gdal(char *map, char *mapset,
520 RASTER_MAP_TYPE map_type)
521{
522 int fd;
523 struct fileinfo *fcb;
524
525 fd = new_fileinfo();
526 fcb = &R__.fileinfo[fd];
527 fcb->data_fd = -1;
528
529 /* mark closed */
530 fcb->map_type = map_type;
531 fcb->open_mode = -1;
532
533 fcb->gdal = Rast_create_gdal_link(map, map_type);
534 if (!fcb->gdal)
535 G_fatal_error(_("Unable to create GDAL link"));
536
537 fcb->cellhd = R__.wr_window;
538 fcb->cellhd.compressed = 0;
539 fcb->nbytes = Rast_cell_size(fcb->map_type);
540 /* for writing fcb->data is allocated to be R__.wr_window.cols *
541 sizeof(CELL or DCELL or FCELL) */
542 fcb->data = G_calloc(R__.wr_window.cols, fcb->nbytes);
543
544 fcb->name = map;
545 fcb->mapset = mapset;
546 fcb->cur_row = 0;
547
548 fcb->row_ptr = NULL;
549 fcb->temp_name = NULL;
550 fcb->null_temp_name = NULL;
551 fcb->null_cur_row = 0;
552 fcb->null_bits = NULL;
553 fcb->null_fd = -1;
554 fcb->null_row_ptr = NULL;
555
556 if (fcb->map_type != CELL_TYPE)
557 Rast_quant_init(&(fcb->quant));
558
559 /* init cell stats */
560 /* now works only for int maps */
561 if (fcb->map_type == CELL_TYPE)
562 if ((fcb->want_histogram = R__.want_histogram))
563 Rast_init_cell_stats(&fcb->statf);
564
565 /* init range and if map is double/float init d/f_range */
566 Rast_init_range(&fcb->range);
567
568 if (fcb->map_type != CELL_TYPE)
569 Rast_init_fp_range(&fcb->fp_range);
570
571 /* mark file as open for write */
572 fcb->open_mode = OPEN_NEW_UNCOMPRESSED;
573 fcb->io_error = 0;
574
575 return fd;
576}
577
578static int open_raster_new(const char *name, int open_mode,
580{
582 struct fileinfo *fcb;
583 int fd, cell_fd;
584 char *tempname;
585 char *map;
586 char *mapset;
587 const char *cell_dir;
588 int nbytes;
589
590 Rast__init();
591
592 switch (map_type) {
593 case CELL_TYPE:
594 cell_dir = "cell";
595 nbytes = R__.nbytes;
596 break;
597 case FCELL_TYPE:
599 cell_dir = "fcell";
600 break;
601 case DCELL_TYPE:
603 cell_dir = "fcell";
604 break;
605 default:
606 G_fatal_error(_("Invalid map type <%d>"), map_type);
607 break;
608 }
609
611 G_fatal_error(_("Raster map <%s> is not in the current mapset (%s)"),
612 name, G_mapset());
613 map = G_store(xname);
615
616 /* check for legal grass name */
617 if (G_legal_filename(map) < 0)
618 G_fatal_error(_("<%s> is an illegal file name"), map);
619
620 if (G_find_file2("", "GDAL", G_mapset()))
621 return open_raster_new_gdal(map, mapset, map_type);
622
623 /* open a tempfile name */
625 cell_fd = creat(tempname, 0666);
626 if (cell_fd < 0) {
627 int err = errno;
628
629 G_free(mapset);
631 G_free(map);
632 G_fatal_error(_("No temp files available: %s"), strerror(err));
633 }
634
635 fd = new_fileinfo();
636 fcb = &R__.fileinfo[fd];
637 fcb->data_fd = cell_fd;
638
639 /*
640 * since we are bypassing the normal open logic
641 * must create the cell element
642 */
644
645 /* mark closed */
646 fcb->map_type = map_type;
647 fcb->open_mode = -1;
648 fcb->gdal = NULL;
649 fcb->vrt = NULL;
650
651 /* for writing fcb->data is allocated to be R__.wr_window.cols *
652 sizeof(CELL or DCELL or FCELL) */
653 fcb->data = (unsigned char *)G_calloc(R__.wr_window.cols,
654 Rast_cell_size(fcb->map_type));
655
656 /*
657 * copy current window into cell header
658 * set format to cell/supercell
659 * for compressed writing
660 * allocate space to hold the row address array
661 */
662 fcb->cellhd = R__.wr_window;
663
664 /* change open_mode to OPEN_NEW_UNCOMPRESSED if R__.compression_type == 0 ?
665 */
666
667 if (open_mode == OPEN_NEW_COMPRESSED && fcb->map_type == CELL_TYPE) {
668 fcb->row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
669 G_zero(fcb->row_ptr, (fcb->cellhd.rows + 1) * sizeof(off_t));
671 fcb->cellhd.compressed = R__.compression_type;
672
673 fcb->nbytes = 1; /* to the minimum */
674 }
675 else {
676 fcb->nbytes = nbytes;
678 fcb->row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
679 G_zero(fcb->row_ptr, (fcb->cellhd.rows + 1) * sizeof(off_t));
681 fcb->cellhd.compressed = R__.compression_type;
682 }
683 else
684 fcb->cellhd.compressed = 0;
685
686 if (fcb->map_type != CELL_TYPE) {
687 Rast_quant_init(&(fcb->quant));
688 }
689 }
690 if (open_mode == OPEN_NEW_COMPRESSED && fcb->map_type != CELL_TYPE &&
691 fcb->cellhd.compressed == 1) {
692 /* fp maps do not use RLE */
693 fcb->cellhd.compressed = 2;
694 }
695
696 /* save name and mapset, and tempfile name */
697 fcb->name = map;
698 fcb->mapset = mapset;
699 fcb->temp_name = tempname;
700
701 /* next row to be written (in order) is zero */
702 fcb->cur_row = 0;
703
704 /* open a null tempfile name */
706 fcb->null_fd = creat(tempname, 0666);
707 if (fcb->null_fd < 0) {
708 int err = errno;
709
711 G_free(fcb->name);
712 G_free(fcb->mapset);
713 G_free(fcb->temp_name);
714 close(cell_fd);
715 G_fatal_error(_("No temp files available: %s"), strerror(err));
716 }
717
718 fcb->null_temp_name = tempname;
719
720 fcb->null_row_ptr = NULL;
721 if (R__.compress_nulls) {
722 fcb->null_row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
723 G_zero(fcb->null_row_ptr, (fcb->cellhd.rows + 1) * sizeof(off_t));
724 Rast__write_null_row_ptrs(fd, fcb->null_fd);
725 }
726
727 /* next row to be written (in order) is zero */
728 fcb->null_cur_row = 0;
729
730 /* allocate null bitstream buffer for writing */
731 fcb->null_bits = Rast__allocate_null_bits(fcb->cellhd.cols);
732
733 /* init cell stats */
734 /* now works only for int maps */
735 if (fcb->map_type == CELL_TYPE)
736 if ((fcb->want_histogram = R__.want_histogram))
737 Rast_init_cell_stats(&fcb->statf);
738
739 /* init range and if map is double/float init d/f_range */
740 Rast_init_range(&fcb->range);
741
742 if (fcb->map_type != CELL_TYPE)
743 Rast_init_fp_range(&fcb->fp_range);
744
745 /* mark file as open for write */
746 fcb->open_mode = open_mode;
747 fcb->io_error = 0;
748
749 return fd;
750}
751
753{
755 struct fileinfo *fcb;
756 int fd;
757 char *tempname;
758 char *map;
759 char *mapset;
760
761 Rast__init();
762
765 _("Raster map <%s> does not exist in the current mapset (%s)"),
766 name, G_mapset());
767
769 G_fatal_error(_("Raster map <%s> is not in the current mapset (%s)"),
770 name, G_mapset());
771 map = G_store(xname);
773
774 fd = new_fileinfo();
775 fcb = &R__.fileinfo[fd];
776
777 G_zero(fcb, sizeof(*fcb));
778
779 fcb->name = map;
780 fcb->mapset = mapset;
781
782 Rast_get_cellhd(map, mapset, &fcb->cellhd);
783
784 /* open a null tempfile name */
786 fcb->null_fd = creat(tempname, 0666);
787 if (fcb->null_fd < 0) {
788 int err = errno;
789
791 G_free(fcb->name);
792 G_free(fcb->mapset);
793 G_fatal_error(_("No temp files available: %s"), strerror(err));
794 }
795 fcb->null_temp_name = tempname;
796
797 if (R__.compress_nulls) {
798 fcb->null_row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
799 G_zero(fcb->null_row_ptr, (fcb->cellhd.rows + 1) * sizeof(off_t));
800 Rast__write_null_row_ptrs(fd, fcb->null_fd);
801 }
802
803 /* allocate null bitstream buffer for writing */
804 fcb->null_bits = Rast__allocate_null_bits(fcb->cellhd.cols);
805
806 return fd;
807}
808
809/*!
810 \brief Set raster map floating-point data format.
811
812 This controls the storage type for floating-point maps. It affects
813 subsequent calls to G_open_fp_map_new(). The <i>type</i> must be
814 one of FCELL_TYPE (float) or DCELL_TYPE (double). The use of this
815 routine by applications is discouraged since its use would override
816 user preferences.
817
818 \param type raster data type
819
820 \return void
821 */
823{
824 Rast__init();
825
826 switch (map_type) {
827 case FCELL_TYPE:
828 case DCELL_TYPE:
830 break;
831 default:
832 G_fatal_error(_("Rast_set_fp_type(): can only be called with "
833 "FCELL_TYPE or DCELL_TYPE"));
834 break;
835 }
836}
837
838/*!
839 \brief Check if raster map is floating-point
840
841 Returns true (1) if raster map <i>name</i> in <i>mapset</i>
842 is a floating-point dataset; false(0) otherwise.
843
844 \param name map name
845 \param mapset mapset name
846
847 \return 1 floating-point
848 \return 0 int
849 */
850int Rast_map_is_fp(const char *name, const char *mapset)
851{
852 char path[GPATH_MAX];
853 const char *xmapset;
854
856 if (!xmapset)
857 G_fatal_error(_("Raster map <%s> not found"),
859
860 G_file_name(path, "fcell", name, xmapset);
861 if (access(path, 0) == 0)
862 return 1;
863
864 G_file_name(path, "g3dcell", name, xmapset);
865 if (access(path, 0) == 0)
866 return 1;
867
868 return 0;
869}
870
871/*!
872 \brief Determine raster data type
873
874 Determines if the raster map is floating point or integer. Returns
875 DCELL_TYPE for double maps, FCELL_TYPE for float maps, CELL_TYPE for
876 integer maps, -1 if error has occurred
877
878 \param name map name
879 \param mapset mapset where map <i>name</i> lives
880
881 \return raster data type
882 */
883RASTER_MAP_TYPE Rast_map_type(const char *name, const char *mapset)
884{
885 char path[GPATH_MAX];
886 const char *xmapset;
887
889 if (!xmapset) {
890 if (mapset && *mapset)
891 G_fatal_error(_("Raster map <%s> not found in mapset <%s>"), name,
892 mapset);
893 else
894 G_fatal_error(_("Raster map <%s> not found"), name);
895 }
896
897 G_file_name(path, "fcell", name, xmapset);
898
899 if (access(path, 0) == 0)
901
902 G_file_name(path, "g3dcell", name, xmapset);
903
904 if (access(path, 0) == 0)
905 return DCELL_TYPE;
906
907 return CELL_TYPE;
908}
909
910/*!
911 \brief Determine raster type from descriptor
912
913 Determines if the raster map is floating point or integer. Returns
914 DCELL_TYPE for double maps, FCELL_TYPE for float maps, CELL_TYPE for
915 integer maps, -1 if error has occurred
916
917 \param fd file descriptor
918
919 \return raster data type
920 */
922{
923 struct fileinfo *fcb = &R__.fileinfo[fd];
924
925 return fcb->map_type;
926}
927
928/*!
929 \brief Determines whether the floating points cell file has double or float
930 type
931
932 \param name map name
933 \param mapset mapset where map <i>name</i> lives
934
935 \return raster type (fcell, dcell)
936 */
938{
939 char path[GPATH_MAX];
940 struct Key_Value *format_keys;
941 const char *str, *str1;
942 RASTER_MAP_TYPE map_type;
943 const char *xmapset;
944
945 xmapset = G_find_raster2(name, mapset);
946 if (!xmapset)
947 G_fatal_error(_("Raster map <%s> not found"),
949
951
952 if (access(path, 0) != 0)
953 G_fatal_error(_("Unable to find '%s'"), path);
954
956
957 if ((str = G_find_key_value("type", format_keys)) != NULL) {
958 if (strcmp(str, "double") == 0)
959 map_type = DCELL_TYPE;
960 else if (strcmp(str, "float") == 0)
961 map_type = FCELL_TYPE;
962 else {
964 G_fatal_error(_("Invalid type: field '%s' in file '%s'"), str,
965 path);
966 }
967 }
968 else {
970 G_fatal_error(_("Missing type: field in file '%s'"), path);
971 }
972
973 if ((str1 = G_find_key_value("byte_order", format_keys)) != NULL) {
974 if (strcmp(str1, "xdr") != 0)
975 G_warning(_("Raster map <%s> is not xdr: byte_order: %s"), name,
976 str);
977 /* here read and translate byte order if not using xdr */
978 }
980 return map_type;
981}
982
983/*!
984 \brief Opens a new raster map
985
986 Opens a new raster map of type <i>wr_type</i>
987
988 See warnings and notes for Rast_open_new().
989
990 Supported data types:
991 - CELL_TYPE
992 - FCELL_TYPE
993 - DCELL_TYPE
994
995 On CELL_TYPE calls Rast_open_new() otherwise Rast_open_fp_new().
996
997 \param name map name
998 \param wr_type raster data type
999
1000 \return nonnegative file descriptor (int)
1001 */
1003{
1004 return open_raster_new(name, OPEN_NEW_COMPRESSED, wr_type);
1005}
1006
1007/*!
1008 \brief Opens a new raster map (uncompressed)
1009
1010 See Rast_open_new().
1011
1012 \param name map name
1013 \param wr_type raster data type
1014
1015 \return nonnegative file descriptor (int)
1016 */
1018{
1019 return open_raster_new(name, OPEN_NEW_UNCOMPRESSED, wr_type);
1020}
1021
1022/*!
1023 \brief Sets quant translation rules for raster map opened for
1024 reading.
1025
1026 Returned by Rast_open_old(). After calling this function,
1027 Rast_get_c_row() and Rast_get_c_row() will use rules defined by q
1028 (instead of using rules defined in map's quant file) to convert floats to
1029 ints.
1030
1031 \param fd file descriptor (cell file)
1032 \param q pointer to Quant structure
1033
1034 \return void
1035 */
1036void Rast_set_quant_rules(int fd, struct Quant *q)
1037{
1038 struct fileinfo *fcb = &R__.fileinfo[fd];
1039 CELL cell;
1040 DCELL dcell;
1041 struct Quant_table *p;
1042
1043 if (fcb->open_mode != OPEN_OLD)
1044 G_fatal_error(_("Rast_set_quant_rules() can be called only for "
1045 "raster maps opened for reading"));
1046
1047 /* copy all info from q to fcb->quant) */
1048 Rast_quant_init(&fcb->quant);
1049 if (q->truncate_only) {
1050 Rast_quant_truncate(&fcb->quant);
1051 return;
1052 }
1053
1054 for (p = &(q->table[q->nofRules - 1]); p >= q->table; p--)
1055 Rast_quant_add_rule(&fcb->quant, p->dLow, p->dHigh, p->cLow, p->cHigh);
1056 if (Rast_quant_get_neg_infinite_rule(q, &dcell, &cell) > 0)
1058 if (Rast_quant_get_pos_infinite_rule(q, &dcell, &cell) > 0)
1060}
#define OPEN_NEW_COMPRESSED
Definition R.h:102
#define OPEN_NEW_UNCOMPRESSED
Definition R.h:103
#define XDR_FLOAT_NBYTES
Definition R.h:6
#define OPEN_OLD
Definition R.h:101
#define XDR_DOUBLE_NBYTES
Definition R.h:7
#define NULL
Definition ccmath.h:32
AMI_err name(char **stream_name)
Definition ami_stream.h:426
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition gis/zero.c:23
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:147
#define G_realloc(p, n)
Definition defs/gis.h:141
int G_unqualified_name(const char *, const char *, char *, char *)
Returns unqualified map name (without @ mapset)
Definition nme_in_mps.c:134
#define G_calloc(m, n)
Definition defs/gis.h:140
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
char * G_compressor_name(int)
Definition compress.c:118
const char * G_projection_name(int)
Get projection name.
Definition proj2.c:55
int G_legal_filename(const char *)
Check for legal database file name.
Definition legal_name.c:34
char * G_file_name_misc(char *, const char *, const char *, const char *, const char *)
Builds full path names to GIS misc data files.
Definition file_name.c:101
int G_open_old_misc(const char *, const char *, const char *, const char *)
open a database misc file for reading
Definition open_misc.c:132
int G_make_mapset_object_group(const char *)
Create directory for group of elements of a given type.
Definition mapset_msc.c:75
char * G_file_name(char *, const char *, const char *, const char *)
Builds full path names to GIS data files.
Definition file_name.c:61
const char * G_find_file2(const char *, const char *, const char *)
Searches for a file from the mapset search list or in a specified mapset. (look but don't touch)
Definition find_file.c:234
int G_open_old(const char *, const char *, const char *)
Open a database file for reading.
Definition gis/open.c:169
void G_free_key_value(struct Key_Value *)
Free allocated Key_Value structure.
Definition key_value1.c:104
char * G_tempfile(void)
Returns a temporary file name.
Definition tempfile.c:62
char * G_fully_qualified_name(const char *, const char *)
Get fully qualified element name.
Definition nme_in_mps.c:101
struct Key_Value * G_read_key_value_file(const char *)
Read key/values pairs from file.
Definition key_value3.c:55
int G_check_compressor(int)
Definition compress.c:140
const char * G_find_key_value(const char *, const struct Key_Value *)
Find given key (case sensitive)
Definition key_value1.c:85
char * G_store(const char *)
Copy string to allocated memory.
Definition strings.c:87
const char * G_find_raster2(const char *, const char *)
Find a raster map (look but don't touch)
Definition find_rast.c:76
const char * G_mapset(void)
Get current mapset name.
Definition gis/mapset.c:33
int Rast__read_null_row_ptrs(int, int)
int Rast_quant_get_neg_infinite_rule(const struct Quant *, DCELL *, CELL *)
Returns in "dLeft" and "c" the rule values.
Definition quant.c:390
int Rast__check_for_auto_masking(void)
Checks for auto masking.
Definition auto_mask.c:33
unsigned char * Rast__allocate_null_bits(int)
Allocates memory for null bits.
Definition alloc_cell.c:133
int Rast_get_reclass(const char *, const char *, struct Reclass *)
Get reclass.
Definition reclass.c:140
int Rast__check_format(int)
void Rast_quant_set_pos_infinite_rule(struct Quant *, DCELL, CELL)
Defines a rule for values "dRight" and larger.
Definition quant.c:412
int Rast_read_quant(const char *, const char *, struct Quant *)
Reads quantization rules for name in mapset and stores them in the quantization structure....
Definition quant_rw.c:187
void Rast_quant_set_neg_infinite_rule(struct Quant *, DCELL, CELL)
Defines a rule for values "dLeft" and smaller.
Definition quant.c:364
struct GDAL_link * Rast_create_gdal_link(const char *, RASTER_MAP_TYPE)
Create GDAL settings for given raster map.
Definition gdal.c:227
int Rast__write_row_ptrs(int)
int Rast__write_null_row_ptrs(int, int)
void Rast_quant_add_rule(struct Quant *, DCELL, DCELL, CELL, CELL)
Adds a new rule to the set of quantization rules.
Definition quant.c:469
size_t Rast_cell_size(RASTER_MAP_TYPE)
Returns size of a raster cell in bytes.
Definition alloc_cell.c:37
void Rast_init_range(struct Range *)
Initialize range structure.
int Rast_quant_get_pos_infinite_rule(const struct Quant *, DCELL *, CELL *)
Returns in "dRight" and "c" the rule values.
Definition quant.c:438
void Rast__init(void)
Definition raster/init.c:61
void Rast_get_cellhd(const char *, const char *, struct Cell_head *)
Read the raster header.
Definition get_cellhd.c:41
void Rast_quant_init(struct Quant *)
Initialize the structure.
Definition quant.c:175
void Rast_init_fp_range(struct FPRange *)
Initialize fp range.
void Rast_quant_truncate(struct Quant *)
Sets the quant rules to perform simple truncation on floats.
Definition quant.c:217
void Rast_init_cell_stats(struct Cell_stats *)
Initialize cell stats.
Definition cell_stats.c:39
struct R_vrt * Rast_get_vrt(const char *, const char *)
Definition vrt.c:47
struct GDAL_link * Rast_get_gdal_link(const char *, const char *)
Get GDAL link settings for given raster map.
Definition gdal.c:53
void Rast__create_window_mapping(int)
Create window mapping.
Header file for msvc/fcntl.c.
#define creat
Definition fcntl.h:34
#define GMAPSET_MAX
Definition gis.h:197
#define GPATH_MAX
Definition gis.h:199
#define GNAME_MAX
Definition gis.h:196
double DCELL
Definition gis.h:635
int CELL
Definition gis.h:634
#define _(str)
Definition glocale.h:10
const char * name
Definition named_colr.c:6
int Rast__open_old(const char *name, const char *mapset)
Lower level function, open cell files, supercell files, and the mask file.
#define NULL_FILE
Definition raster/open.c:29
void Rast_set_fp_type(RASTER_MAP_TYPE map_type)
Set raster map floating-point data format.
int Rast__open_null_write(const char *name)
int Rast_get_cell_format(CELL v)
Get cell value format.
int Rast_open_new(const char *name, RASTER_MAP_TYPE wr_type)
Opens a new raster map.
void Rast_set_quant_rules(int fd, struct Quant *q)
Sets quant translation rules for raster map opened for reading.
void Rast_want_histogram(int flag)
Save histogram for newly create raster map (cell)
RASTER_MAP_TYPE Rast_get_map_type(int fd)
Determine raster type from descriptor.
void Rast_set_cell_format(int n)
Sets the format for subsequent opens on new integer cell files (uncompressed and random only).
int Rast_open_c_new_uncompressed(const char *name)
Opens a new cell file in a database (uncompressed)
int Rast_open_fp_new_uncompressed(const char *name)
Opens new fcell file in a database (uncompressed)
int Rast_open_old(const char *name, const char *mapset)
Open an existing integer raster map (cell)
#define NULLC_FILE
Definition raster/open.c:31
RASTER_MAP_TYPE Rast__check_fp_type(const char *name, const char *mapset)
Determines whether the floating points cell file has double or float type.
int Rast_open_fp_new(const char *name)
Opens new fcell file in a database.
int Rast_open_c_new(const char *name)
Opens a new cell file in a database (compressed)
int Rast_open_new_uncompressed(const char *name, RASTER_MAP_TYPE wr_type)
Opens a new raster map (uncompressed)
int Rast_map_is_fp(const char *name, const char *mapset)
Check if raster map is floating-point.
RASTER_MAP_TYPE Rast_map_type(const char *name, const char *mapset)
Determine raster data type.
#define FORMAT_FILE
Definition raster/open.c:28
#define FCELL_TYPE
Definition raster.h:12
#define DCELL_TYPE
Definition raster.h:13
#define CELL_TYPE
Definition raster.h:11
int RASTER_MAP_TYPE
Definition raster.h:25
2D/3D raster map header (used also for region)
Definition gis.h:446
int compressed
Compression mode (raster header only)
Definition gis.h:459
int format
Max number of bytes per raster data value minus 1 (raster header only)
Definition gis.h:452
int zone
Projection zone (UTM)
Definition gis.h:480
int cols
Number of columns for 2D data.
Definition gis.h:465
int proj
Projection code.
Definition gis.h:478
DCELL dLow
Definition raster.h:74
CELL cHigh
Definition raster.h:77
CELL cLow
Definition raster.h:76
DCELL dHigh
Definition raster.h:75
Definition raster.h:80
int truncate_only
Definition raster.h:81
int nofRules
Definition raster.h:89
struct Quant_table * table
Definition raster.h:102
Definition R.h:82
int compress_nulls
Definition R.h:89
struct fileinfo * fileinfo
Definition R.h:96
int compression_type
Definition R.h:88
int want_histogram
Definition R.h:86
int fileinfo_count
Definition R.h:95
RASTER_MAP_TYPE fp_type
Definition R.h:83
int nbytes
Definition R.h:87
struct Cell_head wr_window
Definition R.h:93
struct Cell_head rd_window
Definition R.h:92
Definition R.h:41
char * mapset
Definition raster.h:33
char * name
Definition raster.h:32
Definition R.h:48
char * mapset
Definition R.h:72
RASTER_MAP_TYPE map_type
Definition R.h:67
int open_mode
Definition R.h:49
int nbytes
Definition R.h:66
Definition path.h:15
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
#define access
Definition unistd.h:7
#define close
Definition unistd.h:8