Added necessary objects for rave accessability
authorAnders Henja <anders@baltrad.eu>
Wed, 31 Aug 2011 13:11:01 +0000 (15:11 +0200)
committerAnders Henja <anders@baltrad.eu>
Wed, 31 Aug 2011 13:11:01 +0000 (15:11 +0200)
pyrack/Makefile
pyrack/pyfmiimage.c [new file with mode: 0644]
pyrack/pyfmiimage.h [new file with mode: 0644]
pyrack/pyropo.c [new file with mode: 0644]
rack/Makefile
rack/ropo/rave_fmi_image.c [new file with mode: 0644]
rack/ropo/rave_fmi_image.h [new file with mode: 0644]

index a9a7f85..0833d04 100644 (file)
@@ -62,11 +62,17 @@ LIBRARIES=-lhlhdf -lproj  $(EXPAT_LIBRARY) -lravetransform $(MAGICK_LIBRARIES) -
 # --------------------------------------------------------------------
 # Fixed definitions
 
-SOURCES= pyrack.c
-                               
-OBJECTS= $(SOURCES:.c=.o)
+RACK_SOURCE= pyrack.c
+RACK_OBJECTS= $(RACK_SOURCE:.c=.o)
+RACK_TARGET= _rack.so
 
-TARGET= _rack.so
+FMIIMAGE_SOURCE= pyfmiimage.c
+FMIIMAGE_OBJECTS= $(FMIIMAGE_SOURCE:.c=.o)
+FMIIMAGE_TARGET= _fmiimage.so
+
+ROPO_SOURCE= pyropo.c
+ROPO_OBJECTS= $(ROPO_SOURCE:.c=.o)
+ROPO_TARGET= _ropo.so
 
 MAKECDEPEND=$(CC) -MM $(CFLAGS) -MT '$(@D)/$(@F)' -o $(DF).d $<
 
@@ -81,15 +87,23 @@ $(DEPDIR):
 # And the rest of the make file targets
 #
 .PHONY=all
-all:           $(TARGET)
+all:           $(RACK_TARGET) $(FMIIMAGE_TARGET) $(ROPO_TARGET)
+
+$(RACK_TARGET): $(DEPDIR) $(RACK_OBJECTS) ../drain/libbdrain.so ../rack/libbrack.so
+       $(LDSHARED) -o $@ $(RACK_OBJECTS) $(LDFLAGS) $(LIBRARIES)
 
-$(TARGET): $(DEPDIR) $(OBJECTS) ../drain/libbdrain.so ../rack/libbrack.so
-       $(LDSHARED) -o $@ $(OBJECTS) $(LDFLAGS) $(LIBRARIES)
+$(FMIIMAGE_TARGET): $(DEPDIR) $(FMIIMAGE_OBJECTS) ../drain/libbdrain.so ../rack/libbrack.so
+       $(LDSHARED) -o $@ $(FMIIMAGE_OBJECTS) $(LDFLAGS) $(LIBRARIES)
+       
+$(ROPO_TARGET): $(DEPDIR) $(ROPO_OBJECTS) ../drain/libbdrain.so ../rack/libbrack.so
+       $(LDSHARED) -o $@ $(ROPO_OBJECTS) $(LDFLAGS) $(LIBRARIES)
 
 .PHONY=install
 install:
        @mkdir --parents ${prefix}/pyrack/
-       @cp -v -u _rack.so ${prefix}/pyrack/
+       @cp -v -u $(RACK_TARGET) ${prefix}/pyrack/
+       @cp -v -u $(FMIIMAGE_TARGET) ${prefix}/pyrack/
+       @cp -v -u $(ROPO_TARGET) ${prefix}/pyrack/
        @echo "$(prefix)/pyrack" > "$(SITEPACK_PYTHON)/pyrack.pth"
 
 .PHONY=clean
@@ -99,7 +113,9 @@ clean:
 
 .PHONY=distclean                
 distclean:     clean
-       @\rm -f $(TARGET)
+       @\rm -f $(RACK_TARGET)
+       @\rm -f $(FMIIMAGE_TARGET)
+       @\rm -f $(ROPO_TARGET)
 
 # --------------------------------------------------------------------
 # Rules
diff --git a/pyrack/pyfmiimage.c b/pyrack/pyfmiimage.c
new file mode 100644 (file)
index 0000000..3c1614b
--- /dev/null
@@ -0,0 +1,308 @@
+/* --------------------------------------------------------------------
+Copyright (C) 2011 Swedish Meteorological and Hydrological Institute, SMHI,
+
+This file is part of bRack.
+
+bRack is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+bRack is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with bRack.  If not, see <http://www.gnu.org/licenses/>.
+------------------------------------------------------------------------*/
+/**
+ * Python version of the fmi image.
+ * @file
+ * @author Anders Henja (Swedish Meteorological and Hydrological Institute, SMHI)
+ * @date 2011-08-31
+ */
+#include "Python.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#define PYFMIIMAGE_MODULE   /**< to get correct part in pyfmiimage */
+#include "pyfmiimage.h"
+
+#include "pypolarvolume.h"
+#include "pyrave_debug.h"
+#include "rave_alloc.h"
+
+/**
+ * Debug this module
+ */
+PYRAVE_DEBUG_MODULE("_pyfmiimage");
+
+/**
+ * Sets a python exception and goto tag
+ */
+#define raiseException_gotoTag(tag, type, msg) \
+{PyErr_SetString(type, msg); goto tag;}
+
+/**
+ * Sets python exception and returns NULL
+ */
+#define raiseException_returnNULL(type, msg) \
+{PyErr_SetString(type, msg); return NULL;}
+
+/**
+ * Error object for reporting errors to the python interpreeter
+ */
+static PyObject *ErrorObject;
+
+/// --------------------------------------------------------------------
+/// FmiImage
+/// --------------------------------------------------------------------
+/*@{ FmiImage */
+/**
+ * Returns the native RaveFmiImage_t instance.
+ * @param[in] pyfmiimage - the python fmi image instance
+ * @returns the native fmi image instance.
+ */
+static RaveFmiImage_t*
+PyFmiImage_GetNative(PyFmiImage* pyfmiimage)
+{
+  RAVE_ASSERT((pyfmiimage != NULL), "pyfmiimage == NULL");
+  return RAVE_OBJECT_COPY(pyfmiimage->image);
+}
+
+/**
+ * Creates a python fmi image from a native fmi image or will create an
+ * initial native FmiImage if p is NULL.
+ * @param[in] p - the native fmi image (or NULL)
+ * @param[in] sweepCount - the number of sweeps to allocate (only used if p != NULL and > 0)
+ * @returns the python fmi image.
+ */
+static PyFmiImage*
+PyFmiImage_New(RaveFmiImage_t* p, int sweepCount)
+{
+  PyFmiImage* result = NULL;
+  RaveFmiImage_t* cp = NULL;
+
+  if (p == NULL) {
+    cp = RAVE_OBJECT_NEW(&RaveFmiImage_TYPE);
+    if (cp == NULL) {
+      RAVE_CRITICAL0("Failed to allocate memory for fmi image.");
+      raiseException_returnNULL(PyExc_MemoryError, "Failed to allocate memory for fmi image.");
+    }
+    if (sweepCount > 0) {
+      if (!RaveFmiImage_initialize(cp, sweepCount)) {
+        RAVE_CRITICAL0("Failed to initialize fmi image");
+        raiseException_gotoTag(done, PyExc_MemoryError, "Failed to initialize fmi image");
+      }
+    }
+  } else {
+    cp = RAVE_OBJECT_COPY(p);
+    result = RAVE_OBJECT_GETBINDING(p); // If p already have a binding, then this should only be increfed.
+    if (result != NULL) {
+      Py_INCREF(result);
+    }
+  }
+
+  if (result == NULL) {
+    result = PyObject_NEW(PyFmiImage, &PyFmiImage_Type);
+    if (result != NULL) {
+      PYRAVE_DEBUG_OBJECT_CREATED;
+      result->image = RAVE_OBJECT_COPY(cp);
+      RAVE_OBJECT_BIND(result->image, result);
+    } else {
+      RAVE_CRITICAL0("Failed to create PyFmiImage instance");
+      raiseException_gotoTag(done, PyExc_MemoryError, "Failed to allocate memory for fmi image.");
+    }
+  }
+
+done:
+  RAVE_OBJECT_RELEASE(cp);
+  return result;
+}
+
+/**
+ * Deallocates the fmi image
+ * @param[in] obj the object to deallocate.
+ */
+static void _pyfmiimage_dealloc(PyFmiImage* obj)
+{
+  /*Nothing yet*/
+  if (obj == NULL) {
+    return;
+  }
+  PYRAVE_DEBUG_OBJECT_DESTROYED;
+  RAVE_OBJECT_UNBIND(obj->image, obj);
+  RAVE_OBJECT_RELEASE(obj->image);
+  PyObject_Del(obj);
+}
+
+/**
+ * Creates a new instance of the fmi image
+ * @param[in] self this instance.
+ * @param[in] args arguments for creation (NOT USED).
+ * @return the object on success, otherwise NULL
+ */
+static PyObject* _pyfmiimage_new(PyObject* self, PyObject* args)
+{
+  int sweepCount = 0;
+  if (!PyArg_ParseTuple(args, "|i", &sweepCount)) {
+    return NULL;
+  }
+  return (PyObject*)PyFmiImage_New(NULL, sweepCount);
+}
+
+/*
+static PyObject* _pyfmiimage_fromRave(PyFmiImage* self, PyObject* args)
+{
+  return NULL;
+  PyObject* inptr = NULL;
+  PyPolarVolume* volume = NULL;
+  char* parameter = NULL;
+  int nrScans = 0;
+  int sweepCount = 0;
+  int i = 0;
+
+  if (!PyArg_ParseTuple(args, "Os", &inptr, &parameter)) {
+    return NULL;
+  }
+
+  if (!PyPolarVolume_Check(inptr)) {
+    raiseException_returnNULL(PyExc_TypeError,"fromRave only takes polar volumes");
+  }
+
+  volume = (PyPolarVolume)inptr;
+
+  PolarVolume_sortByElevations(volume->pvol, 1);
+
+  nrScans = PolarVolume_getNumberOfScans(volume->pvol);
+
+  for (i = 0; i < nrScans; i++) {
+    PolarScan_t* scan = NULL;
+    scan = PolarVolume_getScan(volume->pvol, i);
+    if (scan != NULL && PolarScan_hasParameter(scan, parameter)) {
+      sweepCount++;
+    }
+    RAVE_OBJECT_RELEASE(scan);
+  }
+}
+*/
+
+/*@} End Of FmiImage */
+
+/**
+ * All methods a fmi image can have
+ */
+static struct PyMethodDef _pyfmiimage_methods[] =
+{
+  /*{"longitude", NULL},
+  {"getDistance", (PyCFunction) _pypolarvolume_getDistance, 1},*/
+    /*
+  {"fromRave", (PyCFunction)_pyfmiimage_fromRave, 1},
+  {"toRave", (PyCFunction)_pyfmiimage_toRave, 1},
+  */
+  {NULL, NULL} /* sentinel */
+};
+
+/**
+ * Returns the specified attribute in the fmi image
+ */
+static PyObject* _pyfmiimage_getattr(PyFmiImage* self, char* name)
+{
+  PyObject* res = NULL;
+  res = Py_FindMethod(_pyfmiimage_methods, (PyObject*) self, name);
+  if (res)
+    return res;
+
+  PyErr_Clear();
+  PyErr_SetString(PyExc_AttributeError, name);
+  return NULL;
+}
+
+/**
+ * Returns the specified attribute in the polar volume
+ */
+static int _pyfmiimage_setattr(PyFmiImage* self, char* name, PyObject* val)
+{
+  int result = -1;
+  if (name == NULL) {
+    goto done;
+  }
+
+  raiseException_gotoTag(done, PyExc_AttributeError, name);
+
+  result = 0;
+done:
+  return result;
+}
+
+/*@} End of Fmi Image */
+
+/// --------------------------------------------------------------------
+/// Type definitions
+/// --------------------------------------------------------------------
+/*@{ Type definitions */
+PyTypeObject PyFmiImage_Type =
+{
+  PyObject_HEAD_INIT(NULL)0, /*ob_size*/
+  "FmiImageCore", /*tp_name*/
+  sizeof(PyFmiImage), /*tp_size*/
+  0, /*tp_itemsize*/
+  /* methods */
+  (destructor)_pyfmiimage_dealloc, /*tp_dealloc*/
+  0, /*tp_print*/
+  (getattrfunc)_pyfmiimage_getattr, /*tp_getattr*/
+  (setattrfunc)_pyfmiimage_setattr, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  0, /*tp_as_number */
+  0,
+  0, /*tp_as_mapping */
+  0 /*tp_hash*/
+};
+/*@} End of Type definitions */
+
+/// --------------------------------------------------------------------
+/// Module setup
+/// --------------------------------------------------------------------
+/*@{ Module setup */
+static PyMethodDef functions[] = {
+  {"new", (PyCFunction)_pyfmiimage_new, 1},
+  {NULL,NULL} /*Sentinel*/
+};
+
+/**
+ * Initializes polar volume.
+ */
+void init_fmiimage(void)
+{
+  PyObject *module=NULL,*dictionary=NULL;
+  static void *PyFmiImage_API[PyFmiImage_API_pointers];
+  PyObject *c_api_object = NULL;
+  PyFmiImage_Type.ob_type = &PyType_Type;
+
+  module = Py_InitModule("_fmiimage", functions);
+  if (module == NULL) {
+    return;
+  }
+  PyFmiImage_API[PyFmiImage_Type_NUM] = (void*)&PyFmiImage_Type;
+  PyFmiImage_API[PyFmiImage_GetNative_NUM] = (void *)PyFmiImage_GetNative;
+  PyFmiImage_API[PyFmiImage_New_NUM] = (void*)PyFmiImage_New;
+
+  c_api_object = PyCObject_FromVoidPtr((void *)PyFmiImage_API, NULL);
+
+  if (c_api_object != NULL) {
+    PyModule_AddObject(module, "_C_API", c_api_object);
+  }
+
+  dictionary = PyModule_GetDict(module);
+  ErrorObject = PyString_FromString("_fmiimage.error");
+  if (ErrorObject == NULL || PyDict_SetItemString(dictionary, "error", ErrorObject) != 0) {
+    Py_FatalError("Can't define _fmiimage.error");
+  }
+
+  import_pypolarvolume();
+  PYRAVE_DEBUG_INITIALIZE;
+}
+/*@} End of Module setup */
diff --git a/pyrack/pyfmiimage.h b/pyrack/pyfmiimage.h
new file mode 100644 (file)
index 0000000..b51bdeb
--- /dev/null
@@ -0,0 +1,119 @@
+/* --------------------------------------------------------------------
+Copyright (C) 2011 Swedish Meteorological and Hydrological Institute, SMHI,
+
+This file is part of bRack.
+
+bRack is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+bRack is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with bRack.  If not, see <http://www.gnu.org/licenses/>.
+------------------------------------------------------------------------*/
+/**
+ * Python version of the fmi image.
+ * @file
+ * @author Anders Henja (Swedish Meteorological and Hydrological Institute, SMHI)
+ * @date 2011-08-31
+ */
+#ifndef PYFMIIMAGE_H
+#define PYFMIIMAGE_H
+#include "rack/ropo/rave_fmi_image.h"
+
+/**
+ * The fmi image object
+ */
+typedef struct {
+   PyObject_HEAD /*Always have to be on top*/
+   RaveFmiImage_t* image;  /**< the fmi image */
+} PyFmiImage;
+
+#define PyFmiImage_Type_NUM 0                              /**< index of type */
+
+#define PyFmiImage_GetNative_NUM 1                         /**< index of GetNative*/
+#define PyFmiImage_GetNative_RETURN RaveFmiImage_t*         /**< return type for GetNative */
+#define PyFmiImage_GetNative_PROTO (PyFmiImage*)        /**< arguments for GetNative */
+
+#define PyFmiImage_New_NUM 2                               /**< index of New */
+#define PyFmiImage_New_RETURN PyFmiImage*                  /**< return type for New */
+#define PyFmiImage_New_PROTO (RaveFmiImage_t*, int)        /**< arguments for New */
+
+#define PyFmiImage_API_pointers 3                          /**< number of type and function pointers */
+
+#ifdef PYFMIIMAGE_MODULE
+/** Forward declaration of type */
+extern PyTypeObject PyFmiImage_Type;
+
+/** Checks if the object is a PyPolarVolume or not */
+#define PyFmiImage_Check(op) ((op)->ob_type == &PyFmiImage_Type)
+
+/** Forward declaration of PyFmiImage_GetNative */
+static PyFmiImage_GetNative_RETURN PyFmiImage_GetNative PyFmiImage_GetNative_PROTO;
+
+/** Forward declaration of PyFmiImage_New */
+static PyFmiImage_New_RETURN PyFmiImage_New PyFmiImage_New_PROTO;
+
+#else
+/** Pointers to types and functions */
+static void **PyFmiImage_API;
+
+/**
+ * Returns a pointer to the internal fmi image, remember to release the reference
+ * when done with the object. (RAVE_OBJECT_RELEASE).
+ */
+#define PyFmiImage_GetNative \
+  (*(PyFmiImage_GetNative_RETURN (*)PyFmiImage_GetNative_PROTO) PyFmiImage_API[PyFmiImage_GetNative_NUM])
+
+/**
+ * Creates a new fmi image instance. Release this object with Py_DECREF. If a FmiImage_t instance is
+ * provided and this instance already is bound to a python instance, this instance will be increfed and
+ * returned.
+ * @param[in] image - the RaveFmiImage_t intance.
+ * @param[in] sweepCount - the sweep count, only used if image == NULL and sweepCount > 0
+ * @returns the PyFmiImage instance.
+ */
+#define PyFmiImage_New \
+  (*(PyFmiImage_New_RETURN (*)PyFmiImage_New_PROTO) PyFmiImage_API[PyFmiImage_New_NUM])
+
+/**
+ * Checks if the object is a python fmi image.
+ */
+#define PyFmiImage_Check(op) \
+   ((op)->ob_type == (PyTypeObject *)PyFmiImage_API[PyFmiImage_Type_NUM])
+
+/**
+ * Imports the PyFmiImage module (like import _fmiimage in python).
+ */
+static int
+import_fmiimage(void)
+{
+  PyObject *module;
+  PyObject *c_api_object;
+
+  module = PyImport_ImportModule("_fmiimage");
+  if (module == NULL) {
+    return -1;
+  }
+
+  c_api_object = PyObject_GetAttrString(module, "_C_API");
+  if (c_api_object == NULL) {
+    Py_DECREF(module);
+    return -1;
+  }
+  if (PyCObject_Check(c_api_object)) {
+    PyFmiImage_API = (void **)PyCObject_AsVoidPtr(c_api_object);
+  }
+  Py_DECREF(c_api_object);
+  Py_DECREF(module);
+  return 0;
+}
+
+#endif
+
+#endif /* PYFMIIMAGE_H */
diff --git a/pyrack/pyropo.c b/pyrack/pyropo.c
new file mode 100644 (file)
index 0000000..c50eb5c
--- /dev/null
@@ -0,0 +1,92 @@
+/* --------------------------------------------------------------------
+Copyright (C) 2011 Swedish Meteorological and Hydrological Institute, SMHI,
+
+This file is part of bRack.
+
+bRack is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+bRack is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with bRack.  If not, see <http://www.gnu.org/licenses/>.
+------------------------------------------------------------------------*/
+/**
+ * Python API to the ropo functions
+ * @file
+ * @author Anders Henja (Swedish Meteorological and Hydrological Institute, SMHI)
+ * @date 2011-08-31
+ */
+#include "Python.h"
+#include <limits.h>
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "pyrave_debug.h"
+
+
+/**
+ * Debug this module
+ */
+PYRAVE_DEBUG_MODULE("_pyropo");
+
+/**
+ * Sets a python exception and goto tag
+ */
+#define raiseException_gotoTag(tag, type, msg) \
+{PyErr_SetString(type, msg); goto tag;}
+
+/**
+ * Sets a python exception and return NULL
+ */
+#define raiseException_returnNULL(type, msg) \
+{PyErr_SetString(type, msg); return NULL;}
+
+/**
+ * Error object for reporting errors to the python interpreeter
+ */
+static PyObject *ErrorObject;
+
+/*@{ Functions */
+
+/*@} End of Functions */
+
+/*@{ Module setup */
+static PyMethodDef functions[] = {
+  /*{"rave2fmiimage", (PyCFunction)_pyropo_rave2fmiimage, 1},
+  {"fmiimage2rave", (PyCFunction)_pyropo_fmiimage2rave, 1},*/
+  {NULL,NULL} /*Sentinel*/
+};
+
+PyMODINIT_FUNC
+init_ropo(void)
+{
+  PyObject *module=NULL,*dictionary=NULL;
+
+  module = Py_InitModule("_ropo", functions);
+  if (module == NULL) {
+    return;
+  }
+
+  dictionary = PyModule_GetDict(module);
+  ErrorObject = PyString_FromString("_ropo.error");
+
+  if (ErrorObject == NULL || PyDict_SetItemString(dictionary, "error", ErrorObject) != 0) {
+    Py_FatalError("Can't define _ropo.error");
+  }
+/*
+  import_pypolarvolume();
+  import_pypolarscan();
+  import_pycartesian();
+  import_pyarea();
+  import_array();
+*/
+  PYRAVE_DEBUG_INITIALIZE;
+}
+/*@} End of Module setup */
index 804f65a..f0bddce 100644 (file)
@@ -73,7 +73,7 @@ RACK_SOURCES= rack/Rack.cpp rack/RackIf.cpp
 ROPO_CSOURCES= ropo/fmi_image_arith.c ropo/fmi_image.c ropo/fmi_image_filter.c ropo/fmi_image_filter_line.c \
                                ropo/fmi_image_filter_morpho.c ropo/fmi_image_filter_speck.c ropo/fmi_image_filter_texture.c \
                                ropo/fmi_image_histogram.c ropo/fmi_image_restore.c ropo/fmi_meteosat.c ropo/fmi_radar_image.c \
-                               ropo/fmi_sunpos.c ropo/fmi_util.c ropo/ropo_hdf.c
+                               ropo/fmi_sunpos.c ropo/fmi_util.c ropo/ropo_hdf.c ropo/rave_fmi_image.c
                                
 ROPO_CPPSOURCES= ropo/convertImage.cpp ropo/Ropo.cpp
 
diff --git a/rack/ropo/rave_fmi_image.c b/rack/ropo/rave_fmi_image.c
new file mode 100644 (file)
index 0000000..2349256
--- /dev/null
@@ -0,0 +1,243 @@
+/* --------------------------------------------------------------------
+Copyright (C) 2011 Swedish Meteorological and Hydrological Institute, SMHI,
+
+This file is part of bRack.
+
+bRack is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+bRack is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with bRack.  If not, see <http://www.gnu.org/licenses/>.
+------------------------------------------------------------------------*/
+
+/**
+ * rave object wrapper for the fmi_image.
+ * This object supports \ref #RAVE_OBJECT_CLONE.
+ * @file
+ * @author Anders Henja (Swedish Meteorological and Hydrological Institute, SMHI)
+ * @date 2011-08-31
+ */
+#include "rack/ropo/rave_fmi_image.h"
+#include "rave_debug.h"
+#include "rave_alloc.h"
+
+/**
+ * Represents a rave fmi image
+ */
+struct _RaveFmiImage_t {
+  RAVE_OBJECT_HEAD /** Always on top */
+  FmiImage* image; /**< the fmi image */
+  int sweepCount;  /**< the sweep count */
+};
+
+/*@{ Private functions */
+/**
+ * Constructor
+ */
+static int RaveFmiImage_constructor(RaveCoreObject* obj)
+{
+  RaveFmiImage_t* this = (RaveFmiImage_t*)obj;
+  this->image = NULL;
+  this->sweepCount = 0;
+  return 1;
+}
+
+static void RaveFmiImageInternal_resetImage(RaveFmiImage_t* img)
+{
+  int i = 0;
+  if (img->image != NULL) {
+    for (i = 0; i < img->sweepCount; i++) {
+      if (img->image[i].heights != NULL) {
+        free(img->image[i].heights);
+      }
+      if (img->image[i].array != NULL) {
+        free(img->image[i].array);
+      }
+    }
+    free(img->image);
+  }
+  img->image = NULL;
+  img->sweepCount = 0;
+}
+
+/**
+ * Destructor
+ */
+static void RaveFmiImage_destructor(RaveCoreObject* obj)
+{
+  RaveFmiImage_t* src = (RaveFmiImage_t*)obj;
+  RaveFmiImageInternal_resetImage(src);
+}
+
+/**
+ * Counts the number of sweeps that a volume would result in.
+ * @param[in] volume - the rave volume
+ * @param[in] quantity - the quantity of the parameter (if NULL, default parameter will be used)
+ */
+static int RaveFmiImageInternal_getSweepCount(PolarVolume_t* volume, const char* quantity)
+{
+  int sweepCount = 0;
+  int i = 0;
+  int nrScans = 0;
+  RAVE_ASSERT((volume != NULL), "volume == NULL");
+
+  /**
+   * Count number of scans with wanted quantity
+   */
+  for (i = 0; i < nrScans; i++) {
+    PolarScan_t* scan = PolarVolume_getScan(volume, i);
+    if (scan != NULL) {
+      if (quantity == NULL || PolarScan_hasParameter(scan, quantity)) {
+        sweepCount++;
+      }
+    }
+    RAVE_OBJECT_RELEASE(scan);
+  }
+
+  return sweepCount;
+}
+
+/**
+ * Converts a rave polar scan into a fmi image
+ * @param[in] scan - the rave polar scan
+ * @param[in] quantity - the quantity to use (if NULL, default parameter is assumed)
+ * @param[in] image - the image to be filled
+ * @return 1 on success otherwise 0
+ */
+static int RaveFmiImageInternal_scanToFmiImage(PolarScan_t* scan, const char* quantity, FmiImage* image)
+{
+  int i = 0, j = 0;
+
+  RAVE_ASSERT((scan != NULL), "scan == NULL");
+  RAVE_ASSERT((image != NULL), "image == NULL");
+
+  image->width=PolarScan_getNbins(scan);
+  image->height=PolarScan_getNrays(scan);
+  image->bin_depth=PolarScan_getRscale(scan);
+  image->elevation_angle=PolarScan_getElangle(scan);
+  image->max_value=255;
+  image->channels=1;
+
+  initialize_image(image);
+
+  for (j = 0; j < image->height; j++) {
+    for (i = 0; i < image->width; i++) {
+      double value = 0.0;
+      if (quantity == NULL) {
+        PolarScan_getValue(scan, i, j, &value);
+      } else {
+        PolarScan_getParameterValue(scan, quantity, i, j, &value);
+      }
+      put_pixel(image, i, j, 0, (Byte)(value+0.5));
+    }
+  }
+
+  return 1;
+}
+
+/*@} End of Private functions */
+
+/*@{ Interface functions */
+int RaveFmiImage_initialize(RaveFmiImage_t* self, int sweepCount)
+{
+  int result = 0;
+  RAVE_ASSERT((self != NULL), "self == NULL");
+  FmiImage* images = new_image(sweepCount);
+  if (images != NULL) {
+    RaveFmiImageInternal_resetImage(self);
+    self->image = images;
+    self->sweepCount = sweepCount;
+    result = 1;
+  }
+  return result;
+}
+
+int RaveFmiImage_getSweepCount(RaveFmiImage_t* self)
+{
+  RAVE_ASSERT((self != NULL), "self == NULL");
+  return self->sweepCount;
+}
+
+FmiImage* RaveFmiImage_getImage(RaveFmiImage_t* self)
+{
+  RAVE_ASSERT((self != NULL), "self == NULL");
+  return self->image;
+}
+
+PolarVolume_t* RaveFmiImage_toRave(RaveFmiImage_t* self, const char* quantity)
+{
+  /*PolarVolume_t* result = NULL;
+  PolarVolume_t* volume = NULL;*/
+
+  RAVE_ASSERT((self != NULL), "self == NULL");
+
+  return NULL;
+}
+
+RaveFmiImage_t* RaveFmiImage_new(int sweepCount)
+{
+  RaveFmiImage_t* result = RAVE_OBJECT_NEW(&RaveFmiImage_TYPE);
+  if (result != NULL) {
+    if (!RaveFmiImage_initialize(result, sweepCount)) {
+      RAVE_OBJECT_RELEASE(result);
+    }
+  }
+  return result;
+}
+
+RaveFmiImage_t* RaveFmiImage_fromRave(PolarVolume_t* volume, const char* quantity)
+{
+  int sweepCount = 0;
+  int nrScans = 0;
+  int i = 0;
+  int sweepIndex = 0;
+  RaveFmiImage_t* image = NULL;
+  RaveFmiImage_t* result = NULL;
+
+  RAVE_ASSERT((volume != NULL), "volume == NULL");
+
+  PolarVolume_sortByElevations(volume, 1);
+  nrScans = PolarVolume_getNumberOfScans(volume);
+  sweepCount = RaveFmiImageInternal_getSweepCount(volume, quantity);
+
+  image = RaveFmiImage_new(sweepCount);
+  if (image == NULL) {
+    RAVE_CRITICAL0("Failed to create fmi image");
+    goto done;
+  }
+
+  for (i = 0; i < nrScans; i++) {
+    PolarScan_t* scan = PolarVolume_getScan(volume, i);
+    if (quantity == NULL || PolarScan_hasParameter(scan, quantity)) {
+      if (!RaveFmiImageInternal_scanToFmiImage(scan, quantity, &image->image[sweepIndex])) {
+        RAVE_ERROR0("Failed to convert scan to fmi image");
+        RAVE_OBJECT_RELEASE(scan);
+        goto done;
+      }
+    }
+    RAVE_OBJECT_RELEASE(scan);
+  }
+
+  result = RAVE_OBJECT_COPY(image);
+done:
+  RAVE_OBJECT_RELEASE(image);
+  return result;
+}
+
+
+
+/*@} End of Interface functions */
+RaveCoreObjectType RaveFmiImage_TYPE = {
+    "RaveFmiImage",
+    sizeof(RaveFmiImage_t),
+    RaveFmiImage_constructor,
+    RaveFmiImage_destructor,
+    NULL /* No copy constructor */
+};
diff --git a/rack/ropo/rave_fmi_image.h b/rack/ropo/rave_fmi_image.h
new file mode 100644 (file)
index 0000000..73ae5d8
--- /dev/null
@@ -0,0 +1,89 @@
+/* --------------------------------------------------------------------
+Copyright (C) 2011 Swedish Meteorological and Hydrological Institute, SMHI,
+
+This file is part of bRack.
+
+bRack is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+bRack is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with bRack.  If not, see <http://www.gnu.org/licenses/>.
+------------------------------------------------------------------------*/
+
+/**
+ * rave object wrapper for the fmi_image.
+ * This object DOES NOT support \ref #RAVE_OBJECT_CLONE.
+ * @file
+ * @author Anders Henja (Swedish Meteorological and Hydrological Institute, SMHI)
+ * @date 2011-08-31
+ */
+#ifndef RAVE_FMI_IMAGE_H
+#define RAVE_FMI_IMAGE_H
+#include "rack/ropo/fmi_image.h"
+#include "rave_object.h"
+#include "polarvolume.h"
+
+/**
+ * Defines a RaveFmiImage
+ */
+typedef struct _RaveFmiImage_t RaveFmiImage_t;
+
+/**
+ * Type definition to use when creating a rave object.
+ */
+extern RaveCoreObjectType RaveFmiImage_TYPE;
+
+/**
+ * Initializes the rave image with the specific number of sweeps.
+ * @see \ref RaveFmiImage_new for short cut version
+ * @param[in] self - self
+ * @param[in] sweepCount - number of sweeps this image should consist of
+ * @return 1 on success otherwise 0
+ */
+int RaveFmiImage_initialize(RaveFmiImage_t* self, int sweepCount);
+
+/**
+ * Returns the number of sweeps this image is built from
+ * @param[in] self - self
+ * @return number of sweeps
+ */
+int RaveFmiImage_getSweepCount(RaveFmiImage_t* self);
+
+/**
+ * Returns the internal FmiImage.
+ * @param[in] self - self
+ * @return the internal fmi image (NOTE, THIS IS AN INTERNAL POINTER SO DO NOT RELEASE)
+ */
+FmiImage* RaveFmiImage_getImage(RaveFmiImage_t* self);
+
+/**
+ * Creates a polar volume from a fmi image
+ * @param[in] self - self
+ * @param[in] quantity - the quantity to be set for the parameters (may be NULL)
+ * @return a polar volume on success otherwise NULL
+ */
+PolarVolume_t* RaveFmiImage_toRave(RaveFmiImage_t* self, const char* quantity);
+
+/**
+ * Creates a rave fmi image with specified number of sweeps
+ * @param[in] sweepCount - the number of sweeps
+ * @return the fmi image on success otherwise NULL
+ */
+RaveFmiImage_t* RaveFmiImage_new(int sweepCount);
+
+/**
+ * Creates a fmi image from a polar volume
+ * @param[in] volume - the polar volume
+ * @param[in] quantity - the quantity to use for building the fmi image (NULL == default parameter)
+ * @return 1 on success otherwise 0
+ */
+RaveFmiImage_t* RaveFmiImage_fromRave(PolarVolume_t* volume, const char* quantity);
+
+#endif /* RAVE_FMI_IMAGE_H */