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