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 |
|
|
} |
159 |
|
|
} Projection; |
160 |
|
|
|
161 |
|
|
%{ |
162 |
|
|
// Make a brand new projection |
163 |
|
|
Projection *new_Projection(char **argv, Units units) { |
164 |
|
|
int argc = 0; |
165 |
|
|
char **p; |
166 |
|
|
PJ *proj; |
167 |
|
|
Projection *pj = NULL; |
168 |
|
|
|
169 |
|
|
for(p = argv; p != NULL && *p != NULL; p++) argc++; |
170 |
|
|
proj = pj_init(argc, argv); |
171 |
|
|
if(proj != NULL) { |
172 |
|
|
pj = (Projection *) malloc(sizeof(Projection)); |
173 |
|
|
pj->units = units; |
174 |
|
|
pj->proj = proj; |
175 |
|
|
} |
176 |
|
|
return pj; |
177 |
|
|
} |
178 |
|
|
|
179 |
|
|
// Get rid of a projection |
180 |
|
|
void delete_Projection(Projection *self) { |
181 |
|
|
if(self != NULL) { |
182 |
|
|
if(self->proj != NULL) |
183 |
|
|
pj_free(self->proj); |
184 |
|
|
free(self); |
185 |
|
|
} |
186 |
|
|
} |
187 |
|
|
|
188 |
|
|
// Do a forward (lat/lon --> world) translation |
189 |
|
|
void Projection_Forward(Projection *self, double lat, double lon, double *u, double *v) { |
190 |
|
|
projUV latlon, result; |
191 |
|
|
latlon.u = lat; |
192 |
|
|
latlon.v = lon; |
193 |
|
|
if(self->units == DEGREES) { |
194 |
|
|
latlon.u *= DEG_TO_RAD; |
195 |
|
|
latlon.v *= DEG_TO_RAD; |
196 |
|
|
} |
197 |
|
|
result = pj_fwd(latlon, self->proj); |
198 |
|
|
*u = result.u; |
199 |
|
|
*v = result.v; |
200 |
|
|
} |
201 |
|
|
|
202 |
|
|
// Do a reverse (world --> lat/lon) translation |
203 |
|
|
void Projection_Inverse(Projection *self, double u, double v, double *lat, double *lon) { |
204 |
|
|
projUV world, result; |
205 |
|
|
world.u = u; |
206 |
|
|
world.v = v; |
207 |
|
|
result = pj_inv(world, self->proj); |
208 |
|
|
if(self->units == DEGREES) { |
209 |
|
|
result.u *= RAD_TO_DEG; |
210 |
|
|
result.v *= RAD_TO_DEG; |
211 |
|
|
} |
212 |
|
|
*lat = result.u; |
213 |
|
|
*lon = result.v; |
214 |
|
|
} |
215 |
|
|
%} |