Last active
December 25, 2015 05:39
-
-
Save JulieGoldberg/6926274 to your computer and use it in GitHub Desktop.
A decorator around the WSGITileServer that allows for custom tilestache configuration.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from TileStache import WSGITileServer, splitPathInfo | |
import re | |
# | |
# Decorator for the WSGITileServer that allows for custom tilestache configuration. | |
# | |
# Takes in a tilestache config file and a series of parameter names. Any that are present will be sent to the | |
# provider and the cache classes on each call. | |
# | |
# If the URL is http://mytileserver.com/foo/45/bar/34/layer/x/y/z.png, | |
# it checks the cache and then optionally calls the provider as if | |
# http://mytileserver.com/layer/x/y/z.png were requested. | |
# | |
# Before the cache and/or provider is utilized for a given request, it | |
# checks each of those classes for a function named | |
# "set_tileserver_parameters". If it's there, it calls | |
# "set_tileserver_parameters({foo:45, bar:34})". | |
# | |
# Not all parameters must be sent on any call. If the syntax of the URL doesn't match or none are | |
# sent, it acts just like a regular WSGITileServer | |
# | |
# To run it, use: | |
# gunicorn --pythonpath $PWD "TileServer:DynamicLayersTileServer('tilestache.cfg', 'foo', 'bar')" | |
# gunicorn --pythonpath $PWD "TileServer:DynamicLayersTileServer('tilestache.cfg', 'foo', 'bar', 'baz')" | |
# | |
class ParameterParser(): | |
def __init__(self, parameter_name): | |
self.parameter_name = parameter_name | |
#regex will parse out the parameter value from the path tilestache expects if it contains the parameter name | |
self.regex = re.compile("(?P<prefix>^.*)\/" + parameter_name + "\/(?P<value>\w+)\/(?P<suffix>.*)$") | |
def parse_out_parameter_value(self, string): | |
match = self.regex.match(string) | |
if match: | |
reassembled = "%s/%s" % (match.group('prefix'), match.group('suffix')) | |
return (match.group('value'), reassembled) | |
else: | |
return (None, string) | |
def has_parameter(self, string): | |
return bool(self.regex.match(string)) | |
class DynamicLayersTileServer(): | |
PARAMETER_SETTER_FUNCTION_NAME = "set_tileserver_parameters" | |
def __init__(self, config, *parameter_names): | |
self.tile_server = WSGITileServer(config) | |
self.parameter_parsers = [ParameterParser(parameter_name) for parameter_name in parameter_names] | |
def __call__(self, environ, start_response): | |
path_info = environ['PATH_INFO'] or '' | |
parameter_values = {} | |
for parser in self.parameter_parsers: | |
if parser.has_parameter(path_info): | |
(value, path_info) = parser.parse_out_parameter_value(path_info) | |
parameter_values[parser.parameter_name] = value | |
if parameter_values: | |
environ['PATH_INFO'] = path_info | |
layer_name = splitPathInfo(path_info)[0] | |
config = self.tile_server.config | |
layer = config.layers[layer_name] | |
self.__set_dynamic_parameters__(layer.provider, parameter_values) | |
self.__set_dynamic_parameters__(config.cache, parameter_values) | |
response = self.tile_server.__call__(environ, start_response) | |
return response | |
def __get_regex_variable_name__(self, parameter_name): | |
return parameter_name + "_value" | |
def __set_dynamic_parameters__(self, obj, parameter_values): | |
if hasattr(obj, DynamicLayersTileServer.PARAMETER_SETTER_FUNCTION_NAME): | |
getattr(obj, DynamicLayersTileServer.PARAMETER_SETTER_FUNCTION_NAME)(parameter_values) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment