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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

   
Visit the ZANavi Wiki