예제 #1
0
def parse_point_input( param: QgsProcessingParameterDefinition, kwargs) -> ComplexInput:
    """ Convert processing point input to complex input
    """
    if isinstance(param, QgsProcessingParameterPoint):
        kwargs['supported_formats'] = [Format.from_definition(FORMATS.GEOJSON),
                                       Format.from_definition(FORMATS.GML)]
        return ComplexInput(**kwargs)
예제 #2
0
def test_format_class():
    """Test pyqgiswps.formats.Format class
    """
    frmt = Format('mimetype',
                  schema='halloworld',
                  encoding='asdf',
                  validate=validate)

    assert frmt.mime_type == 'mimetype'
    assert frmt.schema == 'halloworld'
    assert frmt.encoding == 'asdf'
    assert frmt.validate('the input', 1)

    describeel = frmt.describe_xml()
    assert 'Format' == describeel.tag
    mimetype = xpath_ns(describeel, '/Format/MimeType')
    encoding = xpath_ns(describeel, '/Format/Encoding')
    schema = xpath_ns(describeel, '/Format/Schema')

    assert mimetype
    assert encoding
    assert schema

    assert mimetype[0].text == 'mimetype'
    assert encoding[0].text == 'asdf'
    assert schema[0].text == 'halloworld'

    frmt2 = get_format('GML')

    assert not frmt.same_as(frmt2)
예제 #3
0
def parse_layer_output(outdef: QgsProcessingOutputDefinition,
                       kwargs) -> ComplexOutput:
    """ Parse layer output

        A layer output is merged to a qgis project, we return
        the wms uri associated to the project
    """
    if isinstance(outdef, OUTPUT_LAYER_TYPES):
        if isinstance(outdef, QgsProcessingOutputVectorLayer):
            return ComplexOutput(supported_formats=[
                Format("application/x-ogc-wms"),
                Format("application/x-ogc-wfs")
            ],
                                 as_reference=True,
                                 **kwargs)
        elif isinstance(outdef, QgsProcessingOutputRasterLayer):
            return ComplexOutput(supported_formats=[
                Format("application/x-ogc-wms"),
                Format("application/x-ogc-wcs")
            ],
                                 as_reference=True,
                                 **kwargs)
        else:
            return ComplexOutput(
                supported_formats=[Format("application/x-ogc-wms")],
                as_reference=True,
                **kwargs)
예제 #4
0
def parse_file_output( outdef: QgsProcessingOutputDefinition, kwargs, 
                       alg: QgsProcessingAlgorithm=None ) -> ComplexOutput:
    """ Parse file output definition

        QgsProcessingOutputDefinition metadata will be checked to get 
        wps parameter settings:

            - 'wps:as_reference': boolean, True if the file will be sent as reference. If
            false, the file will included in the body of the response. Default is True.
    """
    as_reference = confservice.getboolean('server','outputfile_as_reference')
    if isinstance(outdef, QgsProcessingOutputHtml):
        mime = mimetypes.types_map.get('.html')
        return ComplexOutput(supported_formats=[Format(mime)],**kwargs)
    elif isinstance(outdef, QgsProcessingOutputFile):
        # Try to get a corresponding inputFileDefinition
        # See https://qgis.org/pyqgis/master/core/QgsProcessingParameterFileDestination.html
        mime = None
        if alg:
            inputdef = alg.parameterDefinition(outdef.name())
            if isinstance(inputdef, QgsProcessingParameterFileDestination):
                mime = mimetypes.types_map.get("."+inputdef.defaultFileExtension())
                as_reference = inputdef.metadata().get('wps:as_reference',as_reference)
        if mime is None:
            LOGGER.warning("Cannot set file type for output %s", outdef.name())
            mime = "application/octet-stream"
        return ComplexOutput(supported_formats=[Format(mime)], as_reference=as_reference, **kwargs)
예제 #5
0
def parse_input_definition(param: QgsProcessingParameterDefinition,
                           kwargs,
                           context: MapContext = None) -> WPSInput:
    """ Convert processing input to File Input 
    """
    typ = param.type()

    if typ == 'crs':
        kwargs['data_type'] = 'string'
        return LiteralInput(**kwargs)
    elif typ == "extent":
        return parse_extent_input(param, kwargs, context)
    elif isinstance(param, GeometryParameterTypes):
        kwargs['supported_formats'] = [
            Format.from_definition(FORMATS.GEOJSON),
            Format.from_definition(FORMATS.GML),
            Format.from_definition(FORMATS.WKT)
        ]
        if isinstance(param, QgsProcessingParameterGeometry):
            # Add metadata from requiered geometryTypes
            kwargs['metadata'].extend(
                Metadata('processing:geometryType', QgsWkbTypes.geometryDisplayString(geomtype)) \
                for geomtype in param.geometryTypes()
            )
            if param.allowMultipart():
                kwargs['metadata'].append(
                    Metadata('processing:allowMultipart'))
        return ComplexInput(**kwargs)

    return None
예제 #6
0
def test_complex_output_href():
    """ Test external reference in complex output 
    """

    kwargs = {
        'identifier': 'hreftest',
        'title': '',
        'abstract': '',
    }

    output = ComplexOutput(supported_formats=[
        Format("application/x-ogc-wms"),
        Format("application/x-ogc-wfs")
    ],
                           as_reference=True,
                           **kwargs)

    output.output_format = "application/x-ogc-wms"
    output.url = "http://my.org/external/ref"

    output_elements = output.execute_xml()

    # Check that <wps:Reference href=...> is not namspaced
    element = output_elements.xpath(
        '//wps:Reference',
        namespaces={'wps': "http://www.opengis.net/wps/1.0.0"})

    assert len(element) == 1
    assert 'href' in element[0].attrib
예제 #7
0
def test_complex_input_default_and_supported():
    complex_in = ComplexInput('foo',
                              'Complex foo',
                              supported_formats=[Format('a/b'),
                                                 Format('c/d')])
    doc = complex_in.describe_xml()
    [default_format] = xpath_ns(doc, './ComplexData/Default/Format')
    [default_mime_el] = xpath_ns(default_format, './MimeType')
    assert default_mime_el.text == 'a/b'
    supported_mime_types = []
    for supported_el in xpath_ns(doc, './ComplexData/Supported/Format'):
        [mime_el] = xpath_ns(supported_el, './MimeType')
        supported_mime_types.append(mime_el.text)
    assert supported_mime_types == ['a/b', 'c/d']
예제 #8
0
def test_geometry_script(outputdir, data):
    """ Test geometry script
    """
    alg = _find_algorithm('script:testinputgeometry')

    inputs  = { p.name(): [parse_input_definition(p)] for p in  alg.parameterDefinitions() }
    outputs = { p.name(): parse_output_definition(p) for p in  alg.outputDefinitions() }
   
    inp  = inputs['INPUT'][0]
    inp.data_format = Format.from_definition(FORMATS.WKT)
    inp.data = 'CRS=EPSG:4326;MULTIPOINT((3.5 5.6), (4.8 10.5))'

    # Load source project
    source = QgsProject()
    rv = source.read(str(data/'france_parts.qgs'))
    assert rv == True

    context  = Context(source, outputdir)
    feedback = QgsProcessingFeedback() 

    parameters = dict( input_to_processing(ident, inp, alg, context) for ident,inp in inputs.items() )  

    # Check marshalled value 
    value = parameters['INPUT']
    assert isinstance( value, QgsReferencedGeometry )
    assert value.wkbType() == QgsWkbTypes.MultiPoint

    context.wms_url = "http://localhost/wms/?MAP=test/{name}.qgs".format(name=alg.name())
    # Run algorithm
    with chdir(outputdir):
        results = run_algorithm(alg, parameters=parameters, feedback=feedback, context=context, outputs=outputs)   
   
    out = json.loads(outputs.get('OUTPUT').data)
    assert out['type'] == 'MultiPoint'
예제 #9
0
def parse_file_input(param: QgsProcessingParameterDefinition,
                     kwargs) -> Union[LiteralInput, ComplexInput]:
    """ Input is file
    """
    typ = param.type()
    if typ == 'file':
        if param.behavior() == QgsProcessingParameterFile.Folder:
            kwargs['data_type'] = 'string'
            return LiteralInput(**kwargs)
        ext = param.extension()
        if ext:
            mime = mimetypes.types_map.get(param.extension())
            if mime is not None:
                kwargs['supported_formats'] = [Format(mime)]
            kwargs['metadata'].append(
                Metadata('processing:extension', param.extension()))
        return ComplexInput(**kwargs)
    elif typ == 'fileDestination':
        extension = '.' + param.defaultFileExtension()
        kwargs['data_type'] = 'string'
        kwargs['metadata'].append(
            Metadata('processing:format',
                     mimetypes.types_map.get(extension, '')))
        return LiteralInput(**kwargs)
    elif typ == 'folderDestination':
        kwargs['data_type'] = 'string'
        return LiteralInput(**kwargs)
예제 #10
0
def test_complex_input_identifier():
    complex_in = ComplexInput('foo',
                              'Complex foo',
                              supported_formats=[Format('bar/baz')])
    doc = complex_in.describe_xml()
    assert doc.tag == E.Input().tag
    [identifier_el] = xpath_ns(doc, './ows:Identifier')
    assert identifier_el.text == 'foo'
예제 #11
0
def test_json_in():
    """Test json import
    """

    injson = {}
    injson['schema'] = 'elcepelce'
    injson['extension'] = '.gml'
    injson['mime_type'] = 'application/gml+xml'
    injson['encoding'] = 'utf-8'

    frmt = Format(injson['mime_type'])
    frmt.json = injson

    assert injson['schema'] == frmt.schema
    assert injson['extension'] == frmt.extension
    assert injson['mime_type'] == frmt.mime_type
    assert injson['encoding'] == frmt.encoding
예제 #12
0
def test_complex_output():
    complexo = ComplexOutput('complex', 'Complex foo', [Format('GML')])
    doc = complexo.describe_xml()
    [outpt] = xpath_ns(doc, '/Output')
    [default] = xpath_ns(doc, '/Output/ComplexOutput/Default/Format/MimeType')
    supported = xpath_ns(doc,
                         '/Output/ComplexOutput/Supported/Format/MimeType')
    assert default.text == 'application/gml+xml'
    assert len(supported) == 1
예제 #13
0
def parse_file_output(outdef: QgsProcessingOutputDefinition,
                      kwargs,
                      alg: QgsProcessingAlgorithm = None) -> ComplexOutput:
    """ Parse file output definition
    """
    if isinstance(outdef, QgsProcessingOutputHtml):
        mime = mimetypes.types_map.get('.html')
        return ComplexOutput(supported_formats=[Format(mime)], **kwargs)
    elif isinstance(outdef, QgsProcessingOutputFile):
        # Try to get a corresponding inputFileDefinition
        mime = None
        if alg:
            inputdef = alg.parameterDefinition(outdef.name())
            if isinstance(inputdef, QgsProcessingParameterFileDestination):
                mime = mimetypes.types_map.get("." +
                                               inputdef.defaultFileExtension())
        if mime is None:
            LOGGER.warning("Cannot set file type for output %s", outdef.name())
            mime = "application/octet-stream"
        return ComplexOutput(supported_formats=[Format(mime)], **kwargs)
예제 #14
0
def test_point_input_wkt():
    """ Test input point from wkt
    """
    param = QgsProcessingParameterPoint("POINT")

    inp = parse_input_definition(param)

    assert isinstance(inp,ComplexInput)
    assert inp.as_reference == False

    inp.data_format = Format.from_definition(FORMATS.WKT)
    inp.data = 'CRS=EPSG:4326;POINT(6 10)'

    assert inp.data_format.mime_type == FORMATS.WKT.mime_type

    value = geometryio.input_to_point( inp )
    assert isinstance( value, QgsReferencedPointXY )
예제 #15
0
def test_point_input_json():
    """ Test input point from json
    """
    param = QgsProcessingParameterPoint("POINT")

    inp = parse_input_definition(param)

    assert isinstance(inp,ComplexInput)
    assert inp.as_reference == False

    inp.data_format = Format.from_definition(FORMATS.GEOJSON)
    inp.data = '{"coordinates":[4.0,42.0],"type":"Point"}'

    assert inp.data_format.mime_type == FORMATS.GEOJSON.mime_type

    value = geometryio.input_to_point( inp )
    assert isinstance( value, QgsGeometry )
예제 #16
0
def parse_response(value: Any, outdef: QgsProcessingOutputDefinition,
                   out: WPSOutput,
                   context: ProcessingContext) -> Optional[WPSOutput]:
    """ Map processing output to WPS
    """
    if isinstance(outdef, QgsProcessingOutputHtml):
        out.output_format = mimetypes.types_map['.html']
        return to_output_file(value, out, context)
    elif isinstance(outdef, QgsProcessingOutputFile):
        _, sfx = os.path.splitext(value)
        mime = mimetypes.types_map.get(sfx.lower())
        LOGGER.debug("Return output file '%s' with mime type '%s'", value,
                     mime)
        if mime is None:
            mime = "application/octet-stream"
        out.data_format = Format(mime)
        return to_output_file(value, out, context)
예제 #17
0
def test_point_input_gml():
    """ Test input point from gml
    """
    param = QgsProcessingParameterPoint("POINT")

    inp = parse_input_definition(param)

    assert isinstance(inp, ComplexInput)
    assert inp.as_reference == False

    inp.data_format = Format.from_definition(FORMATS.GML)
    inp.data = '<gml:Point srsName="EPSG:4326"><gml:coordinates>4,42</gml:coordinates></gml:Point>'

    assert inp.data_format.mime_type == FORMATS.GML.mime_type

    value = input_to_point(inp)
    assert isinstance(value, (QgsGeometry, QgsReferencedPointXY))
예제 #18
0
def test_multipoint_input_json():
    """ Test input point from json
    """
    param = QgsProcessingParameterPoint("GEOM")

    inp = parse_input_definition(param)

    assert isinstance(inp,ComplexInput)
    assert inp.as_reference == False

    inp.data_format = Format.from_definition(FORMATS.GEOJSON)
    inp.data = '{"coordinates":[[10, 40], [40, 30], [20, 20], [30, 10]],"type":"MultiPoint"}'

    assert inp.data_format.mime_type == FORMATS.GEOJSON.mime_type

    value = geometryio.input_to_geometry( inp )
    assert isinstance( value, QgsGeometry )
    assert value.wkbType() == QgsWkbTypes.MultiPoint
예제 #19
0
def test_multipoint_input_wkt():
    """ Test input point from gml
    """
    param = QgsProcessingParameterPoint("GEOM")

    inp = parse_input_definition(param)

    assert isinstance(inp,ComplexInput)
    assert inp.as_reference == False

    inp.data_format = Format.from_definition(FORMATS.WKT)
    inp.data = 'CRS=EPSG:4326;MULTIPOINT((3.5 5.6), (4.8 10.5))'

    assert inp.data_format.mime_type == FORMATS.WKT.mime_type

    value = geometryio.input_to_geometry( inp )
    assert isinstance( value, QgsReferencedGeometry )
    assert value.wkbType() == QgsWkbTypes.MultiPoint
예제 #20
0
def test_nocrs_input_wkt():
    """ Test input point from wkt
    """
    param = QgsProcessingParameterPoint("POINT")

    inp = parse_input_definition(param)

    assert isinstance(inp,ComplexInput)
    assert inp.as_reference == False

    inp.data_format = Format.from_definition(FORMATS.WKT)
    inp.data = 'POINT(6 10)'

    assert inp.data_format.mime_type == FORMATS.WKT.mime_type

    value = geometryio.input_to_point( inp )
    assert isinstance( value, QgsGeometry )
    assert value.wkbType() == QgsWkbTypes.Point
예제 #21
0
def parse_response(value: Any, outdef: QgsProcessingOutputDefinition,
                   out: WPSOutput,
                   context: QgsProcessingContext) -> Optional[WPSOutput]:
    """ Process processing response to WPS output 
    """
    if not isinstance(outdef, OUTPUT_LAYER_TYPES):
        return

    out.data_format = Format("application/x-ogc-wms")

    output_url = context.wms_url

    result = add_layer_to_load_on_completion(value, outdef, context)
    if result:
        result = ','.join(result)
        out.url = output_url + '&' + urlencode((('layers', result), ))
    else:
        out.url = output_url

    return out
예제 #22
0
def test_linestring_input_gml():
    """ Test input point from gml
    """
    param = QgsProcessingParameterGeometry("GEOM")

    inp = parse_input_definition(param)

    assert isinstance(inp,ComplexInput)
    assert inp.as_reference == False

    inp.data_format = Format.from_definition(FORMATS.GML)
    inp.data = ('<gml:LineString srsName="EPSG:4326">'
                '<gml:coordinates>45.67,88.56 55.56,89.44</gml:coordinates>'
                '</gml:LineString>')

    assert inp.data_format.mime_type == FORMATS.GML.mime_type

    value = geometryio.input_to_geometry( inp )
    assert isinstance( value, QgsReferencedGeometry )
    assert value.wkbType() == QgsWkbTypes.LineString
예제 #23
0
def test_geometry_crs_json():
    """ Test passing crs from json
    """
    param = QgsProcessingParameterGeometry("GEOM")

    inp = parse_input_definition(param)

    assert isinstance(inp,ComplexInput)
    assert inp.as_reference == False

    inp.data_format = Format.from_definition(FORMATS.GEOJSON)
    inp.data = ('{ "geometry": {"coordinates":[445277.96, 5160979.44],"type":"Point"},'
                '  "crs": { '
                '    "type": "name", '
                '    "properties": { "name": "EPSG:3785" }'
                '}}')

    assert inp.data_format.mime_type == FORMATS.GEOJSON.mime_type

    value = geometryio.input_to_geometry( inp )
    assert isinstance( value, QgsReferencedGeometry )
    assert value.crs().authid() == "EPSG:3785"
    assert value.wkbType() == QgsWkbTypes.Point
예제 #24
0
    def json(self, value):
        """init this request from json back again

        :param value: the json (not string) representation
        """

        self.operation = value['operation']
        self.version = value['version']
        self.language = value['language']
        self.identifiers = value['identifiers']
        self.store_execute = value['store_execute']
        self.status = value['store_execute']
        self.lineage = value['lineage']
        self.outputs = value['outputs']
        self.raw = value['raw']
        self.inputs = {}

        for identifier in value['inputs']:
            inpt = None
            inpt_defs = value['inputs'][identifier]

            for inpt_def in inpt_defs:

                if inpt_def['type'] == 'complex':
                    inpt = ComplexInput(
                        identifier=inpt_def['identifier'],
                        title=inpt_def.get('title'),
                        abstract=inpt_def.get('abstract'),
                        data_format=Format(
                            schema=inpt_def['data_format'].get('schema'),
                            extension=inpt_def['data_format'].get('extension'),
                            mime_type=inpt_def['data_format']['mime_type'],
                            encoding=inpt_def['data_format'].get('encoding')),
                        supported_formats=[
                            Format(schema=infrmt.get('schema'),
                                   extension=infrmt.get('extension'),
                                   mime_type=infrmt['mime_type'],
                                   encoding=infrmt.get('encoding'))
                            for infrmt in inpt_def['supported_formats']
                        ],
                        mode=MODE.NONE)
                    inpt.file = inpt_def['file']
                elif inpt_def['type'] == 'literal':

                    allowed_values = []
                    for allowed_value in inpt_def['allowed_values']:
                        if allowed_value['type'] == 'anyvalue':
                            allowed_values.append(AnyValue())
                        elif allowed_value['type'] == 'novalue':
                            allowed_values.append(NoValue())
                        elif allowed_value['type'] == 'valuesreference':
                            allowed_values.append(ValuesReference())
                        elif allowed_value['type'] == 'allowedvalue':
                            allowed_values.append(
                                AllowedValue(
                                    allowed_type=allowed_value['allowed_type'],
                                    value=allowed_value['value'],
                                    minval=allowed_value['minval'],
                                    maxval=allowed_value['maxval'],
                                    spacing=allowed_value['spacing'],
                                    range_closure=allowed_value[
                                        'range_closure']))

                    inpt = LiteralInput(identifier=inpt_def['identifier'],
                                        title=inpt_def.get('title'),
                                        abstract=inpt_def.get('abstract'),
                                        data_type=inpt_def.get('data_type'),
                                        allowed_values=AnyValue,
                                        uoms=inpt_def.get('uoms'),
                                        mode=inpt_def.get('mode'))
                    inpt.uom = inpt_def.get('uom')
                    inpt.data = inpt_def.get('data')

                elif inpt_def['type'] == 'bbox':
                    inpt = BBoxInput(identifier=inpt_def['identifier'],
                                     title=inpt_def['title'],
                                     abstract=inpt_def['abstract'],
                                     crss=inpt_def['crs'],
                                     dimensions=inpt_def['dimensions'],
                                     mode=inpt_def['mode'])
                    inpt.ll = inpt_def['bbox'][0]
                    inpt.ur = inpt_def['bbox'][1]

            if identifier in self.inputs:
                self.inputs[identifier].append(inpt)
            else:
                self.inputs[identifier] = [inpt]
예제 #25
0
# Map processing source types to string
SourceTypes = {
    QgsProcessing.TypeMapLayer: 'TypeMapLayer',
    QgsProcessing.TypeVectorAnyGeometry: 'TypeVectorAnyGeometry',
    QgsProcessing.TypeVectorPoint: 'TypeVectorPoint',
    QgsProcessing.TypeVectorLine: 'TypeVectorLine',
    QgsProcessing.TypeVectorPolygon: 'TypeVectorPolygon',
    QgsProcessing.TypeRaster: 'TypeRaster',
    QgsProcessing.TypeFile: 'TypeFile',
    QgsProcessing.TypeVector: 'TypeVector',
    QgsProcessing.TypeMesh: 'TypeMesh',
}

# Allowed inputs formats

RASTER_INPUT_FORMATS = (Format.from_definition(FORMATS.NETCDF),
                        Format.from_definition(FORMATS.GEOTIFF))

VECTOR_INPUT_FORMATS = (Format.from_definition(FORMATS.GEOJSON),
                        Format.from_definition(FORMATS.GML),
                        Format.from_definition(FORMATS.SHP))

# ------------------------------------
# Processing parameters ->  WPS input
# ------------------------------------


def get_layers_type(param: QgsProcessingParameterDefinition, kwargs) -> None:
    """ Set datatype as metadata
    """
    datatypes = []
예제 #26
0
def get_data_format(mime_type):
    return Format(mime_type=mime_type, validate=get_validator(mime_type))