def create_mapproxy_image(yaml_file, img_file): with open(yaml_file, 'rb') as f: yaml_text = yaml.load(f) captured = [] # Inline function that accesses captured. Do not refactor out of this function. def start_response(status, headers, exc_info=None): captured[:] = [status, headers, exc_info] return output.append output = [] bbox_req, lay_name = get_path_info_params(yaml_text) path_info = ( '/service?LAYERS={0}&FORMAT=image%2Fpng&SRS=EPSG%3A4326' '&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&TRANSPARENT=TRUE&SERVICE=WMS&VERSION=1.1.1&' 'REQUEST=GetMap&STYLES=&BBOX={1}&WIDTH=200&HEIGHT=150').format( lay_name, bbox_req) conf_options = load_default_config() # Merge both load_config(conf_options, config_dict=yaml_text) conf = ProxyConfiguration(conf_options, seed=False, renderd=False) # Create a MapProxy App app = MapProxyApp(conf.configured_services(), conf.base_config) # Get a response from MapProxyAppy as if it was running standalone. environ = environ_from_url(path_info) app_iter = None try: app_iter = app(environ, start_response) except: return 1 if app_iter is None: return 1 try: with open(img_file, 'wb') as img: img.write(app_iter.next()) except: return 1 content = 'error' with open(img_file, 'rb') as img: content = img.read() if 'error' in content: os.remove(img_file) return 1 return 0
def mapit(mapproxy_conf, layername, outputmimeformat, lonlatbbox, imagesize, outputfilename=None, time=None): """ This automates the creation of a map image. :param mapproxy_conf: The mapproxy in-memory configuration dictionary. :param layername: The name of the layer to image. :param outputmimeformat: The mime format (i.e. image/png, image/jpeg) of the output :param lonlatbbox: The bounding box as a tuple, (west, south, east, north) :param imagesize: The images size as a tuple, (width, height) :param outputfilename: An optional output filename, if None, then no file will be written. :param time: An optional time string for layers that have the time dimension :return: The binary data for the image generated. """ if time is None: time = '' mapproxy_conf = copy.deepcopy(mapproxy_conf) # dup it for replacing time for source in mapproxy_conf['sources']: mapproxy_conf['sources'][source]['url'] = mapproxy_conf['sources'][ source]['url'].replace("{Time}", time) transparent = 'false' if 'png' in outputmimeformat.lower(): transparent = 'true' querystring = "LAYERS=%s&FORMAT=%s&SRS=EPSG:4326&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&TRANSPARENT=%s&STYLES=&BBOX=%f,%f,%f,%f&WIDTH=%d&HEIGHT=%d" % ( layername, outputmimeformat, transparent, lonlatbbox[0], lonlatbbox[1], lonlatbbox[2], lonlatbbox[3], imagesize[0], imagesize[1]) conf = ProxyConfiguration(mapproxy_conf, conf_base_dir='', seed=False, renderd=False) services = conf.configured_services() myreq = { 'QUERY_STRING': querystring, 'SERVER_NAME': '', 'SERVER_PORT': '', 'wsgi.url_scheme': '', } response = services[0].handle(Request(myreq)) data = response.data if outputfilename: f = open(outputfilename, "w") f.write(data) return data
def test_encoding_options_errors(self): conf_dict = { 'globals': { 'image': { 'formats': { 'image/jpeg': { 'encoding_options': { 'foo': 'baz', } } }, } }, } try: conf = ProxyConfiguration(conf_dict) except ConfigurationError: pass else: raise False ('expected ConfigurationError') conf_dict['globals']['image']['formats']['image/jpeg'][ 'encoding_options'] = { 'quantizer': 'foo' } try: conf = ProxyConfiguration(conf_dict) except ConfigurationError: pass else: raise False ('expected ConfigurationError') conf_dict['globals']['image']['formats']['image/jpeg'][ 'encoding_options'] = {} conf = ProxyConfiguration(conf_dict) try: conf.globals.image_options.image_opts( {'encoding_options': { 'quantizer': 'foo' }}, 'image/jpeg') except ConfigurationError: pass else: raise False ('expected ConfigurationError') conf_dict['globals']['image']['formats']['image/jpeg'][ 'encoding_options'] = { 'quantizer': 'fastoctree' } conf = ProxyConfiguration(conf_dict) conf.globals.image_options.image_opts({}, 'image/jpeg')
def test_with_max_res(self): conf = {'grids': {'grid': {'srs': 'EPSG:4326', 'bbox': [5, 50, 10, 55], 'max_res': 0.0048828125}}} conf = ProxyConfiguration(conf) grid = conf.grids['grid'].tile_grid() assert_almost_equal_bbox([5, 50, 10, 55], grid.bbox, 2) eq_(grid.resolution(0), 0.01953125) eq_(grid.resolution(1), 0.01953125/2)
def test_legacy_unordered(self): conf = self._test_conf(''' layers: one: title: Layer One sources: [s] two: title: Layer Two sources: [s] three: title: Layer Three sources: [s] ''') with pytest.warns(RuntimeWarning): conf = ProxyConfiguration(conf) root = conf.wms_root_layer.wms_layer() # no root layer defined assert root.title == None assert root.name == None layers = root.child_layers() # names might not be in order # layers.keys() != ['one', 'two', 'three'] assert len(layers) == 3 assert layers['one'].title == 'Layer One' assert layers['two'].title == 'Layer Two' assert layers['three'].title == 'Layer Three'
def configure_mapproxy(extra_config, seed=False, ignore_warnings=True, renderd=False): """Create an validate mapproxy configuration based on a dict. """ # Start with a sane configuration using MapProxy's defaults conf_options = load_default_config() # Merge both load_config(conf_options, config_dict=extra_config) # Make sure the config is valid. errors, informal_only = validate_options(conf_options) for error in errors: LOGGER.warn(error) if errors and not ignore_warnings: raise ConfigurationError('invalid configuration: %s' % ', '.join(errors)) errors = validate_references(conf_options) for error in errors: LOGGER.warn(error) if errors and not ignore_warnings: raise ConfigurationError('invalid references: %s' % ', '.join(errors)) conf = ProxyConfiguration(conf_options, seed=seed, renderd=renderd) return conf
def test_check_zoom_levels(self, mock_get_tables, mock_get_zoom_levels, mock_tile_matrix, mock_sql): from mapproxy.config.loader import ProxyConfiguration example_geopackage = '/test/example.gpkg' grid_name = 'geodetic' tile_size = (256, 256) table_name = 'tiles' zoom_levels_table = [0,1,2] # tile_matrix is abbreviated, for clarity. tile_matrix = [{"table_name": table_name, "zoom_level": 0}, {"table_name": table_name, "zoom_level": 1}] configuration = {'caches': {'cache': {'cache': {'type': 'geopackage', 'filename': example_geopackage}, 'grids': [grid_name]}}, 'grids': {'geodetic': {'srs': 'EPSG:4326', 'tile_size': tile_size, 'origin': 'nw'}}} mapproxy_configuration = ProxyConfiguration(configuration) mock_get_tables.return_value = (table_name,) mock_get_zoom_levels.return_value = zoom_levels_table mock_tile_matrix.return_value = tile_matrix check_zoom_levels(example_geopackage, mapproxy_configuration) mock_get_tables.assert_called_once_with(example_geopackage) mock_get_zoom_levels.assert_called_once_with(example_geopackage, table_name) mock_tile_matrix.assert_called_once_with(example_geopackage, table_name) mock_sql.connect().__enter__().execute.assert_called_once_with( '\nINSERT OR REPLACE INTO gpkg_tile_matrix (table_name, zoom_level, matrix_width, matrix_height, tile_width, tile_height, pixel_x_size, pixel_y_size) \nVALUES(?, ?, ?, ?, ?, ?, ?, ?)', ('tiles', 2, 4, 2, 256, 256, 0.3515625, 0.3515625))
def test_tagged_source_with_layers_missing(self): conf_dict = { 'sources': { 'osm': { 'type': 'wms', 'req': { 'url': 'http://localhost/service?', 'layers': 'base,poi' }, }, }, 'caches': { 'osm': { 'sources': ['osm:base,roads'], 'grids': ['GLOBAL_MERCATOR'], } } } conf = ProxyConfiguration(conf_dict) try: conf.caches['osm'].caches() except ConfigurationError as ex: assert 'base,roads' in ex.args[0] assert ('base,poi' in ex.args[0] or 'poi,base' in ex.args[0]) else: assert False, 'expected ConfigurationError'
def test_tagged_source_encoding(self): conf_dict = { 'layers': [ { 'name': 'osm', 'title': 'OSM', 'sources': [u'osm:☃'] } ], 'sources': { 'osm': { 'type': 'wms', 'req': { 'url': 'http://localhost/service?', }, }, }, 'caches': { 'osm': { 'sources': [u'osm:☃'], 'grids': ['GLOBAL_MERCATOR'], } } } # from source conf = ProxyConfiguration(conf_dict) wms_layer = conf.layers['osm'].wms_layer() layers = wms_layer.map_layers[0].client.request_template.params.layers assert layers == [u'☃'] # from cache self.check_source_layers(conf_dict, [u'☃'])
def test_with_root(self): conf = self._test_conf(''' layers: name: root title: Root Layer layers: - name: one title: Layer One sources: [s] - name: two title: Layer Two sources: [s] ''') conf = ProxyConfiguration(conf) root = conf.wms_root_layer.wms_layer() assert root.title == 'Root Layer' assert root.name == 'root' layers = root.child_layers() # names are in order assert layers.keys() == ['root', 'one', 'two'] assert len(layers) == 3 assert layers['root'].title == 'Root Layer' assert layers['one'].title == 'Layer One' assert layers['two'].title == 'Layer Two' layers_conf = conf.layers assert len(layers_conf) == 2
def test_with_min_res(self): conf = {'grids': {'grid': {'srs': 'EPSG:4326', 'bbox': [5, 50, 10, 55], 'min_res': 0.0390625}}} conf = ProxyConfiguration(conf) grid = conf.grids['grid'].tile_grid() assert_almost_equal_bbox([5, 50, 10, 55], grid.bbox) assert grid.resolution(0) == 0.0390625 assert grid.resolution(1) == 0.01953125
def generate_confs(tileset, layer, title, ignore_warnings=True, renderd=False): """ Default para productos SATMO Takes a Tileset object and returns mapproxy and seed config files """ # Start with a sane configuration using MapProxy's defaults mapproxy_config = load_default_config() tileset_conf_json = get_mapproxy_conf(tileset, layer, title) tileset_conf = yaml.safe_load(tileset_conf_json) # print tileset_conf_json # merge our config load_config(mapproxy_config, config_dict=tileset_conf) seed_conf_json = get_seed_conf(tileset) seed_conf = yaml.safe_load(seed_conf_json) errors, informal_only = validate_options(mapproxy_config) if not informal_only or (errors and not ignore_warnings): raise ConfigurationError('invalid configuration - {}'.format( ', '.join(errors))) mapproxy_cf = ProxyConfiguration(mapproxy_config, seed=seed, renderd=renderd) errors, informal_only = validate_seed_conf(seed_conf) if not informal_only: raise SeedConfigurationError('invalid seed configuration - {}'.format( ', '.join(errors))) seed_cf = SeedingConfiguration(seed_conf, mapproxy_conf=mapproxy_cf) return mapproxy_cf, seed_cf
def test_with_root(self): conf = self._test_conf(''' layers: name: root title: Root Layer layers: - name: one title: Layer One sources: [s] - name: two title: Layer Two sources: [s] ''') conf = ProxyConfiguration(conf) root = conf.wms_root_layer.wms_layer() eq_(root.title, 'Root Layer') eq_(root.name, 'root') layers = root.child_layers() # names are in order eq_(layers.keys(), ['root', 'one', 'two']) eq_(len(layers), 3) eq_(layers['root'].title, 'Root Layer') eq_(layers['one'].title, 'Layer One') eq_(layers['two'].title, 'Layer Two') layers_conf = conf.layers eq_(len(layers_conf), 2)
def test_simple_grid(self): conf_dict = { 'grids': { 'grid': {'srs': 'EPSG:4326', 'bbox': [5, 50, 10, 55]}, }, 'sources': { 'osm': { 'type': 'wms', 'req': { 'url': 'http://localhost/service?', 'layers': 'base', }, }, }, 'caches': { 'osm': { 'sources': ['osm'], 'grids': ['grid'], } } } conf = ProxyConfiguration(conf_dict) caches = conf.caches['osm'].caches() eq_(len(caches), 1) grid, extent, manager = caches[0] eq_(grid.srs, SRS(4326)) eq_(grid.bbox, (5.0, 50.0, 10.0, 55.0)) assert isinstance(manager, TileManager)
def check_source_layers(self, conf_dict, layers): conf = ProxyConfiguration(conf_dict) caches = conf.caches['osm'].caches() eq_(len(caches), 1) grid, extent, manager = caches[0] source_layers = manager.sources[0].client.request_template.params.layers eq_(source_layers, layers)
def test_legacy_unordered(self): conf = self._test_conf(''' layers: one: title: Layer One sources: [s] two: title: Layer Two sources: [s] three: title: Layer Three sources: [s] ''') conf = ProxyConfiguration(conf) root = conf.wms_root_layer.wms_layer() # no root layer defined eq_(root.title, None) eq_(root.name, None) layers = root.child_layers() # names might not be in order # layers.keys() != ['one', 'two', 'three'] eq_(len(layers), 3) eq_(layers['one'].title, 'Layer One') eq_(layers['two'].title, 'Layer Two') eq_(layers['three'].title, 'Layer Three')
def test_default_grids(self): conf = {} conf = ProxyConfiguration(conf) grid = conf.grids['GLOBAL_MERCATOR'].tile_grid() eq_(grid.srs, SRS(900913)) grid = conf.grids['GLOBAL_GEODETIC'].tile_grid() eq_(grid.srs, SRS(4326))
def test_with_base(self): conf = {'grids': { 'base_grid': {'srs': 'EPSG:4326', 'bbox': [5, 50, 10, 55]}, 'grid': {'base': 'base_grid'} }} conf = ProxyConfiguration(conf) grid = conf.grids['grid'].tile_grid() eq_(grid.srs, SRS(4326))
def test_default_format(self): conf_dict = {} conf = ProxyConfiguration(conf_dict) image_opts = conf.globals.image_options.image_opts({}, 'image/png') assert image_opts.format == 'image/png' assert image_opts.mode == None assert image_opts.colors == 256 assert image_opts.transparent == None assert image_opts.resampling == 'bicubic'
def test_default_format(self): conf_dict = {} conf = ProxyConfiguration(conf_dict) image_opts = conf.globals.image_options.image_opts({}, 'image/png') eq_(image_opts.format, 'image/png') eq_(image_opts.mode, None) eq_(image_opts.colors, 256) eq_(image_opts.transparent, None) eq_(image_opts.resampling, 'bicubic')
def test_default_format_paletted_false(self): conf_dict = {'globals': {'image': { 'paletted': False }}} conf = ProxyConfiguration(conf_dict) image_opts = conf.globals.image_options.image_opts({}, 'image/png') assert image_opts.format == 'image/png' assert image_opts.mode == None assert image_opts.colors == None assert image_opts.transparent == None assert image_opts.resampling == 'bicubic'
def test_default_format_paletted_false(self): conf_dict = {'globals': {'image': { 'paletted': False }}} conf = ProxyConfiguration(conf_dict) image_opts = conf.globals.image_options.image_opts({}, 'image/png') eq_(image_opts.format, 'image/png') eq_(image_opts.mode, None) eq_(image_opts.colors, None) eq_(image_opts.transparent, None) eq_(image_opts.resampling, 'bicubic')
def test_simple(self): conf = { 'grids': { 'grid': { 'srs': 'EPSG:4326', 'bbox': [5, 50, 10, 55] } } } conf = ProxyConfiguration(conf) grid = conf.grids['grid'].tile_grid() assert grid.srs == SRS(4326)
def test_custom_format(self): conf_dict = {'globals': {'image': {'resampling_method': 'bilinear', 'formats': { 'image/foo': {'mode': 'RGBA', 'colors': 42} } }}} conf = ProxyConfiguration(conf_dict) image_opts = conf.globals.image_options.image_opts({}, 'image/foo') eq_(image_opts.format, 'image/foo') eq_(image_opts.mode, 'RGBA') eq_(image_opts.colors, 42) eq_(image_opts.transparent, None) eq_(image_opts.resampling, 'bilinear')
def test_update_default_format(self): conf_dict = {'globals': {'image': {'formats': { 'image/png': {'colors': 16, 'resampling_method': 'nearest', 'encoding_options': {'quantizer': 'mediancut'}} }}}} conf = ProxyConfiguration(conf_dict) image_opts = conf.globals.image_options.image_opts({}, 'image/png') eq_(image_opts.format, 'image/png') eq_(image_opts.mode, None) eq_(image_opts.colors, 16) eq_(image_opts.transparent, None) eq_(image_opts.resampling, 'nearest') eq_(image_opts.encoding_options['quantizer'], 'mediancut')
def test_with_num_levels(self): conf = { 'grids': { 'grid': { 'srs': 'EPSG:4326', 'bbox': [5, 50, 10, 55], 'num_levels': 8 } } } conf = ProxyConfiguration(conf) grid = conf.grids['grid'].tile_grid() assert len(grid.resolutions) == 8
def test_update_default_format(self): conf_dict = {'globals': {'image': {'formats': { 'image/png': {'colors': 16, 'resampling_method': 'nearest', 'encoding_options': {'quantizer': 'mediancut'}} }}}} conf = ProxyConfiguration(conf_dict) image_opts = conf.globals.image_options.image_opts({}, 'image/png') assert image_opts.format == 'image/png' assert image_opts.mode == None assert image_opts.colors == 16 assert image_opts.transparent == None assert image_opts.resampling == 'nearest' assert image_opts.encoding_options['quantizer'] == 'mediancut'
def test_custom_format(self): conf_dict = {'globals': {'image': {'resampling_method': 'bilinear', 'formats': { 'image/foo': {'mode': 'RGBA', 'colors': 42} } }}} conf = ProxyConfiguration(conf_dict) image_opts = conf.globals.image_options.image_opts({}, 'image/foo') assert image_opts.format == 'image/foo' assert image_opts.mode == 'RGBA' assert image_opts.colors == 42 assert image_opts.transparent == None assert image_opts.resampling == 'bilinear'
def test_check_zoom_levels(self, mock_get_tables, mock_get_zoom_levels, mock_tile_matrix, mock_sql): from mapproxy.config.loader import ProxyConfiguration example_geopackage = "/test/example.gpkg" grid_name = "default" tile_size = (256, 256) table_name = "tiles" zoom_levels_table = [0, 1, 2] # tile_matrix is abbreviated, for clarity. tile_matrix = [{ "table_name": table_name, "zoom_level": 0 }, { "table_name": table_name, "zoom_level": 1 }] configuration = { "caches": { "default": { "cache": { "type": "geopackage", "filename": example_geopackage }, "grids": [grid_name] } }, "grids": { "default": { "srs": "EPSG:4326", "tile_size": tile_size, "origin": "nw" } }, } mapproxy_configuration = ProxyConfiguration(configuration) mock_get_tables.return_value = (table_name, ) mock_get_zoom_levels.return_value = zoom_levels_table mock_tile_matrix.return_value = tile_matrix check_zoom_levels(example_geopackage, mapproxy_configuration) mock_get_tables.assert_called_once_with(example_geopackage) mock_get_zoom_levels.assert_called_once_with(example_geopackage, table_name) mock_tile_matrix.assert_called_once_with(example_geopackage, table_name) mock_sql.connect().__enter__().execute.assert_called_once_with( "\nINSERT OR REPLACE INTO gpkg_tile_matrix (table_name, zoom_level, matrix_width, matrix_height, " "tile_width, tile_height,\npixel_x_size, pixel_y_size)\nVALUES(?, ?, ?, ?, ?, ?, ?, ?)", ("tiles", 2, 4, 2, 256, 256, 0.3515625, 0.3515625), )
def test_custom_format_grid(self): conf_dict = { 'globals': { 'image': { 'resampling_method': 'bilinear', 'formats': { 'png8': { 'mode': 'P', 'colors': 256 }, 'image/png': { 'mode': 'RGBA', 'transparent': True } }, } }, 'caches': { 'test': { 'sources': [], 'grids': ['GLOBAL_MERCATOR'], 'format': 'png8', 'image': { 'colors': 16, } }, 'test2': { 'sources': [], 'grids': ['GLOBAL_MERCATOR'], 'format': 'image/png', 'image': { 'colors': 8, } } } } conf = ProxyConfiguration(conf_dict) image_opts = conf.caches['test'].image_opts() assert image_opts.format == 'image/png' assert image_opts.mode == 'P' assert image_opts.colors == 16 assert image_opts.transparent == None assert image_opts.resampling == 'bilinear' image_opts = conf.caches['test2'].image_opts() assert image_opts.format == 'image/png' assert image_opts.mode == 'RGBA' assert image_opts.colors == 8 assert image_opts.transparent == True assert image_opts.resampling == 'bilinear'
def get_mapproxy(layer, seed=False, ignore_warnings=True, renderd=False): """Creates a mapproxy config for a given layers """ bbox = [float(layer.bbox_x0), float(layer.bbox_y0), float(layer.bbox_x1), float(layer.bbox_y1)] url = str(layer.service.url) layer_name = simple_name(layer.name) srs = "EPSG:4326" bbox_srs = "EPSG:4326" grid_srs = "EPSG:3857" if layer.service.type == "ESRI_MapServer" or layer.service.type == "ESRI_ImageServer": url = str(layer.service.url).split("?")[0] + "WMSServer?" # blindly replace it with /arcgis/ url = url.replace("/ArcGIS/rest/", "/arcgis/") # same for uppercase url = url.replace("/arcgis/rest/", "/arcgis/") # and for old versions url = url.replace("ArcX/rest/services", "arcx/services") # in uppercase or lowercase url = url.replace("arcx/rest/services", "arcx/services") srs = "EPSG:3857" bbox_srs = "EPSG:3857" if layer.service.type == "WARPER": url = str(layer.url.replace("maps//wms", "maps/wms")) grid_srs = "EPSG:900913" if layer.service.type == "WM": url = str(layer.url.replace("maps//wms", "maps/wms")) default_source = { "type": "wms", "coverage": { "bbox": bbox, "srs": srs, "bbox_srs": bbox_srs, "supported_srs": ["EPSG:4326", "EPSG:900913", "EPSG:3857"], }, "req": {"layers": layer_name, "url": url, "transparent": True}, } if layer.service.type == "ESRI_MapServer": default_source = { "type": "tile", "url": str(layer.service.url).split("?")[0] + "tile/%(z)s/%(y)s/%(x)s", "grid": "default_grid", "transparent": True, } # A source is the WMS config sources = {"default_source": default_source} # A grid is where it will be projects (Mercator in our case) grids = {"default_grid": {"tile_size": [256, 256], "srs": grid_srs, "origin": "nw"}} # A cache that does not store for now. It needs a grid and a source. caches = { "default_cache": { "cache": { "type": "file", "directory_layout": "tms", "directory": os.path.join( tempfile.gettempdir(), "mapproxy", "layer", "%s" % layer.id, "map", "wmts", layer_name, "default_grid", ), }, "grids": ["default_grid"], "sources": ["default_source"], } } # The layer is connected to the cache layers = [{"name": layer_name, "sources": ["default_cache"], "title": str(layer.title)}] # Services expose all layers. # WMS is used for reprojecting # TMS is used for easy tiles # Demo is used to test our installation, may be disabled in final version services = { "wms": { "image_formats": ["image/png"], "md": {"abstract": "This is the Harvard HyperMap Proxy.", "title": "Harvard HyperMap Proxy"}, "srs": ["EPSG:4326", "EPSG:3857"], "versions": ["1.1.1"], }, "wmts": {"restful": True, "restful_template": "/{Layer}/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png"}, "tms": {"origin": "nw"}, "demo": None, } # Start with a sane configuration using MapProxy's defaults conf_options = load_default_config() # Populate a dictionary with custom config changes extra_config = {"caches": caches, "grids": grids, "layers": layers, "services": services, "sources": sources} yaml_config = yaml.dump(extra_config, default_flow_style=False) # If you want to test the resulting configuration. Turn on the next # line and use that to generate a yaml config. # assert False # Merge both load_config(conf_options, config_dict=extra_config) # Make sure the config is valid. errors, informal_only = validate_options(conf_options) for error in errors: log.warn(error) if not informal_only or (errors and not ignore_warnings): raise ConfigurationError("invalid configuration") errors = validate_references(conf_options) for error in errors: log.warn(error) conf = ProxyConfiguration(conf_options, seed=seed, renderd=renderd) # Create a MapProxy App app = MapProxyApp(conf.configured_services(), conf.base_config) # Wrap it in an object that allows to get requests by path as a string. return TestApp(app), yaml_config
def get_mapproxy(layer, seed=False, ignore_warnings=True, renderd=False): """Creates a mapproxy config for a given layers """ bbox = [float(layer.bbox_x0), float(layer.bbox_y0), float(layer.bbox_x1), float(layer.bbox_y1)] url = str(layer.service.url) layer_name = simple_name(layer.name) srs = 'EPSG:4326' bbox_srs = 'EPSG:4326' grid_srs = 'EPSG:3857' if layer.type == 'ESRI:ArcGIS:MapServer' or layer.type == 'ESRI:ArcGIS:ImageServer': url = str(layer.service.url).split('?')[0] + 'WMSServer?' # blindly replace it with /arcgis/ url = url.replace("/ArcGIS/rest/", "/arcgis/") # same for uppercase url = url.replace("/arcgis/rest/", "/arcgis/") # and for old versions url = url.replace("ArcX/rest/services", "arcx/services") # in uppercase or lowercase url = url.replace("arcx/rest/services", "arcx/services") srs = 'EPSG:3857' bbox_srs = 'EPSG:3857' if layer.type == 'Hypermap:WARPER': url = str(layer.url.replace("maps//wms", "maps/wms")) grid_srs = 'EPSG:900913' if layer.type == 'Hypermap:WorldMap': url = str(layer.url.replace("maps//wms", "maps/wms")) default_source = { 'type': 'wms', 'coverage': { 'bbox': bbox, 'srs': srs, 'bbox_srs': bbox_srs, 'supported_srs': ['EPSG:4326', 'EPSG:900913', 'EPSG:3857'], }, 'req': { 'layers': layer_name, 'url': url, 'transparent': True, }, } if layer.type == 'ESRI:ArcGIS:MapServer': default_source = { 'type': 'tile', 'url': str(layer.service.url).split('?')[0] + 'tile/%(z)s/%(y)s/%(x)s', 'grid': 'default_grid', 'transparent': True, } # A source is the WMS config sources = { 'default_source': default_source } # A grid is where it will be projects (Mercator in our case) grids = { 'default_grid': { 'tile_size': [256, 256], 'srs': grid_srs, 'origin': 'nw', } } # A cache that does not store for now. It needs a grid and a source. caches = {'default_cache': { 'cache': { 'type': 'file', 'directory_layout': 'tms', 'directory': os.path.join(tempfile.gettempdir(), 'mapproxy', 'layer', '%s' % layer.id, 'map', 'wmts', layer_name, 'default_grid', ), }, 'grids': ['default_grid'], 'sources': ['default_source']}, } # The layer is connected to the cache layers = [ {'name': layer_name, 'sources': ['default_cache'], 'title': str(layer.title), }, ] # Services expose all layers. # WMS is used for reprojecting # TMS is used for easy tiles # Demo is used to test our installation, may be disabled in final version services = { 'wms': {'image_formats': ['image/png'], 'md': {'abstract': 'This is the Harvard HyperMap Proxy.', 'title': 'Harvard HyperMap Proxy'}, 'srs': ['EPSG:4326', 'EPSG:3857'], 'versions': ['1.1.1']}, 'wmts': { 'restful': True, 'restful_template': '/{Layer}/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png', }, 'tms': { 'origin': 'nw', }, 'demo': None, } global_config = { 'http': {'ssl_no_cert_checks': True}, } # Start with a sane configuration using MapProxy's defaults conf_options = load_default_config() # Populate a dictionary with custom config changes extra_config = { 'caches': caches, 'grids': grids, 'layers': layers, 'services': services, 'sources': sources, 'globals': global_config, } yaml_config = yaml.dump(extra_config, default_flow_style=False) # If you want to test the resulting configuration. Turn on the next # line and use that to generate a yaml config. # assert False # Merge both load_config(conf_options, config_dict=extra_config) # Make sure the config is valid. errors, informal_only = validate_options(conf_options) for error in errors: log.warn(error) if not informal_only or (errors and not ignore_warnings): raise ConfigurationError('invalid configuration') errors = validate_references(conf_options) for error in errors: log.warn(error) conf = ProxyConfiguration(conf_options, seed=seed, renderd=renderd) # Create a MapProxy App app = MapProxyApp(conf.configured_services(), conf.base_config) # Wrap it in an object that allows to get requests by path as a string. return TestApp(app), yaml_config