ROPO
Loading...
Searching...
No Matches
rave_fmi_image.c
Go to the documentation of this file.
1/* --------------------------------------------------------------------
2Copyright (C) 2011 Swedish Meteorological and Hydrological Institute, SMHI,
3
4This file is part of bRopo.
5
6bRopo is free software: you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
10
11bRopo is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with bRopo. If not, see <http://www.gnu.org/licenses/>.
18------------------------------------------------------------------------*/
19
27#include "rave_fmi_image.h"
28#include "raveobject_hashtable.h"
29#include "rave_debug.h"
30#include "rave_alloc.h"
31#include <string.h>
32
37 RAVE_OBJECT_HEAD
39 RaveObjectHashTable_t* attrs;
40 double offset;
41 double gain;
42 double nodata;
43 double undetect;
44};
45
52static void RaveFmiImageInternal_resetImage(RaveFmiImage_t* img)
53{
54 if (img->image != NULL) {
55 if (img->image->heights != NULL) {
56 RAVE_FREE(img->image->heights);
57 }
58 if (img->image->array != NULL) {
59 RAVE_FREE(img->image->array);
60 }
61 if (img->image->original != NULL) {
62 RAVE_FREE(img->image->original);
63 }
64 RAVE_FREE(img->image);
65 }
66 img->image = NULL;
67}
68
72static int RaveFmiImage_constructor(RaveCoreObject* obj)
73{
74 RaveFmiImage_t* this = (RaveFmiImage_t*)obj;
75 this->offset = 0.0;
76 this->gain = 1.0;
77 this->nodata = 255.0;
78 this->undetect = 0.0;
79 this->image = new_image(1);
80 this->attrs = RAVE_OBJECT_NEW(&RaveObjectHashTable_TYPE);
81 if (this->image == NULL || this->attrs == NULL) {
82 goto error;
83 }
84
85 return 1;
86error:
87 RaveFmiImageInternal_resetImage(this);
88 RAVE_OBJECT_RELEASE(this->attrs);
89 return 0;
90}
91
95static void RaveFmiImage_destructor(RaveCoreObject* obj)
96{
97 RaveFmiImage_t* src = (RaveFmiImage_t*)obj;
98 RaveFmiImageInternal_resetImage(src);
99 RAVE_OBJECT_RELEASE(src->attrs);
100}
101
108static int RaveFmiImage_copyconstructor(RaveCoreObject* obj, RaveCoreObject* srcobj)
109{
110 RaveFmiImage_t* this = (RaveFmiImage_t*)obj;
111 RaveFmiImage_t* src = (RaveFmiImage_t*)srcobj;
112 this->offset = src->offset;
113 this->gain = src->gain;
114 this->nodata = src->nodata;
115 this->undetect = src->undetect;
116 this->image = new_image(1);
117 this->attrs = RAVE_OBJECT_CLONE(src->attrs);
118 if (this->image == NULL || this->attrs == NULL) {
119 goto error;
120 }
121 canonize_image(src->image, this->image);
122 return 1;
123error:
124 RaveFmiImageInternal_resetImage(this);
125 RAVE_OBJECT_RELEASE(this->attrs);
126 return 0;
127}
128
136static int RaveFmiImageInternal_scanToFmiImage(PolarScan_t* scan, const char* quantity, RaveFmiImage_t* raveimg)
137{
138 int i = 0, j = 0;
139 int result = 0;
140 double gain, offset;
141 PolarScanParam_t* param = NULL;
142 FmiImage* image = NULL;
143
144 RAVE_ASSERT((scan != NULL), "scan == NULL");
145 RAVE_ASSERT((raveimg != NULL), "image == NULL");
146
147 image = RaveFmiImage_getImage(raveimg);
148 reset_image(image);
149 image->width=PolarScan_getNbins(scan);
150 image->height=PolarScan_getNrays(scan);
151 image->bin_depth=PolarScan_getRscale(scan);
152 image->elevation_angle=PolarScan_getElangle(scan) * 180.0 / M_PI; /* elangles in degrees for ropo */
153 image->max_value=255;
154 image->channels=1;
155 initialize_image(image);
156
157 if (quantity == NULL) {
158 param = PolarScan_getParameter(scan, "DBZH");
159 } else {
160 param = PolarScan_getParameter(scan, quantity);
161 }
162
163 if (param == NULL) {
164 RAVE_WARNING1("Failed to extract parameter %s from scan", quantity);
165 goto done;
166 }
167
168 gain = PolarScanParam_getGain(param);
169 offset = PolarScanParam_getOffset(param);
170
171 RaveFmiImage_setGain(raveimg, PolarScanParam_getGain(param));
172 RaveFmiImage_setOffset(raveimg, PolarScanParam_getOffset(param));
173 RaveFmiImage_setNodata(raveimg, PolarScanParam_getNodata(param));
174 RaveFmiImage_setUndetect(raveimg, PolarScanParam_getUndetect(param));
175
176 RaveFmiImage_setOriginalGain(raveimg, PolarScanParam_getGain(param));
177 RaveFmiImage_setOriginalOffset(raveimg, PolarScanParam_getOffset(param));
178 RaveFmiImage_setOriginalNodata(raveimg, PolarScanParam_getNodata(param));
179 RaveFmiImage_setOriginalUndetect(raveimg, PolarScanParam_getUndetect(param));
180
181 image->original_type = PolarScanParam_getDataType(param);
182
183 if (image->original_type != RaveDataType_CHAR && image->original_type != RaveDataType_UCHAR) {
184 /* adjust nodata/undetect/gain/offset to be in range that is used when changing from >= short type into char type */
185 RaveFmiImage_setGain(raveimg, 0.5);
186 RaveFmiImage_setOffset(raveimg, -32.0);
187 RaveFmiImage_setNodata(raveimg, 255);
188 RaveFmiImage_setUndetect(raveimg, 0);
189 }
190
191 for (j = 0; j < image->height; j++) {
192 for (i = 0; i < image->width; i++) {
193 double value = 0.0, bvalue = 0.0;;
194 if (image->original_type == RaveDataType_CHAR || image->original_type == RaveDataType_UCHAR) {
195 PolarScanParam_getValue(param, i, j, &value);
196 bvalue = value;
197 } else {
198 /* This is slightly dangerous since there might actually be data that is 0 but hopefully it's not going to be an issue since we create a new range that is used in the array used for the bropo calculations */
199 RaveValueType t = PolarScanParam_getValue(param, i, j, &value);
200 if (t == RaveValueType_UNDETECT) {
201 bvalue = 0;
202 } else if (t == RaveValueType_NODATA) {
203 bvalue = 255;
204 } else {
205 bvalue = ((value*gain + offset) - (-32.0))/0.5;
206 }
207 }
208 put_pixel(image, i, j, 0, (Byte)(bvalue)); // why + 0.5 ?
209 put_pixel_orig(image, i, j, 0, value);
210 }
211 }
212
213 result = 1;
214done:
215 RAVE_OBJECT_RELEASE(param);
216 return result;
217}
218
225static int RaveFmiImageInternal_fieldToFmiImage(RaveField_t* field, RaveFmiImage_t* raveimg)
226{
227 int i = 0, j = 0;
228 int result = 0;
229 double nodata=255.0, undetect=0.0, gain=1.0, offset=0.0;
230 RaveAttribute_t* attr = NULL;
231 FmiImage* image = NULL;
232
233 RAVE_ASSERT((field != NULL), "field == NULL");
234 RAVE_ASSERT((raveimg != NULL), "raveimg == NULL");
235
236 image = RaveFmiImage_getImage(raveimg);
237 reset_image(image);
238 image->width=RaveField_getXsize(field);
239 image->height=RaveField_getYsize(field);
240 image->channels=1;
241 initialize_image(image);
242
243 attr = RaveField_getAttribute(field, "what/gain");
244 if (attr != NULL) {
245 RaveAttribute_getDouble(attr, &gain);
246 }
247 RAVE_OBJECT_RELEASE(attr);
248 attr = RaveField_getAttribute(field, "what/offset");
249 if (attr != NULL) {
250 RaveAttribute_getDouble(attr, &offset);
251 }
252 RAVE_OBJECT_RELEASE(attr);
253 attr = RaveField_getAttribute(field, "what/nodata");
254 if (attr != NULL) {
255 RaveAttribute_getDouble(attr, &nodata);
256 }
257 RAVE_OBJECT_RELEASE(attr);
258 attr = RaveField_getAttribute(field, "what/undetect");
259 if (attr != NULL) {
260 RaveAttribute_getDouble(attr, &undetect);
261 }
262 RAVE_OBJECT_RELEASE(attr);
263
264 image->original_type = RaveField_getDataType(field);
265
266 RaveFmiImage_setGain(raveimg, gain);
267 RaveFmiImage_setOffset(raveimg, offset);
268 RaveFmiImage_setNodata(raveimg, nodata);
269 RaveFmiImage_setUndetect(raveimg, undetect);
270
271 RaveFmiImage_setOriginalGain(raveimg, gain);
272 RaveFmiImage_setOriginalOffset(raveimg, offset);
273 RaveFmiImage_setOriginalNodata(raveimg, nodata);
274 RaveFmiImage_setOriginalUndetect(raveimg, undetect);
275
276 if (image->original_type != RaveDataType_CHAR && image->original_type != RaveDataType_UCHAR) {
277 /* adjust nodata/undetect/gain/offset to be in other range */
278 RaveFmiImage_setGain(raveimg, 0.5);
279 RaveFmiImage_setOffset(raveimg, -32.0);
280 RaveFmiImage_setNodata(raveimg, 255);
281 RaveFmiImage_setUndetect(raveimg, 0);
282 }
283
284 for (j = 0; j < image->height; j++) {
285 for (i = 0; i < image->width; i++) {
286 double value = 0.0, bvalue = 0.0;;
287
288 if (image->original_type == RaveDataType_CHAR || image->original_type == RaveDataType_UCHAR) {
289 RaveField_getValue(field, i, j, &value);
290 bvalue = value;
291 } else {
292 /* This is slightly dangerous since there might actually be data that is 0 but hopefully it's not going to be an issue since we create a new range that is used in the array used for the bropo calculations */
293 RaveField_getValue(field, i, j, &value);
294 if (value == undetect) {
295 bvalue = 0;
296 } else if (value == nodata) {
297 bvalue = 255;
298 } else {
299 bvalue = ((value*gain + offset) - (-32.0))/0.5;
300 }
301 }
302
303 put_pixel(image, i, j, 0, (Byte)(bvalue)); // why + 0.5 ?
304 put_pixel_orig(image, i, j, 0, value);
305 }
306 }
307
308 result = 1;
309 return result;
310}
311
318static PolarScan_t* RaveFmiImageInternal_fmiImageToScan(RaveFmiImage_t* self, const char* quantity, int datatype)
319{
320 PolarScan_t* scan = NULL;
321 PolarScan_t* result = NULL;
322 PolarScanParam_t* param = NULL;
323 int ray = 0, bin = 0;
324 FmiImage* image = NULL;
325
326 RAVE_ASSERT((self != NULL), "self == NULL");
327
328 image = RaveFmiImage_getImage(self);
329
330 scan = RAVE_OBJECT_NEW(&PolarScan_TYPE);
331 param = RAVE_OBJECT_NEW(&PolarScanParam_TYPE);
332 if (scan == NULL || param == NULL) {
333 RAVE_CRITICAL0("Failed to allocate memory for polar scan");
334 goto done;
335 }
336
337 if (datatype != 2 && (image->original_type == RaveDataType_CHAR || image->original_type == RaveDataType_UCHAR || datatype == 1)) {
338 PolarScanParam_setGain(param, self->gain);
339 PolarScanParam_setOffset(param, self->offset);
340 PolarScanParam_setNodata(param, self->nodata);
341 PolarScanParam_setUndetect(param, self->undetect);
342 } else {
343 if (datatype == 2) {
344 PolarScanParam_setGain(param, 0.5);
345 PolarScanParam_setOffset(param, -32.0);
346 PolarScanParam_setNodata(param, 255.0);
347 PolarScanParam_setUndetect(param, 0.0);
348 } else {
349 PolarScanParam_setGain(param, RaveFmiImage_getOriginalGain(self));
350 PolarScanParam_setOffset(param, RaveFmiImage_getOriginalOffset(self));
351 PolarScanParam_setNodata(param, RaveFmiImage_getOriginalNodata(self));
352 PolarScanParam_setUndetect(param, RaveFmiImage_getOriginalUndetect(self));
353 }
354 }
355
356 if (quantity != NULL) {
357 PolarScanParam_setQuantity(param, quantity);
358 } else {
359 PolarScanParam_setQuantity(param, "DBZH");
360 }
361
362 if (datatype == 0) {
363 if (!PolarScanParam_createData(param, image->width, image->height, image->original_type)) {
364 RAVE_CRITICAL0("Failed to allocate memory for data");
365 goto done;
366 }
367 } else {
368 if (!PolarScanParam_createData(param, image->width, image->height, RaveDataType_UCHAR)) {
369 RAVE_CRITICAL0("Failed to allocate memory for data");
370 goto done;
371 }
372 }
373
374 for (ray = 0; ray < image->height; ray++) {
375 for (bin = 0; bin < image->width; bin++) {
376 if (datatype != 2 && (image->original_type == RaveDataType_CHAR || image->original_type == RaveDataType_UCHAR || datatype == 1)) {
377 PolarScanParam_setValue(param, bin, ray, (double)get_pixel(image, bin, ray, 0));
378 } else {
379 double v = (double)get_pixel_orig(image, bin, ray, 0);
380 if (datatype == 2) {
381 if (v == image->original_nodata) {
382 v = 255;
383 } else if (v == image->original_undetect) {
384 v = 0;
385 } else {
386 v = v*image->original_gain + v*image->original_offset;
387 v = (v - (-32.0))/0.5;
388 }
389 }
390 PolarScanParam_setValue(param, bin, ray, v);
391 }
392 }
393 }
394 if (!PolarScan_addParameter(scan, param)) {
395 RAVE_CRITICAL0("Failed to add parameter to scan");
396 goto done;
397 }
398 PolarScan_setRscale(scan, image->bin_depth);
399 PolarScan_setElangle(scan, image->elevation_angle * M_PI / 180.0);
400 PolarScan_setRstart(scan, 0.0);
401
402 result = RAVE_OBJECT_COPY(scan);
403done:
404 RAVE_OBJECT_RELEASE(scan);
405 RAVE_OBJECT_RELEASE(param);
406 return result;
407}
408
415static RaveField_t* RaveFmiImageInternal_fmiImageToField(FmiImage* image, int datatype)
416{
417 RaveField_t* field = NULL;
418 RaveField_t* result = NULL;
419 int ray = 0, bin = 0;
420 RAVE_ASSERT((image != NULL), "image == NULL");
421
422 field = RAVE_OBJECT_NEW(&RaveField_TYPE);
423 if (field == NULL) {
424 RAVE_CRITICAL0("Failed to allocate memory for field");
425 goto done;
426 }
427
428 if (datatype == 0) {
429 if (!RaveField_createData(field, image->width, image->height, image->original_type)) {
430 RAVE_CRITICAL0("Failed to allocate memory for data");
431 goto done;
432 }
433 } else {
434 if (!RaveField_createData(field, image->width, image->height, RaveDataType_UCHAR)) {
435 RAVE_CRITICAL0("Failed to allocate memory for data");
436 goto done;
437 }
438 }
439
440 for (ray = 0; ray < image->height; ray++) {
441 for (bin = 0; bin < image->width; bin++) {
442 if (datatype != 2 && (image->original_type == RaveDataType_CHAR || image->original_type == RaveDataType_UCHAR || datatype == 1)) {
443 RaveField_setValue(field, bin, ray, (double)get_pixel(image, bin, ray, 0));
444 } else {
445 RaveField_setValue(field, bin, ray, (double)get_pixel_orig(image, bin, ray, 0));
446 }
447 }
448 }
449
450 result = RAVE_OBJECT_COPY(field);
451done:
452 RAVE_OBJECT_RELEASE(field);
453 return result;
454}
455
459int RaveFmiImage_initialize(RaveFmiImage_t* self, int width, int height)
460{
461 int result = 0;
462 RAVE_ASSERT((self != NULL), "self == NULL");
463 if (width <= 0 || height <= 0) {
464 RAVE_ERROR0("You can not initialize a fmi image with width or height = 0");
465 } else {
466 FmiImage* images = new_image(1);
467 if (images != NULL) {
468 RaveFmiImageInternal_resetImage(self);
469 self->image = images;
470 self->image->width = width;
471 self->image->height = height;
472 self->image->channels = 1;
473 initialize_image(self->image);
474 result = 1;
475 }
476 }
477 return result;
478}
479
480void RaveFmiImage_fill(RaveFmiImage_t* self, unsigned char v)
481{
482 RAVE_ASSERT((self != NULL), "self == NULL");
483 if (self->image != NULL) {
484 fill_image(self->image, (Byte)v);
485 if (self->image->original != NULL) {
486 int i;
487 for (i = 0; i < self->image->volume; i++) {
488 self->image->original[i] = (double)v;
489 }
490 }
491 }
492}
493
495{
496 RAVE_ASSERT((self != NULL), "self == NULL");
497 if (self->image != NULL) {
498 if (self->image->original != NULL) {
499 int i;
500 int nv = self->image->width*self->image->height*self->image->channels;
501 for (i = 0; i < nv; i++) {
502 self->image->original[i] = (double)v;
503 }
504 }
505 }
506}
507
509{
510 RAVE_ASSERT((self != NULL), "self == NULL");
511 return self->image;
512}
513
514PolarScan_t* RaveFmiImage_toPolarScan(RaveFmiImage_t* self, const char* quantity, int datatype)
515{
516 PolarScan_t* result = NULL;
517 PolarScan_t* scan = NULL;
518 RaveObjectList_t* attributes = NULL;
519
520 int i = 0;
521 int nrAttrs = 0;
522
523 RAVE_ASSERT((self != NULL), "self == NULL");
524
525 scan = RaveFmiImageInternal_fmiImageToScan(self, quantity, datatype);
526 if (scan == NULL) {
527 RAVE_CRITICAL0("Failed to convert image to scan");
528 goto done;
529 }
530
531 attributes = RaveObjectHashTable_values(self->attrs);
532 if (attributes == NULL) {
533 RAVE_CRITICAL0("Failed to get attributes");
534 goto done;
535 }
536 nrAttrs = RaveObjectList_size(attributes);
537 for (i = 0; i < nrAttrs; i++) {
538 RaveAttribute_t* attr = (RaveAttribute_t*)RaveObjectList_get(attributes, i);
539 PolarScan_addAttribute(scan, attr);
540 RAVE_OBJECT_RELEASE(attr);
541 }
542
543 result = RAVE_OBJECT_COPY(scan);
544done:
545 RAVE_OBJECT_RELEASE(attributes);
546 RAVE_OBJECT_RELEASE(scan);
547 return result;
548}
549
550RaveField_t* RaveFmiImage_toRaveField(RaveFmiImage_t* self, int datatype)
551{
552 RaveField_t* result = NULL;
553 RaveField_t* field = NULL;
554 RaveObjectList_t* attributes = NULL;
555
556 int i = 0;
557 int nrAttrs = 0;
558
559 RAVE_ASSERT((self != NULL), "self == NULL");
560
561 field = RaveFmiImageInternal_fmiImageToField(&self->image[0], datatype);
562 if (field == NULL) {
563 RAVE_CRITICAL0("Failed to convert image to field");
564 goto done;
565 }
566
567 attributes = RaveObjectHashTable_values(self->attrs);
568 if (attributes == NULL) {
569 RAVE_CRITICAL0("Failed to get attributes");
570 goto done;
571 }
572
573 nrAttrs = RaveObjectList_size(attributes);
574 for (i = 0; i < nrAttrs; i++) {
575 RaveAttribute_t* attr = (RaveAttribute_t*)RaveObjectList_get(attributes, i);
576 RaveField_addAttribute(field, attr);
577 RAVE_OBJECT_RELEASE(attr);
578 }
579
580 result = RAVE_OBJECT_COPY(field);
581done:
582 RAVE_OBJECT_RELEASE(attributes);
583 RAVE_OBJECT_RELEASE(field);
584 return result;
585}
586
587int RaveFmiImage_addAttribute(RaveFmiImage_t* self, RaveAttribute_t* attribute)
588{
589 char* aname = NULL;
590 char* gname = NULL;
591 const char* name = NULL;
592 int result = 0;
593
594 RAVE_ASSERT((self != NULL), "self == NULL");
595
596 name = RaveAttribute_getName(attribute);
597 if (!RaveAttributeHelp_extractGroupAndName(name, &gname, &aname)) {
598 RAVE_ERROR1("Failed to extract group and name from %s", name);
599 goto done;
600 }
601
602 if ((strcasecmp("how", gname)==0 ||
603 strcasecmp("what", gname)==0 ||
604 strcasecmp("where", gname)==0) &&
605 strchr(aname, '/') == NULL) {
606 result = RaveObjectHashTable_put(self->attrs, name, (RaveCoreObject*)attribute);
607 }
608
609done:
610 RAVE_FREE(gname);
611 RAVE_FREE(aname);
612 return result;
613}
614
615RaveAttribute_t* RaveFmiImage_getAttribute(RaveFmiImage_t* self, const char* name)
616{
617 RAVE_ASSERT((self != NULL), "self == NULL");
618 if (name == NULL) {
619 RAVE_ERROR0("Trying to get an attribute with NULL name");
620 return NULL;
621 }
622 return (RaveAttribute_t*)RaveObjectHashTable_get(self->attrs, name);
623}
624
626{
627 RAVE_ASSERT((self != NULL), "self == NULL");
628 return RaveObjectHashTable_keys(self->attrs);
629}
630
631void RaveFmiImage_setGain(RaveFmiImage_t* self, double gain)
632{
633 RAVE_ASSERT((self != NULL), "self == NULL");
634 self->gain = gain;
635}
636
638{
639 RAVE_ASSERT((self != NULL), "self == NULL");
640 return self->gain;
641}
642
643void RaveFmiImage_setOffset(RaveFmiImage_t* self, double offset)
644{
645 RAVE_ASSERT((self != NULL), "self == NULL");
646 self->offset = offset;
647}
648
650{
651 RAVE_ASSERT((self != NULL), "self == NULL");
652 return self->offset;
653}
654
656{
657 RAVE_ASSERT((self != NULL), "self == NULL");
658 self->nodata = v;
659}
660
662{
663 RAVE_ASSERT((self != NULL), "self == NULL");
664 return self->nodata;
665}
666
668{
669 RAVE_ASSERT((self != NULL), "self == NULL");
670 self->undetect = v;
671}
672
674{
675 RAVE_ASSERT((self != NULL), "self == NULL");
676 return self->undetect;
677}
678
680{
681 RAVE_ASSERT((self != NULL), "self == NULL");
682 self->image->original_gain = gain;
683}
684
686{
687 RAVE_ASSERT((self != NULL), "self == NULL");
688 return self->image->original_gain;
689}
690
692{
693 RAVE_ASSERT((self != NULL), "self == NULL");
694 self->image->original_offset = offset;
695}
696
698{
699 RAVE_ASSERT((self != NULL), "self == NULL");
700 return self->image->original_offset;
701}
702
704{
705 RAVE_ASSERT((self != NULL), "self == NULL");
706 self->image->original_nodata = v;
707}
708
710{
711 RAVE_ASSERT((self != NULL), "self == NULL");
712 return self->image->original_nodata;
713}
714
716{
717 RAVE_ASSERT((self != NULL), "self == NULL");
718 self->image->original_undetect = v;
719}
720
722{
723 RAVE_ASSERT((self != NULL), "self == NULL");
724 return self->image->original_undetect;
725}
726
727RaveFmiImage_t* RaveFmiImage_new(int width, int height)
728{
729 RaveFmiImage_t* result = RAVE_OBJECT_NEW(&RaveFmiImage_TYPE);
730 if (result != NULL) {
731 if (!RaveFmiImage_initialize(result, width, height)) {
732 RAVE_OBJECT_RELEASE(result);
733 }
734 }
735 return result;
736}
737
738RaveFmiImage_t* RaveFmiImage_fromPolarVolume(PolarVolume_t* volume, int scannr, const char* quantity)
739{
740 int nrScans = 0;
741 PolarScan_t* scan = NULL;
742 RaveFmiImage_t* image = NULL;
743 RaveFmiImage_t* result = NULL;
744
745 RAVE_ASSERT((volume != NULL), "volume == NULL");
746
747 nrScans = PolarVolume_getNumberOfScans(volume);
748
749 if (scannr < 0 || scannr >= nrScans) {
750 RAVE_ERROR1("There is no scan at index %d for this volume.", scannr);
751 goto done;
752 }
753
754 image = RAVE_OBJECT_NEW(&RaveFmiImage_TYPE);
755 if (image == NULL) {
756 RAVE_CRITICAL0("Failed to create fmi image");
757 goto done;
758 }
759
760 scan = PolarVolume_getScan(volume, scannr);
761 if (scan == NULL) {
762 RAVE_ERROR1("Could not read scan at index %d.", scannr);
763 goto done;
764 }
765 if (quantity == NULL || PolarScan_hasParameter(scan, quantity)) {
766 if (!RaveFmiImageInternal_scanToFmiImage(scan, quantity, image)) {
767 RAVE_ERROR0("Failed to convert scan to fmi image");
768 goto done;
769 }
770 }
771
772 result = RAVE_OBJECT_COPY(image);
773done:
774 RAVE_OBJECT_RELEASE(scan);
775 RAVE_OBJECT_RELEASE(image);
776 return result;
777}
778
779RaveFmiImage_t* RaveFmiImage_fromPolarScan(PolarScan_t* scan, const char* quantity)
780{
781 RaveFmiImage_t* image = NULL;
782 RaveFmiImage_t* result = NULL;
783
784 RAVE_ASSERT((scan != NULL), "scan == NULL");
785
786 image = RAVE_OBJECT_NEW(&RaveFmiImage_TYPE);
787 if (image == NULL) {
788 RAVE_CRITICAL0("Failed to create fmi image");
789 goto done;
790 }
791
792 if (quantity == NULL || PolarScan_hasParameter(scan, quantity)) {
793 if (!RaveFmiImageInternal_scanToFmiImage(scan, quantity, image)) {
794 RAVE_ERROR0("Failed to convert scan to fmi image");
795 goto done;
796 }
797 }
798
799 result = RAVE_OBJECT_COPY(image);
800done:
801 RAVE_OBJECT_RELEASE(image);
802 return result;
803}
804
806{
807 RaveFmiImage_t* image = NULL;
808 RaveFmiImage_t* result = NULL;
809
810 RAVE_ASSERT((field != NULL), "field == NULL");
811
812 image = RAVE_OBJECT_NEW(&RaveFmiImage_TYPE);
813 if (image == NULL) {
814 RAVE_CRITICAL0("Failed to create fmi image");
815 goto done;
816 }
817
818 if (!RaveFmiImageInternal_fieldToFmiImage(field, image)) {
819 RAVE_ERROR0("Failed to convert rave field to fmi image");
820 goto done;
821 }
822
823 result = RAVE_OBJECT_COPY(image);
824done:
825 RAVE_OBJECT_RELEASE(image);
826 return result;
827}
828
829RaveFmiImage_t* RaveFmiImage_fromRave(RaveCoreObject* object, const char* quantity)
830{
831 RAVE_ASSERT((object != NULL), "object == NULL");
832 if (RAVE_OBJECT_CHECK_TYPE(object, &PolarVolume_TYPE)) {
833 return RaveFmiImage_fromPolarVolume((PolarVolume_t*)object, 0, quantity);
834 } else if (RAVE_OBJECT_CHECK_TYPE(object, &PolarScan_TYPE)) {
835 return RaveFmiImage_fromPolarScan((PolarScan_t*)object, quantity);
836 } else if (RAVE_OBJECT_CHECK_TYPE(object, &RaveField_TYPE)) {
837 return RaveFmiImage_fromRaveField((RaveField_t*)object);
838 } else {
839 RAVE_ERROR1("RaveFmiImage_fromRave does not support %s", object->roh_type->name);
840 }
841 return NULL;
842}
843
845RaveCoreObjectType RaveFmiImage_TYPE = {
846 "RaveFmiImage",
847 sizeof(RaveFmiImage_t),
848 RaveFmiImage_constructor,
849 RaveFmiImage_destructor,
850 RaveFmiImage_copyconstructor /* No copy constructor */
851};
FmiImage * RaveFmiImage_getImage(RaveFmiImage_t *self)
RaveFmiImage_t * RaveFmiImage_new(int width, int height)
void RaveFmiImage_fill(RaveFmiImage_t *self, unsigned char v)
double RaveFmiImage_getOriginalUndetect(RaveFmiImage_t *self)
double RaveFmiImage_getOffset(RaveFmiImage_t *self)
int RaveFmiImage_addAttribute(RaveFmiImage_t *self, RaveAttribute_t *attribute)
RaveFmiImage_t * RaveFmiImage_fromRave(RaveCoreObject *object, const char *quantity)
RaveAttribute_t * RaveFmiImage_getAttribute(RaveFmiImage_t *self, const char *name)
void RaveFmiImage_setGain(RaveFmiImage_t *self, double gain)
void RaveFmiImage_setOriginalGain(RaveFmiImage_t *self, double gain)
void RaveFmiImage_setOriginalNodata(RaveFmiImage_t *self, double v)
RaveField_t * RaveFmiImage_toRaveField(RaveFmiImage_t *self, int datatype)
RaveCoreObjectType RaveFmiImage_TYPE
void RaveFmiImage_fillOriginal(RaveFmiImage_t *self, double v)
PolarScan_t * RaveFmiImage_toPolarScan(RaveFmiImage_t *self, const char *quantity, int datatype)
void RaveFmiImage_setOriginalUndetect(RaveFmiImage_t *self, double v)
void RaveFmiImage_setNodata(RaveFmiImage_t *self, double v)
double RaveFmiImage_getUndetect(RaveFmiImage_t *self)
double RaveFmiImage_getGain(RaveFmiImage_t *self)
RaveList_t * RaveFmiImage_getAttributeNames(RaveFmiImage_t *self)
double RaveFmiImage_getOriginalNodata(RaveFmiImage_t *self)
RaveFmiImage_t * RaveFmiImage_fromPolarVolume(PolarVolume_t *volume, int scannr, const char *quantity)
void RaveFmiImage_setOriginalOffset(RaveFmiImage_t *self, double offset)
int RaveFmiImage_initialize(RaveFmiImage_t *self, int width, int height)
double RaveFmiImage_getNodata(RaveFmiImage_t *self)
double RaveFmiImage_getOriginalGain(RaveFmiImage_t *self)
void RaveFmiImage_setUndetect(RaveFmiImage_t *self, double v)
RaveFmiImage_t * RaveFmiImage_fromRaveField(RaveField_t *field)
double RaveFmiImage_getOriginalOffset(RaveFmiImage_t *self)
RaveFmiImage_t * RaveFmiImage_fromPolarScan(PolarScan_t *scan, const char *quantity)
void RaveFmiImage_setOffset(RaveFmiImage_t *self, double offset)
struct _RaveFmiImage_t RaveFmiImage_t
RAVE_OBJECT_HEAD FmiImage * image
RaveObjectHashTable_t * attrs
double * original
Definition fmi_image.h:154