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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines