Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
def generate_confs(tileset, ignore_warnings=True, renderd=False):
    """
    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)
    tileset_conf = yaml.safe_load(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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
def create_mapproxy_app(slug: str, user: User = None) -> TestApp:
    mapproxy_config_key = get_mapproxy_config_template(slug, user=user)
    mapproxy_config = cache.get(mapproxy_config_key)
    conf_dict = cache.get_or_set(f"base-config-{slug}", lambda: get_conf_dict(slug), 360)
    if not mapproxy_config:
        # TODO: place this somewhere else consolidate settings.
        base_config: Dict[str, Any] = {
            "services": {
                "demo": None,
                "tms": None,
                "wmts": {
                    "featureinfo_formats": [
                        {"mimetype": "application/json", "suffix": "json"},
                        {"mimetype": "application/gml+xml; version=3.1", "suffix": "gml"},
                    ]
                },
            },
            # Cache based on slug so that the caches don't overwrite each other.
            "caches": {slug: {"cache": {"type": "file"}, "sources": ["default"], "grids": ["default"]}},
            "layers": [{"name": slug, "title": slug, "sources": [slug]}],
            "globals": {"cache": {"base_dir": getattr(settings, "TILE_CACHE_DIR")}},
        }
        if conf_dict["sources"].get("info"):
            base_config["caches"][slug]["sources"] += ["info"]
        if conf_dict["sources"].get("footprint"):
            base_config["caches"][get_footprint_layer_name(slug)] = {
                "cache": {"type": "file"},
                "sources": ["footprint"],
                "grids": ["default"],
            }
            base_config["layers"] += [
                {
                    "name": get_footprint_layer_name(slug),
                    "title": get_footprint_layer_name(slug),
                    "sources": [get_footprint_layer_name(slug)],
                }
            ]
        base_config, conf_dict = add_restricted_regions_to_config(base_config, conf_dict, slug, None)
        try:
            mapproxy_config = load_default_config()
            load_config(mapproxy_config, config_dict=base_config)
            load_config(mapproxy_config, config_dict=conf_dict)
            mapproxy_configuration = ProxyConfiguration(mapproxy_config)

            if settings.REGIONAL_JUSTIFICATION_TIMEOUT_DAYS:
                regional_justification_timeout = settings.REGIONAL_JUSTIFICATION_TIMEOUT_DAYS * 86400
            else:
                regional_justification_timeout = None
            mapproxy_configs_set = cache.get_or_set(mapproxy_config_keys_index, set())
            mapproxy_configs_set.add(mapproxy_config_key)
            cache.set(mapproxy_config_keys_index, mapproxy_configs_set)
            cache.set(mapproxy_config_key, mapproxy_config, regional_justification_timeout)

        except ConfigurationError as e:
            logger.error(e)
            raise
    else:
        try:
            mapproxy_configuration = ProxyConfiguration(mapproxy_config)
        except ConfigurationError as e:
            logger.error(e)
            raise

    cert_info = conf_dict.get("cert_info")
    auth_requests.patch_https(cert_info=cert_info)

    cred_var = conf_dict.get("cred_var")
    auth_requests.patch_mapproxy_opener_cache(slug=slug, cred_var=cred_var)

    app = MapProxyApp(mapproxy_configuration.configured_services(), mapproxy_config)

    return TestApp(app)
Ejemplo n.º 7
0
    def get_check_config(self):
        """
        Create a MapProxy configuration object and verifies its validity
        """
        if self.config or self.projection:
            conf_dict = yaml.safe_load(self.config) or dict()
        else:
            raise ConfigurationError("MapProxy configuration is required for raster data providers")

        if not conf_dict.get("grids"):
            conf_dict["grids"] = {
                "default": {"srs": "EPSG:4326", "tile_size": [256, 256], "origin": "nw"},
                "webmercator": {"srs": "EPSG:3857", "tile_size": [256, 256], "origin": "nw"},
            }
        elif self.projection:
            conf_dict["grids"].update(
                {str(self.projection): {"srs": f"EPSG:{self.projection}", "tile_size": [256, 256], "origin": "nw"}}
            )

        # If user provides a cache setup then use that and substitute in the geopackage file for the placeholder.
        conf_dict["caches"] = conf_dict.get("caches", {})
        try:
            conf_dict["caches"]["default"]["cache"]["filename"] = self.gpkgfile
        except KeyError:
            conf_dict["caches"]["default"] = get_cache_template(
                ["{0}".format(self.layer)],
                [grids for grids in conf_dict.get("grids")],
                self.gpkgfile,
                table_name=self.layer,
            )

        if self.projection:
            conf_dict["caches"]["repro_cache"] = copy.deepcopy(conf_dict["caches"]["default"])
            conf_dict["caches"]["repro_cache"]["cache"]["filename"] = self.input_gpkg
            conf_dict["caches"]["repro_cache"]["sources"] = []
            conf_dict["caches"]["default"]["meta_size"] = [4, 4]
            conf_dict["caches"]["default"]["bulk_meta_tiles"] = True
            conf_dict["caches"]["default"] = get_cache_template(
                ["repro_cache"], [str(self.projection)], self.gpkgfile, "default"
            )

        # Need something listed as a service to pass the mapproxy validation.
        conf_dict["services"] = ["demo"]

        # disable SSL cert checks

        ssl_verify = getattr(settings, "SSL_VERIFICATION", True)
        if isinstance(ssl_verify, bool):
            if not ssl_verify:
                conf_dict["globals"] = {"http": {"ssl_no_cert_checks": ssl_verify}}
        else:
            conf_dict["globals"] = {"http": {"ssl_ca_certs": ssl_verify}}

        # Add autoconfiguration to base_config
        mapproxy_config = load_default_config()
        load_config(mapproxy_config, config_dict=conf_dict)

        # Create a configuration object
        mapproxy_configuration = ProxyConfiguration(mapproxy_config, seed=seeder.seed, renderd=None)

        # # As of Mapproxy 1.9.x, datasource files covering a small area cause a bbox error.
        if self.bbox:
            if isclose(self.bbox[0], self.bbox[2], rel_tol=0.001) or isclose(self.bbox[1], self.bbox[3], rel_tol=0.001):
                logger.warning("Using bbox instead of selection, because the area is too small")
                self.selection = None

        seed_dict = get_seed_template(
            bbox=self.bbox,
            level_from=self.level_from,
            level_to=self.level_to,
            coverage_file=self.selection,
            projection=self.projection,
        )

        # Create a seed configuration object
        seed_configuration = SeedingConfiguration(seed_dict, mapproxy_conf=mapproxy_configuration)
        errors = validate_references(conf_dict)
        if errors:
            logger.error("MapProxy configuration failed.")
            logger.error("Using Configuration:")
            logger.error(conf_dict)
            raise ConfigurationError("MapProxy returned the error - {0}".format(", ".join(errors)))

        return conf_dict, seed_configuration, mapproxy_configuration
Ejemplo n.º 8
0
def get_mapproxy(layer, seed=False, ignore_warnings=True, renderd=False):
    """Creates a mapproxy config for a given layer-like object.
       Compatible with django-registry and GeoNode.
    """
    bbox = list(wkt2geom(layer.wkt_geometry))

    # TODO: Check for correct url
    url = 'http://test.registry.org'
    # url = str(layer.service.url)

    layer_name = str(layer.title)

    srs = 'EPSG:4326'
    bbox_srs = 'EPSG:4326'
    grid_srs = 'EPSG:3857'

    default_source = {
        'type': 'wms',
        'coverage': {
            'bbox': bbox,
            'srs': srs,
            'bbox_srs': bbox_srs,
            'supported_srs': ['EPSG:4326', 'EPSG:900913', 'EPSG:3857'],
        },
        'req': {
            'layers': str(layer.title),
            'url': url,
            'transparent': True,
        },
    }

    if layer.type == 'ESRI:ArcGIS:MapServer' or layer.type == 'ESRI:ArcGIS:ImageServer':
        # 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'

        default_source = {
            'type': 'arcgis',
            'req': {
                'url': url,
                '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': {
            'disable_storage': True,
            '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)

    # TODO: Make sure the config is valid.
    errors, informal_only = validate_options(conf_options)
    for error in errors:
        LOGGER.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:
        LOGGER.warn(error)

    conf = ProxyConfiguration(conf_options, seed=seed, renderd=renderd)

    # Create a MapProxy App
    app = MapProxyApp(conf.configured_services(), conf.base_config)

    return app, yaml_config
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
    def get_check_config(self):
        """
        Create a MapProxy configuration object and verifies its validity
        """
        if self.config:
            conf_dict = yaml.load(self.config)
        else:
            conf_dict = create_conf_from_url(self.service_url)

        if not conf_dict.get('grids'):
            conf_dict['grids'] = {
                'geodetic': {
                    'srs': 'EPSG:4326',
                    'tile_size': [256, 256],
                    'origin': 'nw'
                },
                'webmercator': {
                    'srs': 'EPSG:3857',
                    'tile_size': [256, 256],
                    'origin': 'nw'
                }
            }

        # If user provides a cache setup then use that and substitute in the geopackage file for the placeholder.
        conf_dict['caches'] = conf_dict.get('caches', {})
        try:
            conf_dict['caches']['cache']['cache']['filename'] = self.gpkgfile
        except KeyError:
            conf_dict['caches']['cache'] = get_cache_template(
                ["{0}_{1}".format(self.layer, self.service_type)],
                [grids for grids in conf_dict.get('grids')],
                self.gpkgfile,
                table_name=self.layer)

        conf_dict['services'] = ['demo']

        # Prevent the service from failing if source has missing tiles.
        for source in conf_dict.get('sources') or []:
            if 'wmts' in source:
                conf_dict['sources'][source]['transparent'] = True
                # You can set any number of error codes here, and mapproxy will ignore them any time they appear and
                # just skip the tile instead (normally it retries the tile for a very long time before finally erroring
                # out and quitting the job). Putting the string "other" as an additional error code will cause mapproxy
                # to skip tiles with ANY retrieval error. For now, we want to have mapproxy skip 404 tiles, and retry
                # everything else.
                conf_dict['sources'][source]['on_error'] = {
                    404: {
                        "response": "transparent",
                        "cache": False
                    }
                }

        # disable SSL cert checks
        if getattr(settings, "DISABLE_SSL_VERIFICATION", False):
            conf_dict['globals'] = {'http': {'ssl_no_cert_checks': True}}

        # Add autoconfiguration to base_config
        # default = load_default_config()
        mapproxy_config = load_default_config()
        load_config(mapproxy_config, config_dict=conf_dict)

        # Create a configuration object
        mapproxy_configuration = ProxyConfiguration(mapproxy_config,
                                                    seed=seed,
                                                    renderd=None)

        # # As of Mapproxy 1.9.x, datasource files covering a small area cause a bbox error.
        if self.bbox:
            if isclose(self.bbox[0], self.bbox[2], rel_tol=0.001) or isclose(
                    self.bbox[0], self.bbox[2], rel_tol=0.001):
                logger.warn(
                    'Using bbox instead of selection, because the area is too small'
                )
                self.selection = None

        seed_dict = get_seed_template(bbox=self.bbox,
                                      level_from=self.level_from,
                                      level_to=self.level_to,
                                      coverage_file=self.selection)

        # Create a seed configuration object
        seed_configuration = SeedingConfiguration(
            seed_dict, mapproxy_conf=mapproxy_configuration)

        errors = validate_references(conf_dict)
        if errors:
            logger.error("MapProxy configuration failed.")
            logger.error("Using Configuration:")
            logger.error(conf_dict)
            raise ConfigurationError(
                "MapProxy returned the error - {0}".format(", ".join(errors)))

        return conf_dict, seed_configuration, mapproxy_configuration
Ejemplo n.º 11
0
    def get_check_config(self):
        """
        Create a MapProxy configuration object and verifies its validity
        """
        if self.config:
            conf_dict = yaml.load(self.config)
        else:
            raise ConfigurationError("MapProxy configuration is required for raster data providers")

        if not conf_dict.get('grids'):
            conf_dict['grids'] = {'geodetic': {'srs': 'EPSG:4326',
                                               'tile_size': [256, 256],
                                               'origin': 'nw'},
                                  'webmercator': {'srs': 'EPSG:3857',
                                                  'tile_size': [256, 256],
                                                  'origin': 'nw'}}

        # If user provides a cache setup then use that and substitute in the geopackage file for the placeholder.
        conf_dict['caches'] = conf_dict.get('caches', {})
        try:
            conf_dict['caches']['cache']['cache']['filename'] = self.gpkgfile
        except KeyError:
            conf_dict['caches']['cache'] = get_cache_template(["{0}".format(self.layer)],
                                                              [grids for grids in conf_dict.get('grids')],
                                                              self.gpkgfile, table_name=self.layer)

        # Need something listed as a service to pass the mapproxy validation.
        conf_dict['services'] = ['demo']

        # disable SSL cert checks
        ssl_verify = getattr(settings, "SSL_VERIFICATION", True)
        if not ssl_verify:
            conf_dict['globals'] = {'http': {'ssl_no_cert_checks': True}}

        # Add autoconfiguration to base_config
        # default = load_default_config()
        mapproxy_config = load_default_config()
        load_config(mapproxy_config, config_dict=conf_dict)

        # Create a configuration object
        mapproxy_configuration = ProxyConfiguration(mapproxy_config, seed=seeder.seed, renderd=None)

        # # As of Mapproxy 1.9.x, datasource files covering a small area cause a bbox error.
        if self.bbox:
            if isclose(self.bbox[0], self.bbox[2], rel_tol=0.001) or isclose(self.bbox[0], self.bbox[2], rel_tol=0.001):
                logger.warning('Using bbox instead of selection, because the area is too small')
                self.selection = None

        seed_dict = get_seed_template(bbox=self.bbox, level_from=self.level_from, level_to=self.level_to,
                                      coverage_file=self.selection)

        # Create a seed configuration object
        seed_configuration = SeedingConfiguration(seed_dict, mapproxy_conf=mapproxy_configuration)

        errors = validate_references(conf_dict)
        if errors:
            logger.error("MapProxy configuration failed.")
            logger.error("Using Configuration:")
            logger.error(conf_dict)
            raise ConfigurationError("MapProxy returned the error - {0}".format(", ".join(errors)))

        return conf_dict, seed_configuration, mapproxy_configuration
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
    def get_check_config(self):
        """
        Create a MapProxy configuration object and verifies its validity
        """
        if self.config:
            conf_dict = yaml.load(self.config)
        else:
            raise ConfigurationError(
                "MapProxy configuration is required for raster data providers")

        if not conf_dict.get('grids'):
            conf_dict['grids'] = {
                'geodetic': {
                    'srs': 'EPSG:4326',
                    'tile_size': [256, 256],
                    'origin': 'nw'
                },
                'webmercator': {
                    'srs': 'EPSG:3857',
                    'tile_size': [256, 256],
                    'origin': 'nw'
                }
            }

        # If user provides a cache setup then use that and substitute in the geopackage file for the placeholder.
        conf_dict['caches'] = conf_dict.get('caches', {})
        try:
            conf_dict['caches']['cache']['cache']['filename'] = self.gpkgfile
        except KeyError:
            conf_dict['caches']['cache'] = get_cache_template(
                ["{0}".format(self.layer)],
                [grids for grids in conf_dict.get('grids')],
                self.gpkgfile,
                table_name=self.layer)

        # Need something listed as a service to pass the mapproxy validation.
        conf_dict['services'] = ['demo']

        # disable SSL cert checks
        ssl_verify = getattr(settings, "SSL_VERIFICATION", True)
        if not ssl_verify:
            conf_dict['globals'] = {'http': {'ssl_no_cert_checks': True}}

        # Add autoconfiguration to base_config
        # default = load_default_config()
        mapproxy_config = load_default_config()
        load_config(mapproxy_config, config_dict=conf_dict)

        # Create a configuration object
        mapproxy_configuration = ProxyConfiguration(mapproxy_config,
                                                    seed=seed,
                                                    renderd=None)

        # # As of Mapproxy 1.9.x, datasource files covering a small area cause a bbox error.
        if self.bbox:
            if isclose(self.bbox[0], self.bbox[2], rel_tol=0.001) or isclose(
                    self.bbox[0], self.bbox[2], rel_tol=0.001):
                logger.warn(
                    'Using bbox instead of selection, because the area is too small'
                )
                self.selection = None

        seed_dict = get_seed_template(bbox=self.bbox,
                                      level_from=self.level_from,
                                      level_to=self.level_to,
                                      coverage_file=self.selection)

        # Create a seed configuration object
        seed_configuration = SeedingConfiguration(
            seed_dict, mapproxy_conf=mapproxy_configuration)

        errors = validate_references(conf_dict)
        if errors:
            logger.error("MapProxy configuration failed.")
            logger.error("Using Configuration:")
            logger.error(conf_dict)
            raise ConfigurationError(
                "MapProxy returned the error - {0}".format(", ".join(errors)))

        return conf_dict, seed_configuration, mapproxy_configuration
Ejemplo n.º 14
0
    def convert(self, ):
        """
        Convert external service to gpkg.
        """

        from ..tasks.task_process import TaskProcess
        from .geopackage import remove_empty_zoom_levels

        if self.config:
            conf_dict = yaml.load(self.config)
        else:
            conf_dict = create_conf_from_url(self.service_url)

        if not conf_dict.get('grids'):
            conf_dict['grids'] = {
                'geodetic': {
                    'srs': 'EPSG:4326',
                    'tile_size': [256, 256],
                    'origin': 'nw'
                },
                'webmercator': {
                    'srs': 'EPSG:3857',
                    'tile_size': [256, 256],
                    'origin': 'nw'
                }
            }

        # If user provides a cache setup then use that and substitute in the geopackage file for the placeholder.
        conf_dict['caches'] = conf_dict.get('caches', {})
        try:
            conf_dict['caches']['cache']['cache']['filename'] = self.gpkgfile
        except KeyError:
            conf_dict['caches']['cache'] = get_cache_template(
                ["{0}_{1}".format(self.layer, self.service_type)],
                [grids for grids in conf_dict.get('grids')], self.gpkgfile)

        # Prevent the service from failing if source has missing tiles.
        for source in conf_dict.get('sources'):
            if 'wmts' in source:
                conf_dict['sources'][source]['transparent'] = True
                conf_dict['sources'][source]['on_error'] = {
                    "other": {
                        "response": "transparent",
                        "cache": False
                    }
                }

        # disable SSL cert checks
        if getattr(settings, "DISABLE_SSL_VERIFICATION", False):
            conf_dict['globals'] = {'http': {'ssl_no_cert_checks': True}}

        # Add autoconfiguration to base_config
        # default = load_default_config()
        mapproxy_config = load_default_config()
        load_config(mapproxy_config, config_dict=conf_dict)

        # Create a configuration object
        mapproxy_configuration = ProxyConfiguration(mapproxy_config,
                                                    seed=seed,
                                                    renderd=None)

        # # As of Mapproxy 1.9.x, datasource files covering a small area cause a bbox error.
        if isclose(self.bbox[0], self.bbox[2], rel_tol=0.01) or isclose(
                self.bbox[0], self.bbox[2], rel_tol=0.01):
            logger.warn(
                'Using bbox instead of selection, because the area is too small'
            )
            self.selection = None

        seed_dict = get_seed_template(bbox=self.bbox,
                                      level_from=self.level_from,
                                      level_to=self.level_to,
                                      coverage_file=self.selection)

        # Create a seed configuration object
        seed_configuration = SeedingConfiguration(
            seed_dict, mapproxy_conf=mapproxy_configuration)

        logger.info("Beginning seeding to {0}".format(self.gpkgfile))
        logger.error(mapproxy_config)
        try:
            check_service(conf_dict)
            progress_logger = CustomLogger(verbose=True,
                                           task_uid=self.task_uid)
            task_process = TaskProcess(task_uid=self.task_uid)
            task_process.start_process(
                billiard=True,
                target=seeder.seed,
                kwargs={
                    "tasks":
                    seed_configuration.seeds(['seed']),
                    "concurrency":
                    int(getattr(settings, 'MAPPROXY_CONCURRENCY', 1)),
                    "progress_logger":
                    progress_logger
                })
            remove_empty_zoom_levels(self.gpkgfile)
        except Exception as e:
            logger.error("Export failed for url {}.".format(self.service_url))
            errors, informal_only = validate_options(mapproxy_config)
            if not informal_only:
                logger.error("MapProxy configuration failed.")
                logger.error("Using Configuration:")
                logger.error(mapproxy_config)
            errors, informal_only = validate_seed_conf(seed_dict)
            if not informal_only:
                logger.error("Mapproxy Seed failed.")
                logger.error("Using Seed Configuration:")
                logger.error(seed_dict)
                raise SeedConfigurationError(
                    'MapProxy seed configuration error  - {}'.format(
                        ', '.join(errors)))
            raise e
        finally:
            connections.close_all()
        return self.gpkgfile