source: subversion/applications/utils/mod_tile/mysql2file.c @ 29256

Last change on this file since 29256 was 4955, checked in by jonb, 12 years ago

mod_tile: Apache module and rendering daemon for serving OSM tiles

File size: 3.9 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <stdarg.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/socket.h>
8#include <sys/un.h>
9#include <unistd.h>
10#include <fcntl.h>
11#include <errno.h>
12#include <limits.h>
13#include <time.h>
14#include <utime.h>
15
16
17#include <mysql.h>
18#include <mysqld_error.h>
19#include <signal.h>
20#include <stdarg.h>
21#include <sslopt-vars.h>
22#include <assert.h>
23
24#define WWW_ROOT "/var/www/html"
25// TILE_PATH must have tile z directory z(0..18)/x/y.png
26#define TILE_PATH "/osm_tiles2"
27
28
29// Build parent directories for the specified file name
30// Note: the part following the trailing / is ignored
31// e.g. mkdirp("/a/b/foo.png") == shell mkdir -p /a/b
32static int mkdirp(const char *path) {
33    struct stat s;
34    char tmp[PATH_MAX];
35    char *p;
36
37    strncpy(tmp, path, sizeof(tmp));
38
39    // Look for parent directory
40    p = strrchr(tmp, '/');
41    if (!p)
42        return 0;
43
44    *p = '\0';
45
46    if (!stat(tmp, &s))
47        return !S_ISDIR(s.st_mode);
48    *p = '/';
49    // Walk up the path making sure each element is a directory
50    p = tmp;
51    if (!*p)
52        return 0;
53    p++; // Ignore leading /
54    while (*p) {
55        if (*p == '/') {
56            *p = '\0';
57            if (!stat(tmp, &s)) {
58                if (!S_ISDIR(s.st_mode))
59                    return 1;
60            } else if (mkdir(tmp, 0777))
61                return 1;
62            *p = '/';
63        }
64        p++;
65    }
66    return 0;
67}
68
69void parseDate(struct tm *tm, const char *str)
70{
71    // 2007-05-20 13:51:35
72    bzero(tm, sizeof(*tm));
73    int n = sscanf(str, "%d-%d-%d %d:%d:%d",
74       &tm->tm_year, &tm->tm_mon, &tm->tm_mday, &tm->tm_hour, &tm->tm_min, &tm->tm_sec);
75
76    if (n !=6)
77        printf("failed to parse date string, got(%d): %s\n", n, str);
78 
79    tm->tm_year -= 1900;
80}
81
82int main(int argc, char **argv)
83{
84  MYSQL mysql;
85  char query[255];
86  MYSQL_RES *res;
87  MYSQL_ROW row;
88  mysql_init(&mysql);
89
90  if (!(mysql_real_connect(&mysql,"","tile","tile","tile",MYSQL_PORT,NULL,0)))
91  {
92    fprintf(stderr,"%s: %s\n",argv[0],mysql_error(&mysql));
93    exit(1);
94  }
95  mysql.reconnect= 1;
96
97  snprintf(query, sizeof(query), "SELECT x,y,z,data,created_at FROM tiles");
98
99  if ((mysql_query(&mysql, query)) || !(res= mysql_use_result(&mysql)))
100  {
101    fprintf(stderr,"Cannot query tiles: %s\n", mysql_error(&mysql));
102    exit(1);
103  }
104
105  while ((row= mysql_fetch_row(res)))
106  {
107      ulong *lengths= mysql_fetch_lengths(res);
108      char path[PATH_MAX];
109      unsigned long int x,y,z,length;
110      time_t created_at;
111      const char *data;
112      struct tm date;
113      int fd;
114      struct utimbuf utb;
115
116      assert(mysql_num_fields(res) == 5);
117
118      //printf("x(%s) y(%s) z(%s) data_length(%lu): %s\n", row[0], row[1], row[2], lengths[3], row[4]);
119
120      x = strtoul(row[0], NULL, 10);
121      y = strtoul(row[1], NULL, 10);
122      z = strtoul(row[2], NULL, 10);
123      data = row[3];
124      length = lengths[3];
125      parseDate(&date, row[4]);
126      created_at = mktime(&date);
127
128      //printf("x(%lu) y(%lu) z(%lu) data_length(%lu): %s", x,y,z,length,ctime(&created_at));
129
130      if (!length) {
131          printf("skipping empty tile x(%lu) y(%lu) z(%lu) data_length(%lu): %s", x,y,z,length,ctime(&created_at));
132          continue;
133      }
134
135      snprintf(path, PATH_MAX, WWW_ROOT TILE_PATH "/%lu/%lu/%lu.png", z, x, y);
136      printf("%s\n", path);
137      mkdirp(path);
138
139      fd = open(path, O_CREAT | O_WRONLY, 0644);
140      if (fd <0) {
141          perror(path);
142          exit(1);
143      }
144      if (write(fd, data, length) != length) {
145          perror("writing tile");
146          exit(2);
147      }
148      close(fd);
149      utb.actime  = created_at;
150      utb.modtime = created_at;
151      if (utime(path, &utb) < 0) {
152          perror("utime");
153          exit(3);
154      }
155  }
156
157  printf ("Number of rows: %lu\n", (unsigned long) mysql_num_rows(res));
158  mysql_free_result(res);
159
160  mysql_close(&mysql);  /* Close & free connection */
161  return 0;
162}
Note: See TracBrowser for help on using the repository browser.