/[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 - (hide annotations) (download)
Fri Oct 28 21:39:42 2011 UTC (12 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 61326 byte(s)
import
1 zoff99 8 /**
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