Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100755 212 lines (203 sloc) 8.803 kb
fc18dc6 Rebuild: Clean up code that handle turn_restrictions
nic authored
1 #include <stdlib.h>
2 #include <ctype.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include <unistd.h>
6 #include <sys/types.h>
7 #include <fcntl.h>
8 //#include <libxml/xmlreader.h>
9 //#include <libxml/xmlwriter.h>
10 #include <vector>
11 #include <map>
12 #include <assert.h>
13 using namespace std;
14
15 struct younion { // Union of 1 or more bboxes. Terminated with -1.
16 int *i;
17 younion (int *_i) : i (_i) {}
18 };
19
20 bool operator < (const younion &a, const younion &b)
21 {
22 int *ap = a.i, *bp;
23 for (bp = b.i; *bp == *ap && *bp != -1; bp++) ap++;
24 return *ap < *bp;
25 }
26
e2b8239 Routing tweaking
nic authored
27 char buf[2048000]; // I assume the largest object will fit in 1 MB
fc18dc6 Rebuild: Clean up code that handle turn_restrictions
nic authored
28
29 int main (int argc, char *argv[])
30 {
31 int bcnt = (argc - 1) / 6;
32 double b[bcnt][4], lat, lon;
33 FILE *f[bcnt];
34 if (argc <= 1 || argc % 6 != 1) {
35 fprintf (stderr, "Usage: %s bottom left top right pname fname [...]\n"
36 "Reads an OSM-XML file from standard in and cut it into the given rectangles.\n"
37 "pname is exectuted for each rectangle and the XML is piped to it. It's output\n"
38 "is redirected to 'fname'. %s does not properly implement job control, but\n"
39 "gzip, bzip and cat are acceptable values for pname\n" , argv[0], argv[0]);
40 return 1;
41 }
42 for (int i = 0; i < bcnt; i++) {
43 #if 0
44 int p[2]; //p[(argc - 1) / 6][2], i;
45 pipe (p);
46 if (fork () == 0) {
47 close (p[STDOUT_FILENO]);
48 //for (i--; i >= 0; i--) close (p[i][STDOUT_FILENO]);
49 dup2 (p[STDIN_FILENO], STDIN_FILENO);
50 FILE *out = fopen (argv[i * 6 + 6], "w");
51 dup2 (fileno (out), STDOUT_FILENO);
52 execlp (argv[i * 6 + 5], argv[i * 6 + 5], NULL);
53 }
54 f[i] = fdopen (p[STDOUT_FILENO], "w");
55 #else
56 FILE *out = fopen (argv[i*6+6], "w");
57 dup2 (fileno (out), STDOUT_FILENO);
58 f[i] = popen (argv[i*6+5], "w");
59 assert (f[i]);
60 fclose (out);
61 #endif
62 fprintf (f[i], "<?xml version='1.0' encoding='UTF-8'?>\n"
63 "<osm version=\"0.6\" generator=\"bboxSplit %s\">\n"
64 "<bound box=\"%s,%s,%s,%s\""
65 /* origin=\"http://www.openstreetmap.org/api/0.6\" */ "/>\n" , __DATE__,
66 argv[i * 6 + 1], argv[i * 6 + 2], argv[i * 6 + 3], argv[i * 6 + 4]);
67 for (int j = 0; j < 4; j++) b[i][j] = atof (argv[i * 6 + j + 1]);
68 }
69 vector<int*> areas;
70 // This vector maps area ids to a list of bboxes and 'amap' maps a list
71 // of bboxes back to the id.
72 areas.push_back (new int[1]); // Tiny once off memory leak.
73 areas.back ()[0] = -1; // Make 0 the empty area
74 map<younion,int> amap;
75 amap[younion (areas.back ())] = 0;
76
77 areas.push_back (new int[bcnt + 1]); // Tiny once off memory leak.
78 areas.back ()[0] = -1; // Always have an empty set ready.
79
80 #define areasIndexType unsigned short
81 vector<areasIndexType> nwr[3]; // Nodes, relations, ways
82 char *start = buf;
83 long tipe[10], id, olevel = 0, memberTipe = 0, ref, acnt = 0, level;
84 for (int cnt = 0, i; (i = fread (buf + cnt, 1, sizeof (buf) - cnt, stdin)) > 0;) {
85 cnt += i;
86 char *ptr = start, *n;
87 level = olevel;
88 do {
89 //printf ("-- %d %.20s\n", level, ptr);
90 int isEnd = (ptr + 1 < buf + cnt) &&
91 ((ptr[0] == '<' && ptr[1] == '/') || (ptr[0] == '/' && ptr[1] == '>'));
92 for (n = ptr; n < buf + cnt &&
93 (isEnd ? *n != '>' : !isspace (*n) && *n != '/'); n++) {
94 if (*n == '\"') {
95 for (++n; n < buf + cnt && *n != '\"'; n++) {}
96 }
97 else if (*n == '\'') {
98 for (++n; n < buf + cnt && *n != '\''; n++) {}
99 }
100 }
101 if (isEnd && n < buf + cnt) n++; // Get rid of the '>'
102 while (n < buf + cnt && isspace (*n)) n++;
103
104 if (isEnd && level == 2 && tipe[level - 1] == 'o') { // Note: n may be at buf + cnt
0acbff4 New way of doing junction penalties. Still not perfect.
nic authored
105 nwr[0].clear (); // Free some memory for in case one or more
106 nwr[1].clear (); // processes does heavy postprocessing.
107 nwr[2].clear ();
106f07f bboxSplit: Allow children to do post processing in parallel.
nic authored
108 for (int j = 0; j < bcnt; j++) fprintf (f[j], "</osm>\n");
109 // By splitting these two steps we allow downstream XML converters
110 // like gosmore to do their post-XML processing in parallel.
111 for (int j = 0; j < bcnt; j++) pclose (f[j]);
112
fc18dc6 Rebuild: Clean up code that handle turn_restrictions
nic authored
113 // Should we close the files and wait for the children to exit ?
e2b8239 Routing tweaking
nic authored
114 fprintf (stderr, "%s done using %ld area combinations\n", argv[0], areas.size () - 1);
fc18dc6 Rebuild: Clean up code that handle turn_restrictions
nic authored
115 return 0;
116 }
117 if (n >= buf + cnt) {}
118 else if (isEnd) {
119 //printf ("Ending %c at %d\n", tipe[level - 1], level);
120 if (--level == 2 && tipe[level] == 'n') { // End of a node
121 for (int j = 0; j < bcnt; j++) {
122 if (b[j][0] < lat && b[j][1] < lon && lat < b[j][2] && lon < b[j][3]) {
123 areas.back ()[acnt++] = j;
124 }
125 }
126 areas.back ()[acnt] = -1;
127 }
128 else if ((tipe[level] == 'n' || tipe[level] == 'm')
129 && level == 3) { // End of an '<nd ..>' or a '<member ...>
130 memberTipe = tipe[2] == 'w' || memberTipe == 'n' ? 0
131 : memberTipe == 'w' ? 1 : 2;
132 if (ref < nwr[memberTipe].size ()) {
133 for (int j = 0, k = 0; areas[nwr[memberTipe][ref]][j] != -1; j++) {
134 while (k < acnt && areas.back()[k] < areas[nwr[memberTipe][ref]][j]) k++;
135 if (k >= acnt || areas.back()[k] > areas[nwr[memberTipe][ref]][j]) {
136 memmove (&areas.back()[k + 1], &areas.back()[k],
137 sizeof (areas[0][0]) * (acnt++ - k));
138 areas.back()[k] = areas[nwr[memberTipe][ref]][j];
139 }
140 } // Merge the two lists
141 }
142 }
143 if (level == 2 && acnt > 0) { // areas.back()[0] != -1) {
144 //(tipe[2] == 'n' || tipe[2] == 'w' || tipe[2] == 'r')) { // not needed for valid OSM-XML
145 for (int j = 0; j < acnt /* areas.back()[j] != -1*/; j++) {
146 //assert (areas.back ()[j] < bcnt);
147 fwrite (start, 1, n - start, f[areas.back()[j]]);
148 }
149 areas.back ()[acnt] = -1;
fdbd062 WinCE: Add input method (Keyboard).
nic authored
150 map<younion,int>::iterator mf = amap.find (younion (areas.back()));
151 if (mf == amap.end ()) {
fc18dc6 Rebuild: Clean up code that handle turn_restrictions
nic authored
152 int pos = areas.size () - 1;
153 if (pos >> (sizeof (areasIndexType) * 8)) {
106f07f bboxSplit: Allow children to do post processing in parallel.
nic authored
154 for (int j = 0; j < bcnt; j++) fprintf (f[j], "</osm>\n");
155 // By splitting these two steps we allow downstream XML converters
156 // like gosmore to do their post-XML processing in parallel.
157 for (int j = 0; j < bcnt; j++) pclose (f[j]);
fc18dc6 Rebuild: Clean up code that handle turn_restrictions
nic authored
158 fprintf (stderr, "%s FATAL: Too many combinations of areas\n", argv[0]);
159 return 2;
160 }
161 amap[younion (areas.back ())] = pos;
fdbd062 WinCE: Add input method (Keyboard).
nic authored
162 mf = amap.find (younion (areas.back()));
fc18dc6 Rebuild: Clean up code that handle turn_restrictions
nic authored
163 areas.push_back (new int[bcnt + 1]); // Tiny once off memory leak.
164 //assert (f != amap.end());
165 }
166 int nwrIdx = tipe[2] == 'n' ? 0 : tipe[2] == 'w' ? 1 : 2;
167 //printf (stderr, "Extending %c to %ld\n", tipe[2], id);
168 while (nwr[nwrIdx].size () <= id) nwr[nwrIdx].push_back (0);
169 // Initialize nwr with 0 which implies the empty union
fdbd062 WinCE: Add input method (Keyboard).
nic authored
170 nwr[nwrIdx][id] = mf->second;
fc18dc6 Rebuild: Clean up code that handle turn_restrictions
nic authored
171 areas.back ()[0] = -1;
172 acnt = 0;
173 } // if we found an entity that belongs to at least 1 bbox
174 if (level == 2) {
175 start = n;
176 olevel = level;
177 }
178 } // If it's /> or </..>
c9233e8 bboxSplit: Fix bug in handling of copyright comment in planet file
nic authored
179 else if (*ptr == '<') {
180 if (ptr[1] != '!') tipe[level++] = ptr[1];
181 }
fc18dc6 Rebuild: Clean up code that handle turn_restrictions
nic authored
182 // The tests for 'level' is not necessary for valid OSM-XML
183 else if (level == 3 && strncasecmp (ptr, "id=", 3) == 0) {
184 id = atoi (ptr[3] == '\'' || ptr[3] == '\"' ? ptr + 4 : ptr + 3);
185 }
186 else if (level == 3 && strncasecmp (ptr, "lat=", 4) == 0) {
187 lat = atof (ptr[4] == '\'' || ptr[4] == '\"' ? ptr + 5 : ptr + 4);
188 }
189 else if (level == 3 && strncasecmp (ptr, "lon=", 4) == 0) {
190 lon = atof (ptr[4] == '\'' || ptr[4] == '\"' ? ptr + 5 : ptr + 4);
191 }
192 else if (level == 4 && strncasecmp (ptr, "type=", 4) == 0) {
193 memberTipe = ptr[5] == '\'' || ptr[5] == '\"' ? ptr[6] : ptr[5];
194 }
195 else if (level == 4 && strncasecmp (ptr, "ref=", 4) == 0) {
196 ref = atoi (ptr[4] == '\'' || ptr[4] == '\"' ? ptr + 5 : ptr + 4);
197 }
198 ptr = n;
199 } while (ptr + 1 < buf + cnt);
200 memmove (buf, start, buf + cnt - start);
201 cnt -= start - buf;
202 start = buf;
203 }
106f07f bboxSplit: Allow children to do post processing in parallel.
nic authored
204 for (int j = 0; j < bcnt; j++) fprintf (f[j], "</osm>\n");
205 // By splitting these two steps we allow downstream XML converters
206 // like gosmore to do their post-XML processing in parallel.
207 for (int j = 0; j < bcnt; j++) pclose (f[j]);
fdbd062 WinCE: Add input method (Keyboard).
nic authored
208 fprintf (stderr, "Warning: Xml termination not found. Files should be OK.\n");
e2b8239 Routing tweaking
nic authored
209 fprintf (stderr, "%s done using %ld area combinations\n", argv[0], areas.size () - 1);
fc18dc6 Rebuild: Clean up code that handle turn_restrictions
nic authored
210 return 1;
211 }
Something went wrong with that request. Please try again.