source: subversion/applications/utils/mod_tile/render_list.c @ 7866

Last change on this file since 7866 was 7866, checked in by tomhughes, 12 years ago

Include limits.h for PATH_MAX definition.

File size: 6.7 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 <limits.h>
17
18#include "gen_tile.h"
19#include "protocol.h"
20#include "render_config.h"
21#include "dir_utils.h"
22
23#define DEG_TO_RAD (M_PIl/180)
24#define RAD_TO_DEG (180/M_PIl)
25
26static int minZoom = 0;
27static int maxZoom = 18;
28static int verbose = 0;
29
30void display_rate(struct timeval start, struct timeval end, int num) 
31{
32    int d_s, d_us;
33    float sec;
34
35    d_s  = end.tv_sec  - start.tv_sec;
36    d_us = end.tv_usec - start.tv_usec;
37
38    sec = d_s + d_us / 1000000.0;
39
40    printf("Rendered %d tiles in %.2f seconds (%.2f tiles/s)\n", num, sec, num / sec);
41    fflush(NULL);
42}
43
44static time_t getPlanetTime(void)
45{
46    static time_t last_check;
47    static time_t planet_timestamp;
48    time_t now = time(NULL);
49    struct stat buf;
50
51    // Only check for updates periodically
52    if (now < last_check + 300)
53        return planet_timestamp;
54
55    last_check = now;
56    if (stat(PLANET_TIMESTAMP, &buf)) {
57        fprintf(stderr, "Planet timestamp file " PLANET_TIMESTAMP " is missing");
58        // Make something up
59        planet_timestamp = now - 3 * 24 * 60 * 60;
60    } else {
61        if (buf.st_mtime != planet_timestamp) {
62            fprintf(stderr, "Planet file updated at %s", ctime(&buf.st_mtime));
63            planet_timestamp = buf.st_mtime;
64        }
65    }
66    return planet_timestamp;
67}
68
69int process_loop(int fd, int x, int y, int z)
70{
71    struct protocol cmd, rsp;
72    //struct pollfd fds[1];
73    int ret = 0;
74
75    bzero(&cmd, sizeof(cmd));
76
77    cmd.ver = 1;
78    cmd.cmd = cmdRender;
79    cmd.z = z;
80    cmd.x = x;
81    cmd.y = y;
82    //strcpy(cmd.path, "/tmp/foo.png");
83
84        //printf("Sending request\n");
85    ret = send(fd, &cmd, sizeof(cmd), 0);
86    if (ret != sizeof(cmd)) {
87        perror("send error");
88    }
89        //printf("Waiting for response\n");
90    bzero(&rsp, sizeof(rsp));
91    ret = recv(fd, &rsp, sizeof(rsp), 0);
92    if (ret != sizeof(rsp)) {
93        perror("recv error");
94        return 0;
95    }
96        //printf("Got response\n");
97
98    if (!ret)
99        perror("Socket send error");
100    return ret;
101}
102
103
104int main(int argc, char **argv)
105{
106    const char *spath = RENDER_SOCKET;
107    int fd;
108    struct sockaddr_un addr;
109    int ret=0;
110    int x, y, z;
111    char name[PATH_MAX];
112    struct timeval start, end;
113    int num_render = 0, num_all = 0;
114    time_t planetTime = getPlanetTime();
115    int c;
116
117    while (1) {
118        int option_index = 0;
119        static struct option long_options[] = {
120            {"min-zoom", 1, 0, 'z'},
121            {"max-zoom", 1, 0, 'Z'},
122            {"verbose", 0, 0, 'v'},
123            {"help", 0, 0, 'h'},
124            {0, 0, 0, 0}
125        };
126
127        c = getopt_long(argc, argv, "hvz:Z:", long_options, &option_index);
128        if (c == -1)
129            break;
130
131        switch (c) {
132            case 'z':
133                minZoom=atoi(optarg);
134                if (minZoom < 0 || minZoom > 18) {
135                    fprintf(stderr, "Invalid minimum zoom selected, must be between 0 and 18\n");
136                    return 1;
137                }
138                break;
139            case 'Z':
140                maxZoom=atoi(optarg);
141                if (maxZoom < 0 || maxZoom > 18) {
142                    fprintf(stderr, "Invalid maximum zoom selected, must be between 0 and 18\n");
143                    return 1;
144                }
145                break;
146            case 'v':
147                verbose=1;
148                break;
149            case 'h':
150                fprintf(stderr, "Send a list of tiles to be rendered from STDIN in the format:\n");
151                fprintf(stderr, "\tX    Y    Z\n");
152                fprintf(stderr, "e.g.\n");
153                fprintf(stderr, "\t0    0    1\n");
154                fprintf(stderr, "\t0    1    1\n");
155                fprintf(stderr, "\t1    0    1\n");
156                fprintf(stderr, "\t1    1    1\n");
157                fprintf(stderr, "The above would cause all 4 tiles at zoom 1 to be rendered\n");
158                fprintf(stderr, "\t-z|--min-zoom\tFilter input to only render tiles greater or equal this zoom level (default 0)\n");
159                fprintf(stderr, "\t-Z|--max-zoom\tFilter input to only render tiles less than or equal to this zoom level (default 18)\n");
160                return -1;
161            default:
162                fprintf(stderr, "unhandled char '%c'\n", c);
163                break;
164        }
165    }
166
167    if (maxZoom < minZoom) {
168        fprintf(stderr, "Invalid zoom range, max zoom must be greater or equal to minimum zoom\n");
169        return 1;
170    }
171
172    fprintf(stderr, "Rendering client\n");
173
174    fd = socket(PF_UNIX, SOCK_STREAM, 0);
175    if (fd < 0) {
176        fprintf(stderr, "failed to create unix socket\n");
177        exit(2);
178    }
179
180    bzero(&addr, sizeof(addr));
181    addr.sun_family = AF_UNIX;
182    strncpy(addr.sun_path, spath, sizeof(addr.sun_path));
183
184    if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
185        fprintf(stderr, "socket connect failed for: %s\n", spath);
186        close(fd);
187        exit(3);
188    }
189
190    gettimeofday(&start, NULL);
191
192    while(!feof(stdin)) {
193        struct stat s;
194        int n = fscanf(stdin, "%d %d %d", &x, &y, &z);
195
196        if (n != 3) {
197            // Discard input line
198            char tmp[1024];
199            char *r = fgets(tmp, sizeof(tmp), stdin);
200            if (!r)
201                continue;
202            // fprintf(stderr, "bad line %d: %s", num_all, tmp);
203            continue;
204        }
205
206        if (z < minZoom || z > maxZoom)
207            continue;
208
209        printf("got: x(%d) y(%d) z(%d)\n", x, y, z);
210
211        num_all++;
212        xyz_to_path(name, sizeof(name), x, y, z);
213
214        if ((stat(name, &s) < 0) || (planetTime > s.st_mtime)) {
215            // missing or old, render it
216            ret = process_loop(fd, x, y, z);
217            num_render++;
218            if (!(num_render % 10)) {
219                gettimeofday(&end, NULL);
220                printf("\n");
221                printf("Meta tiles rendered: ");
222                display_rate(start, end, num_render);
223                printf("Total tiles rendered: ");
224                display_rate(start, end, num_render * METATILE * METATILE);
225                printf("Total tiles handled from input: ");
226                display_rate(start, end, num_all);
227            }
228        }
229    }
230    gettimeofday(&end, NULL);
231    printf("\nTotal for all tiles rendered\n");
232    printf("Meta tiles rendered: ");
233    display_rate(start, end, num_render);
234    printf("Total tiles rendered: ");
235    display_rate(start, end, num_render * METATILE * METATILE);
236    printf("Total tiles handled: ");
237    display_rate(start, end, num_all);
238
239    close(fd);
240    return ret;
241}
Note: See TracBrowser for help on using the repository browser.