alaCarte Maps
Renderer for OpenStreetMap tiles
tile_identifier.cpp
Go to the documentation of this file.
1 
26 #include "utils/exceptions.hpp"
27 #include <boost/algorithm/string.hpp>
28 #include <boost/lexical_cast.hpp>
29 
31  "png",
32 // "jpg",
33 // "gif",
34  "svg",
35 // "svgz"
36 };
44 int TileIdentifier::stringToInt(const char *p) {
45  int x = 0;
46  bool neg = false;
47  if (*p == '-') {
48  neg = true;
49  ++p;
50  }
51  while (*p >= '0' && *p <= '9') {
52  x = (x*10) + (*p - '0');
53  ++p;
54  }
55  if (*p != 0) {
56  BOOST_THROW_EXCEPTION(excp::MalformedURLException() << excp::InfoWhat("Incorrect argument (No integer)."));
57  }
58  if (neg) {
59  x = -x;
60  }
61  return x;
62 }
63 
72 shared_ptr<TileIdentifier> TileIdentifier::Create(const string& url, shared_ptr<StylesheetManager> stylesheetManager, const shared_ptr<Configuration>& config)
73 {
74  int x, y, zoom;
75  string styleSheetpath;
77  // Boundaries for each Zoomlevel
78  static int boundaries[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144};
79 
80  // Parsing the URL
81  std::vector<string> parts;
82  boost::split(parts, url, boost::is_any_of("/"));
83  int length = parts.size();
84  // Check if there are enough parts for a valid url.
85  // /stylesheet/zoom/x/y.format -> Minimum 4 parts. (stylesheet can be omitted)
86  if (length < 4) {
87  BOOST_THROW_EXCEPTION(excp::MalformedURLException() << excp::InfoWhat("Not enough arguments."));
88  }
89  std::vector<string> subparts;
90  boost::split(subparts, parts.at(length-1), boost::is_any_of("."));
91  if (subparts.size() < 2) {
92  BOOST_THROW_EXCEPTION(excp::MalformedURLException() << excp::InfoWhat("Not enough arguments (No y.format)."));
93  }
94  // Convert format to enum
95  string& format = subparts.at(1);
96  std::transform(format.begin(), format.end(), format.begin(), ::tolower);
97  if (format == "png") {
98  imageFormat = PNG;
99 // } else if (format == "jpg" | format == "jpeg") {
100 // imageFormat = JPEG;
101 // BOOST_THROW_EXCEPTION(excp::UnknownImageFormatException() << excp::InfoWhat("jpeg/jpg is not supported"));
102 // } else if (format == "gif") {
103 // imageFormat = GIF;
104 // BOOST_THROW_EXCEPTION(excp::UnknownImageFormatException() << excp::InfoWhat("gif is not supported"));
105  } else if (format == "svg") {
106  imageFormat = SVG;
107 // } else if (format == "svgz") {
108 // imageFormat = SVGZ;
109 // BOOST_THROW_EXCEPTION(excp::UnknownImageFormatException() << excp::InfoWhat("svgz is not supported"));
110  } else {
111  BOOST_THROW_EXCEPTION(excp::UnknownImageFormatException() << excp::InfoWhat("Unknown image format."));
112  }
113  // Parse zoom
114  zoom = stringToInt(parts[length-3].c_str());
115  if (zoom < 0 || zoom > 18) {
116  BOOST_THROW_EXCEPTION(excp::MalformedURLException() << excp::InfoWhat("Incorrect zoom argument (Out of range 0 - 18)."));
117  }
118  // Parse y coordinate
119  y = stringToInt(subparts[0].c_str());
120  if (y < 0 || y >= boundaries[zoom]) {
121  BOOST_THROW_EXCEPTION(excp::MalformedURLException() << excp::InfoWhat("Incorrect y argument (Out of range 0 - 2^zoom)."));
122  }
123  // Parse x coordinate
124  x = stringToInt(parts[length-2].c_str());
125  if (x < 0 || x >= boundaries[zoom]) {
126  BOOST_THROW_EXCEPTION(excp::MalformedURLException() << excp::InfoWhat("Incorrect x argument (Out of range 0 - 2^zoom)."));
127  }
128  // Build stylesheetPath.
129  styleSheetpath = "";
130  for (int i = 1; i < length - 3; i++) {
131  if (i != 1) {
132  styleSheetpath += "/";
133  }
134  styleSheetpath += parts.at(i);
135  }
136  if (styleSheetpath == "" || !stylesheetManager->hasStylesheet(styleSheetpath))
137  {
138  styleSheetpath = config->get<string>(opt::server::path_to_default_style);
139 
140  if (!stylesheetManager->hasStylesheet(styleSheetpath))
141  styleSheetpath = ".fallback";
142  }
143 
144  return boost::make_shared<TileIdentifier>(x, y, zoom, styleSheetpath, imageFormat);
145 }
146 
152 shared_ptr<TileIdentifier> TileIdentifier::CreateEmptyTID(const string& stylesheetPath, TileIdentifier::Format format)
153 {
154  return boost::make_shared<TileIdentifier>(-2, -2, -2, stylesheetPath, format);
155 }
156 
167  x(x),
168  y(y),
169  zoom(zoom),
170  styleSheetpath(styleSheetpath),
171  imageFormat(imageFormat)
172 {
173  assert(imageFormat != enumSize);
174 }
175 
182 {
183  return x;
184 }
185 
192 {
193  return y;
194 }
195 
202 {
203  return zoom;
204 }
205 
212 {
213  return imageFormat;
214 }
215 
222 {
223  assert(getImageFormat() != enumSize);
224  return FormatString[getImageFormat()];
225 }
226 
233 {
234  return styleSheetpath;
235 }
236 
243 {
244  return x==-1 && y==-1 && zoom==-1 && styleSheetpath=="/";
245 }
246 
248 {
249  return x==-2 && y==-2 && zoom==-2;
250 }
251 
252 
260 std::ostream& operator<<(std::ostream& out, const TileIdentifier& ti)
261 {
262  return out << "TileIdentifier(x=" << ti.getX()
263  << ", y=" << ti.getY()
264  << ", z=" << ti.getZoom()
265  << ", css=" << ti.getStylesheetPath()
266  << ", format=" << ti.getImageFormatString() << ")";
267 }
268 
274 std::size_t hash_value(const TileIdentifier &ti)
275 {
276  std::size_t seed = 0;
277  boost::hash_combine(seed, ti.getX());
278  boost::hash_combine(seed, ti.getY());
279  boost::hash_combine(seed, ti.getZoom());
280  boost::hash_combine(seed, ti.getImageFormat());
281  boost::hash_combine(seed, ti.getStylesheetPath());
282  return seed;
283 }
284 
290 bool operator==(const TileIdentifier &a, const TileIdentifier &b)
291 {
292  return a.getX() == b.getX() &&
293  a.getY() == b.getY() &&
294  a.getZoom() == b.getZoom() &&
295  a.getImageFormat() == b.getImageFormat() &&
297 }
string styleSheetpath
path to the Stylesheet which should be used for rendering.
TileIdentifier(int x, int y, int zoom, string styleSheetpath, Format imageFormat)
Constructs a new TileIdentifier with the given parameters.
Thrown if an unknown image format is requested.
Definition: exceptions.hpp:83
static const char * path_to_default_style
Path to the default stylesheet (type: string)
TESTABLE bool isDefaultIdentifier() const
Determine whether this is the Identifier for the default tile.
static const string FormatString[enumSize]
This file is part of alaCarte.
Format
Enumeration which contains all supported image formats.
TESTABLE const string & getImageFormatString() const
Returns the image Format of the Tile.
A TileIdentifier identifies a Tile.
TESTABLE int getY() const
Returns the y coordinate of the Tile.
int x
x coordinate of the Tile.
TESTABLE int getZoom() const
Returns the zoom level of the Tile.
boost::error_info< struct TagWhatInfo, string > InfoWhat
Use this info to give an what msg to the exception.
Definition: exceptions.hpp:41
TESTABLE bool isNoneDataIdentifier() const
TESTABLE const string & getStylesheetPath() const
Returns the path to the Stylesheet which should be used for rendering.
TESTABLE Format getImageFormat() const
Returns the image Format of the Tile.
int y
y coordinate of the Tile.
TESTABLE int getX() const
Returns the x coordinate of the Tile.
static int stringToInt(const char *c)
Converts the given char* to integer.
std::size_t hash_value(const TileIdentifier &ti)
Returns a hash for the TileIdentifier.
static const char * config
Option to get the configuration filename (type: string)
Format imageFormat
Format of the image.
static shared_ptr< TileIdentifier > CreateEmptyTID(const string &stylesheetPath, TileIdentifier::Format format)
Return the TileIdentifier used for Tiles without data.
static shared_ptr< TileIdentifier > Create(const string &url, shared_ptr< StylesheetManager > StylesheetManager, const shared_ptr< Configuration > &config)
Constructs a new TileIdentifier with the given url.
std::ostream & operator<<(std::ostream &out, const TileIdentifier &ti)
toString method for TileIdentifier (overloading << operator).
int zoom
zoom level of the Tile.
Thrown if URL is not in SlippyMap-URL-Format.
Definition: exceptions.hpp:81
bool operator==(const TileIdentifier &a, const TileIdentifier &b)
Equals operator for two TileIdentifiers.