source: subversion/applications/utils/mod_tile/render_old.c @ 8647

Last change on this file since 8647 was 8425, checked in by jonb, 11 years ago

mod_tile: Move map style & font location into render_config.h. Fix up operation with non-metatile rendering. Several utilities are not implemented for non-metatile (render_list, render_old, speedtest).

File size: 7.8 KB
Line 
1#define _GNU_SOURCE
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <sys/types.h>
7#include <sys/socket.h>
8#include <sys/stat.h>
9#include <sys/time.h>
10#include <sys/un.h>
11#include <poll.h>
12#include <errno.h>
13#include <math.h>
14#include <getopt.h>
15#include <time.h>
16#include <sys/types.h>
17#include <dirent.h>
18
19#include "gen_tile.h"
20#include "protocol.h"
21#include "render_config.h"
22#include "dir_utils.h"
23
24#ifndef METATILE
25#warning("render_old not implemented for non-metatile mode. Feel free to submit fix")
26int main(int argc, char **argv)
27{
28    fprintf(stderr, "render_old not implemented for non-metatile mode. Feel free to submit fix!\n");
29    return -1;
30}
31#else
32
33#define DEG_TO_RAD (M_PIl/180)
34#define RAD_TO_DEG (180/M_PIl)
35
36static int minZoom = 0;
37static int maxZoom = 18;
38static int verbose = 0;
39static int num_render = 0, num_all = 0;
40static time_t planetTime;
41static struct timeval start, end;
42
43
44void display_rate(struct timeval start, struct timeval end, int num) 
45{
46    int d_s, d_us;
47    float sec;
48
49    d_s  = end.tv_sec  - start.tv_sec;
50    d_us = end.tv_usec - start.tv_usec;
51
52    sec = d_s + d_us / 1000000.0;
53
54    printf("Rendered %d tiles in %.2f seconds (%.2f tiles/s)\n", num, sec, num / sec);
55    fflush(NULL);
56}
57
58static time_t getPlanetTime(void)
59{
60    static time_t last_check;
61    static time_t planet_timestamp;
62    time_t now = time(NULL);
63    struct stat buf;
64
65    // Only check for updates periodically
66    if (now < last_check + 300)
67        return planet_timestamp;
68
69    last_check = now;
70    if (stat(PLANET_TIMESTAMP, &buf)) {
71        printf("Planet timestamp file " PLANET_TIMESTAMP " is missing");
72        // Make something up
73        planet_timestamp = now - 3 * 24 * 60 * 60;
74    } else {
75        if (buf.st_mtime != planet_timestamp) {
76            printf("Planet file updated at %s", ctime(&buf.st_mtime));
77            planet_timestamp = buf.st_mtime;
78        }
79    }
80    return planet_timestamp;
81}
82
83int get_load_avg(void)
84{
85    FILE *loadavg = fopen("/proc/loadavg", "r");
86    int avg = 1000;
87
88    if (!loadavg) {
89        fprintf(stderr, "failed to read /proc/loadavg");
90        return 1000;
91    }
92    if (fscanf(loadavg, "%d", &avg) != 1) {
93        fprintf(stderr, "failed to parse /proc/loadavg");
94        fclose(loadavg);
95        return 1000;
96    }
97    fclose(loadavg);
98
99    return avg;
100}
101
102
103int process_loop(int fd, int x, int y, int z)
104{
105    struct protocol cmd, rsp;
106    //struct pollfd fds[1];
107    int ret = 0;
108
109    bzero(&cmd, sizeof(cmd));
110
111    cmd.ver = 1;
112    cmd.cmd = cmdRender;
113    cmd.z = z;
114    cmd.x = x;
115    cmd.y = y;
116    //strcpy(cmd.path, "/tmp/foo.png");
117
118    //printf("Sending request\n");
119    ret = send(fd, &cmd, sizeof(cmd), 0);
120    if (ret != sizeof(cmd)) {
121        perror("send error");
122    }
123        //printf("Waiting for response\n");
124    bzero(&rsp, sizeof(rsp));
125    ret = recv(fd, &rsp, sizeof(rsp), 0);
126    if (ret != sizeof(rsp)) {
127        perror("recv error");
128        return 0;
129    }
130        //printf("Got response\n");
131
132    if (rsp.cmd != cmdDone) {
133        printf("rendering failed, pausing\n");
134        sleep(10);
135    }
136
137    if (!ret)
138        perror("Socket send error");
139    return ret;
140}
141
142void process(int fd, const char *name)
143{
144    struct stat s;
145    int x, y, z;
146
147    if (path_to_xyz(name, &x, &y, &z))
148        return;
149
150    num_all++;
151
152    if ((stat(name, &s) < 0) || (planetTime > s.st_mtime)) {
153         // missing or old, render it
154        printf("Requesting x(%d) y(%d) z(%d)\n", x, y, z);
155        process_loop(fd, x, y, z);
156        num_render++;
157        if (!(num_render % 10)) {
158            gettimeofday(&end, NULL);
159            printf("\n");
160            printf("Meta tiles rendered: ");
161            display_rate(start, end, num_render);
162            printf("Total tiles rendered: ");
163            display_rate(start, end, num_render * METATILE * METATILE);
164            printf("Total tiles handled from input: ");
165            display_rate(start, end, num_all);
166        }
167    }
168}
169
170static void check_load(void)
171{
172    int avg = get_load_avg();
173
174    while (avg >= MAX_LOAD_OLD) {
175        printf("Load average %d, sleeping\n", avg);
176        sleep(5);
177        avg = get_load_avg();
178    }
179}
180
181static void descend(int fd, const char *search)
182{
183    DIR *tiles = opendir(search);
184    struct dirent *entry;
185    char path[PATH_MAX];
186
187    if (!tiles) {
188        fprintf(stderr, "Unable to open directory: %s\n", search);
189        return;
190    }
191
192    while ((entry = readdir(tiles))) {
193        struct stat b;
194        char *p;
195
196        check_load();
197
198        if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
199            continue;
200        snprintf(path, sizeof(path), "%s/%s", search, entry->d_name);
201        if (stat(path, &b))
202            continue;
203        if (S_ISDIR(b.st_mode)) {
204            descend(fd, path);
205            continue;
206        }
207        p = strrchr(path, '.');
208        if (p && !strcmp(p, ".meta")) {
209            //printf("Found tile %s\n", path);
210            process(fd, path);
211        }
212    }
213    closedir(tiles);
214}
215
216
217int main(int argc, char **argv)
218{
219    const char *spath = RENDER_SOCKET;
220    int fd;
221    struct sockaddr_un addr;
222    int z, c;
223
224    while (1) {
225        int option_index = 0;
226        static struct option long_options[] = {
227            {"min-zoom", 1, 0, 'z'},
228            {"max-zoom", 1, 0, 'Z'},
229            {"verbose", 0, 0, 'v'},
230            {"help", 0, 0, 'h'},
231            {0, 0, 0, 0}
232        };
233
234        c = getopt_long(argc, argv, "hvz:Z:", long_options, &option_index);
235        if (c == -1)
236            break;
237
238        switch (c) {
239            case 'z':
240                minZoom=atoi(optarg);
241                if (minZoom < 0 || minZoom > 18) {
242                    fprintf(stderr, "Invalid minimum zoom selected, must be between 0 and 18\n");
243                    return 1;
244                }
245                break;
246            case 'Z':
247                maxZoom=atoi(optarg);
248                if (maxZoom < 0 || maxZoom > 18) {
249                    fprintf(stderr, "Invalid maximum zoom selected, must be between 0 and 18\n");
250                    return 1;
251                }
252                break;
253            case 'v':
254                verbose=1;
255                break;
256            case 'h':
257                fprintf(stderr, "Search the rendered tiles and re-render tiles which are older then the last planet import\n");
258                fprintf(stderr, "\t-z|--min-zoom\tonly render tiles greater or equal this zoom level (default 0)\n");
259                fprintf(stderr, "\t-Z|--max-zoom\tonly render tiles less than or equal to this zoom level (default 18)\n");
260                return -1;
261            default:
262                fprintf(stderr, "unhandled char '%c'\n", c);
263                break;
264        }
265    }
266
267    if (maxZoom < minZoom) {
268        fprintf(stderr, "Invalid zoom range, max zoom must be greater or equal to minimum zoom\n");
269        return 1;
270    }
271
272    fprintf(stderr, "Rendering old tiles\n");
273
274    planetTime = getPlanetTime();
275
276    fd = socket(PF_UNIX, SOCK_STREAM, 0);
277    if (fd < 0) {
278        fprintf(stderr, "failed to create unix socket\n");
279        exit(2);
280    }
281
282    bzero(&addr, sizeof(addr));
283    addr.sun_family = AF_UNIX;
284    strncpy(addr.sun_path, spath, sizeof(addr.sun_path));
285
286    if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
287        fprintf(stderr, "socket connect failed for: %s\n", spath);
288        close(fd);
289        exit(3);
290    }
291
292    gettimeofday(&start, NULL);
293
294    for (z=minZoom; z<=maxZoom; z++) {
295        char path[PATH_MAX];
296        snprintf(path, PATH_MAX, WWW_ROOT HASH_PATH "/%d", z);
297        descend(fd, path);
298    }
299
300    gettimeofday(&end, NULL);
301    printf("\nTotal for all tiles rendered\n");
302    printf("Meta tiles rendered: ");
303    display_rate(start, end, num_render);
304    printf("Total tiles rendered: ");
305    display_rate(start, end, num_render * METATILE * METATILE);
306    printf("Total tiles handled: ");
307    display_rate(start, end, num_all);
308
309    close(fd);
310    return 0;
311}
312#endif
Note: See TracBrowser for help on using the repository browser.