/[zanavi_public1]/navit/navit/maptool/osm.c
ZANavi

Contents of /navit/navit/maptool/osm.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 36 - (show annotations) (download)
Sat Mar 8 17:10:49 2014 UTC (10 years, 1 month ago) by zoff99
File MIME type: text/plain
File size: 80595 byte(s)
new market version, lots of new features
1 /**
2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2011 Navit Team
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 #include <unistd.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <math.h>
23 #include "maptool.h"
24 #include "debug.h"
25 #include "linguistics.h"
26 #include "country.h"
27 #include "file.h"
28
29 #define _FILE_OFFSET_BITS 64
30 #define _LARGEFILE_SOURCE
31 #define _LARGEFILE64_SOURCE
32
33 extern int doway2poi;
34
35 static int in_way, in_node, in_relation;
36 static int nodeid,wayid;
37 long long current_id;
38
39 static GHashTable *attr_hash,*country_table_hash,*attr_hash;
40
41 static char *attr_present;
42 static int attr_present_count;
43
44 static struct item_bin item;
45
46
47 int maxspeed_attr_value;
48
49 char debug_attr_buffer[BUFFER_SIZE];
50
51 int flags[4];
52
53 int flags_attr_value;
54
55 struct attr_bin osmid_attr;
56 long int osmid_attr_value;
57
58 char is_in_buffer[BUFFER_SIZE];
59
60 char attr_strings_buffer[BUFFER_SIZE*16];
61 int attr_strings_buffer_len;
62
63
64 struct coord coord_buffer[65536];
65
66 struct attr_mapping {
67 enum item_type type;
68 int attr_present_idx_count;
69 int attr_present_idx[0];
70 };
71
72 static void nodes_ref_item_bin(struct item_bin *ib);
73
74
75 static struct attr_mapping **attr_mapping_node;
76 static int attr_mapping_node_count;
77 static struct attr_mapping **attr_mapping_way;
78 static int attr_mapping_way_count;
79 static struct attr_mapping **attr_mapping_way2poi;
80 static int attr_mapping_way2poi_count;
81
82 static char *attr_present;
83 static int attr_present_count;
84
85
86
87 enum attr_strings {
88 attr_string_phone,
89 attr_string_fax,
90 attr_string_email,
91 attr_string_url,
92 attr_string_street_name,
93 attr_string_street_name_systematic,
94 attr_string_house_number,
95 attr_string_label,
96 attr_string_postal,
97 attr_string_population,
98 attr_string_county_name,
99 attr_string_last,
100 };
101
102 char *attr_strings[attr_string_last];
103
104 char *osm_types[]={"unknown","node","way","relation"};
105
106 #define IS_REF(c) ((c).x >= (1 << 30))
107 #define REF(c) ((c).y)
108 #define SET_REF(c,ref) do { (c).x = 1 << 30; (c).y = ref ; } while(0)
109
110 struct country_table {
111 int countryid;
112 char *names;
113 char *admin_levels;
114 FILE *file;
115 int size;
116 struct rect r;
117 } country_table[] = {
118 { 4,"Afghanistan"},
119 { 8,"Albania"},
120 { 10,"Antarctica"},
121 { 12,"Algeria"},
122 { 16,"American Samoa"},
123 { 20,"Andorra"},
124 { 24,"Angola"},
125 { 28,"Antigua and Barbuda"},
126 { 31,"Azerbaijan"},
127 { 32,"Argentina,República Argentina,AR "},
128 { 36,"Australia,AUS"},
129 { 40,"Austria,Österreich,AUT"},
130 { 44,"Bahamas"},
131 { 48,"Bahrain"},
132 { 50,"Bangladesh"},
133 { 51,"Armenia"},
134 { 52,"Barbados"},
135 { 56,"Belgium,Belgique,Belgie,België,Belgien"},
136 { 60,"Bermuda"},
137 { 64,"Bhutan"},
138 { 68,"Bolivia, Plurinational State of"},
139 { 70,"Bosnia and Herzegovina,Bosna i Hercegovina,Босна и Херцеговина"},
140 { 72,"Botswana"},
141 { 74,"Bouvet Island"},
142 { 76,"Brazil"},
143 { 84,"Belize"},
144 { 86,"British Indian Ocean Territory"},
145 { 90,"Solomon Islands"},
146 { 92,"Virgin Islands, British"},
147 { 96,"Brunei Darussalam"},
148 { 100,"Bulgaria,България"},
149 { 104,"Myanmar"},
150 { 108,"Burundi"},
151 { 112,"Belarus"},
152 { 116,"Cambodia"},
153 { 120,"Cameroon"},
154 { 124,"Canada"},
155 { 132,"Cape Verde"},
156 { 136,"Cayman Islands"},
157 { 140,"Central African Republic"},
158 { 144,"Sri Lanka"},
159 { 148,"Chad"},
160 { 152,"Chile"},
161 { 156,"China"},
162 { 158,"Taiwan, Province of China"},
163 { 162,"Christmas Island"},
164 { 166,"Cocos (Keeling) Islands"},
165 { 170,"Colombia"},
166 { 174,"Comoros"},
167 { 175,"Mayotte"},
168 { 178,"Congo"},
169 { 180,"Congo, the Democratic Republic of the"},
170 { 184,"Cook Islands"},
171 { 188,"Costa Rica"},
172 { 191,"Croatia,Republika Hrvatska,HR"},
173 { 192,"Cuba"},
174 { 196,"Cyprus"},
175 { 203,"Czech Republic,Česká republika,CZ"},
176 { 204,"Benin"},
177 { 208,"Denmark,Danmark,DK"},
178 { 212,"Dominica"},
179 { 214,"Dominican Republic"},
180 { 218,"Ecuador"},
181 { 222,"El Salvador"},
182 { 226,"Equatorial Guinea"},
183 { 231,"Ethiopia"},
184 { 232,"Eritrea"},
185 { 233,"Estonia"},
186 { 234,"Faroe Islands,Føroyar"},
187 { 238,"Falkland Islands (Malvinas)"},
188 { 239,"South Georgia and the South Sandwich Islands"},
189 { 242,"Fiji"},
190 { 246,"Finland,Suomi"},
191 { 248,"Åland Islands"},
192 { 250,"France,République française,FR"},
193 { 254,"French Guiana"},
194 { 258,"French Polynesia"},
195 { 260,"French Southern Territories"},
196 { 262,"Djibouti"},
197 { 266,"Gabon"},
198 { 268,"Georgia"},
199 { 270,"Gambia"},
200 { 275,"Palestinian Territory, Occupied"},
201 { 276,"Germany,Deutschland,Bundesrepublik Deutschland","345c7m"},
202 { 288,"Ghana"},
203 { 292,"Gibraltar"},
204 { 296,"Kiribati"},
205 { 300,"Greece"},
206 { 304,"Greenland"},
207 { 308,"Grenada"},
208 { 312,"Guadeloupe"},
209 { 316,"Guam"},
210 { 320,"Guatemala"},
211 { 324,"Guinea"},
212 { 328,"Guyana"},
213 { 332,"Haiti"},
214 { 334,"Heard Island and McDonald Islands"},
215 { 336,"Holy See (Vatican City State)"},
216 { 340,"Honduras"},
217 { 344,"Hong Kong"},
218 { 348,"Hungary,Magyarország"},
219 { 352,"Iceland"},
220 { 356,"India"},
221 { 360,"Indonesia"},
222 { 364,"Iran, Islamic Republic of"},
223 { 368,"Iraq"},
224 { 372,"Ireland"},
225 { 376,"Israel"},
226 { 380,"Italy,Italia"},
227 { 384,"Côte d'Ivoire"},
228 { 388,"Jamaica"},
229 { 392,"Japan"},
230 { 398,"Kazakhstan"},
231 { 400,"Jordan"},
232 { 404,"Kenya"},
233 { 408,"Korea, Democratic People's Republic of"},
234 { 410,"Korea, Republic of"},
235 { 414,"Kuwait"},
236 { 417,"Kyrgyzstan"},
237 { 418,"Lao People's Democratic Republic"},
238 { 422,"Lebanon"},
239 { 426,"Lesotho"},
240 { 428,"Latvia"},
241 { 430,"Liberia"},
242 { 434,"Libyan Arab Jamahiriya"},
243 { 438,"Liechtenstein"},
244 { 440,"Lithuania,Lietuva"},
245 { 442,"Luxembourg"},
246 { 446,"Macao"},
247 { 450,"Madagascar"},
248 { 454,"Malawi"},
249 { 458,"Malaysia"},
250 { 462,"Maldives"},
251 { 466,"Mali"},
252 { 470,"Malta"},
253 { 474,"Martinique"},
254 { 478,"Mauritania"},
255 { 480,"Mauritius"},
256 { 484,"Mexico"},
257 { 492,"Monaco"},
258 { 496,"Mongolia"},
259 { 498,"Moldova, Republic of"},
260 { 499,"Montenegro,Црна Гора,Crna Gora"},
261 { 500,"Montserrat"},
262 { 504,"Morocco"},
263 { 508,"Mozambique"},
264 { 512,"Oman"},
265 { 516,"Namibia"},
266 { 520,"Nauru"},
267 { 524,"Nepal"},
268 { 528,"Nederland,The Netherlands,Niederlande,NL,Netherlands"},
269 { 530,"Netherlands Antilles"},
270 { 533,"Aruba"},
271 { 540,"New Caledonia"},
272 { 548,"Vanuatu"},
273 { 554,"New Zealand"},
274 { 558,"Nicaragua"},
275 { 562,"Niger"},
276 { 566,"Nigeria"},
277 { 570,"Niue"},
278 { 574,"Norfolk Island"},
279 { 578,"Norway,Norge,Noreg,NO"},
280 { 580,"Northern Mariana Islands"},
281 { 581,"United States Minor Outlying Islands"},
282 { 583,"Micronesia, Federated States of"},
283 { 584,"Marshall Islands"},
284 { 585,"Palau"},
285 { 586,"Pakistan"},
286 { 591,"Panama"},
287 { 598,"Papua New Guinea"},
288 { 600,"Paraguay"},
289 { 604,"Peru"},
290 { 608,"Philippines"},
291 { 612,"Pitcairn"},
292 { 616,"Poland,Polska,PL"},
293 { 620,"Portugal"},
294 { 624,"Guinea-Bissau"},
295 { 626,"Timor-Leste"},
296 { 630,"Puerto Rico"},
297 { 634,"Qatar"},
298 { 638,"Réunion"},
299 { 642,"România,Romania,RO"},
300 { 643,"Россия,Российская Федерация,Russia,Russian Federation"},
301 { 646,"Rwanda"},
302 { 652,"Saint Barthélemy"},
303 { 654,"Saint Helena, Ascension and Tristan da Cunha"},
304 { 659,"Saint Kitts and Nevis"},
305 { 660,"Anguilla"},
306 { 662,"Saint Lucia"},
307 { 663,"Saint Martin (French part)"},
308 { 666,"Saint Pierre and Miquelon"},
309 { 670,"Saint Vincent and the Grenadines"},
310 { 674,"San Marino"},
311 { 678,"Sao Tome and Principe"},
312 { 682,"Saudi Arabia"},
313 { 686,"Senegal"},
314 { 688,"Srbija,Србија,Serbia"},
315 { 690,"Seychelles"},
316 { 694,"Sierra Leone"},
317 { 702,"Singapore"},
318 { 703,"Slovakia,Slovensko,SK"},
319 { 704,"Viet Nam"},
320 { 705,"Slovenia,Republika Slovenija,SI"},
321 { 706,"Somalia"},
322 { 710,"South Africa"},
323 { 716,"Zimbabwe"},
324 { 724,"Spain,Espana,España,Reino de Espana,Reino de España"},
325 { 732,"Western Sahara"},
326 { 736,"Sudan"},
327 { 740,"Suriname"},
328 { 744,"Svalbard and Jan Mayen"},
329 { 748,"Swaziland"},
330 { 752,"Sweden,Sverige,Konungariket Sverige,SE"},
331 { 756,"Switzerland,Schweiz"},
332 { 760,"Syrian Arab Republic"},
333 { 762,"Tajikistan"},
334 { 764,"Thailand"},
335 { 768,"Togo"},
336 { 772,"Tokelau"},
337 { 776,"Tonga"},
338 { 780,"Trinidad and Tobago"},
339 { 784,"United Arab Emirates"},
340 { 788,"Tunisia"},
341 { 792,"Turkey"},
342 { 795,"Turkmenistan"},
343 { 796,"Turks and Caicos Islands"},
344 { 798,"Tuvalu"},
345 { 800,"Uganda"},
346 { 804,"Ukraine"},
347 { 807,"Macedonia,Македонија"},
348 { 818,"Egypt"},
349 { 826,"United Kingdom,UK"},
350 { 831,"Guernsey"},
351 { 832,"Jersey"},
352 { 833,"Isle of Man"},
353 { 834,"Tanzania, United Republic of"},
354 { 840,"USA"},
355 { 850,"Virgin Islands, U.S."},
356 { 854,"Burkina Faso"},
357 { 858,"Uruguay"},
358 { 860,"Uzbekistan"},
359 { 862,"Venezuela, Bolivarian Republic of"},
360 { 876,"Wallis and Futuna"},
361 { 882,"Samoa"},
362 { 887,"Yemen"},
363 { 894,"Zambia"},
364 { 999,"Unknown"},
365 };
366
367 // first char - item type
368 // =w - ways
369 // =? - used both for nodes and ways
370 // otherwise - nodes
371
372
373 // for coastline-only map
374 static char *attrmap_cl={
375 "n *=* point_unkn\n"
376 "w *=* street_unkn\n"
377 "w natural=coastline water_line\n"
378 };
379
380 // for border-only map
381 static char *attrmap_bo={
382 "n *=* point_unkn\n"
383 "w *=* street_unkn\n"
384 "w boundary=administrative,admin_level=2 border_country\n"
385 "w boundary=territorial,admin_level=2 border_country\n"
386 "w boundary=maritime,admin_level=2 border_country\n"
387 "w administrative=boundary,admin_level=2 border_country\n"
388 "w boundary=administrative,maritime=yes,admin_level=4 border_country\n"
389 "w boundary=administrative,border_type=state,admin_level=4 border_country\n"
390 };
391
392 // ==========================
393 // for USA
394 // ==========================
395 // admin_level = 4
396 // border_type = state
397 // boundary = administrative
398 // ==========================
399
400
401 // for normal map
402 static char *attrmap_normal={
403 "n *=* point_unkn\n"
404 //// "n Annehmlichkeit=Hochsitz poi_hunting_stand\n"
405 "n addr:housenumber=* house_number\n"
406 "n aeroway=aerodrome poi_airport\n"
407 "n aeroway=airport poi_airport\n"
408 "n aeroway=helipad poi_heliport\n"
409 "n aeroway=terminal poi_airport\n"
410 "n amenity=atm poi_bank\n"
411 "n amenity=bank poi_bank\n"
412 "n amenity=bar poi_bar\n"
413 //"n amenity=bench poi_bench\n"
414 "n amenity=biergarten poi_biergarten\n"
415 "n amenity=bus_station poi_bus_station\n"
416 "n amenity=cafe poi_cafe\n"
417 "n amenity=car_wash poi_car_wash\n"
418 "n amenity=cinema poi_cinema\n"
419 "n amenity=college poi_school_college\n"
420 "n amenity=courthouse poi_justice\n"
421 //"n amenity=drinking_water poi_potable_water\n"
422 "n amenity=fast_food poi_fastfood\n"
423 "n amenity=fire_station poi_firebrigade\n"
424 //"n amenity=fountain poi_fountain\n"
425 "n amenity=fuel poi_fuel\n"
426 "n amenity=grave_yard poi_cemetery\n"
427 "n amenity=hospital poi_hospital\n"
428 //"n amenity=hunting_stand poi_hunting_stand\n"
429 "n amenity=kindergarten poi_kindergarten\n"
430 "n amenity=library poi_library\n"
431 "n amenity=nightclub poi_nightclub\n"
432 //"n amenity=park_bench poi_bench\n"
433 "n amenity=parking poi_car_parking\n"
434 "n amenity=pharmacy poi_pharmacy\n"
435 "n amenity=place_of_worship,religion=christian poi_church\n"
436 "n amenity=place_of_worship poi_worship\n"
437 "n amenity=police poi_police\n"
438 //"n amenity=post_box poi_post_box\n"
439 "n amenity=post_office poi_post_office\n"
440 "n amenity=prison poi_prison\n"
441 "n amenity=pub poi_pub\n"
442 "n amenity=public_building poi_public_office\n"
443 //"n amenity=recycling poi_recycling\n"
444 "n amenity=restaurant,cuisine=fine_dining poi_dining\n"
445 "n amenity=restaurant poi_restaurant\n"
446 "n amenity=school poi_school\n"
447 //"n amenity=shelter poi_shelter\n"
448 "n amenity=taxi poi_taxi\n"
449 //"n amenity=tec_common tec_common\n"
450 //"n amenity=telephone poi_telephone\n"
451 "n amenity=theatre poi_theater\n"
452 "n amenity=toilets poi_restroom\n"
453 "n amenity=townhall poi_townhall\n"
454 "n amenity=university poi_school_university\n"
455 //"n amenity=vending_machine poi_vending_machine\n"
456 "n barrier=bollard barrier_bollard\n"
457 "n barrier=cycle_barrier barrier_cycle\n"
458 "n barrier=lift_gate barrier_lift_gate\n"
459 //"n car=car_rental poi_car_rent\n"
460 "n highway=bus_station poi_bus_station\n"
461 "n highway=bus_stop poi_bus_stop\n"
462 "n highway=mini_roundabout mini_roundabout\n"
463 "n highway=motorway_junction highway_exit\n"
464 "n highway=stop traffic_sign_stop\n"
465 "n highway=toll_booth poi_toll_booth\n"
466 "n highway=traffic_signals traffic_signals\n"
467 "n highway=turning_circle turning_circle\n"
468 //"n historic=boundary_stone poi_boundary_stone\n"
469 "n historic=castle poi_castle\n"
470 "n historic=memorial poi_memorial\n"
471 "n historic=monument poi_monument\n"
472 "n historic=ruins poi_ruins\n"
473 //// "n historic=* poi_ruins\n"
474 "n landuse=cemetery poi_cemetery\n"
475 //"n leisure=fishing poi_fish\n"
476 "n leisure=golf_course poi_golf\n"
477 "n leisure=marina poi_marine\n"
478 //"n leisure=playground poi_playground\n"
479 //"n leisure=slipway poi_boat_ramp\n"
480 //"n leisure=sports_centre poi_sport\n"
481 "n leisure=stadium poi_stadium\n"
482 //"n man_made=tower poi_tower\n"
483 "n military=airfield poi_military\n"
484 //"n military=barracks poi_military\n"
485 //"n military=bunker poi_military\n"
486 "n military=danger_area poi_danger_area\n"
487 "n military=range poi_military\n"
488 "n natural=bay poi_bay\n"
489 "n natural=peak,ele=* poi_peak\n" // show only major peaks with elevation
490 //"n natural=tree poi_tree\n"
491 "n place=city town_label_2e5\n"
492 "n place=hamlet town_label_2e2\n"
493 "n place=locality town_label_2e0\n"
494 "n place=suburb district_label\n"
495 "n place=town town_label_2e4\n"
496 "n place=village town_label_2e3\n"
497 //"n power=tower power_tower\n"
498 //"n power=sub_station power_substation\n"
499 "n railway=halt poi_rail_halt\n"
500 "n railway=level_crossing poi_level_crossing\n"
501 "n railway=station poi_rail_station\n"
502 "n railway=tram_stop poi_rail_tram_stop\n"
503 //"n shop=baker poi_shop_baker\n"
504 //"n shop=bakery poi_shop_baker\n"
505 //"n shop=beverages poi_shop_beverages\n"
506 //"n shop=bicycle poi_shop_bicycle\n"
507 //"n shop=butcher poi_shop_butcher\n"
508 "n shop=car poi_car_dealer_parts\n"
509 "n shop=car_repair poi_repair_service\n"
510 //"n shop=clothes poi_shop_apparel\n"
511 //"n shop=convenience poi_shop_grocery\n"
512 //"n shop=drogist poi_shop_drugstore\n"
513 //"n shop=florist poi_shop_florist\n"
514 //"n shop=fruit poi_shop_fruit\n"
515 //"n shop=furniture poi_shop_furniture\n"
516 //"n shop=garden_centre poi_shop_handg\n"
517 //"n shop=hardware poi_shop_handg\n"
518 //"n shop=hairdresser poi_hairdresser\n"
519 //"n shop=kiosk poi_shop_kiosk\n"
520 //"n shop=optician poi_shop_optician\n"
521 //"n shop=parfum poi_shop_parfum\n"
522 //"n shop=photo poi_shop_photo\n"
523 //"n shop=shoes poi_shop_shoes\n"
524 "n shop=supermarket poi_shopping\n"
525 //"n sport=10pin poi_bowling\n"
526 //"n sport=baseball poi_baseball\n"
527 //"n sport=basketball poi_basketball\n"
528 //"n sport=climbing poi_climbing\n"
529 //"n sport=golf poi_golf\n"
530 //"n sport=motor_sports poi_motor_sport\n"
531 //"n sport=skiing poi_skiing\n"
532 //"n sport=soccer poi_soccer\n"
533 "n sport=stadium poi_stadium\n"
534 "n sport=swimming poi_swimming\n"
535 //"n sport=tennis poi_tennis\n"
536 "n tourism=attraction poi_attraction\n"
537 "n tourism=camp_site poi_camp_rv\n"
538 "n tourism=caravan_site poi_camp_rv\n"
539 "n tourism=guest_house poi_guesthouse\n"
540 "n tourism=hostel poi_hostel\n"
541 "n tourism=hotel poi_hotel\n"
542 "n tourism=information poi_information\n"
543 "n tourism=motel poi_motel\n"
544 "n tourism=museum poi_museum_history\n"
545 //"n tourism=picnic_site poi_picnic\n"
546 "n tourism=theme_park poi_resort\n"
547 //"n tourism=viewpoint poi_viewpoint\n"
548 "n tourism=zoo poi_zoo\n"
549 "n traffic_sign=city_limit traffic_sign_city_limit\n"
550 "n highway=speed_camera tec_common\n"
551 "w *=* street_unkn\n"
552 "w addr:interpolation=even house_number_interpolation_even\n"
553 "w addr:interpolation=odd house_number_interpolation_odd\n"
554 "w addr:interpolation=all house_number_interpolation_all\n"
555 "w addr:interpolation=alphabetic house_number_interpolation_alphabetic\n"
556 //"w aerialway=cable_car lift_cable_car\n"
557 //"w aerialway=chair_lift lift_chair\n"
558 //"w aerialway=drag_lift lift_drag\n"
559 "w aeroway=aerodrome poly_airport\n"
560 "w aeroway=apron poly_apron\n"
561 "w aeroway=runway aeroway_runway\n"
562 "w aeroway=taxiway aeroway_taxiway\n"
563 "w aeroway=terminal poly_terminal\n"
564 "w amenity=college poly_college\n"
565 //"w amenity=grave_yard poly_cemetery\n"
566 "w amenity=parking poly_car_parking\n"
567 "w amenity=place_of_worship poly_building\n"
568 "w amenity=university poly_university\n"
569 // "w boundary=administrative,admin_level=2 border_country\n" --> in border map
570 //"w boundary=civil border_civil\n"
571 "w boundary=national_park border_national_park\n"
572 "w boundary=political border_political\n"
573 "w building=* poly_building\n"
574 "w contour_ext=elevation_major height_line_1\n"
575 "w contour_ext=elevation_medium height_line_2\n"
576 "w contour_ext=elevation_minor height_line_3\n"
577 "w highway=bridleway bridleway\n"
578 "w highway=bus_guideway bus_guideway\n"
579 "w highway=construction street_construction\n"
580 "w highway=cyclepath cycleway\n"
581 "w highway=cycleway cycleway\n"
582 "w highway=footway footway\n"
583 "w highway=footway,piste:type=nordic footway_and_piste_nordic\n"
584 "w highway=living_street living_street\n"
585 "w highway=minor street_1_land\n"
586 "w highway=parking_lane street_parking_lane\n"
587 "w highway=path path\n"
588 "w highway=path,bicycle=designated cycleway\n"
589 "w highway=path,bicycle=official cycleway\n"
590 "w highway=path,foot=designated footway\n"
591 "w highway=path,foot=official footway\n"
592 "w highway=path,horse=designated bridleway\n"
593 "w highway=path,horse=official bridleway\n"
594 //"w highway=path,sac_scale=alpine_hiking hiking_alpine\n"
595 //"w highway=path,sac_scale=demanding_alpine_hiking hiking_alpine_demanding\n"
596 //"w highway=path,sac_scale=demanding_mountain_hiking hiking_mountain_demanding\n"
597 //"w highway=path,sac_scale=difficult_alpine_hiking hiking_alpine_difficult\n"
598 //"w highway=path,sac_scale=hiking hiking\n"
599 //"w highway=path,sac_scale=mountain_hiking hiking_mountain\n"
600 "w highway=pedestrian street_pedestrian\n"
601 "w highway=pedestrian,area=1 poly_pedestrian\n"
602 "w highway=plaza poly_plaza\n"
603 "w highway=motorway highway_land\n"
604 "w highway=motorway,rural=0 highway_city\n"
605 "w highway=motorway_link ramp\n"
606 "w highway=trunk street_4_land\n"
607 "w highway=trunk,name=*,rural=1 street_4_land\n"
608 "w highway=trunk,name=* street_4_city\n"
609 "w highway=trunk,rural=0 street_4_city\n"
610 "w highway=trunk_link ramp\n"
611 "w highway=primary street_4_land\n"
612 "w highway=primary,name=*,rural=1 street_4_land\n"
613 "w highway=primary,name=* street_4_city\n"
614 "w highway=primary,rural=0 street_4_city\n"
615 "w highway=primary_link ramp\n"
616 "w highway=secondary street_3_land\n"
617 "w highway=secondary,name=*,rural=1 street_3_land\n"
618 "w highway=secondary,name=* street_3_city\n"
619 "w highway=secondary,rural=0 street_3_city\n"
620 "w highway=secondary,area=1 poly_street_3\n"
621 "w highway=secondary_link ramp\n"
622 "w highway=tertiary street_2_land\n"
623 "w highway=tertiary,name=*,rural=1 street_2_land\n"
624 "w highway=tertiary,name=* street_2_city\n"
625 "w highway=tertiary,rural=0 street_2_city\n"
626 "w highway=tertiary,area=1 poly_street_2\n"
627 "w highway=tertiary_link ramp\n"
628 "w highway=residential street_1_city\n"
629 "w highway=residential,area=1 poly_street_1\n"
630 "w highway=unclassified street_1_city\n"
631 "w highway=unclassified,area=1 poly_street_1\n"
632 "w highway=road street_1_city\n"
633 "w highway=service street_service\n"
634 "w highway=service,area=1 poly_service\n"
635 "w highway=service,service=parking_aisle street_parking_lane\n"
636 "w highway=track track_gravelled\n"
637 "w highway=track,surface=grass track_grass\n"
638 "w highway=track,surface=gravel track_gravelled\n"
639 "w highway=track,surface=ground track_ground\n"
640 "w highway=track,surface=paved track_paved\n"
641 "w highway=track,surface=unpaved track_unpaved\n"
642 "w highway=track,tracktype=grade1 track_paved\n"
643 "w highway=track,tracktype=grade2 track_gravelled\n"
644 "w highway=track,tracktype=grade3 track_unpaved\n"
645 "w highway=track,tracktype=grade4 track_ground\n"
646 "w highway=track,tracktype=grade5 track_grass\n"
647 "w highway=track,surface=paved,tracktype=grade1 track_paved\n"
648 "w highway=track,surface=gravel,tracktype=grade2 track_gravelled\n"
649 "w highway=track,surface=unpaved,tracktype=grade3 track_unpaved\n"
650 "w highway=track,surface=ground,tracktype=grade4 track_ground\n"
651 "w highway=track,surface=grass,tracktype=grade5 track_grass\n"
652 "w highway=unsurfaced track_gravelled\n"
653 "w highway=steps steps\n"
654 "w historic=archaeological_site poly_archaeological_site\n"
655 "w historic=battlefield poly_battlefield\n"
656 "w historic=ruins poly_ruins\n"
657 "w historic=town gate poly_building\n"
658 //"w landuse=allotments poly_allotments\n"
659 //"w landuse=basin poly_basin\n"
660 //"w landuse=brownfield poly_brownfield\n"
661 "w landuse=cemetery poly_cemetery\n"
662 //"w landuse=commercial poly_commercial\n"
663 //"w landuse=construction poly_construction\n"
664 //"w landuse=farm poly_farm\n"
665 //"w landuse=farmland poly_farm\n"
666 //"w landuse=farmyard poly_town\n"
667 "w landuse=forest poly_wood\n"
668 "w landuse=greenfield poly_greenfield\n"
669 //"w landuse=industrial poly_industry\n"
670 //"w landuse=landfill poly_landfill\n"
671 "w landuse=military poly_military\n"
672 "w landuse=plaza poly_plaza\n"
673 //"w landuse=quarry poly_quarry\n"
674 "w landuse=railway poly_railway\n"
675 //"w landuse=recreation_ground poly_recreation_ground\n"
676 "w landuse=reservoir poly_reservoir\n"
677 //"w landuse=residential poly_town\n"
678 //"w landuse=residential,area=1 poly_town\n"
679 //"w landuse=retail poly_retail\n"
680 //"w landuse=village_green poly_village_green\n"
681 //"w landuse=vineyard poly_farm\n"
682 //"w leisure=common poly_common\n"
683 //"w leisure=fishing poly_fishing\n"
684 //"w leisure=garden poly_garden\n"
685 //"w leisure=golf_course poly_golf_course\n"
686 //"w leisure=marina poly_marina\n"
687 //"w leisure=nature_reserve poly_nature_reserve\n"
688 "w leisure=park poly_park\n"
689 //"w leisure=pitch poly_sports_pitch\n"
690 "w leisure=playground poly_playground\n"
691 //"w leisure=sports_centre poly_sport\n"
692 "w leisure=stadium poly_sports_stadium\n"
693 //"w leisure=track poly_sports_track\n"
694 "w leisure=water_park poly_water_park\n"
695 "w military=airfield poly_airfield\n"
696 //"w military=barracks poly_barracks\n"
697 "w military=danger_area poly_danger_area\n"
698 "w military=naval_base poly_naval_base\n"
699 //"w military=range poly_range\n"
700 "w natural=beach poly_beach\n"
701 // "w natural=coastline water_line\n" --> in coastline map
702 "w natural=fell poly_fell\n"
703 "w natural=glacier poly_glacier\n"
704 "w natural=heath poly_heath\n"
705 "w natural=land poly_land\n"
706 "w natural=marsh poly_marsh\n"
707 "w natural=mud poly_mud\n"
708 "w natural=scree poly_scree\n"
709 "w natural=scrub poly_scrub\n"
710 "w natural=water poly_water\n"
711 "w natural=wood poly_wood\n"
712 //"w piste:type=downhill,piste:difficulty=advanced piste_downhill_advanced\n"
713 //"w piste:type=downhill,piste:difficulty=easy piste_downhill_easy\n"
714 //"w piste:type=downhill,piste:difficulty=expert piste_downhill_expert\n"
715 //"w piste:type=downhill,piste:difficulty=freeride piste_downhill_freeride\n"
716 //"w piste:type=downhill,piste:difficulty=intermediate piste_downhill_intermediate\n"
717 //"w piste:type=downhill,piste:difficulty=novice piste_downhill_novice\n"
718 //"w piste:type=nordic piste_nordic\n"
719 "w place=suburb poly_place1\n"
720 "w place=hamlet poly_place2\n"
721 "w place=village poly_place3\n"
722 "w place=municipality poly_place4\n"
723 "w place=town poly_place5\n"
724 "w place=city poly_place6\n"
725 //"w power=line powerline\n"
726 //"w railway=abandoned rail_abandoned\n"
727 //"w railway=disused rail_disused\n"
728 //"w railway=light_rail rail_light\n"
729 //"w railway=monorail rail_mono\n"
730 //"w railway=narrow_gauge rail_narrow_gauge\n"
731 //"w railway=preserved rail_preserved\n"
732 "w railway=rail rail\n"
733 "w railway=subway rail_subway\n"
734 "w railway=tram rail_tram\n"
735 "w route=ferry ferry\n"
736 //"w route=ski piste_nordic\n"
737 //"w sport=* poly_sport\n"
738 "w tourism=artwork poly_artwork\n"
739 "w tourism=attraction poly_attraction\n"
740 "w tourism=camp_site poly_camp_site\n"
741 "w tourism=caravan_site poly_caravan_site\n"
742 "w tourism=picnic_site poly_picnic_site\n"
743 "w tourism=theme_park poly_theme_park\n"
744 "w tourism=zoo poly_zoo\n"
745 "w waterway=canal water_canal\n"
746 "w waterway=drain water_drain\n"
747 "w waterway=river water_river\n"
748 "w waterway=riverbank poly_water\n"
749 "w waterway=stream water_stream\n"
750 "w barrier=ditch ditch\n"
751 "w barrier=hedge hedge\n"
752 "w barrier=fence fence\n"
753 "w barrier=wall wall\n"
754 "w barrier=retaining_wall retaining_wall\n"
755 "w barrier=city_wall city_wall\n"
756 };
757
758
759
760 static void
761 build_attrmap_line(char *line)
762 {
763 char *t=NULL,*kvl=NULL,*i=NULL,*p,*kv;
764 struct attr_mapping *attr_mapping=g_malloc0(sizeof(struct attr_mapping));
765 int idx,attr_mapping_count=0;
766 t=line;
767 p=strchr(t,'\t');
768 if (p) {
769 while (*p == '\t')
770 *p++='\0';
771 kvl=p;
772 p=strchr(kvl,'\t');
773 }
774 if (p) {
775 while (*p == '\t')
776 *p++='\0';
777 i=p;
778 }
779 if (t[0] == 'w') {
780 if (! i)
781 i="street_unkn";
782 } else {
783 if (! i)
784 i="point_unkn";
785 }
786 attr_mapping->type=item_from_name(i);
787 if (!attr_mapping->type) {
788 printf("no id found for '%s'\n",i);
789 }
790 while ((kv=strtok(kvl, ","))) {
791 kvl=NULL;
792 if (!(idx=(int)(long)g_hash_table_lookup(attr_hash, kv))) {
793 idx=attr_present_count++;
794 g_hash_table_insert(attr_hash, kv, (gpointer)(long)idx);
795 }
796 attr_mapping=g_realloc(attr_mapping, sizeof(struct attr_mapping)+(attr_mapping_count+1)*sizeof(int));
797 attr_mapping->attr_present_idx[attr_mapping_count++]=idx;
798 attr_mapping->attr_present_idx_count=attr_mapping_count;
799 }
800 if (t[0]== 'w') {
801 attr_mapping_way=g_realloc(attr_mapping_way, sizeof(*attr_mapping_way)*(attr_mapping_way_count+1));
802 attr_mapping_way[attr_mapping_way_count++]=attr_mapping;
803 }
804 if (t[0]== '?' && doway2poi) {
805 attr_mapping_way2poi=g_realloc(attr_mapping_way2poi, sizeof(*attr_mapping_way2poi)*(attr_mapping_way2poi_count+1));
806 attr_mapping_way2poi[attr_mapping_way2poi_count++]=attr_mapping;
807 }
808 if (t[0]!= 'w') {
809 attr_mapping_node=g_realloc(attr_mapping_node, sizeof(*attr_mapping_node)*(attr_mapping_node_count+1));
810 attr_mapping_node[attr_mapping_node_count++]=attr_mapping;
811 }
812
813 }
814
815 static void
816 build_attrmap(FILE* rule_file)
817 {
818 attr_hash=g_hash_table_new(g_str_hash, g_str_equal);
819 attr_present_count=1;
820
821 // build attribute map from rule file if given
822 if( rule_file )
823 {
824 char buffer[200], *p;
825 while (fgets( buffer, 200, rule_file )) {
826 p=strchr(buffer,'\n');
827 if(p)
828 *p = 0;
829 build_attrmap_line( g_strdup( buffer ) );
830 }
831 fclose( rule_file );
832 }
833 // use hardcoded default attributes
834 else
835 {
836 char *p,*map;
837 if (border_only_map==1)
838 {
839 map=g_strdup(attrmap_bo);
840 }
841 else if (coastline_only_map==1)
842 {
843 map=g_strdup(attrmap_cl);
844 }
845 else
846 {
847 map=g_strdup(attrmap_normal);
848 }
849
850 while (map) {
851 p=strchr(map,'\n');
852 if (p)
853 *p++='\0';
854 if (strlen(map))
855 build_attrmap_line(map);
856 map=p;
857 }
858 }
859
860 attr_present=g_malloc0(sizeof(*attr_present)*attr_present_count);
861 }
862
863 static void
864 build_countrytable(void)
865 {
866 int i;
867 char *names,*str,*tok;
868 country_table_hash=g_hash_table_new(g_str_hash, g_str_equal);
869 for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) {
870 names=g_strdup(country_table[i].names);
871 str=names;
872 while ((tok=strtok(str, ","))) {
873 str=NULL;
874 g_hash_table_insert(country_table_hash, tok, (gpointer)&country_table[i]);
875 }
876 }
877 }
878
879 void
880 osm_warning(char *type, long long id, int cont, char *fmt, ...)
881 {
882 char str[4096];
883 va_list ap;
884 va_start(ap, fmt);
885 vsnprintf(str, sizeof(str), fmt, ap);
886 va_end(ap);
887 fprintf(stderr,"%shttp://www.openstreetmap.org/browse/%s/"LONGLONG_FMT" %s",cont ? "":"OSM Warning:",type,id,str);
888 }
889
890 void
891 osm_info(char *type, long long id, int cont, char *fmt, ...)
892 {
893 char str[4096];
894 va_list ap;
895 va_start(ap, fmt);
896 vsnprintf(str, sizeof(str), fmt, ap);
897 va_end(ap);
898 fprintf(stderr,"%shttp://www.openstreetmap.org/browse/%s/"LONGLONG_FMT" %s",cont ? "":"OSM Info:",type,id,str);
899 }
900
901 static void
902 attr_strings_clear(void)
903 {
904 attr_strings_buffer_len=0;
905 memset(attr_strings, 0, sizeof(attr_strings));
906 }
907
908 static void
909 attr_strings_save(enum attr_strings id, char *str)
910 {
911 attr_strings[id]=attr_strings_buffer+attr_strings_buffer_len;
912 strcpy(attr_strings[id], str);
913 attr_strings_buffer_len+=strlen(str)+1;
914 }
915
916 long long
917 item_bin_get_nodeid(struct item_bin *ib)
918 {
919 long long *ret=item_bin_get_attr(ib, attr_osm_nodeid, NULL);
920 if (ret)
921 return *ret;
922 return 0;
923 }
924
925 long long
926 item_bin_get_wayid(struct item_bin *ib)
927 {
928 long long *ret=item_bin_get_attr(ib, attr_osm_wayid, NULL);
929 if (ret)
930 return *ret;
931 return 0;
932 }
933
934 long long
935 item_bin_get_relationid(struct item_bin *ib)
936 {
937 long long *ret=item_bin_get_attr(ib, attr_osm_relationid, NULL);
938 if (ret)
939 return *ret;
940 return 0;
941 }
942
943 long long
944 item_bin_get_id(struct item_bin *ib)
945 {
946 long long ret;
947 if (ib->type < 0x80000000)
948 return item_bin_get_nodeid(ib);
949 ret=item_bin_get_wayid(ib);
950 if (!ret)
951 ret=item_bin_get_relationid(ib);
952 return ret;
953 }
954
955 static int node_is_tagged;
956 static void relation_add_tag(char *k, char *v);
957
958 static int
959 access_value(char *v)
960 {
961 if (!strcmp(v,"1"))
962 return 1;
963 if (!strcmp(v,"yes"))
964 return 1;
965 if (!strcmp(v,"designated"))
966 return 1;
967 if (!strcmp(v,"official"))
968 return 1;
969 if (!strcmp(v,"permissive"))
970 return 1;
971 if (!strcmp(v,"0"))
972 return 2;
973 if (!strcmp(v,"no"))
974 return 2;
975 if (!strcmp(v,"agricultural"))
976 return 2;
977 if (!strcmp(v,"forestry"))
978 return 2;
979 if (!strcmp(v,"private"))
980 return 2;
981 if (!strcmp(v,"delivery"))
982 return 2;
983 if (!strcmp(v,"destination"))
984 return 2;
985 return 3;
986 }
987
988 void
989 osm_add_tag(char *k, char *v)
990 {
991 int idx,level=2;
992 char buffer[BUFFER_SIZE*2+2];
993 if (in_relation) {
994 relation_add_tag(k,v);
995 return;
996 }
997 if (! strcmp(k,"ele"))
998 level=9;
999 if (! strcmp(k,"time"))
1000 level=9;
1001 if (! strcmp(k,"created_by"))
1002 level=9;
1003 if (! strncmp(k,"tiger:",6) || !strcmp(k,"AND_nodes"))
1004 level=9;
1005 if (! strcmp(k,"converted_by") || ! strcmp(k,"source"))
1006 level=8;
1007 if (! strncmp(k,"osmarender:",11) || !strncmp(k,"svg:",4))
1008 level=8;
1009 if (! strcmp(k,"layer"))
1010 level=7;
1011 if (! strcasecmp(v,"true") || ! strcasecmp(v,"yes"))
1012 v="1";
1013 if (! strcasecmp(v,"false") || ! strcasecmp(v,"no"))
1014 v="0";
1015 if (! strcmp(k,"oneway")) {
1016 if (!strcmp(v,"1")) {
1017 flags[0] |= AF_ONEWAY | AF_ROUNDABOUT_VALID;
1018 }
1019 if (! strcmp(v,"-1")) {
1020 flags[0] |= AF_ONEWAYREV | AF_ROUNDABOUT_VALID;
1021 }
1022 if (!in_way)
1023 level=6;
1024 else
1025 level=5;
1026 }
1027 if (! strcmp(k,"junction")) {
1028 if (! strcmp(v,"roundabout"))
1029 flags[0] |= AF_ONEWAY | AF_ROUNDABOUT | AF_ROUNDABOUT_VALID;
1030 }
1031 if (! strcmp(k,"maxspeed")) {
1032 if (strstr(v, "mph")) {
1033 maxspeed_attr_value = (int)floor(atof(v) * 1.609344);
1034 } else {
1035 maxspeed_attr_value = atoi(v);
1036 }
1037 if (maxspeed_attr_value)
1038 flags[0] |= AF_SPEED_LIMIT;
1039 level=5;
1040 }
1041 if (! strcmp(k,"toll")) {
1042 if (!strcmp(v,"1")) {
1043 flags[0] |= AF_TOLL;
1044 }
1045 }
1046 if (! strcmp(k,"access")) {
1047 flags[access_value(v)] |= AF_DANGEROUS_GOODS|AF_EMERGENCY_VEHICLES|AF_TRANSPORT_TRUCK|AF_DELIVERY_TRUCK|AF_PUBLIC_BUS|AF_TAXI|AF_HIGH_OCCUPANCY_CAR|AF_CAR|AF_MOTORCYCLE|AF_MOPED|AF_HORSE|AF_BIKE|AF_PEDESTRIAN;
1048 level=5;
1049 }
1050 if (! strcmp(k,"vehicle")) {
1051 flags[access_value(v)] |= AF_DANGEROUS_GOODS|AF_EMERGENCY_VEHICLES|AF_TRANSPORT_TRUCK|AF_DELIVERY_TRUCK|AF_PUBLIC_BUS|AF_TAXI|AF_HIGH_OCCUPANCY_CAR|AF_CAR|AF_MOTORCYCLE|AF_MOPED|AF_BIKE;
1052 level=5;
1053 }
1054 if (! strcmp(k,"motorvehicle")) {
1055 flags[access_value(v)] |= AF_DANGEROUS_GOODS|AF_EMERGENCY_VEHICLES|AF_TRANSPORT_TRUCK|AF_DELIVERY_TRUCK|AF_PUBLIC_BUS|AF_TAXI|AF_HIGH_OCCUPANCY_CAR|AF_CAR|AF_MOTORCYCLE|AF_MOPED;
1056 level=5;
1057 }
1058 if (! strcmp(k,"bicycle")) {
1059 flags[access_value(v)] |= AF_BIKE;
1060 level=5;
1061 }
1062 if (! strcmp(k,"foot")) {
1063 flags[access_value(v)] |= AF_PEDESTRIAN;
1064 level=5;
1065 }
1066 if (! strcmp(k,"horse")) {
1067 flags[access_value(v)] |= AF_HORSE;
1068 level=5;
1069 }
1070 if (! strcmp(k,"moped")) {
1071 flags[access_value(v)] |= AF_MOPED;
1072 level=5;
1073 }
1074 if (! strcmp(k,"motorcycle")) {
1075 flags[access_value(v)] |= AF_MOTORCYCLE;
1076 level=5;
1077 }
1078 if (! strcmp(k,"motorcar")) {
1079 flags[access_value(v)] |= AF_CAR;
1080 level=5;
1081 }
1082 if (! strcmp(k,"hov")) {
1083 flags[access_value(v)] |= AF_HIGH_OCCUPANCY_CAR;
1084 level=5;
1085 }
1086 if (! strcmp(k,"bus")) {
1087 flags[access_value(v)] |= AF_PUBLIC_BUS;
1088 level=5;
1089 }
1090 if (! strcmp(k,"taxi")) {
1091 flags[access_value(v)] |= AF_TAXI;
1092 level=5;
1093 }
1094 if (! strcmp(k,"goods")) {
1095 flags[access_value(v)] |= AF_DELIVERY_TRUCK;
1096 level=5;
1097 }
1098 if (! strcmp(k,"hgv")) {
1099 flags[access_value(v)] |= AF_TRANSPORT_TRUCK;
1100 level=5;
1101 }
1102 if (! strcmp(k,"emergency")) {
1103 flags[access_value(v)] |= AF_EMERGENCY_VEHICLES;
1104 level=5;
1105 }
1106 if (! strcmp(k,"hazmat")) {
1107 flags[access_value(v)] |= AF_DANGEROUS_GOODS;
1108 level=5;
1109 }
1110 if (! strcmp(k,"tunnel") && !strcmp(v,"1")) {
1111 flags[0] |= AF_UNDERGROUND;
1112 }
1113 if (! strcmp(k,"note"))
1114 level=5;
1115 if (! strcmp(k,"name")) {
1116 attr_strings_save(attr_string_label, v);
1117 level=5;
1118 }
1119 if (! strcmp(k,"addr:email")) {
1120 attr_strings_save(attr_string_email, v);
1121 level=5;
1122 }
1123 if (! strcmp(k,"addr:housenumber")) {
1124 attr_strings_save(attr_string_house_number, v);
1125 level=5;
1126 }
1127 if (! strcmp(k,"addr:street")) {
1128 attr_strings_save(attr_string_street_name, v);
1129 level=5;
1130 }
1131 if (! strcmp(k,"phone")) {
1132 attr_strings_save(attr_string_phone, v);
1133 level=5;
1134 }
1135 if (! strcmp(k,"fax")) {
1136 attr_strings_save(attr_string_fax, v);
1137 level=5;
1138 }
1139 if (! strcmp(k,"postal_code")) {
1140 attr_strings_save(attr_string_postal, v);
1141 level=5;
1142 }
1143 if (! strcmp(k,"openGeoDB:postal_codes") && !attr_strings[attr_string_postal]) {
1144 attr_strings_save(attr_string_postal, v);
1145 level=5;
1146 }
1147 if (! strcmp(k,"population")) {
1148 attr_strings_save(attr_string_population, v);
1149 level=5;
1150 }
1151 if (! strcmp(k,"openGeoDB:population") && !attr_strings[attr_string_population]) {
1152 attr_strings_save(attr_string_population, v);
1153 level=5;
1154 }
1155 if (! strcmp(k,"ref")) {
1156 if (in_way)
1157 attr_strings_save(attr_string_street_name_systematic, v);
1158 level=5;
1159 }
1160 if (! strcmp(k,"openGeoDB:is_in")) {
1161 if (!is_in_buffer[0])
1162 strcpy(is_in_buffer, v);
1163 level=5;
1164 }
1165 if (! strcmp(k,"is_in")) {
1166 if (!is_in_buffer[0])
1167 strcpy(is_in_buffer, v);
1168 level=5;
1169 }
1170 if (! strcmp(k,"is_in:country")) {
1171 /**
1172 * Sometimes there is no is_in tag, only is_in:country.
1173 * I put this here so it can be overwritten by the previous if clause if there IS an is_in tag.
1174 */
1175 strcpy(is_in_buffer, v);
1176 level=5;
1177 }
1178 if (! strcmp(k,"place_county")) {
1179 /**
1180 * Ireland uses the place_county OSM tag to describe what county a town is in.
1181 * This would be equivalent to is_in: Town; Locality; Country
1182 * A real world example would be Node: Moycullen (52234625)
1183 * The tag is processed as Moycullen; Galway; Ireland
1184 * where Galway is the county
1185 */
1186 strcpy(is_in_buffer, "Ireland");
1187 attr_strings_save(attr_string_county_name, v);
1188 level=5;
1189 }
1190 if (! strcmp(k,"gnis:ST_alpha")) {
1191 /* assume a gnis tag means it is part of the USA:
1192 http://en.wikipedia.org/wiki/Geographic_Names_Information_System
1193 many US towns do not have is_in tags
1194 */
1195 strcpy(is_in_buffer, "USA");
1196 level=5;
1197 }
1198 if (! strcmp(k,"lanes")) {
1199 level=5;
1200 }
1201 if (attr_debug_level >= level) {
1202 int bytes_left = sizeof( debug_attr_buffer ) - strlen(debug_attr_buffer) - 1;
1203 if ( bytes_left > 0 )
1204 {
1205 snprintf(debug_attr_buffer+strlen(debug_attr_buffer), bytes_left, " %s=%s", k, v);
1206 debug_attr_buffer[ sizeof( debug_attr_buffer ) - 1 ] = '\0';
1207 node_is_tagged=1;
1208 }
1209 }
1210 if (level < 6)
1211 node_is_tagged=1;
1212
1213 strcpy(buffer,"*=*");
1214 if ((idx=(int)(long)g_hash_table_lookup(attr_hash, buffer)))
1215 attr_present[idx]=1;
1216
1217 sprintf(buffer,"%s=*", k);
1218 if ((idx=(int)(long)g_hash_table_lookup(attr_hash, buffer)))
1219 attr_present[idx]=2;
1220
1221 sprintf(buffer,"*=%s", v);
1222 if ((idx=(int)(long)g_hash_table_lookup(attr_hash, buffer)))
1223 attr_present[idx]=2;
1224
1225 sprintf(buffer,"%s=%s", k, v);
1226 if ((idx=(int)(long)g_hash_table_lookup(attr_hash, buffer)))
1227 attr_present[idx]=4;
1228 }
1229
1230 int coord_count;
1231
1232 static void
1233 extend_buffer(struct buffer *b)
1234 {
1235 b->malloced+=b->malloced_step;
1236 b->base=realloc(b->base, (size_t)b->malloced);
1237 if (b->base == NULL) {
1238 fprintf(stderr,"realloc of %d bytes failed\n",(int)b->malloced);
1239 exit(1);
1240 }
1241
1242 }
1243
1244 int nodeid_last;
1245 GHashTable *node_hash,*way_hash;
1246
1247 static void
1248 node_buffer_to_hash(void)
1249 {
1250 int i,count=node_buffer.size/sizeof(struct node_item);
1251 struct node_item *ni=(struct node_item *)node_buffer.base;
1252 for (i = 0 ; i < count ; i++)
1253 g_hash_table_insert(node_hash, (gpointer)(long)(ni[i].id), (gpointer)(long)i);
1254 }
1255
1256 static struct node_item *ni;
1257
1258 void
1259 flush_nodes(int final)
1260 {
1261 fprintf(stderr,"flush_nodes %d\n",final);
1262 save_buffer("coords.tmp",&node_buffer,slices*slice_size);
1263 if (!final) {
1264 node_buffer.size=0;
1265 }
1266 slices++;
1267 }
1268
1269 void
1270 osm_add_node(osmid id, double lat, double lon)
1271 {
1272 in_node=1;
1273 if (node_buffer.size + sizeof(struct node_item) > node_buffer.malloced)
1274 extend_buffer(&node_buffer);
1275 attr_strings_clear();
1276 node_is_tagged=0;
1277 nodeid=id;
1278 item.type=type_point_unkn;
1279 debug_attr_buffer[0]='\0';
1280 is_in_buffer[0]='\0';
1281 debug_attr_buffer[0]='\0';
1282 osmid_attr.type=attr_osm_nodeid;
1283 osmid_attr.len=3;
1284 osmid_attr_value=id;
1285 if (node_buffer.size + sizeof(struct node_item) > slice_size) {
1286 flush_nodes(0);
1287 }
1288 ni=(struct node_item *)(node_buffer.base+node_buffer.size);
1289 ni->id=id;
1290 ni->ref_node=0;
1291 ni->ref_way=0;
1292 ni->ref_ref=0;
1293 ni->dummy=0;
1294 ni->c.x=lon*6371000.0*M_PI/180;
1295 ni->c.y=log(tan(M_PI_4+lat*M_PI/360))*6371000.0;
1296 node_buffer.size+=sizeof(struct node_item);
1297 if (! node_hash) {
1298 if (ni->id > nodeid_last) {
1299 nodeid_last=ni->id;
1300 } else {
1301 //fprintf(stderr,"INFO: Nodes out of sequence (new %d vs old %d), adding hash\n", ni->id, nodeid_last);
1302 node_hash=g_hash_table_new(NULL, NULL);
1303 node_buffer_to_hash();
1304 }
1305 } else
1306 if (!g_hash_table_lookup(node_hash, (gpointer)(long)(ni->id)))
1307 g_hash_table_insert(node_hash, (gpointer)(long)(ni->id), (gpointer)(long)(ni-(struct node_item *)node_buffer.base));
1308 else {
1309 node_buffer.size-=sizeof(struct node_item);
1310 nodeid=0;
1311 }
1312
1313 }
1314
1315 void
1316 clear_node_item_buffer(void)
1317 {
1318 int j,count=node_buffer.size/sizeof(struct node_item);
1319 struct node_item *ni=(struct node_item *)(node_buffer.base);
1320 for (j = 0 ; j < count ; j++) {
1321 ni[j].ref_way=0;
1322 }
1323 }
1324
1325 static struct node_item *
1326 node_item_get(int id)
1327 {
1328 struct node_item *ni=(struct node_item *)(node_buffer.base);
1329 int count=node_buffer.size/sizeof(struct node_item);
1330 int interval=count/4;
1331 int p=count/2;
1332 if(interval==0) {
1333 // If fewer than 4 nodes defined so far set interval to 1 to
1334 // avoid infinite loop
1335 interval = 1;
1336 }
1337 if (node_hash) {
1338 int i;
1339 i=(int)(long)(g_hash_table_lookup(node_hash, (gpointer)(long)id));
1340 return ni+i;
1341 }
1342 if (ni[0].id > id)
1343 return NULL;
1344 if (ni[count-1].id < id)
1345 return NULL;
1346 while (ni[p].id != id) {
1347 #if 0
1348 fprintf(stderr,"p=%d count=%d interval=%d id=%d ni[p].id=%d\n", p, count, interval, id, ni[p].id);
1349 #endif
1350 if (ni[p].id < id) {
1351 p+=interval;
1352 if (interval == 1) {
1353 if (p >= count)
1354 return NULL;
1355 if (ni[p].id > id)
1356 return NULL;
1357 } else {
1358 if (p >= count)
1359 p=count-1;
1360 }
1361 } else {
1362 p-=interval;
1363 if (interval == 1) {
1364 if (p < 0)
1365 return NULL;
1366 if (ni[p].id < id)
1367 return NULL;
1368 } else {
1369 if (p < 0)
1370 p=0;
1371 }
1372 }
1373 if (interval > 1)
1374 interval/=2;
1375 }
1376 return &ni[p];
1377 }
1378
1379 static int
1380 load_node(FILE *coords, int p, struct node_item *ret)
1381 {
1382 fseek(coords, p*sizeof(struct node_item), SEEK_SET);
1383 if (fread(ret, sizeof(*ret), 1, coords) != 1) {
1384 fprintf(stderr,"read failed\n");
1385 return 0;
1386 }
1387 return 1;
1388 }
1389
1390 static int
1391 node_item_get_from_file(FILE *coords, int id, struct node_item *ret)
1392 {
1393 int count;
1394 int interval;
1395 int p;
1396 if (node_hash) {
1397 int i;
1398 i=(int)(long)(g_hash_table_lookup(node_hash, (gpointer)(long)id));
1399 fseek(coords, i*sizeof(*ret), SEEK_SET);
1400 if (fread(ret, sizeof(*ret), 1, coords) == 1)
1401 return 1;
1402 else
1403 return 0;
1404 }
1405
1406 fseek(coords, 0, SEEK_END);
1407 count=ftell(coords)/sizeof(struct node_item);
1408 interval=count/4;
1409 p=count/2;
1410 if(interval==0) {
1411 // If fewer than 4 nodes defined so far set interval to 1 to
1412 // avoid infinite loop
1413 interval = 1;
1414 }
1415 if (!load_node(coords, p, ret))
1416 return 0;
1417 for (;;) {
1418 if (ret->id == id)
1419 return 1;
1420 if (ret->id < id) {
1421 p+=interval;
1422 if (interval == 1) {
1423 if (p >= count)
1424 return 0;
1425 if (!load_node(coords, p, ret))
1426 return 0;
1427 if (ret->id > id)
1428 return 0;
1429 } else {
1430 if (p >= count)
1431 p=count-1;
1432 if (!load_node(coords, p, ret))
1433 return 0;
1434 }
1435 } else {
1436 p-=interval;
1437 if (interval == 1) {
1438 if (p < 0)
1439 return 0;
1440 if (!load_node(coords, p, ret))
1441 return 0;
1442 if (ret->id < id)
1443 return 0;
1444 } else {
1445 if (p < 0)
1446 p=0;
1447 if (!load_node(coords, p, ret))
1448 return 0;
1449 }
1450 }
1451 if (interval > 1)
1452 interval/=2;
1453 }
1454 }
1455
1456 void
1457 osm_add_way(osmid id)
1458 {
1459 static int wayid_last;
1460
1461 in_way=1;
1462 wayid=id;
1463 coord_count=0;
1464 attr_strings_clear();
1465 item.type=type_street_unkn;
1466 debug_attr_buffer[0]='\0';
1467 maxspeed_attr_value=0;
1468 flags_attr_value = 0;
1469 memset(flags, 0, sizeof(flags));
1470 debug_attr_buffer[0]='\0';
1471 osmid_attr_value=id;
1472 if (wayid < wayid_last && !way_hash) {
1473 fprintf(stderr,"INFO: Ways out of sequence (new %d vs old %d), adding hash\n", wayid, wayid_last);
1474 way_hash=g_hash_table_new(NULL, NULL);
1475 }
1476 wayid_last=wayid;
1477 }
1478
1479 char relation_type[BUFFER_SIZE];
1480 char iso_code[BUFFER_SIZE];
1481 int admin_level;
1482 int boundary;
1483
1484 void
1485 osm_add_relation(osmid id)
1486 {
1487 current_id=id;
1488 in_relation=1;
1489 debug_attr_buffer[0]='\0';
1490 relation_type[0]='\0';
1491 iso_code[0]='\0';
1492 admin_level=-1;
1493 boundary=0;
1494 item_bin_init(item_bin, type_none);
1495 item_bin_add_attr_longlong(item_bin, attr_osm_relationid, current_id);
1496 }
1497
1498 static int
1499 country_id_from_iso2(char *iso)
1500 {
1501 int ret=0;
1502 if (iso)
1503 {
1504 // make lowercase
1505 int i99;
1506 for (i99 = 0; iso[i99]; i99++)
1507 {
1508 iso[i99] = tolower(iso[i99]);
1509 }
1510 struct country_search *search;
1511 struct attr country_iso2,country_id;
1512 struct item *item;
1513 country_iso2.type=attr_country_iso2;
1514 country_iso2.u.str=iso;
1515 search=country_search_new(&country_iso2,0);
1516 if ((item=country_search_get_item(search)) && item_attr_get(item, attr_country_id, &country_id))
1517 {
1518 ret=country_id.u.num;
1519 if (debug_itembin(3))
1520 {
1521 fprintf(stderr,"country id(1)=%d\n", ret);
1522 }
1523 }
1524 else
1525 {
1526 if (debug_itembin(3))
1527 {
1528 fprintf(stderr,"country id(2)=%d\n", ret);
1529 }
1530 }
1531 country_search_destroy(search);
1532 }
1533 return ret;
1534 }
1535
1536 static struct country_table *
1537 country_from_countryid(int id)
1538 {
1539 int i;
1540 for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++)
1541 {
1542 //if (debug_itembin(3))
1543 //{
1544 // fprintf(stderr,"== country_from_countryid: %d ==\n", country_table[i].countryid);
1545 //}
1546
1547 if (country_table[i].countryid == id)
1548 {
1549 return &country_table[i];
1550 }
1551 }
1552
1553 //if (debug_itembin(3))
1554 //{
1555 // fprintf(stderr,"== country_from_countryid: return NULL ==\n");
1556 //}
1557
1558 return NULL;
1559 }
1560
1561 struct country_table *
1562 country_from_iso2(char *iso)
1563 {
1564 return country_from_countryid(country_id_from_iso2(iso));
1565 }
1566
1567
1568 void
1569 osm_end_relation(struct maptool_osm *osm)
1570 {
1571 in_relation=0;
1572 if ((!strcmp(relation_type, "multipolygon") || !strcmp(relation_type, "boundary")) && boundary) {
1573 #if 0
1574 if (admin_level == 2) {
1575 FILE *f;
1576 fprintf(stderr,"Multipolygon for %s\n", iso_code);
1577 char *name=g_strdup_printf("country_%s.tmp",iso_code);
1578 f=fopen(name,"w");
1579 item_bin_write(item_bin, f);
1580 fclose(f);
1581 }
1582 #endif
1583 item_bin_write(item_bin, osm->boundaries);
1584 }
1585
1586 if (!strcmp(relation_type, "restriction") && (item_bin->type == type_street_turn_restriction_no || item_bin->type == type_street_turn_restriction_only))
1587 item_bin_write(item_bin, osm->turn_restrictions);
1588 }
1589
1590 void
1591 osm_add_member(int type, osmid ref, char *role)
1592 {
1593 char member_buffer[BUFFER_SIZE*3+3];
1594 struct attr memberattr = { attr_osm_member };
1595
1596 sprintf(member_buffer,"%d:"LONGLONG_FMT":%s", type, (long long) ref, role);
1597 memberattr.u.str=member_buffer;
1598 item_bin_add_attr(item_bin, &memberattr);
1599 }
1600
1601 static void
1602 relation_add_tag(char *k, char *v)
1603 {
1604 int add_tag=1;
1605 #if 0
1606 fprintf(stderr,"add tag %s %s\n",k,v);
1607 #endif
1608 if (!strcmp(k,"type")) {
1609 strcpy(relation_type, v);
1610 add_tag=0;
1611 }
1612 else if (!strcmp(k,"restriction")) {
1613 if (!strncmp(v,"no_",3)) {
1614 item_bin->type=type_street_turn_restriction_no;
1615 add_tag=0;
1616 } else if (!strncmp(v,"only_",5)) {
1617 item_bin->type=type_street_turn_restriction_only;
1618 add_tag=0;
1619 } else {
1620 item_bin->type=type_none;
1621 osm_warning("relation", current_id, 0, "Unknown restriction %s\n",v);
1622 }
1623 } else if (!strcmp(k,"admin_level")) {
1624 admin_level=atoi(v);
1625 } else if (!strcmp(k,"boundary")) {
1626 if (!strcmp(v,"administrative") || (experimental && !strcmp(v,"postal_code"))) {
1627 boundary=1;
1628 }
1629 } else if (!strcmp(k,"ISO3166-1")) {
1630 strcpy(iso_code, v);
1631 }
1632 if (add_tag) {
1633 char tag[strlen(k)+strlen(v)+2];
1634 sprintf(tag,"%s=%s",k,v);
1635 item_bin_add_attr_string(item_bin, attr_osm_tag, tag);
1636 }
1637 }
1638
1639
1640 static int
1641 attr_longest_match(struct attr_mapping **mapping, int mapping_count, enum item_type *types, int types_count)
1642 {
1643 int i,j,longest=0,ret=0,sum,val;
1644 struct attr_mapping *curr;
1645 for (i = 0 ; i < mapping_count ; i++) {
1646 sum=0;
1647 curr=mapping[i];
1648 for (j = 0 ; j < curr->attr_present_idx_count ; j++) {
1649 val=attr_present[curr->attr_present_idx[j]];
1650 if (val)
1651 sum+=val;
1652 else {
1653 sum=-1;
1654 break;
1655 }
1656 }
1657 if (sum > longest) {
1658 longest=sum;
1659 ret=0;
1660 }
1661 if (sum > 0 && sum == longest && ret < types_count)
1662 types[ret++]=curr->type;
1663 }
1664 return ret;
1665 }
1666
1667 static void
1668 attr_longest_match_clear(void)
1669 {
1670 memset(attr_present, 0, sizeof(*attr_present)*attr_present_count);
1671 }
1672
1673 void
1674 osm_end_way(struct maptool_osm *osm)
1675 {
1676 int i,count;
1677 int *def_flags,add_flags;
1678 enum item_type types[10];
1679 struct item_bin *item_bin;
1680 int count_lines=0, count_areas=0;
1681
1682 in_way=0;
1683
1684 if (! osm->ways)
1685 {
1686 return;
1687 }
1688
1689 if (dedupe_ways_hash)
1690 {
1691 if (g_hash_table_lookup(dedupe_ways_hash, (gpointer)(long)wayid))
1692 return;
1693 g_hash_table_insert(dedupe_ways_hash, (gpointer)(long)wayid, (gpointer)1);
1694 }
1695
1696 count=attr_longest_match(attr_mapping_way, attr_mapping_way_count, types, sizeof(types)/sizeof(enum item_type));
1697 if (!count)
1698 {
1699 count=1;
1700 types[0]=type_street_unkn;
1701 }
1702 if (count >= 10)
1703 {
1704 fprintf(stderr,"way id %ld\n",osmid_attr_value);
1705 dbg_assert(count < 10);
1706 }
1707 for (i = 0 ; i < count ; i++)
1708 {
1709 add_flags=0;
1710 if (types[i] == type_none)
1711 continue;
1712 if (ignore_unkown && (types[i] == type_street_unkn || types[i] == type_point_unkn))
1713 continue;
1714 if (types[i] != type_street_unkn)
1715 {
1716 if(types[i]<type_area)
1717 count_lines++;
1718 else
1719 count_areas++;
1720 }
1721 item_bin=init_item(types[i]);
1722 item_bin_add_coord(item_bin, coord_buffer, coord_count);
1723 nodes_ref_item_bin(item_bin);
1724 def_flags=item_get_default_flags(types[i]);
1725 if (def_flags)
1726 {
1727 flags_attr_value=(*def_flags | flags[0] | flags[1]) & ~flags[2];
1728 if (flags_attr_value != *def_flags)
1729 add_flags=1;
1730 }
1731 item_bin_add_attr_string(item_bin, def_flags ? attr_street_name : attr_label, attr_strings[attr_string_label]);
1732 item_bin_add_attr_string(item_bin, attr_street_name_systematic, attr_strings[attr_string_street_name_systematic]);
1733 item_bin_add_attr_longlong(item_bin, attr_osm_wayid, osmid_attr_value);
1734 if (debug_attr_buffer[0])
1735 item_bin_add_attr_string(item_bin, attr_debug, debug_attr_buffer);
1736 if (add_flags)
1737 item_bin_add_attr_int(item_bin, attr_flags, flags_attr_value);
1738 if (maxspeed_attr_value)
1739 item_bin_add_attr_int(item_bin, attr_maxspeed, maxspeed_attr_value);
1740
1741 // with special match
1742 // **buggy** item_bin_write_match(item_bin, attr_street_name, attr_street_name_match, osm->ways);
1743 // just original string
1744 item_bin_write(item_bin,osm->ways);
1745 }
1746
1747 /*
1748 if(osm->line2poi) {
1749 count=attr_longest_match(attr_mapping_way2poi, attr_mapping_way2poi_count, types, sizeof(types)/sizeof(enum item_type));
1750 dbg_assert(count < 10);
1751 for (i = 0 ; i < count ; i++) {
1752 if (types[i] == type_none || types[i] == type_point_unkn)
1753 continue;
1754 item_bin=init_item(types[i]);
1755 item_bin_add_coord(item_bin, coord_buffer, coord_count);
1756 item_bin_add_attr_string(item_bin, attr_label, attr_strings[attr_string_label]);
1757 item_bin_add_attr_string(item_bin, attr_house_number, attr_strings[attr_string_house_number]);
1758 item_bin_add_attr_string(item_bin, attr_street_name, attr_strings[attr_string_street_name]);
1759 item_bin_add_attr_string(item_bin, attr_phone, attr_strings[attr_string_phone]);
1760 item_bin_add_attr_string(item_bin, attr_fax, attr_strings[attr_string_fax]);
1761 item_bin_add_attr_string(item_bin, attr_email, attr_strings[attr_string_email]);
1762 item_bin_add_attr_string(item_bin, attr_county_name, attr_strings[attr_string_county_name]);
1763 item_bin_add_attr_string(item_bin, attr_url, attr_strings[attr_string_url]);
1764 item_bin_add_attr_longlong(item_bin, attr_osm_wayid, osmid_attr_value);
1765 item_bin_write(item_bin, count_areas<count_lines?osm->line2poi:osm->poly2poi);
1766 }
1767 }
1768 */
1769
1770 attr_longest_match_clear();
1771 }
1772
1773 void
1774 osm_end_node(struct maptool_osm *osm)
1775 {
1776 int count,i;
1777 char *postal;
1778 enum item_type types[10];
1779 struct item_bin *item_bin;
1780 in_node=0;
1781
1782 if (!osm->nodes || ! node_is_tagged || ! nodeid)
1783 return;
1784 count=attr_longest_match(attr_mapping_node, attr_mapping_node_count, types, sizeof(types)/sizeof(enum item_type));
1785 if (!count) {
1786 types[0]=type_point_unkn;
1787 count=1;
1788 }
1789 dbg_assert(count < 10);
1790 for (i = 0 ; i < count ; i++) {
1791 if (types[i] == type_none)
1792 continue;
1793 if (ignore_unkown && (types[i] == type_street_unkn || types[i] == type_point_unkn))
1794 continue;
1795 item_bin=init_item(types[i]);
1796
1797 if (item_is_town(*item_bin) && attr_strings[attr_string_label])
1798 {
1799 if (debug_itembin(ib))
1800 {
1801 fprintf(stderr,"osm_end_node: have town: %s\n", attr_strings[attr_string_label]);
1802 }
1803 }
1804
1805 if (item_is_town(*item_bin) && attr_strings[attr_string_population])
1806 item_bin_set_type_by_population(item_bin, atoi(attr_strings[attr_string_population]));
1807 item_bin_add_coord(item_bin, &ni->c, 1);
1808 item_bin_add_attr_string(item_bin, item_is_town(*item_bin) ? attr_town_name : attr_label, attr_strings[attr_string_label]);
1809 item_bin_add_attr_string(item_bin, attr_house_number, attr_strings[attr_string_house_number]);
1810 item_bin_add_attr_string(item_bin, attr_street_name, attr_strings[attr_string_street_name]);
1811 item_bin_add_attr_string(item_bin, attr_phone, attr_strings[attr_string_phone]);
1812 item_bin_add_attr_string(item_bin, attr_fax, attr_strings[attr_string_fax]);
1813 item_bin_add_attr_string(item_bin, attr_email, attr_strings[attr_string_email]);
1814 item_bin_add_attr_string(item_bin, attr_county_name, attr_strings[attr_string_county_name]);
1815 item_bin_add_attr_string(item_bin, attr_url, attr_strings[attr_string_url]);
1816 item_bin_add_attr_longlong(item_bin, attr_osm_nodeid, osmid_attr_value);
1817 item_bin_add_attr_string(item_bin, attr_debug, debug_attr_buffer);
1818 postal=attr_strings[attr_string_postal];
1819 if (postal) {
1820 char *sep=strchr(postal,',');
1821 if (sep)
1822 *sep='\0';
1823 item_bin_add_attr_string(item_bin, item_is_town(*item_bin) ? attr_town_postal : attr_postal, postal);
1824 }
1825 item_bin_write(item_bin,osm->nodes);
1826 if (item_is_town(*item_bin) && attr_strings[attr_string_label] && osm->towns) {
1827 item_bin=init_item(item_bin->type);
1828 item_bin_add_coord(item_bin, &ni->c, 1);
1829 item_bin_add_attr_string(item_bin, attr_osm_is_in, is_in_buffer);
1830 item_bin_add_attr_longlong(item_bin, attr_osm_nodeid, osmid_attr_value);
1831 item_bin_add_attr_string(item_bin, attr_town_postal, postal);
1832 item_bin_add_attr_string(item_bin, attr_county_name, attr_strings[attr_string_county_name]);
1833 item_bin_add_attr_string(item_bin, attr_town_name, attr_strings[attr_string_label]);
1834 item_bin_write(item_bin, osm->towns);
1835 }
1836 }
1837 processed_nodes_out++;
1838 attr_longest_match_clear();
1839 }
1840
1841 static struct country_table *
1842 osm_process_town_unknown_country(void)
1843 {
1844 static struct country_table *unknown;
1845 unknown=country_from_countryid(999);
1846 return unknown;
1847 }
1848
1849 static struct country_table *
1850 osm_process_item_fixed_country(void)
1851 {
1852 static struct country_table *fixed;
1853 fixed=country_from_countryid(global_fixed_country_id);
1854 return fixed;
1855 }
1856
1857 static struct country_table *
1858 osm_process_town_by_is_in(struct item_bin *ib,char *is_in)
1859 {
1860 struct country_table *result=NULL, *lookup;
1861 char *tok,*dup=g_strdup(is_in),*buf=dup;
1862 int conflict;
1863
1864 while ((tok=strtok(buf, ",;")))
1865 {
1866 while (*tok==' ')
1867 {
1868 tok++;
1869 }
1870 lookup=g_hash_table_lookup(country_table_hash,tok);
1871 if (lookup)
1872 {
1873 if (result && result->countryid != lookup->countryid)
1874 {
1875 char *label=item_bin_get_attr(ib, attr_town_name, NULL);
1876 osm_warning("node",item_bin_get_nodeid(ib),0,"conflict for %s is_in=%s country %d vs %d\n", label, is_in, lookup->countryid, result->countryid);
1877 conflict=1;
1878 }
1879 result=lookup;
1880 }
1881 buf=NULL;
1882 }
1883 g_free(dup);
1884 return result;
1885 }
1886
1887 static struct country_table *
1888 osm_process_town_by_boundary(GList *bl, struct item_bin *ib, struct coord *c, struct attr *attrs)
1889 {
1890 GList *l,*matches=boundary_find_matches(bl, c);
1891 struct boundary *match=NULL;
1892
1893 l=matches;
1894 while (l) {
1895 struct boundary *b=l->data;
1896 if (b->country) {
1897 if (match) {
1898 //osm_warning("node",item_bin_get_nodeid(ib),0,"node (0x%x,0x%x) conflict country ", c->x, c->y);
1899 //osm_warning("relation",boundary_relid(match),1,"country %d vs ",match->country->countryid);
1900 //osm_warning("relation",boundary_relid(b),1,"country %d\n",b->country->countryid);
1901 }
1902 match=b;
1903 }
1904 l=g_list_next(l);
1905 }
1906 if (match) {
1907 if (match && match->country && match->country->admin_levels) {
1908 l=matches;
1909 while (l) {
1910 struct boundary *b=l->data;
1911 char *admin_level=osm_tag_value(b->ib, "admin_level");
1912 char *postal=osm_tag_value(b->ib, "postal_code");
1913 if (admin_level) {
1914 int a=atoi(admin_level);
1915 int end=strlen(match->country->admin_levels)+3;
1916 char *name;
1917 if (a > 2 && a < end) {
1918 enum attr_type attr_type=attr_none;
1919 switch(match->country->admin_levels[a-3]) {
1920 case 's':
1921 attr_type=attr_state_name;
1922 break;
1923 case 'c':
1924 attr_type=attr_county_name;
1925 break;
1926 case 'm':
1927 attr_type=attr_municipality_name;
1928 break;
1929 }
1930 name=osm_tag_value(b->ib, "name");
1931 if (name && attr_type != attr_none) {
1932 attrs[a-2].type=attr_type;
1933 attrs[a-2].u.str=name;
1934 }
1935 }
1936 }
1937 if (postal) {
1938 attrs[0].type=attr_town_postal;
1939 attrs[0].u.str=postal;
1940 }
1941 l=g_list_next(l);
1942 }
1943 }
1944 return match->country;
1945 } else
1946 return NULL;
1947 }
1948
1949 void
1950 osm_process_towns(FILE *in, FILE *boundaries, FILE *ways)
1951 {
1952 struct item_bin *ib;
1953 GList *bl=NULL;
1954 struct attr attrs[10];
1955
1956 if (debug_itembin(1))
1957 {
1958 fprintf(stderr,"osm_process_towns == START ==\n");
1959 }
1960
1961 bl=process_boundaries(boundaries, ways);
1962 while ((ib=read_item(in)))
1963 {
1964 struct coord *c=(struct coord *)(ib+1);
1965 struct country_table *result=NULL;
1966 char *is_in=item_bin_get_attr(ib, attr_osm_is_in, NULL);
1967 int i;
1968
1969 if (debug_itembin(ib))
1970 {
1971 fprintf(stderr,"== item ==\n");
1972 dump_itembin(ib);
1973 }
1974
1975 memset(attrs, 0, sizeof(attrs));
1976 if (debug_itembin(ib))
1977 {
1978 fprintf(stderr,"== osm_process_town_by_boundary ==\n");
1979 }
1980
1981 if (use_global_fixed_country_id == 1)
1982 {
1983 result=osm_process_item_fixed_country();
1984 if (debug_itembin(ib))
1985 {
1986 if (result==NULL)
1987 {
1988 fprintf(stderr,"== osm_process_item_fixed_country == #NULL# ==\n");
1989 }
1990 else
1991 {
1992 fprintf(stderr,"== osm_process_item_fixed_country == %d ==\n",result->countryid);
1993 }
1994 }
1995 }
1996
1997 if (!result)
1998 {
1999 result=osm_process_town_by_boundary(bl, ib, c, attrs);
2000 }
2001
2002 if (!result)
2003 {
2004 if (debug_itembin(ib))
2005 {
2006 fprintf(stderr,"== osm_process_town_by_is_in == %s ==\n",is_in);
2007 }
2008 result=osm_process_town_by_is_in(ib, is_in);
2009 }
2010
2011 if (!result && unknown_country)
2012 {
2013 if (debug_itembin(ib))
2014 {
2015 fprintf(stderr,"== osm_process_town_unknown_country ==\n");
2016 }
2017 result=osm_process_town_unknown_country();
2018 }
2019
2020 if (result)
2021 {
2022 if (!result->file)
2023 {
2024 char *name=g_strdup_printf("country_%d.unsorted.tmp", result->countryid);
2025 result->file=fopen(name,"wb");
2026
2027 if (debug_itembin(ib))
2028 {
2029 fprintf(stderr,"== create: country_%d.unsorted.tmp == FILEP: %p ==\n", result->countryid, result->file);
2030 }
2031
2032 g_free(name);
2033 }
2034
2035 if (result->file)
2036 {
2037 long long *nodeid;
2038 if (is_in)
2039 item_bin_remove_attr(ib, is_in);
2040 nodeid=item_bin_get_attr(ib, attr_osm_nodeid, NULL);
2041 if (nodeid)
2042 item_bin_remove_attr(ib, nodeid);
2043 if (attrs[0].type != attr_none)
2044 {
2045 char *postal=item_bin_get_attr(ib, attr_town_postal, NULL);
2046 if (postal)
2047 item_bin_remove_attr(ib, postal);
2048 }
2049 for (i = 0 ; i < 10 ; i++)
2050 {
2051 if (attrs[i].type != attr_none)
2052 item_bin_add_attr(ib, &attrs[i]);
2053 }
2054 // ** used until 2011-11-06 seems bad ** item_bin_write_match(ib, attr_town_name, attr_town_name_match, result->file);
2055 item_bin_town_write_match(ib, attr_town_name, attr_town_name_match, result->file);
2056 // ** origname ** item_bin_write(ib,result->file);
2057 }
2058 }
2059 else
2060 {
2061 if (debug_itembin(ib))
2062 {
2063 fprintf(stderr,"== no result ==\n");
2064 }
2065 }
2066 }
2067
2068 if (debug_itembin(1))
2069 {
2070 fprintf(stderr,"osm_process_towns == END ==\n");
2071 }
2072
2073 }
2074
2075 void
2076 sort_countries(int keep_tmpfiles)
2077 {
2078 int i;
2079 struct country_table *co;
2080 char *name_in,*name_out;
2081 for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) {
2082 co=&country_table[i];
2083 if (co->file) {
2084 fclose(co->file);
2085 co->file=NULL;
2086 }
2087 name_in=g_strdup_printf("country_%d.unsorted.tmp", co->countryid);
2088 name_out=g_strdup_printf("country_%d.tmp", co->countryid);
2089
2090 if (debug_itembin(2))
2091 {
2092 fprintf(stderr,"in=country_%d.unsorted.tmp\n", co->countryid);
2093 fprintf(stderr,"out=country_%d.tmp\n", co->countryid);
2094 }
2095
2096 co->r=world_bbox;
2097 item_bin_sort_file(name_in, name_out, &co->r, &co->size);
2098 if (!keep_tmpfiles)
2099 unlink(name_in);
2100 g_free(name_in);
2101 g_free(name_out);
2102 }
2103 }
2104
2105 struct relation_member {
2106 int type;
2107 long long id;
2108 char *role;
2109 };
2110
2111 static int
2112 get_relation_member(char *str, struct relation_member *memb)
2113 {
2114 int len;
2115 sscanf(str,"%d:"LONGLONG_FMT":%n",&memb->type,&memb->id,&len);
2116 memb->role=str+len;
2117 return 1;
2118 }
2119
2120 static int
2121 search_relation_member(struct item_bin *ib, char *role, struct relation_member *memb, int *min_count)
2122 {
2123 char *str=NULL;
2124 int count=0;
2125 while ((str=item_bin_get_attr(ib, attr_osm_member, str))) {
2126 if (!get_relation_member(str, memb))
2127 return 0;
2128 count++;
2129 if (!strcmp(memb->role, role) && (!min_count || *min_count < count)) {
2130 if (min_count)
2131 *min_count=count;
2132 return 1;
2133 }
2134 }
2135 return 0;
2136 }
2137
2138 static int
2139 load_way_index(FILE *ways_index, int p, long long *idx)
2140 {
2141 int step=sizeof(*idx)*2;
2142 fseek(ways_index, p*step, SEEK_SET);
2143 if (fread(idx, step, 1, ways_index) != 1) {
2144 fprintf(stderr,"read failed\n");
2145 return 0;
2146 }
2147 return 1;
2148 }
2149
2150
2151 static int
2152 seek_to_way(FILE *way, FILE *ways_index, long long wayid)
2153 {
2154 long offset;
2155 long long idx[2];
2156 int count,interval,p;
2157 if (way_hash) {
2158 if (!(g_hash_table_lookup_extended(way_hash, (gpointer)(long)wayid, NULL, (gpointer)&offset)))
2159 return 0;
2160 fseek(way, offset, SEEK_SET);
2161 return 1;
2162 }
2163 fseek(ways_index, 0, SEEK_END);
2164 count=ftell(ways_index)/sizeof(idx);
2165 interval=count/4;
2166 p=count/2;
2167 if(interval==0) {
2168 // If fewer than 4 nodes defined so far set interval to 1 to
2169 // avoid infinite loop
2170 interval = 1;
2171 }
2172 if (!load_way_index(ways_index, p, idx))
2173 return 0;
2174 for (;;) {
2175 if (idx[0] == wayid) {
2176 fseek(way, idx[1], SEEK_SET);
2177 return 1;
2178 }
2179 if (idx[0] < wayid) {
2180 p+=interval;
2181 if (interval == 1) {
2182 if (p >= count)
2183 return 0;
2184 if (!load_way_index(ways_index, p, idx))
2185 return 0;
2186 if (idx[0] > wayid)
2187 return 0;
2188 } else {
2189 if (p >= count)
2190 p=count-1;
2191 if (!load_way_index(ways_index, p, idx))
2192 return 0;
2193 }
2194 } else {
2195 p-=interval;
2196 if (interval == 1) {
2197 if (p < 0)
2198 return 0;
2199 if (!load_way_index(ways_index, p, idx))
2200 return 0;
2201 if (idx[0] < wayid)
2202 return 0;
2203 } else {
2204 if (p < 0)
2205 p=0;
2206 if (!load_way_index(ways_index, p, idx))
2207 return 0;
2208 }
2209 }
2210 if (interval > 1)
2211 interval/=2;
2212 }
2213 }
2214
2215
2216 static struct coord *
2217 get_way(FILE *way, FILE *ways_index, struct coord *c, long long wayid, struct item_bin *ret, int debug)
2218 {
2219 long long currid;
2220 int last;
2221 struct coord *ic;
2222 if (!seek_to_way(way, ways_index, wayid)) {
2223 if (debug)
2224 fprintf(stderr,"not found in index");
2225 return NULL;
2226 }
2227 while (item_bin_read(ret, way)) {
2228 currid=item_bin_get_wayid(ret);
2229 if (debug)
2230 fprintf(stderr,LONGLONG_FMT":",currid);
2231 if (currid != wayid)
2232 return NULL;
2233 ic=(struct coord *)(ret+1);
2234 last=ret->clen/2-1;
2235 if (debug)
2236 fprintf(stderr,"(0x%x,0x%x)-(0x%x,0x%x)",ic[0].x,ic[0].y,ic[last].x,ic[last].y);
2237 if (!c)
2238 return &ic[0];
2239 if (ic[0].x == c->x && ic[0].y == c->y)
2240 return &ic[last];
2241 if (ic[last].x == c->x && ic[last].y == c->y)
2242 return &ic[0];
2243 }
2244 return NULL;
2245 }
2246
2247 struct turn_restriction {
2248 osmid relid;
2249 enum item_type type;
2250 struct coord *c[3];
2251 int c_count[3];
2252 };
2253
2254 static void
2255 process_turn_restrictions_member(void *func_priv, void *relation_priv, struct item_bin *member, void *member_priv)
2256 {
2257 int count,type=(long)member_priv;
2258 struct turn_restriction *turn_restriction=relation_priv;
2259 struct coord *c=(struct coord *)(member+1);
2260 int ccount=member->clen/2;
2261
2262 if (member->type < type_line)
2263 count=1;
2264 else
2265 count=2;
2266 turn_restriction->c[type]=g_renew(struct coord, turn_restriction->c[type], turn_restriction->c_count[type]+count);
2267 turn_restriction->c[type][turn_restriction->c_count[type]++]=c[0];
2268 if (count > 1)
2269 turn_restriction->c[type][turn_restriction->c_count[type]++]=c[ccount-1];
2270 }
2271
2272 static void
2273 process_turn_restrictions_fromto(struct turn_restriction *t, int type, struct coord **c)
2274 {
2275 int i,j;
2276 for (i = 0 ; i < t->c_count[type] ; i+=2) {
2277 for (j = 0 ; j < t->c_count[1] ; j++) {
2278 if (coord_is_equal(t->c[type][i],t->c[1][j])) {
2279 c[0]=&t->c[type][i+1];
2280 c[1]=&t->c[type][i];
2281 return;
2282 }
2283 if (coord_is_equal(t->c[type][i+1],t->c[1][j])) {
2284 c[0]=&t->c[type][i];
2285 c[1]=&t->c[type][i+1];
2286 return;
2287 }
2288 }
2289 }
2290 }
2291
2292 static void
2293 process_turn_restrictions_dump_coord(struct coord *c, int count)
2294 {
2295 int i;
2296 for (i = 0 ; i < count ; i++) {
2297 fprintf(stderr,"(0x%x,0x%x)",c[i].x,c[i].y);
2298 }
2299 }
2300
2301 static void
2302 process_turn_restrictions_finish(GList *tr, FILE *out)
2303 {
2304 GList *l=tr;
2305 while (l) {
2306 struct turn_restriction *t=l->data;
2307 struct coord *c[4];
2308 struct item_bin *ib=item_bin;
2309
2310 if (!t->c_count[0]) {
2311 //osm_warning("relation",t->relid,0,"turn restriction: from member not found\n");
2312 } else if (!t->c_count[1]) {
2313 //osm_warning("relation",t->relid,0,"turn restriction: via member not found\n");
2314 } else if (!t->c_count[2]) {
2315 //osm_warning("relation",t->relid,0,"turn restriction: to member not found\n");
2316 } else {
2317 process_turn_restrictions_fromto(t, 0, c);
2318 process_turn_restrictions_fromto(t, 2, c+2);
2319 if (!c[0] || !c[2]) {
2320 //osm_warning("relation",t->relid,0,"turn restriction: via (");
2321 //process_turn_restrictions_dump_coord(t->c[1], t->c_count[1]);
2322 //fprintf(stderr,")");
2323 if (!c[0]) {
2324 //fprintf(stderr," failed to connect to from (");
2325 //process_turn_restrictions_dump_coord(t->c[0], t->c_count[0]);
2326 //fprintf(stderr,")");
2327 }
2328 if (!c[2]) {
2329 //fprintf(stderr," failed to connect to to (");
2330 //process_turn_restrictions_dump_coord(t->c[2], t->c_count[2]);
2331 //fprintf(stderr,")");
2332 }
2333 //fprintf(stderr,"\n");
2334 } else {
2335 if (t->c_count[1] <= 2) {
2336 item_bin_init(ib,t->type);
2337 item_bin_add_coord(ib, c[0], 1);
2338 item_bin_add_coord(ib, c[1], 1);
2339 if (t->c_count[1] > 1)
2340 item_bin_add_coord(ib, c[3], 1);
2341 item_bin_add_coord(ib, c[2], 1);
2342 item_bin_write(ib, out);
2343 }
2344
2345 }
2346 }
2347 g_free(t);
2348 l=g_list_next(l);
2349 }
2350 g_list_free(tr);
2351 }
2352
2353 static GList *
2354 process_turn_restrictions_setup(FILE *in, struct relations *relations)
2355 {
2356 struct relation_member fromm,tom,viam,tmpm;
2357 long long relid;
2358 struct item_bin *ib;
2359 struct relations_func *relations_func;
2360 int min_count;
2361 GList *turn_restrictions=NULL;
2362
2363 fseek(in, 0, SEEK_SET);
2364 relations_func=relations_func_new(process_turn_restrictions_member, NULL);
2365 while ((ib=read_item(in))) {
2366 struct turn_restriction *turn_restriction=g_new0(struct turn_restriction, 1);
2367 relid=item_bin_get_relationid(ib);
2368 turn_restriction->relid=relid;
2369 turn_restriction->type=ib->type;
2370 min_count=0;
2371 if (!search_relation_member(ib, "from",&fromm,&min_count)) {
2372 //osm_warning("relation",relid,0,"turn restriction: from member missing\n");
2373 continue;
2374 }
2375 if (search_relation_member(ib, "from",&tmpm,&min_count)) {
2376 //osm_warning("relation",relid,0,"turn restriction: multiple from members\n");
2377 continue;
2378 }
2379 min_count=0;
2380 if (!search_relation_member(ib, "to",&tom,&min_count)) {
2381 //osm_warning("relation",relid,0,"turn restriction: to member missing\n");
2382 continue;
2383 }
2384 if (search_relation_member(ib, "to",&tmpm,&min_count)) {
2385 //osm_warning("relation",relid,0,"turn restriction: multiple to members\n");
2386 continue;
2387 }
2388 min_count=0;
2389 if (!search_relation_member(ib, "via",&viam,&min_count)) {
2390 //osm_warning("relation",relid,0,"turn restriction: via member missing\n");
2391 continue;
2392 }
2393 if (search_relation_member(ib, "via",&tmpm,&min_count)) {
2394 //osm_warning("relation",relid,0,"turn restriction: multiple via member\n");
2395 continue;
2396 }
2397 if (fromm.type != 2) {
2398 //osm_warning("relation",relid,0,"turn restriction: wrong type for from member ");
2399 //osm_warning(osm_types[fromm.type],fromm.id,1,"\n");
2400 continue;
2401 }
2402 if (tom.type != 2) {
2403 //osm_warning("relation",relid,0,"turn restriction: wrong type for to member ");
2404 //osm_warning(osm_types[tom.type],tom.id,1,"\n");
2405 continue;
2406 }
2407 if (viam.type != 1 && viam.type != 2) {
2408 //osm_warning("relation",relid,0,"turn restriction: wrong type for via member ");
2409 //osm_warning(osm_types[viam.type],viam.id,1,"\n");
2410 continue;
2411 }
2412 relations_add_func(relations, relations_func, turn_restriction, (gpointer) 0, fromm.type, fromm.id);
2413 relations_add_func(relations, relations_func, turn_restriction, (gpointer) 1, viam.type, viam.id);
2414 relations_add_func(relations, relations_func, turn_restriction, (gpointer) 2, tom.type, tom.id);
2415 turn_restrictions=g_list_append(turn_restrictions, turn_restriction);
2416 }
2417 return turn_restrictions;
2418 }
2419
2420 void
2421 process_turn_restrictions(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, FILE *out)
2422 {
2423 struct relations *relations=relations_new();
2424 GList *turn_restrictions;
2425 fseek(in, 0, SEEK_SET);
2426 turn_restrictions=process_turn_restrictions_setup(in, relations);
2427 relations_process(relations, coords, ways, NULL);
2428 process_turn_restrictions_finish(turn_restrictions, out);
2429 }
2430
2431 void
2432 process_turn_restrictions_old(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, FILE *out)
2433 {
2434 struct relation_member fromm,tom,viam,tmpm;
2435 struct node_item ni;
2436 long long relid;
2437 char from_buffer[65536],to_buffer[65536],via_buffer[65536];
2438 struct item_bin *ib,*from=(struct item_bin *)from_buffer,*to=(struct item_bin *)to_buffer,*via=(struct item_bin *)via_buffer;
2439 struct coord *fromc,*toc,*viafrom,*viato,*tmp;
2440 int min_count;
2441 while ((ib=read_item(in))) {
2442 relid=item_bin_get_relationid(ib);
2443 min_count=0;
2444 if (!search_relation_member(ib, "from",&fromm,&min_count)) {
2445 osm_warning("relation",relid,0,"turn restriction: from member missing\n");
2446 continue;
2447 }
2448 if (search_relation_member(ib, "from",&tmpm,&min_count)) {
2449 osm_warning("relation",relid,0,"turn restriction: multiple from members\n");
2450 continue;
2451 }
2452 min_count=0;
2453 if (!search_relation_member(ib, "to",&tom,&min_count)) {
2454 osm_warning("relation",relid,0,"turn restriction: to member missing\n");
2455 continue;
2456 }
2457 if (search_relation_member(ib, "to",&tmpm,&min_count)) {
2458 osm_warning("relation",relid,0,"turn restriction: multiple to members\n");
2459 continue;
2460 }
2461 min_count=0;
2462 if (!search_relation_member(ib, "via",&viam,&min_count)) {
2463 osm_warning("relation",relid,0,"turn restriction: via member missing\n");
2464 continue;
2465 }
2466 if (search_relation_member(ib, "via",&tmpm,&min_count)) {
2467 osm_warning("relation",relid,0,"turn restriction: multiple via member\n");
2468 continue;
2469 }
2470 if (fromm.type != 2) {
2471 osm_warning("relation",relid,0,"turn restriction: wrong type for from member ");
2472 osm_warning(osm_types[fromm.type],fromm.id,1,"\n");
2473 continue;
2474 }
2475 if (tom.type != 2) {
2476 osm_warning("relation",relid,0,"turn restriction: wrong type for to member ");
2477 osm_warning(osm_types[tom.type],tom.id,1,"\n");
2478 continue;
2479 }
2480 if (viam.type != 1 && viam.type != 2) {
2481 osm_warning("relation",relid,0,"turn restriction: wrong type for via member ");
2482 osm_warning(osm_types[viam.type],viam.id,1,"\n");
2483 continue;
2484 }
2485 if (viam.type == 1) {
2486 if (!node_item_get_from_file(coords, viam.id, &ni)) {
2487 osm_warning("relation",relid,0,"turn restriction: failed to get via member ");
2488 osm_warning(osm_types[viam.type],viam.id,1,"\n");
2489 continue;
2490 }
2491 viafrom=&ni.c;
2492 viato=&ni.c;
2493 } else {
2494 if (!(viafrom=get_way(ways, ways_index, NULL, viam.id, via, 0))) {
2495 osm_warning("relation",relid,0,"turn restriction: failed to get first via coordinate from ");
2496 osm_warning(osm_types[viam.type],viam.id,1,"\n");
2497 continue;
2498 }
2499 if (!(viato=get_way(ways, ways_index, viafrom, viam.id, via, 0))) {
2500 osm_warning("relation",relid,0,"turn restriction: failed to get last via coordinate from ");
2501 osm_warning(osm_types[viam.type],viam.id,1,"\n");
2502 continue;
2503 }
2504
2505 }
2506 #if 0
2507 fprintf(stderr,"via "LONGLONG_FMT" vs %d\n",viam.id, ni.id);
2508 fprintf(stderr,"coord 0x%x,0x%x\n",ni.c.x,ni.c.y);
2509 fprintf(stderr,"Lookup "LONGLONG_FMT"\n",fromm.id);
2510 #endif
2511 if (!(fromc=get_way(ways, ways_index, viafrom, fromm.id, from, 0))) {
2512 if (viam.type == 1 || !(fromc=get_way(ways, ways_index, viato, fromm.id, from, 0))) {
2513 //osm_warning("relation",relid,0,"turn restriction: failed to connect via ");
2514 //osm_warning(osm_types[viam.type],viam.id,1," 0x%x,0x%x-0x%x,0x%x to from member ",viafrom->x,viafrom->y,viato->x,viato->y);
2515 //osm_warning(osm_types[fromm.type],fromm.id,1," (");
2516 //get_way(ways, ways_index, viafrom, fromm.id, from, 1);
2517 //fprintf(stderr,")\n");
2518 continue;
2519 } else {
2520 tmp=viato;
2521 viato=viafrom;
2522 viafrom=tmp;
2523 }
2524 }
2525 if (!(toc=get_way(ways, ways_index, viato, tom.id, to, 0))) {
2526 //osm_warning("relation",relid,0,"turn restriction: failed to connect via ");
2527 //osm_warning(osm_types[viam.type],viam.id,1," 0x%x,0x%x-0x%x,0x%x to to member ",viafrom->x,viafrom->y,viato->x,viato->y);
2528 //osm_warning(osm_types[tom.type],tom.id,1," (");
2529 //get_way(ways, ways_index, viato, tom.id, to, 1);
2530 //fprintf(stderr,")\n");
2531 continue;
2532 }
2533 #if 0
2534 fprintf(stderr,"(0x%x,0x%x)-(0x%x,0x%x)-(0x%x,0x%x)\n",fromc->x,fromc->y, ni.c.x, ni.c.y, toc->x, toc->y);
2535 #endif
2536 item_bin_init(ib,ib->type);
2537 item_bin_add_coord(ib, fromc, 1);
2538 item_bin_add_coord(ib, viafrom, 1);
2539 if (viam.type == 2)
2540 item_bin_add_coord(ib, viato, 1);
2541 item_bin_add_coord(ib, toc, 1);
2542 item_bin_write(item_bin, out);
2543 }
2544 }
2545
2546 #if 0
2547 static void
2548 process_countries(FILE *way, FILE *ways_index)
2549 {
2550 FILE *in=fopen("country_de.tmp","r");
2551 struct item_bin *ib;
2552 char buffer2[400000];
2553 struct item_bin *ib2=(struct item_bin *)buffer2;
2554 GList *segments=NULL,*sort_segments;
2555 fseek(in, 0, SEEK_SET);
2556 while ((ib=read_item(in))) {
2557 char *str=NULL;
2558 struct relation_member member;
2559 while ((str=item_bin_get_attr(ib, attr_osm_member, str))) {
2560 if (!get_relation_member(str, &member))
2561 break;
2562 if (member.type == 2) {
2563 if (!seek_to_way(way, ways_index, member.id)) {
2564 fprintf(stderr,"not found in index");
2565 break;
2566 }
2567 while (item_bin_read(ib2, way)) {
2568 if (item_bin_get_wayid(ib2) != member.id)
2569 break;
2570 segments=g_list_prepend(segments,item_bin_to_poly_segment(ib2, geom_poly_segment_type_way_unknown));
2571 break;
2572 }
2573 }
2574 }
2575 }
2576 sort_segments=geom_poly_segments_sort(segments, geom_poly_segment_type_way_left_side);
2577 FILE *tmp=fopen("tst.txt","w");
2578 while (sort_segments) {
2579 struct geom_poly_segment *seg=sort_segments->data;
2580 if (!seg) {
2581 fprintf(stderr,"is null\n");
2582 } else {
2583 fprintf(stderr,"segment %p %s area "LONGLONG_FMT"\n",sort_segments,coord_is_equal(*seg->first, *seg->last) ? "closed":"open",geom_poly_area(seg->first,seg->last-seg->first+1));
2584 }
2585 #if 0
2586 int count=seg->last-seg->first+1;
2587 item_bin_init(ib, type_border_country);
2588 item_bin_add_coord(ib, seg->first, count);
2589 item_bin_dump(ib, tmp);
2590 #endif
2591
2592 sort_segments=g_list_next(sort_segments);
2593 }
2594 fclose(tmp);
2595 fclose(in);
2596 }
2597 #endif
2598
2599 static void
2600 node_ref_way(osmid node)
2601 {
2602 struct node_item *ni;
2603 ni=node_item_get(node);
2604 if (ni)
2605 ni->ref_way++;
2606 }
2607
2608 static void
2609 nodes_ref_item_bin(struct item_bin *ib)
2610 {
2611 int i;
2612 struct coord *c=(struct coord *)(ib+1);
2613 for (i = 0 ; i < ib->clen/2 ; i++)
2614 node_ref_way(REF(c[i]));
2615 }
2616
2617
2618 void
2619 osm_add_nd(osmid ref)
2620 {
2621 SET_REF(coord_buffer[coord_count], ref);
2622 coord_count++;
2623 if (coord_count > 65536) {
2624 fprintf(stderr,"ERROR: Overflow\n");
2625 exit(1);
2626 }
2627 }
2628
2629 static void
2630 write_item_part(FILE *out, FILE *out_index, FILE *out_graph, struct item_bin *orig, int first, int last, long long *last_id)
2631 {
2632 struct item_bin new;
2633 struct coord *c=(struct coord *)(orig+1);
2634 char *attr=(char *)(c+orig->clen/2);
2635 int attr_len=orig->len-orig->clen-2;
2636 processed_ways++;
2637 new.type=orig->type;
2638 new.clen=(last-first+1)*2;
2639 new.len=new.clen+attr_len+2;
2640 if (out_index) {
2641 long long idx[2];
2642 idx[0]=item_bin_get_wayid(orig);
2643 idx[1]=ftell(out);
2644 if (way_hash) {
2645 if (!(g_hash_table_lookup_extended(way_hash, (gpointer)(long)idx[0], NULL, NULL)))
2646 g_hash_table_insert(way_hash, (gpointer)(long)idx[0], (gpointer)(long)idx[1]);
2647 } else {
2648 if (!last_id || *last_id != idx[0])
2649 fwrite(idx, sizeof(idx), 1, out_index);
2650 if (last_id)
2651 *last_id=idx[0];
2652 }
2653
2654 }
2655 #if 0
2656 fprintf(stderr,"first %d last %d type 0x%x len %d clen %d attr_len %d\n", first, last, new.type, new.len, new.clen, attr_len);
2657 #endif
2658 fwrite(&new, sizeof(new), 1, out);
2659 fwrite(c+first, new.clen*4, 1, out);
2660 fwrite(attr, attr_len*4, 1, out);
2661 #if 0
2662 fwrite(&new, sizeof(new), 1, out_graph);
2663 fwrite(c+first, new.clen*4, 1, out_graph);
2664 fwrite(attr, attr_len*4, 1, out_graph);
2665 #endif
2666 }
2667
2668 void
2669 ref_ways(FILE *in)
2670 {
2671 struct item_bin *ib;
2672
2673 fseek(in, 0, SEEK_SET);
2674 while ((ib=read_item(in)))
2675 nodes_ref_item_bin(ib);
2676 }
2677
2678 void
2679 resolve_ways(FILE *in, FILE *out)
2680 {
2681 struct item_bin *ib;
2682 struct coord *c;
2683 int i;
2684 struct node_item *ni;
2685
2686 fseek(in, 0, SEEK_SET);
2687 while ((ib=read_item(in))) {
2688 c=(struct coord *)(ib+1);
2689 for (i = 0 ; i < ib->clen/2 ; i++) {
2690 if(!IS_REF(c[i]))
2691 continue;
2692 ni=node_item_get(REF(c[i]));
2693 if(ni) {
2694 c[i].x=ni->c.x;
2695 c[i].y=ni->c.y;
2696 }
2697 }
2698 item_bin_write(ib,out);
2699 }
2700 }
2701
2702 FILE *
2703 resolve_ways_file(FILE *in, char *suffix, char *filename)
2704 {
2705 char *newfilename=g_strdup_printf("%s_new",filename);
2706 FILE *new=tempfile(suffix,newfilename,1);
2707 resolve_ways(in, new);
2708 fclose(in);
2709 fclose(new);
2710 tempfile_rename(suffix,newfilename,filename);
2711 g_free(newfilename);
2712 return tempfile(suffix,filename,0);
2713 }
2714
2715 /**
2716 * Get POI coordinates from area/line coordinates.
2717 * @param in *in input file with area/line coordinates.
2718 * @param in *out output file with POI coordinates
2719 * @param in type input file original contents type: type_line or type_area
2720 * @returns nothing
2721 */
2722 void
2723 process_way2poi(FILE *in, FILE *out, int type)
2724 {
2725 struct item_bin *ib;
2726 while ((ib=read_item(in))) {
2727 int count=ib->clen/2;
2728 if(count>1 && ib->type<type_line) {
2729 struct coord *c=(struct coord *)(ib+1), c1, c2;
2730 int done=0;
2731 if(type==type_area) {
2732 if(count<3) {
2733 osm_warning("way",item_bin_get_wayid(ib),0,"Broken polygon, less than 3 points defined\n");
2734 } else if(!geom_poly_centroid(c, count, &c1)) {
2735 osm_warning("way",item_bin_get_wayid(ib),0,"Broken polygon, area is 0\n");
2736 } else {
2737 if(geom_poly_point_inside(c, count, &c1)) {
2738 c[0]=c1;
2739 } else {
2740 geom_poly_closest_point(c, count, &c1, &c2);
2741 c[0]=c2;
2742 }
2743 done=1;
2744 }
2745 }
2746 if(!done) {
2747 geom_line_middle(c,count,&c1);
2748 c[0]=c1;
2749 }
2750 write_item_part(out, NULL, NULL, ib, 0, 0, NULL);
2751 }
2752 }
2753 }
2754
2755
2756 int
2757 map_find_intersections(FILE *in, FILE *out, FILE *out_index, FILE *out_graph, FILE *out_coastline, int final)
2758 {
2759 struct coord *c;
2760 int i,ccount,last,remaining;
2761 osmid ndref;
2762 struct item_bin *ib;
2763 struct node_item *ni;
2764 long long last_id=0;
2765
2766 processed_nodes=processed_nodes_out=processed_ways=processed_relations=processed_tiles=0;
2767 sig_alrm(0);
2768 while ((ib=read_item(in))) {
2769 #if 0
2770 fprintf(stderr,"type 0x%x len %d clen %d\n", ib->type, ib->len, ib->clen);
2771 #endif
2772 ccount=ib->clen/2;
2773 if (ccount <= 1)
2774 continue;
2775 c=(struct coord *)(ib+1);
2776 last=0;
2777 for (i = 0 ; i < ccount ; i++) {
2778 if (IS_REF(c[i])) {
2779 ndref=REF(c[i]);
2780 ni=node_item_get(ndref);
2781 if (ni) {
2782 c[i]=ni->c;
2783 if (ni->ref_way > 1 && i != 0 && i != ccount-1 && i != last && item_get_default_flags(ib->type)) {
2784 write_item_part(out, out_index, out_graph, ib, last, i, &last_id);
2785 last=i;
2786 }
2787 } else if (final) {
2788 //osm_warning("way",item_bin_get_wayid(ib),0,"Non-existing reference to ");
2789 //osm_warning("node",ndref,1,"\n");
2790 remaining=(ib->len+1)*4-sizeof(struct item_bin)-i*sizeof(struct coord);
2791 memmove(&c[i], &c[i+1], remaining);
2792 ib->clen-=2;
2793 ib->len-=2;
2794 i--;
2795 ccount--;
2796 }
2797 }
2798 }
2799 if (ccount) {
2800 write_item_part(out, out_index, out_graph, ib, last, ccount-1, &last_id);
2801 if (final && ib->type == type_water_line && out_coastline) {
2802 write_item_part(out_coastline, NULL, NULL, ib, last, ccount-1, NULL);
2803 }
2804 }
2805 }
2806 sig_alrm(0);
2807 sig_alrm_end();
2808 return 0;
2809 }
2810
2811 static void
2812 index_country_add(struct zip_info *info, int country_id, int zipnum)
2813 {
2814 struct item_bin *item_bin=init_item(type_countryindex);
2815 item_bin_add_attr_int(item_bin, attr_country_id, country_id);
2816 item_bin_add_attr_int(item_bin, attr_zipfile_ref, zipnum);
2817 item_bin_write(item_bin, zip_get_index(info));
2818 }
2819
2820 void
2821 write_countrydir(struct zip_info *zip_info)
2822 {
2823 int i,zipnum,num;
2824 int max=11;
2825 char tilename[32];
2826 char filename[32];
2827 char suffix[32];
2828 struct country_table *co;
2829 for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) {
2830 co=&country_table[i];
2831 if (co->size) {
2832 num=0;
2833 do {
2834 tilename[0]='\0';
2835 sprintf(suffix,"s%d", num);
2836 num++;
2837 tile(&co->r, suffix, tilename, max, overlap, NULL);
2838
2839 sprintf(filename,"country_%d.tmp", co->countryid);
2840 if (debug_itembin(4))
2841 {
2842 fprintf(stderr,"write_countrydir: tilename=%s country_%d.tmp\n", tilename ,co->countryid);
2843 }
2844 zipnum=add_aux_tile(zip_info, tilename, filename, co->size);
2845 } while (zipnum == -1);
2846 index_country_add(zip_info,co->countryid,zipnum);
2847 }
2848 }
2849 }
2850
2851 void
2852 load_countries(void)
2853 {
2854 char filename[32];
2855 FILE *f;
2856 int i;
2857 struct country_table *co;
2858
2859 for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) {
2860 co=&country_table[i];
2861 sprintf(filename,"country_%d.tmp", co->countryid);
2862 if (debug_itembin(4))
2863 {
2864 fprintf(stderr,"load_countries: country_%d.tmp\n", co->countryid);
2865 }
2866
2867 f=fopen(filename,"rb");
2868 if (f) {
2869 int i,first=1;
2870 struct item_bin *ib;
2871 while ((ib=read_item(f))) {
2872 struct coord *c=(struct coord *)(ib+1);
2873 co->size+=ib->len*4+4;
2874 for (i = 0 ; i < ib->clen/2 ; i++) {
2875 if (first) {
2876 co->r.l=c[i];
2877 co->r.h=c[i];
2878 first=0;
2879 } else
2880 bbox_extend(&c[i], &co->r);
2881 }
2882 }
2883 fseek(f, 0, SEEK_END);
2884 co->size=ftell(f);
2885 fclose(f);
2886 }
2887 }
2888 }
2889
2890 void
2891 remove_countryfiles(void)
2892 {
2893 int i;
2894 char filename[32];
2895 struct country_table *co;
2896
2897 for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) {
2898 co=&country_table[i];
2899 if (co->size) {
2900 sprintf(filename,"country_%d.tmp", co->countryid);
2901 unlink(filename);
2902 }
2903 }
2904 }
2905
2906 void osm_init(FILE* rule_file)
2907 {
2908 build_attrmap(rule_file);
2909 build_countrytable();
2910 }
2911

   
Visit the ZANavi Wiki