source: subversion/applications/utils/tirex/backend-mapnik/renderd.cc @ 29342

Last change on this file since 29342 was 29342, checked in by frederik, 7 years ago

fix font registration bug introduced in #29248; attempt to register font without directory name was prone to silently fail, leading to mapnik complaining about missing fonts.

File size: 6.7 KB
Line 
1/*
2 * Tirex Tile Rendering System
3 *
4 * Mapnik rendering backend
5 *
6 * Originally written by Jochen Topf & Frederik Ramm.
7 *
8 */
9
10#include "renderd.h"
11
12#include <iostream>
13#include <syslog.h>
14
15#include <mapnik/version.hpp>
16#include <mapnik/datasource_cache.hpp>
17#include <mapnik/font_engine_freetype.hpp>
18#include <exception>
19
20#include "networklistener.h"
21
22bool RenderDaemon::loadFonts(const boost::filesystem::path &dir, bool recurse)
23{
24    if (!boost::filesystem::exists(dir)) return false;
25    boost::filesystem::directory_iterator end_itr;
26    for (boost::filesystem::directory_iterator itr(dir); itr != end_itr; ++itr)
27    {
28        if (boost::filesystem::is_directory(*itr) && recurse)
29        {
30            if (!loadFonts(*itr, true)) return false;
31        }
32        else 
33        {
34#if (BOOST_FILESYSTEM_VERSION == 3)
35            mapnik::freetype_engine::register_font(itr->path().string());
36#else // v2
37            mapnik::freetype_engine::register_font(itr->string());
38#endif
39        }
40    }
41    return true;
42}
43
44bool RenderDaemon::loadMapnikWrapper(const char *configfile)
45{
46    // create mapnik instances
47    bool rv = false;
48    FILE *f = fopen(configfile, "r");
49    if (!f)
50    {
51        warning("cannot open '%s'", configfile);
52        return rv;
53    }
54
55    char linebuf[255];
56    std::string tiledir;
57    std::string mapfile;
58    std::string stylename;
59    unsigned int tilesize = 256;
60    unsigned int mtrowcol = 8;
61    double scalefactor = 1.0;
62   
63    while (char *line = fgets(linebuf, sizeof(linebuf), f))
64    {
65        while (isspace(*line)) line++;
66        if (*line == '#') continue;
67        char *eq = strchr(line, '=');
68        if (eq)
69        {
70            char *last = eq-1;
71            // trim space before equal sign
72            while (last > line && isspace(*last)) *last-- = 0;
73            *eq++ = 0;
74            // trim space after equal sign
75            while (isspace(*eq)) eq++;
76            // trim space at end of line
77            last = eq + strlen(eq) - 1;
78            while (last > eq && isspace(*last)) *last-- = 0;
79            if (!strcmp(line, "tiledir"))
80            {
81                tiledir.assign(eq);
82            }
83            else if (!strcmp(line, "mapfile"))
84            {
85                mapfile.assign(eq);
86            }
87            else if (!strcmp(line, "scalefactor"))
88            {
89                scalefactor = atof(eq);
90            }
91            else if (!strcmp(line, "tilesize"))
92            {
93                tilesize = atoi(eq);
94            }
95            else if (!strcmp(line, "metarowscols"))
96            {
97                mtrowcol = atoi(eq);
98            }
99            else if (!strcmp(line, "name"))
100            {
101                stylename.assign(eq);
102            }
103        }
104    }
105    fclose(f);
106
107    if (mapfile.empty())
108    {
109        warning("cannot add %s: missing mapfile option", configfile);
110        return rv;
111    }
112
113    if (access(mapfile.c_str(), R_OK) == -1)
114    {
115        warning("cannot add %s: map file '%s' not accessible", configfile, mapfile.c_str());
116        return rv;
117    }
118
119    if (tiledir.empty())
120    {
121        warning("cannot add %s: missing tiledir option", configfile);
122        return rv;
123    }
124
125    if (access(tiledir.c_str(), W_OK) == -1)
126    {
127        warning("cannot add %s: tile directory '%s' not accessible", configfile, tiledir.c_str());
128        return rv;
129    }
130
131    if (stylename.empty())
132    {
133        warning("cannot add %s: missing name option", configfile);
134        return rv;
135    }
136
137    try
138    {
139        mHandlerMap[stylename] = new MetatileHandler(tiledir, mapfile, tilesize, scalefactor, mtrowcol);
140        mHandlerMap[stylename]->setStatusReceiver(this);
141        debug("added style '%s' from map %s", stylename.c_str(), configfile);
142        rv = true;
143    }
144    catch (std::exception const& ex)
145    {
146        warning("cannot add %s", configfile);
147        warning("%s", ex.what());
148    }
149    return rv;
150}
151
152RenderDaemon::RenderDaemon(int argc, char **argv)
153{
154    // store for later use in setProgramName
155    mArgc = argc;
156    mArgv = argv;
157    if (argc) mProgramName.assign(argv[0]);
158
159    setStatus("initializing");
160
161    char *tmp = getenv("TIREX_BACKEND_DEBUG");
162    Debuggable::msDebugLogging = tmp ? true : false;
163
164    std::string strfac;
165    tmp = getenv("TIREX_BACKEND_SYSLOG_FACILITY");
166    if (tmp) strfac = tmp;
167    int fac = LOG_DAEMON;
168    if (strfac.empty()) fac = LOG_DAEMON;
169    else if (strfac == "local0") fac = LOG_LOCAL0;
170    else if (strfac == "local1") fac = LOG_LOCAL1;
171    else if (strfac == "local2") fac = LOG_LOCAL2;
172    else if (strfac == "local3") fac = LOG_LOCAL3;
173    else if (strfac == "local4") fac = LOG_LOCAL4;
174    else if (strfac == "local5") fac = LOG_LOCAL4;
175    else if (strfac == "local6") fac = LOG_LOCAL6;
176    else if (strfac == "user") fac = LOG_USER;
177    else if (strfac == "daemon") fac = LOG_DAEMON;
178    else
179    {
180        die("Cannot use log facility '%s' - only local0-local7, user, daemon are allowed.", strfac.c_str());
181    }
182    openlog("tirex-backend-mapnik", Debuggable::msDebugLogging ? LOG_PERROR|LOG_PID : LOG_PID, fac);
183    info("Renderer started (name=%s)", getenv("TIREX_BACKEND_NAME"));
184
185    tmp = getenv("TIREX_BACKEND_SOCKET_FILENO");
186    mSocketFd = tmp ? atoi(tmp) : -1;
187
188    tmp = getenv("TIREX_BACKEND_PIPE_FILENO");
189    mParentFd = tmp ? atoi(tmp) : -1;
190
191    tmp = getenv("TIREX_BACKEND_PORT");
192    mPort = tmp ? atoi(tmp) : 9320;
193
194    tmp = getenv("TIREX_BACKEND_CFG_plugindir");
195#if MAPNIK_VERSION >= 200200
196    if (tmp) mapnik::datasource_cache::instance().register_datasources(tmp);
197#else
198    if (tmp) mapnik::datasource_cache::instance()->register_datasources(tmp);
199#endif
200
201    tmp = getenv("TIREX_BACKEND_CFG_fontdir_recurse");
202    bool fr = tmp ? atoi(tmp) : false;
203    tmp = getenv("TIREX_BACKEND_CFG_fontdir");
204    if (tmp) loadFonts(tmp, fr);
205
206    tmp = getenv("TIREX_BACKEND_MAP_CONFIGS");
207    if (tmp)
208    {
209        char *dup = strdup(tmp);
210        char *tkn = strtok(dup, " ");
211        while (tkn)
212        {
213            loadMapnikWrapper(tkn);
214            tkn = strtok(NULL, " ");
215        }
216    }
217
218    if (mHandlerMap.empty())
219        die("Cannot load any Mapnik styles");
220
221}
222
223RenderDaemon::~RenderDaemon() 
224{
225};
226
227void RenderDaemon::run()
228{
229    NetworkListener listener(mPort, mSocketFd, mParentFd, &mHandlerMap);
230    setStatus("idle");
231    listener.run();
232}
233
234void RenderDaemon::setStatus(const char *status)
235{
236#ifdef linux
237    char **p = mArgv;
238    for (int i=1;i<mArgc;i++) { for (char *c = *(++p); *c != 0; c++) *c=0; }
239//    sprintf(*mArgv, "%s: %s", mProgramName.c_str(), status);
240    sprintf(*mArgv, "mapnik: %s                                ", status);
241#endif
242}
243
244int main(int argc, char **argv)
245{
246    RenderDaemon mtd(argc, argv);
247    mtd.run();
248    exit(9); // return with EXIT_CODE_RESTART==9 which means everything is ok, the backend can be restartet if the backend-manager wants to
249}
250
Note: See TracBrowser for help on using the repository browser.