ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Geo-LatLon2Place/LatLon2Place.xs
(Generate patch)

Comparing Geo-LatLon2Place/LatLon2Place.xs (file contents):
Revision 1.1 by root, Mon Mar 14 02:41:51 2022 UTC vs.
Revision 1.6 by root, Thu Mar 17 22:55:34 2022 UTC

1#include "EXTERN.h" 1#include "EXTERN.h"
2#include "perl.h" 2#include "perl.h"
3#include "XSUB.h" 3#include "XSUB.h"
4 4
5#include <math.h>
6
7#include "perlmulticore.h"
8
9#if EMBED_CDB
10 #include "cdb-embedded.c"
11#else
5#include <cdb.h> 12 #include <cdb.h>
13#endif
14
15#define TORAD(r) ((r) * (M_PI / 180.))
6 16
7static struct cdb_make make; 17static struct cdb_make make;
18
19struct res
20{
21 double mind;
22 unsigned int respos, reslen;
23 double x, y;
24};
25
26static inline int
27intmin (int a, int b)
28{
29 return a > b ? b : a;
30}
31
32static inline int
33intmax (int a, int b)
34{
35 return a > b ? a : b;
36}
37
38static inline int
39get_u16 (const U8 *ptr)
40{
41 return ptr[0] | (ptr[1] << 8);
42}
8 43
9MODULE = Geo::LatLon2Place PACKAGE = Geo::LatLon2Place 44MODULE = Geo::LatLon2Place PACKAGE = Geo::LatLon2Place
10 45
11PROTOTYPES: ENABLE 46PROTOTYPES: ENABLE
12 47
13int 48SV *
14cdb_make_start (int fd) 49lookup_ext_ (SV *cdb, int km, int boxes, NV lat, NV lon, int r0, int r1, int flags)
15 CODE:
16 RETVAL = cdb_make_start (&make, fd);
17 OUTPUT: RETVAL
18
19int
20cdb_make_add (SV *k, SV *v)
21 CODE: 50 CODE:
22{ 51{
23 STRLEN klen; const char *kp = SvPVbyte (k, klen); 52 struct cdb *db = (struct cdb *)SvPVX (cdb);
24 STRLEN vlen; const char *vp = SvPVbyte (v, vlen); 53
25 RETVAL = cdb_make_add (&make, kp, klen, vp, vlen); 54 if (!r1)
55 r1 = km;
56
57 r0 = r0 / km;
58 r1 = (r1 + km - 1) / km;
59 double coslat = cos (TORAD (lat));
60 int cy = (lat + 90.) * boxes * (1. / 180.);
61 int x, y;
62
63 if (r1 < r0 || r0 < 0 || r1 < 0 || r0 >= boxes / 2 || r1 >= boxes / 2)
64 XSRETURN_EMPTY;
65
66 if (lat < -90. || lat > 90. || lon < -180 || lon > 180.)
67 XSRETURN_EMPTY;
68
69 double mind = 1e99;
70 const U8 *resptr;
71 int reslen = 0;
72
73 for (y = intmax (0, cy - r1); y <= intmin (boxes - 1, cy + r1); ++y)
74 {
75 double glat = y * (180. / boxes) - 90.;
76 double coslat = cos (TORAD (glat));
77 int blat = boxes * coslat; /* can be zero */
78 int cx = (lon + 180.) * blat * (1. / 360.);
79
80 for (x = cx - r1; x <= cx + r1; ++x)
81 {
82 int rx = x;
83 rx += rx < 0 ? blat : 0;
84 rx -= rx >= blat ? blat : 0;
85
86 unsigned char key[4];
87 key[0] = rx;
88 key[1] = rx >> 8;
89 key[2] = y;
90 key[3] = y >> 8;
91
92 //printf ("x,y %4d,%4d blat %d %d %g %02x%02x%02x%02x %d\n", rx, y, blat, (int)glat, TORAD(glat), key[0],key[1],key[2],key[3], sizeof(key));
93
94 if (cdb_find (db, key, sizeof (key)) <= 0)
95 continue;
96
97 int len = cdb_datalen (db);
98 const U8 *ptr = (const U8 *)cdb_get (db, len, cdb_datapos (db));
99
100 while (len > 0)
101 {
102 int datalen = ptr[5];
103
104 double plat = get_u16 (ptr + 0) * ( 90. / 32767.);
105 double plon = get_u16 (ptr + 2) * (180. / 32767.);
106 int w = ptr[4];
107
108 double dx = TORAD (lon - plon) * coslat;
109 double dy = TORAD (lat - plat);
110 double d2 = (dx * dx + dy * dy) * w;
111 //printf ("%g,%g %g %.*s\n", plat,plon,d2, datalen,ptr+6);
112
113 if (d2 < mind)
114 {
115 mind = d2;
116 resptr = ptr;
117 reslen = datalen;
118 }
119
120 len -= datalen + 6;
121 ptr += datalen + 6;
122 }
123 }
124 }
125
126 if (!reslen)
127 XSRETURN_EMPTY;
128
129 RETVAL = newSVpvn ((const char *)resptr + 6, reslen);
26} 130}
27 OUTPUT: RETVAL 131 OUTPUT: RETVAL
28 132
29int 133#############################################################################
30cdb_make_finish ()
31 CODE:
32 RETVAL = cdb_make_finish (&make);
33 OUTPUT: RETVAL
34 134
35int 135int
36cdb_init (SV *self, int fd) 136cdb_init (SV *self, int fd)
37 CODE: 137 CODE:
38 sv_upgrade (self, SVt_PV); 138 sv_upgrade (self, SVt_PV);
139 sv_grow (self, sizeof (struct cdb));
39 SvCUR_set (self, sizeof (struct cdb)); 140 SvCUR_set (self, sizeof (struct cdb));
40 SvPOK_only (self); 141 SvPOK_only (self);
41 RETVAL = cdb_init ((struct cdb *)SvPVX (self), fd); 142 RETVAL = cdb_init ((struct cdb *)SvPVX (self), fd);
42 OUTPUT: RETVAL 143 OUTPUT: RETVAL
43 144
58 if (cdb_find (db, s, l) <= 0) 159 if (cdb_find (db, s, l) <= 0)
59 XSRETURN_UNDEF; 160 XSRETURN_UNDEF;
60 161
61 p = cdb_datapos (db); 162 p = cdb_datapos (db);
62 l = cdb_datalen (db); 163 l = cdb_datalen (db);
63 RETVAL = newSVpvn (cdb_get (db, l, p), l); 164 RETVAL = newSVpvn ((const char *)cdb_get (db, l, p), l);
64} 165}
65 OUTPUT: RETVAL 166 OUTPUT: RETVAL
66 167
168#############################################################################
169
170int
171cdb_make_start (int fd)
172 CODE:
173 RETVAL = cdb_make_start (&make, fd);
174 OUTPUT: RETVAL
175
176int
177cdb_make_add (SV *k, SV *v)
178 CODE:
179{
180 STRLEN klen; const char *kp = SvPVbyte (k, klen);
181 STRLEN vlen; const char *vp = SvPVbyte (v, vlen);
182 RETVAL = cdb_make_add (&make, kp, klen, vp, vlen);
183}
184 OUTPUT: RETVAL
185
186int
187cdb_make_finish ()
188 CODE:
189 RETVAL = cdb_make_finish (&make);
190 OUTPUT: RETVAL
191

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines