1 |
/**
|
2 |
* ZANavi, Zoff Android Navigation system.
|
3 |
* Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
|
4 |
*
|
5 |
* This program is free software; you can redistribute it and/or
|
6 |
* modify it under the terms of the GNU General Public License
|
7 |
* version 2 as published by the Free Software Foundation.
|
8 |
*
|
9 |
* This program is distributed in the hope that it will be useful,
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12 |
* GNU General Public License for more details.
|
13 |
*
|
14 |
* You should have received a copy of the GNU General Public License
|
15 |
* along with this program; if not, write to the
|
16 |
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
17 |
* Boston, MA 02110-1301, USA.
|
18 |
*/
|
19 |
|
20 |
/**
|
21 |
* Navit, a modular navigation system.
|
22 |
* Copyright (C) 2005-2011 Navit Team
|
23 |
*
|
24 |
* This program is free software; you can redistribute it and/or
|
25 |
* modify it under the terms of the GNU General Public License
|
26 |
* version 2 as published by the Free Software Foundation.
|
27 |
*
|
28 |
* This program is distributed in the hope that it will be useful,
|
29 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
30 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
31 |
* GNU General Public License for more details.
|
32 |
*
|
33 |
* You should have received a copy of the GNU General Public License
|
34 |
* along with this program; if not, write to the
|
35 |
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
36 |
* Boston, MA 02110-1301, USA.
|
37 |
*/
|
38 |
|
39 |
#define _FILE_OFFSET_BITS 64
|
40 |
#define _LARGEFILE_SOURCE
|
41 |
#define _LARGEFILE64_SOURCE
|
42 |
#include <string.h>
|
43 |
#include <stdlib.h>
|
44 |
#include "maptool.h"
|
45 |
#include "linguistics.h"
|
46 |
#include "file.h"
|
47 |
#include "debug.h"
|
48 |
|
49 |
int item_bin_read(struct item_bin *ib, FILE *in)
|
50 |
{
|
51 |
if (fread(ib, 4, 1, in) == 0)
|
52 |
return 0;
|
53 |
if (!ib->len)
|
54 |
return 1;
|
55 |
if (fread((unsigned char *) ib + 4, ib->len * 4, 1, in))
|
56 |
return 2;
|
57 |
return 0;
|
58 |
}
|
59 |
|
60 |
void item_bin_set_type(struct item_bin *ib, enum item_type type)
|
61 |
{
|
62 |
ib->type = type;
|
63 |
}
|
64 |
|
65 |
void item_bin_init(struct item_bin *ib, enum item_type type)
|
66 |
{
|
67 |
ib->clen = 0;
|
68 |
ib->len = 2;
|
69 |
item_bin_set_type(ib, type);
|
70 |
}
|
71 |
|
72 |
void item_bin_add_coord(struct item_bin *ib, struct coord *c, int count)
|
73 |
{
|
74 |
struct coord *c2 = (struct coord *) (ib + 1);
|
75 |
c2 += ib->clen / 2;
|
76 |
memcpy(c2, c, count * sizeof(struct coord));
|
77 |
ib->clen += count * 2;
|
78 |
ib->len += count * 2;
|
79 |
}
|
80 |
|
81 |
void item_bin_add_coord_reverse(struct item_bin *ib, struct coord *c, int count)
|
82 |
{
|
83 |
int i;
|
84 |
for (i = count - 1; i >= 0; i--)
|
85 |
{
|
86 |
item_bin_add_coord(ib, &c[i], 1);
|
87 |
}
|
88 |
}
|
89 |
|
90 |
void item_bin_bbox(struct item_bin *ib, struct rect *r)
|
91 |
{
|
92 |
struct coord c;
|
93 |
item_bin_add_coord(ib, &r->l, 1);
|
94 |
c.x = r->h.x;
|
95 |
c.y = r->l.y;
|
96 |
item_bin_add_coord(ib, &c, 1);
|
97 |
item_bin_add_coord(ib, &r->h, 1);
|
98 |
c.x = r->l.x;
|
99 |
c.y = r->h.y;
|
100 |
item_bin_add_coord(ib, &c, 1);
|
101 |
item_bin_add_coord(ib, &r->l, 1);
|
102 |
}
|
103 |
|
104 |
void item_bin_copy_coord(struct item_bin *ib, struct item_bin *from, int dir)
|
105 |
{
|
106 |
struct coord *c = (struct coord *) (from + 1);
|
107 |
int i, count = from->clen / 2;
|
108 |
if (dir >= 0)
|
109 |
{
|
110 |
item_bin_add_coord(ib, c, count);
|
111 |
return;
|
112 |
}
|
113 |
for (i = 1; i <= count; i++)
|
114 |
{
|
115 |
item_bin_add_coord(ib, &c[count - i], 1);
|
116 |
}
|
117 |
}
|
118 |
|
119 |
void item_bin_add_coord_rect(struct item_bin *ib, struct rect *r)
|
120 |
{
|
121 |
item_bin_add_coord(ib, &r->l, 1);
|
122 |
item_bin_add_coord(ib, &r->h, 1);
|
123 |
}
|
124 |
|
125 |
int attr_bin_write_data(struct attr_bin *ab, enum attr_type type, void *data, int size)
|
126 |
{
|
127 |
int pad = (4 - (size % 4)) % 4;
|
128 |
ab->type = type;
|
129 |
memcpy(ab + 1, data, size);
|
130 |
memset((unsigned char *) (ab + 1) + size, 0, pad);
|
131 |
ab->len = (size + pad) / 4 + 1;
|
132 |
return ab->len + 1;
|
133 |
}
|
134 |
|
135 |
int attr_bin_write_attr(struct attr_bin *ab, struct attr *attr)
|
136 |
{
|
137 |
return attr_bin_write_data(ab, attr->type, attr_data_get(attr), attr_data_size(attr));
|
138 |
}
|
139 |
|
140 |
void item_bin_add_attr_data(struct item_bin *ib, enum attr_type type, void *data, int size)
|
141 |
{
|
142 |
struct attr_bin *ab = (struct attr_bin *) ((int *) ib + ib->len + 1);
|
143 |
ib->len += attr_bin_write_data(ab, type, data, size);
|
144 |
}
|
145 |
|
146 |
void item_bin_add_attr(struct item_bin *ib, struct attr *attr)
|
147 |
{
|
148 |
struct attr_bin *ab = (struct attr_bin *) ((int *) ib + ib->len + 1);
|
149 |
if (ATTR_IS_GROUP(attr->type))
|
150 |
{
|
151 |
int i = 0;
|
152 |
int *abptr;
|
153 |
ab->type = attr->type;
|
154 |
ab->len = 1;
|
155 |
abptr = (int *) (ab + 1);
|
156 |
while (attr->u.attrs[i].type)
|
157 |
{
|
158 |
int size = attr_bin_write_attr((struct attr_bin *) abptr, &attr->u.attrs[i]);
|
159 |
ab->len += size;
|
160 |
abptr += size;
|
161 |
i++;
|
162 |
}
|
163 |
ib->len += ab->len + 1;
|
164 |
|
165 |
}
|
166 |
else
|
167 |
{
|
168 |
ib->len += attr_bin_write_attr(ab, attr);
|
169 |
}
|
170 |
}
|
171 |
|
172 |
static char *coord_to_str(struct coord *c);
|
173 |
|
174 |
void item_bin_remove_attr(struct item_bin *ib, void *ptr)
|
175 |
{
|
176 |
unsigned char *s = (unsigned char *) ib;
|
177 |
unsigned char *e = s + (ib->len + 1) * 4;
|
178 |
s += sizeof(struct item_bin) + ib->clen * 4;
|
179 |
while (s < e)
|
180 |
{
|
181 |
struct attr_bin *ab = (struct attr_bin *) s;
|
182 |
s += (ab->len + 1) * 4;
|
183 |
if ((void *) (ab + 1) == ptr)
|
184 |
{
|
185 |
ib->len -= ab->len + 1;
|
186 |
memmove(ab, s, e - s);
|
187 |
return;
|
188 |
}
|
189 |
}
|
190 |
}
|
191 |
|
192 |
void item_bin_add_attr_int(struct item_bin *ib, enum attr_type type, int val)
|
193 |
{
|
194 |
struct attr attr;
|
195 |
attr.type = type;
|
196 |
attr.u.num = val;
|
197 |
item_bin_add_attr(ib, &attr);
|
198 |
}
|
199 |
|
200 |
void *
|
201 |
item_bin_get_attr(struct item_bin *ib, enum attr_type type, void *last)
|
202 |
{
|
203 |
unsigned char *s = (unsigned char *) ib;
|
204 |
unsigned char *e = s + (ib->len + 1) * 4;
|
205 |
s += sizeof(struct item_bin) + ib->clen * 4;
|
206 |
while (s < e)
|
207 |
{
|
208 |
struct attr_bin *ab = (struct attr_bin *) s;
|
209 |
s += (ab->len + 1) * 4;
|
210 |
if (ab->type == type && (void *) (ab + 1) > last)
|
211 |
{
|
212 |
return (ab + 1);
|
213 |
}
|
214 |
}
|
215 |
return NULL;
|
216 |
}
|
217 |
|
218 |
struct attr_bin *
|
219 |
item_bin_get_attr_bin_last(struct item_bin *ib)
|
220 |
{
|
221 |
struct attr_bin *ab = NULL;
|
222 |
unsigned char *s = (unsigned char *) ib;
|
223 |
unsigned char *e = s + (ib->len + 1) * 4;
|
224 |
s += sizeof(struct item_bin) + ib->clen * 4;
|
225 |
while (s < e)
|
226 |
{
|
227 |
ab = (struct attr_bin *) s;
|
228 |
s += (ab->len + 1) * 4;
|
229 |
}
|
230 |
return ab;
|
231 |
}
|
232 |
|
233 |
void item_bin_add_attr_longlong(struct item_bin *ib, enum attr_type type, long long val)
|
234 |
{
|
235 |
struct attr attr;
|
236 |
attr.type = type;
|
237 |
attr.u.num64 = &val;
|
238 |
item_bin_add_attr(ib, &attr);
|
239 |
}
|
240 |
|
241 |
void item_bin_add_attr_string(struct item_bin *ib, enum attr_type type, char *str)
|
242 |
{
|
243 |
struct attr attr;
|
244 |
if (!str)
|
245 |
return;
|
246 |
attr.type = type;
|
247 |
attr.u.str = str;
|
248 |
item_bin_add_attr(ib, &attr);
|
249 |
}
|
250 |
|
251 |
void item_bin_add_attr_range(struct item_bin *ib, enum attr_type type, short min, short max)
|
252 |
{
|
253 |
struct attr attr;
|
254 |
attr.type = type;
|
255 |
attr.u.range.min = min;
|
256 |
attr.u.range.max = max;
|
257 |
item_bin_add_attr(ib, &attr);
|
258 |
}
|
259 |
|
260 |
void item_bin_write_xml(struct item_bin *ib, char *filename)
|
261 |
{
|
262 |
FILE *out = tempfile("", filename, 2);
|
263 |
|
264 |
struct coord *c;
|
265 |
struct attr_bin *a;
|
266 |
struct attr attr;
|
267 |
int *attr_start;
|
268 |
int *attr_end;
|
269 |
int i;
|
270 |
char *str;
|
271 |
|
272 |
c = (struct coord *) (ib + 1);
|
273 |
|
274 |
// LOTS of output ---------
|
275 |
if (ib->type < type_line)
|
276 |
{
|
277 |
//dump_coord(c, out);
|
278 |
// fprintf(out, " ");
|
279 |
}
|
280 |
// LOTS of output ---------
|
281 |
|
282 |
|
283 |
attr_start = (int *) (ib + 1) + ib->clen;
|
284 |
attr_end = (int *) ib + ib->len + 1;
|
285 |
|
286 |
|
287 |
// fprintf(out, "type=%s", item_to_name(ib->type));
|
288 |
// char *item_type = item_to_name(ib->type);
|
289 |
|
290 |
fprintf(out, "<way visible=\"true\" version=\"1\"");
|
291 |
// fprintf(out, "boundary=administrative,admin_level=2");
|
292 |
|
293 |
// "w boundary=administrative,admin_level=2 border_country\n"
|
294 |
// "w boundary=territorial,admin_level=2 border_country\n"
|
295 |
// "w boundary=maritime,admin_level=2 border_country\n"
|
296 |
// "w administrative=boundary,admin_level=2 border_country\n"
|
297 |
// "w boundary=administrative,maritime=yes,admin_level=2 border_country\n"
|
298 |
// "w boundary=administrative,maritime=yes,admin_level=4 border_country\n"
|
299 |
// "w boundary=administrative,border_type=state,admin_level=4 border_country\n" };
|
300 |
|
301 |
|
302 |
while (attr_start < attr_end)
|
303 |
{
|
304 |
a = (struct attr_bin *) (attr_start);
|
305 |
attr_start += a->len + 1;
|
306 |
attr.type = a->type;
|
307 |
attr_data_set(&attr, (a + 1));
|
308 |
str = attr_to_text(&attr, NULL, 1);
|
309 |
|
310 |
if (!strcmp("osm_wayid", attr_to_name(a->type)))
|
311 |
{
|
312 |
fprintf(out, " id=\"%s\"", str);
|
313 |
}
|
314 |
else
|
315 |
{
|
316 |
fprintf(out, " %s=\"%s\"", attr_to_name(a->type), str);
|
317 |
}
|
318 |
g_free(str);
|
319 |
}
|
320 |
// fprintf(out, " debug=\"length=%d\"", ib->len);
|
321 |
fprintf(out, ">\n");
|
322 |
|
323 |
// LOTS of output -----------
|
324 |
if (ib->type >= type_line)
|
325 |
{
|
326 |
// long x_;
|
327 |
long y_;
|
328 |
for (i = 0; i < ib->clen / 2; i++)
|
329 |
{
|
330 |
// x_ = (c + i)->x;
|
331 |
y_ = (c + i)->y;
|
332 |
fprintf(out, "<nd ref=\"%lu\"/>\n", y_);
|
333 |
}
|
334 |
}
|
335 |
// LOTS of output -----------
|
336 |
|
337 |
fprintf(out, "<tag k=\"admin_level\" v=\"2\"/>\n");
|
338 |
fprintf(out, "<tag k=\"boundary\" v=\"administrative\"/>\n");
|
339 |
fprintf(out, "</way>\n");
|
340 |
|
341 |
//if (debug_itembin(ib))
|
342 |
//{
|
343 |
// fprintf(stderr,"\n== item_bin_dump == END ==\n");
|
344 |
//}
|
345 |
|
346 |
fclose(out);
|
347 |
}
|
348 |
|
349 |
void item_bin_write(struct item_bin *ib, FILE *out)
|
350 |
{
|
351 |
if (debug_itembin(ib))
|
352 |
{
|
353 |
fprintf(stderr, "== item_bin_write == FILE: %p ==\n", out);
|
354 |
dump_itembin(ib);
|
355 |
fprintf(stderr, "== item_bin_write == END ==\n");
|
356 |
}
|
357 |
|
358 |
// long long t=(ib->len+1)*4;
|
359 |
// fprintf(stderr,"item_bin_write:fwrite "LONGLONG_FMT"\n", t);
|
360 |
fwrite(ib, (ib->len + 1) * 4, 1, out);
|
361 |
}
|
362 |
|
363 |
struct item_bin *
|
364 |
item_bin_dup(struct item_bin *ib)
|
365 |
{
|
366 |
int len = (ib->len + 1) * 4;
|
367 |
struct item_bin *ret = g_malloc(len);
|
368 |
memcpy(ret, ib, len);
|
369 |
|
370 |
return ret;
|
371 |
}
|
372 |
|
373 |
void item_bin_write_range(struct item_bin *ib, FILE *out, int min, int max)
|
374 |
{
|
375 |
struct range r;
|
376 |
|
377 |
r.min = min;
|
378 |
r.max = max;
|
379 |
fwrite(&r, sizeof(r), 1, out);
|
380 |
item_bin_write(ib, out);
|
381 |
}
|
382 |
|
383 |
void item_bin_write_clipped(struct item_bin *ib, struct tile_parameter *param, struct item_bin_sink *out)
|
384 |
{
|
385 |
struct tile_data tile_data;
|
386 |
int i;
|
387 |
bbox((struct coord *) (ib + 1), ib->clen / 2, &tile_data.item_bbox);
|
388 |
tile_data.buffer[0] = '\0';
|
389 |
tile_data.tile_depth = tile(&tile_data.item_bbox, NULL, tile_data.buffer, param->max, param->overlap, &tile_data.tile_bbox);
|
390 |
if (tile_data.tile_depth == param->max || tile_data.tile_depth >= param->min)
|
391 |
{
|
392 |
item_bin_write_to_sink(ib, out, &tile_data);
|
393 |
return;
|
394 |
}
|
395 |
for (i = 0; i < 4; i++)
|
396 |
{
|
397 |
struct rect clip_rect;
|
398 |
tile_data.buffer[tile_data.tile_depth] = 'a' + i;
|
399 |
tile_data.buffer[tile_data.tile_depth + 1] = '\0';
|
400 |
tile_bbox(tile_data.buffer, &clip_rect, param->overlap);
|
401 |
if (ib->type < type_area)
|
402 |
clip_line(ib, &clip_rect, param, out);
|
403 |
else
|
404 |
clip_polygon(ib, &clip_rect, param, out);
|
405 |
}
|
406 |
}
|
407 |
|
408 |
static char *
|
409 |
coord_to_str(struct coord *c)
|
410 |
{
|
411 |
int x = c->x;
|
412 |
int y = c->y;
|
413 |
char *sx = "";
|
414 |
char *sy = "";
|
415 |
|
416 |
if (x < 0)
|
417 |
{
|
418 |
sx = "-";
|
419 |
x = -x;
|
420 |
}
|
421 |
|
422 |
if (y < 0)
|
423 |
{
|
424 |
sy = "-";
|
425 |
y = -y;
|
426 |
}
|
427 |
|
428 |
return g_strdup_printf("%s0x%x %s0x%x", sx, x, sy, y);
|
429 |
}
|
430 |
|
431 |
static void dump_coord(struct coord *c, FILE *out)
|
432 |
{
|
433 |
char *str = coord_to_str(c);
|
434 |
fprintf(out, "%s", str);
|
435 |
g_free(str);
|
436 |
}
|
437 |
|
438 |
void item_bin_dump(struct item_bin *ib, FILE *out)
|
439 |
{
|
440 |
struct coord *c;
|
441 |
struct attr_bin *a;
|
442 |
struct attr attr;
|
443 |
int *attr_start;
|
444 |
int *attr_end;
|
445 |
int i;
|
446 |
char *str;
|
447 |
|
448 |
//if (debug_itembin(ib))
|
449 |
//{
|
450 |
// fprintf(stderr,"\n== item_bin_dump == START ==\n");
|
451 |
//}
|
452 |
|
453 |
c = (struct coord *) (ib + 1);
|
454 |
|
455 |
// LOTS of output ---------
|
456 |
if (ib->type < type_line)
|
457 |
{
|
458 |
dump_coord(c, out);
|
459 |
fprintf(out, " ");
|
460 |
}
|
461 |
// LOTS of output ---------
|
462 |
|
463 |
|
464 |
attr_start = (int *) (ib + 1) + ib->clen;
|
465 |
attr_end = (int *) ib + ib->len + 1;
|
466 |
fprintf(out, "type=%s", item_to_name(ib->type));
|
467 |
while (attr_start < attr_end)
|
468 |
{
|
469 |
a = (struct attr_bin *) (attr_start);
|
470 |
attr_start += a->len + 1;
|
471 |
attr.type = a->type;
|
472 |
attr_data_set(&attr, (a + 1));
|
473 |
str = attr_to_text(&attr, NULL, 1);
|
474 |
fprintf(out, " %s=\"%s\"", attr_to_name(a->type), str);
|
475 |
g_free(str);
|
476 |
}
|
477 |
fprintf(out, " debug=\"length=%d\"", ib->len);
|
478 |
fprintf(out, "\n");
|
479 |
|
480 |
// LOTS of output -----------
|
481 |
if (ib->type >= type_line)
|
482 |
{
|
483 |
for (i = 0; i < ib->clen / 2; i++)
|
484 |
{
|
485 |
dump_coord(c + i, out);
|
486 |
fprintf(out, "\n");
|
487 |
}
|
488 |
}
|
489 |
// LOTS of output -----------
|
490 |
|
491 |
//if (debug_itembin(ib))
|
492 |
//{
|
493 |
// fprintf(stderr,"\n== item_bin_dump == END ==\n");
|
494 |
//}
|
495 |
}
|
496 |
|
497 |
void dump_itembin(struct item_bin *ib)
|
498 |
{
|
499 |
// item_bin_dump(ib, stdout);
|
500 |
item_bin_dump(ib, stderr);
|
501 |
}
|
502 |
|
503 |
struct population_table
|
504 |
{
|
505 |
enum item_type type;
|
506 |
int population;
|
507 |
};
|
508 |
|
509 |
static struct population_table town_population[] =
|
510 |
{
|
511 |
{ type_town_label_0e0, 0 },
|
512 |
{ type_town_label_1e0, 1 },
|
513 |
{ type_town_label_2e0, 2 },
|
514 |
{ type_town_label_5e0, 5 },
|
515 |
{ type_town_label_1e1, 10 },
|
516 |
{ type_town_label_2e1, 20 },
|
517 |
{ type_town_label_5e1, 50 },
|
518 |
{ type_town_label_1e2, 100 },
|
519 |
{ type_town_label_2e2, 200 },
|
520 |
{ type_town_label_5e2, 500 },
|
521 |
{ type_town_label_1e3, 1000 },
|
522 |
{ type_town_label_2e3, 2000 },
|
523 |
{ type_town_label_5e3, 5000 },
|
524 |
{ type_town_label_1e4, 10000 },
|
525 |
{ type_town_label_2e4, 20000 },
|
526 |
{ type_town_label_5e4, 50000 },
|
527 |
{ type_town_label_1e5, 100000 },
|
528 |
{ type_town_label_2e5, 200000 },
|
529 |
{ type_town_label_5e5, 500000 },
|
530 |
{ type_town_label_1e6, 1000000 },
|
531 |
{ type_town_label_2e6, 2000000 },
|
532 |
{ type_town_label_5e6, 5000000 },
|
533 |
{ type_town_label_1e7, 10000000 }, };
|
534 |
|
535 |
static struct population_table district_population[] =
|
536 |
{
|
537 |
{ type_district_label_0e0, 0 },
|
538 |
{ type_district_label_1e0, 1 },
|
539 |
{ type_district_label_2e0, 2 },
|
540 |
{ type_district_label_5e0, 5 },
|
541 |
{ type_district_label_1e1, 10 },
|
542 |
{ type_district_label_2e1, 20 },
|
543 |
{ type_district_label_5e1, 50 },
|
544 |
{ type_district_label_1e2, 100 },
|
545 |
{ type_district_label_2e2, 200 },
|
546 |
{ type_district_label_5e2, 500 },
|
547 |
{ type_district_label_1e3, 1000 },
|
548 |
{ type_district_label_2e3, 2000 },
|
549 |
{ type_district_label_5e3, 5000 },
|
550 |
{ type_district_label_1e4, 10000 },
|
551 |
{ type_district_label_2e4, 20000 },
|
552 |
{ type_district_label_5e4, 50000 },
|
553 |
{ type_district_label_1e5, 100000 },
|
554 |
{ type_district_label_2e5, 200000 },
|
555 |
{ type_district_label_5e5, 500000 },
|
556 |
{ type_district_label_1e6, 1000000 },
|
557 |
{ type_district_label_2e6, 2000000 },
|
558 |
{ type_district_label_5e6, 5000000 },
|
559 |
{ type_district_label_1e7, 10000000 }, };
|
560 |
|
561 |
void item_bin_set_type_by_population(struct item_bin *ib, int population)
|
562 |
{
|
563 |
struct population_table *table;
|
564 |
int i, count;
|
565 |
|
566 |
if (population < 0)
|
567 |
population = 0;
|
568 |
if (item_is_district(*ib))
|
569 |
{
|
570 |
table = district_population;
|
571 |
count = sizeof(district_population) / sizeof(district_population[0]);
|
572 |
}
|
573 |
else
|
574 |
{
|
575 |
table = town_population;
|
576 |
count = sizeof(town_population) / sizeof(town_population[0]);
|
577 |
}
|
578 |
for (i = 0; i < count; i++)
|
579 |
{
|
580 |
if (population < table[i].population)
|
581 |
break;
|
582 |
}
|
583 |
item_bin_set_type(ib, table[i - 1].type);
|
584 |
}
|
585 |
|
586 |
void item_bin_town_write_match(struct item_bin *ib, enum attr_type type, enum attr_type match, FILE *out)
|
587 |
{
|
588 |
char *word_orig = item_bin_get_attr(ib, type, NULL);
|
589 |
int i;
|
590 |
// ?? int len=ib->len;
|
591 |
|
592 |
if (!word_orig)
|
593 |
{
|
594 |
// fprintf(stderr,"**** NULL value ****\n");
|
595 |
return;
|
596 |
}
|
597 |
|
598 |
// fprintf(stderr,"###################################\n");
|
599 |
// fprintf(stderr,"###################################\n");
|
600 |
// fprintf(stderr,"name=%s\n",word_orig);
|
601 |
|
602 |
// xx ++ item_bin_add_attr_string(ib, match, str);
|
603 |
|
604 |
//for (i = 1 ; i < 2 ; i++)
|
605 |
//{
|
606 |
i = 1;
|
607 |
char *str = linguistics_expand_special(word_orig, i);
|
608 |
if (str)
|
609 |
{
|
610 |
char *str2;
|
611 |
str2 = linguistics_casefold(str);
|
612 |
if (str2)
|
613 |
{
|
614 |
// ?? ib->len=len-(len-strlen(str2));
|
615 |
//fprintf(stderr,"i=%d match1=%s\n",i,str);
|
616 |
//fprintf(stderr,"i=%d match2=%s\n",i,str2);
|
617 |
item_bin_add_attr_string(ib, match, str2);
|
618 |
g_free(str2);
|
619 |
}
|
620 |
g_free(str);
|
621 |
}
|
622 |
//}
|
623 |
|
624 |
item_bin_write(ib, out);
|
625 |
|
626 |
//if (word_orig!=NULL)
|
627 |
//{
|
628 |
// g_free(word_orig);
|
629 |
//}
|
630 |
}
|
631 |
|
632 |
void item_bin_write_match(struct item_bin *ib, enum attr_type type, enum attr_type match, FILE *out)
|
633 |
{
|
634 |
char *word = item_bin_get_attr(ib, type, NULL);
|
635 |
int i;
|
636 |
//int words=0;
|
637 |
int len = ib->len;
|
638 |
//int first=1;
|
639 |
if (!word)
|
640 |
{
|
641 |
return;
|
642 |
}
|
643 |
|
644 |
if (debug_itembin(ib))
|
645 |
{
|
646 |
fprintf(stderr, "###################################\n");
|
647 |
fprintf(stderr, "###################################\n");
|
648 |
fprintf(stderr, "name=%s\n", word);
|
649 |
}
|
650 |
|
651 |
word = linguistics_next_word(word);
|
652 |
|
653 |
while (word)
|
654 |
{
|
655 |
if (debug_itembin(ib))
|
656 |
{
|
657 |
fprintf(stderr, "word=%s\n", word);
|
658 |
}
|
659 |
for (i = 0; i < 3; i++)
|
660 |
{
|
661 |
char *str = linguistics_expand_special(word, i);
|
662 |
if (str)
|
663 |
{
|
664 |
ib->len = len;
|
665 |
if (debug_itembin(ib))
|
666 |
{
|
667 |
fprintf(stderr, "i=%d match=%s\n", i, str);
|
668 |
}
|
669 |
item_bin_add_attr_string(ib, match, str);
|
670 |
item_bin_write(ib, out);
|
671 |
g_free(str);
|
672 |
}
|
673 |
}
|
674 |
word = linguistics_next_word(NULL);
|
675 |
}
|
676 |
|
677 |
if (word != NULL)
|
678 |
{
|
679 |
g_free(word);
|
680 |
}
|
681 |
}
|
682 |
|
683 |
static int item_bin_sort_compare(const void *p1, const void *p2)
|
684 |
{
|
685 |
struct item_bin *ib1 = *((struct item_bin **) p1), *ib2 = *((struct item_bin **) p2);
|
686 |
struct attr_bin *attr1, *attr2;
|
687 |
char *s1, *s2;
|
688 |
int ret;
|
689 |
|
690 |
#if 0
|
691 |
dbg_assert(ib1->clen==2);
|
692 |
dbg_assert(ib2->clen==2);
|
693 |
attr1=(struct attr_bin *)((int *)(ib1+1)+ib1->clen);
|
694 |
attr2=(struct attr_bin *)((int *)(ib2+1)+ib1->clen);
|
695 |
#else
|
696 |
attr1 = item_bin_get_attr_bin_last(ib1);
|
697 |
attr2 = item_bin_get_attr_bin_last(ib2);
|
698 |
#endif
|
699 |
#if 0
|
700 |
dbg_assert(attr1->type == attr_town_name || attr1->type == attr_town_name_match);
|
701 |
dbg_assert(attr2->type == attr_town_name || attr2->type == attr_town_name_match);
|
702 |
#endif
|
703 |
s1 = (char *) (attr1 + 1);
|
704 |
s2 = (char *) (attr2 + 1);
|
705 |
if (attr1->type == attr_house_number && attr2->type == attr_house_number)
|
706 |
{
|
707 |
ret = atoi(s1) - atoi(s2);
|
708 |
if (ret)
|
709 |
{
|
710 |
return ret;
|
711 |
}
|
712 |
}
|
713 |
ret = strcmp(s1, s2);
|
714 |
if (!ret)
|
715 |
{
|
716 |
int match1 = 0, match2 = 0;
|
717 |
match1 = (attr1->type == attr_town_name_match || attr1->type == attr_district_name_match);
|
718 |
match2 = (attr2->type == attr_town_name_match || attr2->type == attr_district_name_match);
|
719 |
ret = match1 - match2;
|
720 |
}
|
721 |
|
722 |
#if 0
|
723 |
fprintf(stderr,"sort_countries_compare p1=%p p2=%p %s %s\n",p1,p2,s1,s2);
|
724 |
#endif
|
725 |
|
726 |
return ret;
|
727 |
}
|
728 |
|
729 |
int item_bin_sort_file(char *in_file, char *out_file, struct rect *r, int *size)
|
730 |
{
|
731 |
int j, k, count, rc = 0;
|
732 |
struct coord *c;
|
733 |
struct item_bin *ib;
|
734 |
FILE *f;
|
735 |
unsigned char *p, **idx, *buffer;
|
736 |
if (file_get_contents(in_file, &buffer, size))
|
737 |
{
|
738 |
ib = (struct item_bin *) buffer;
|
739 |
p = buffer;
|
740 |
count = 0;
|
741 |
while (p < buffer + *size)
|
742 |
{
|
743 |
count++;
|
744 |
p += (*((int *) p) + 1) * 4;
|
745 |
}
|
746 |
idx = malloc(count * sizeof(void *));
|
747 |
dbg_assert(idx != NULL);
|
748 |
p = buffer;
|
749 |
for (j = 0; j < count; j++)
|
750 |
{
|
751 |
idx[j] = p;
|
752 |
p += (*((int *) p) + 1) * 4;
|
753 |
}
|
754 |
qsort(idx, count, sizeof(void *), item_bin_sort_compare);
|
755 |
f = fopen(out_file, "wb");
|
756 |
for (j = 0; j < count; j++)
|
757 |
{
|
758 |
ib = (struct item_bin *) (idx[j]);
|
759 |
c = (struct coord *) (ib + 1);
|
760 |
fwrite(ib, (ib->len + 1) * 4, 1, f);
|
761 |
if (r)
|
762 |
{
|
763 |
for (k = 0; k < ib->clen / 2; k++)
|
764 |
{
|
765 |
if (rc)
|
766 |
bbox_extend(&c[k], r);
|
767 |
else
|
768 |
{
|
769 |
r->l = c[k];
|
770 |
r->h = c[k];
|
771 |
}
|
772 |
rc++;
|
773 |
}
|
774 |
}
|
775 |
}
|
776 |
fclose(f);
|
777 |
return 1;
|
778 |
}
|
779 |
return 0;
|
780 |
}
|
781 |
|