/[thuban]/branches/WIP-pyshapelib-bramz/libraries/pyprojection/Projection.i
ViewVC logotype

Annotation of /branches/WIP-pyshapelib-bramz/libraries/pyprojection/Projection.i

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2452 - (hide annotations)
Mon Dec 13 17:54:36 2004 UTC (20 years, 2 months ago) by bh
Original Path: trunk/thuban/libraries/pyprojection/Projection.i
File size: 6655 byte(s)
* libraries/pyprojection/Projection.i: Work around a bug in the
generated python code which leads to exception in the __del__
method when the constructor fails.  See the comments in the code
for more details.

* libraries/pyprojection/Projection.py: Updated from Projection.i
with SWIG.

1 jan 1610 // This looks most like -*- c -*- code
2    
3     //
4     // Projection.i: SWIG interface file for PROJ.4 projection library.
5     //
6     // Copyright (c) 2001 Meridian Environmental Technology, Inc
7     // All rights reserved.
8     //
9     // Author: Douglas K. Rand <[email protected]>
10     //
11     // Redistribution and use in source and binary forms, with or without
12     // modification, are permitted provided that the following conditions
13     // are met:
14     // 1. Redistributions of source code must retain the above copyright
15     // notice, this list of conditions and the following disclaimer.
16     // 2. Redistributions in binary form must reproduce the above copyright
17     // notice, this list of conditions and the following disclaimer in the
18     // documentation and/or other materials provided with the distribution.
19     //
20     // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21     // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22     // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23     // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24     // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25     // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26     // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27     // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28     // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29     // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30     // SUCH DAMAGE.
31     //
32     //
33    
34    
35     %module Projection
36     %{
37     #include <projects.h>
38    
39     // We wrap the PJ structure in our own so we can keep the
40     // type of units the user wants to operate in along.
41     typedef enum {DEGREES, RADIANS} Units;
42     typedef struct {
43     Units units;
44     PJ *proj;
45     } Projection;
46     %}
47    
48     %include typemaps.i
49     %include constraints.i
50     %include array.i
51    
52     typedef enum {DEGREES, RADIANS} Units;
53    
54     // Because that stupid pj_init() function requires a count of the args,
55     // we have to do a typemap for EACH language terminating it with a null
56     // so we can count the items in our wrapper. Sigh.
57     %typemap(python, in) char **argv {
58     /* Check if is a list */
59     if (PyList_Check($source)) {
60     int size = PyList_Size($source);
61     int i = 0;
62     $target = (char **) malloc((size+1)*sizeof(char *));
63     for (i = 0; i < size; i++) {
64     PyObject *o = PyList_GetItem($source,i);
65     if (PyString_Check(o))
66     $target[i] = PyString_AsString(PyList_GetItem($source,i));
67     else {
68     PyErr_SetString(PyExc_TypeError,"list must contain strings");
69     free($target);
70     return NULL;
71     }
72     }
73     $target[i] = 0;
74     } else {
75     PyErr_SetString(PyExc_TypeError,"not a list"); return NULL;
76     }
77     }
78    
79     // Free up the argv structure created above
80     %typemap(python, freearg) char **argv {
81     free((char *) $source);
82     }
83    
84     /* Assign the pointer to a local variable */
85     %typemap(python, ignore) double *outvalue(double temp) {
86     $target = &temp;
87     }
88    
89     // This tells SWIG to treat an double * argument with name 'outvalue' as
90     // an output value. We'll append the value to the current result which
91     // is guaranteed to be a List object by SWIG.
92     %typemap(python,argout) double *outvalue {
93     PyObject *o;
94     o = PyFloat_FromDouble(*$source);
95     if ((!$target) || ($target == Py_None)) {
96     $target = o;
97     } else {
98     if (!PyList_Check($target)) {
99     PyObject *o2 = $target;
100     $target = PyList_New(0);
101     PyList_Append($target,o2);
102     Py_XDECREF(o2);
103     }
104     PyList_Append($target,o);
105     Py_XDECREF(o);
106     }
107     }
108    
109     //%typemap(perl5, argout) double *outvalue {
110     // $target = sv_newmortal();
111     // sv_setnv($target, *$source);
112     // argvi++;
113     //}
114    
115     /* Assign the pointer to a local variable */
116     %typemap(python,in) double *outvalue {
117     static double junk;
118     $target = &junk;
119     }
120    
121     //%typemap(perl5, in) double *outvalue {
122     // static double junk;
123     // $target = &junk;
124     //}
125    
126    
127     /* Exception handler for the Projection constructor */
128     %typemap(python,except) Projection * {
129 bh 1686 /* Use pj_get_errno_ref to access the pj_errno because directly
130     * accessing pj_errno doesn't work on windows if the proj library is
131     * in a DLL */
132     *pj_get_errno_ref() = 0;
133 jan 1610 $function;
134     if (!$source)
135     {
136 bh 1686 /* FIXME: There's a case where $source is NULL and pj_errno is
137     * not set, namely when memory allocation of the Projection
138     * struct fails. */
139     SWIG_exception(SWIG_IOError, pj_strerrno(*pj_get_errno_ref()));
140 jan 1610 }
141     }
142    
143    
144     typedef struct {
145     Units units;
146     PJ *proj;
147    
148     %addmethods {
149     Projection(char **argv, Units units = DEGREES);
150     ~Projection();
151     void Forward(double lat, double lon, double *outvalue, double *outvalue);
152     void Inverse(double u, double v, double *outvalue, double *outvalue);
153    
154     PyObject * cobject() {
155     return PyCObject_FromVoidPtr(self->proj, NULL);
156     }
157    
158 bh 2452
159     /* The __del__ method generated by the old SWIG version we're
160     * tries to access self.thisown which may not be set at all when
161     * there was an exception during construction. Therefore we
162     * override it with our own version.
163     * FIXME: It would be better to upgrade to a newer SWIG version
164     * or to get rid of SWIG entirely.
165     */
166     %pragma(python) addtoclass = "
167     def __del__(self,Projectionc=Projectionc):
168     if getattr(self, 'thisown', 0):
169     Projectionc.delete_Projection(self)
170     "
171    
172 jan 1610 }
173     } Projection;
174    
175     %{
176     // Make a brand new projection
177     Projection *new_Projection(char **argv, Units units) {
178     int argc = 0;
179     char **p;
180     PJ *proj;
181     Projection *pj = NULL;
182    
183     for(p = argv; p != NULL && *p != NULL; p++) argc++;
184     proj = pj_init(argc, argv);
185     if(proj != NULL) {
186     pj = (Projection *) malloc(sizeof(Projection));
187     pj->units = units;
188     pj->proj = proj;
189     }
190     return pj;
191     }
192    
193     // Get rid of a projection
194     void delete_Projection(Projection *self) {
195     if(self != NULL) {
196     if(self->proj != NULL)
197     pj_free(self->proj);
198     free(self);
199     }
200     }
201    
202     // Do a forward (lat/lon --> world) translation
203     void Projection_Forward(Projection *self, double lat, double lon, double *u, double *v) {
204     projUV latlon, result;
205     latlon.u = lat;
206     latlon.v = lon;
207     if(self->units == DEGREES) {
208     latlon.u *= DEG_TO_RAD;
209     latlon.v *= DEG_TO_RAD;
210     }
211     result = pj_fwd(latlon, self->proj);
212     *u = result.u;
213     *v = result.v;
214     }
215    
216     // Do a reverse (world --> lat/lon) translation
217     void Projection_Inverse(Projection *self, double u, double v, double *lat, double *lon) {
218     projUV world, result;
219     world.u = u;
220     world.v = v;
221     result = pj_inv(world, self->proj);
222     if(self->units == DEGREES) {
223     result.u *= RAD_TO_DEG;
224     result.v *= RAD_TO_DEG;
225     }
226     *lat = result.u;
227     *lon = result.v;
228     }
229     %}

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26