diff --git a/mapproxy/client/http.py b/mapproxy/client/http.py index 7bc7202b9..294218fc5 100644 --- a/mapproxy/client/http.py +++ b/mapproxy/client/http.py @@ -176,8 +176,16 @@ def open(self, url, data=None): def open_image(self, url, data=None): resp = self.open(url, data=data) if 'content-type' in resp.headers: - if not resp.headers['content-type'].lower().startswith('image'): - raise HTTPClientError('response is not an image: (%s)' % (resp.read())) + content_type = resp.headers['content-type'].lower() + img_content_type = content_type.startswith('image') + protobuf_content_type = content_type.endswith('x-protobuf') + + if not img_content_type and not protobuf_content_type: + raise HTTPClientError( + 'response is not a valid content-type: (%s)' % (content_type,) + ) + + # TODO: return TileSource if application/x-protobuf return ImageSource(resp) def auth_data_from_url(url): @@ -269,4 +277,4 @@ def __init__(self, connection_class=VerifiedHTTPSConnection): urllib2.HTTPSHandler.__init__(self) def https_open(self, req): - return self.do_open(self.specialized_conn_class, req) \ No newline at end of file + return self.do_open(self.specialized_conn_class, req) diff --git a/mapproxy/config/loader.py b/mapproxy/config/loader.py index 4a7fb7778..da41ab43b 100644 --- a/mapproxy/config/loader.py +++ b/mapproxy/config/loader.py @@ -1096,7 +1096,7 @@ def _tile_filter(self): @memoize def image_opts(self): - from mapproxy.image.opts import ImageFormat + from mapproxy.image.opts import ImageFormat, MVTFormat format = None if 'format' not in self.conf.get('image', {}): @@ -1105,6 +1105,8 @@ def image_opts(self): if image_opts.format is None: if format is not None and format.startswith('image/'): image_opts.format = ImageFormat(format) + elif format is not None and format.endswith('/pbf'): + image_opts.format = MVTFormat('application/pbf') # THIS IS WHAT SET FORMAT else: image_opts.format = ImageFormat('image/png') return image_opts diff --git a/mapproxy/image/opts.py b/mapproxy/image/opts.py index 09d3ba82b..562c26bf3 100644 --- a/mapproxy/image/opts.py +++ b/mapproxy/image/opts.py @@ -59,6 +59,43 @@ def __eq__(self, other): def copy(self): return copy.copy(self) +class MVTFormat(str): + def __new__(cls, value, *args, **keywargs): + if isinstance(value, ImageFormat): + return value + return str.__new__(cls, value) + + @property + def mime_type(self): + if self.startswith('application/'): + return self + return 'application/' + self + + @property + def ext(self): + ext = self + if '/' in ext: + ext = ext.split('/', 1)[1] + if ';' in ext: + ext = ext.split(';', 1)[0] + + return ext.strip() + + def __eq__(self, other): + if isinstance(other, string_type): + other = ImageFormat(other) + elif not isinstance(other, ImageFormat): + return NotImplemented + + return self.ext == other.ext + + def __hash__(self): + return hash(str(self)) + + def __ne__(self, other): + return not (self == other) + + class ImageFormat(str): def __new__(cls, value, *args, **keywargs): if isinstance(value, ImageFormat): @@ -179,4 +216,4 @@ def compatible_image_options(img_opts, base_opts=None): options.transparent = transparent options.mode = mode - return options \ No newline at end of file + return options diff --git a/mapproxy/service/tile.py b/mapproxy/service/tile.py index 8885d961d..29b5b3270 100644 --- a/mapproxy/service/tile.py +++ b/mapproxy/service/tile.py @@ -42,6 +42,7 @@ from mapproxy.template import template_loader, bunch get_template = template_loader(__name__, 'templates') + class TileServer(Server): """ A Tile Server. Supports strict TMS and non-TMS requests. The difference is the @@ -287,7 +288,6 @@ def render(self, tile_request, use_profiles=False, coverage=None, decorate_img=N raise RequestError('invalid format (%s). this tile set only supports (%s)' % (tile_request.format, self.format), request=tile_request, code='InvalidParameterValue') - tile_coord = self._internal_tile_coord(tile_request, use_profiles=use_profiles) coverage_intersects = False