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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2452 - (show 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 // 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 /* 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 $function;
134 if (!$source)
135 {
136 /* 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 }
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
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 }
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