gisserver.types module¶
Internal XSD type definitions.
These types are the internal schema definition, and the foundation for all output generation.
The end-users of this library typically create a WFS feature type definition by using
the FeatureType / FeatureField classes.
The feature type classes use the model metadata to construct the internal XMLSchema structure.
Nearly all WFS requests are handled by walking this structure (like DescribeFeatureType
or GetFeature). The rendered output is created by walking through this structure,
and writing the XML elements. All search queries (using XPath) are processed by
resolving the corresponding element/attributes, to find to the underlying Django model field.
The structure has the following elements:
XsdElementto define the schema of a single XML element (<xsd:element>).XsdAttributeto define the schema of a single XML attribute (<xsd:attribute>).
Each XMLSchema node defines it’s “data type” as either:
XsdTypesfor simple well-known data types (e.g. text/int, etc..)XsdComplexTypefor a complete class definition (holding elements and attributes)
Custom field types could also generate these field types.
XML Schema Types¶
- class gisserver.types.XsdAnyType¶
Base class for all types used in the XML definition. This includes the enum values (
XsdTypes) for well-known types, adn theXsdComplexTypethat represents a while class definition.- is_complex_type = False¶
Whether this is a complex type
- is_geometry = False¶
Whether this is a geometry
- namespace = None¶
Namespace of the XML element
- to_python(raw_value)¶
Convert a raw string value to this type representation
- class gisserver.types.XsdTypes(*values)¶
Bases:
XsdAnyType,EnumBrief enumeration of common XMLSchema types.
The
XsdElementandXsdAttributecan use these enum members to indicate their value is a well-known XML Schema. Some GML types are included as well.Each member value is a fully qualified XML name. The output rendering will convert these to the chosen prefixes.
- __init__(value)¶
- anyType = '{http://www.w3.org/2001/XMLSchema}anyType'¶
- anyURI = '{http://www.w3.org/2001/XMLSchema}anyURI'¶
- base64Binary = '{http://www.w3.org/2001/XMLSchema}base64Binary'¶
- boolean = '{http://www.w3.org/2001/XMLSchema}boolean'¶
- byte = '{http://www.w3.org/2001/XMLSchema}byte'¶
- date = '{http://www.w3.org/2001/XMLSchema}date'¶
- dateTime = '{http://www.w3.org/2001/XMLSchema}dateTime'¶
- decimal = '{http://www.w3.org/2001/XMLSchema}decimal'¶
- double = '{http://www.w3.org/2001/XMLSchema}double'¶
- duration = '{http://www.w3.org/2001/XMLSchema}duration'¶
- float = '{http://www.w3.org/2001/XMLSchema}float'¶
- gYear = '{http://www.w3.org/2001/XMLSchema}gYear'¶
- gmlAbstractFeatureType = '{http://www.opengis.net/gml/3.2}AbstractFeatureType'¶
A feature that has a gml:name and gml:boundedBy as possible child element.
- gmlAbstractGMLType = '{http://www.opengis.net/gml/3.2}AbstractGMLType'¶
The base of gml:AbstractFeatureType
- gmlAbstractGeometryType = '{http://www.opengis.net/gml/3.2}AbstractGeometryType'¶
A direct geometry value, sometimes used as function argument type.
- gmlBoundingShapeType = '{http://www.opengis.net/gml/3.2}BoundingShapeType'¶
The type for
<gml:boundedBy>elements.
- gmlCodeType = '{http://www.opengis.net/gml/3.2}CodeType'¶
The type for
<gml:name>elements.
- gmlCurvePropertyType = '{http://www.opengis.net/gml/3.2}CurvePropertyType'¶
- gmlEnvelopeType = '{http://www.opengis.net/gml/3.2}EnvelopeType'¶
The type for
<gml:Envelope>elements, sometimes used as function argument type.
- gmlGeometryPropertyType = '{http://www.opengis.net/gml/3.2}GeometryPropertyType'¶
- gmlMultiCurvePropertyType = '{http://www.opengis.net/gml/3.2}MultiCurvePropertyType'¶
- gmlMultiGeometryPropertyType = '{http://www.opengis.net/gml/3.2}MultiGeometryPropertyType'¶
- gmlMultiPointPropertyType = '{http://www.opengis.net/gml/3.2}MultiPointPropertyType'¶
- gmlMultiSurfacePropertyType = '{http://www.opengis.net/gml/3.2}MultiSurfacePropertyType'¶
- gmlPointPropertyType = '{http://www.opengis.net/gml/3.2}PointPropertyType'¶
- gmlSurfacePropertyType = '{http://www.opengis.net/gml/3.2}SurfacePropertyType'¶
- hexBinary = '{http://www.w3.org/2001/XMLSchema}hexBinary'¶
- int = '{http://www.w3.org/2001/XMLSchema}int'¶
- integer = '{http://www.w3.org/2001/XMLSchema}integer'¶
- language = '{http://www.w3.org/2001/XMLSchema}language'¶
- long = '{http://www.w3.org/2001/XMLSchema}long'¶
- nonNegativeInteger = '{http://www.w3.org/2001/XMLSchema}nonNegativeInteger'¶
- short = '{http://www.w3.org/2001/XMLSchema}short'¶
- string = '{http://www.w3.org/2001/XMLSchema}string'¶
- time = '{http://www.w3.org/2001/XMLSchema}time'¶
- to_python(raw_value)¶
Convert a raw string value to this type representation.
- Raises:
ExternalParsingError – When the value can’t be converted to the proper type.
- token = '{http://www.w3.org/2001/XMLSchema}token'¶
- unsignedByte = '{http://www.w3.org/2001/XMLSchema}unsignedByte'¶
- unsignedInt = '{http://www.w3.org/2001/XMLSchema}unsignedInt'¶
- unsignedLong = '{http://www.w3.org/2001/XMLSchema}unsignedLong'¶
- unsignedShort = '{http://www.w3.org/2001/XMLSchema}unsignedShort'¶
- class gisserver.types.XsdComplexType(name: str, namespace: str | None = None, elements: list[XsdElement] = <factory>, attributes: list[XsdAttribute] = <factory>, base: XsdAnyType | None = None, source: type[Model] | None = None)¶
Bases:
XsdAnyTypeDefine an
<xsd:complexType>that represents a whole class definition.Typically, this maps into a Django model, with each element pointing to a model field. For example:
XsdComplexType( "PersonType", elements=[ XsdElement("name", type=XsdTypes.string), XsdElement("age", type=XsdTypes.integer), XsdElement("address", type=XsdComplexType( "AddressType", elements=[ XsdElement("street", type=XsdTypes.string), ... ] )), ], attributes=[ XsdAttribute("id", type=XsdTypes.integer), ], )
A complex type can hold multiple
XsdElementandXsdAttributenodes as children, composing an object. Itsbasemay point to aXsdComplexTypeas base class, allowing to define those inherited elements too.Each element can be a complex type themselves, to create a nested class structure. That also allows embedding models with their relations into a single response.
Note
Good to know This object definition is the internal “source of truth” regarding which field names and field elements are used in the WFS server:
The
DescribeFeatureTyperequest uses this definition to render the matching XMLSchema.Incoming XPath queries are parsed using this object to resolve the XPath to model attributes.
Objects of this type are typically generated by the
FeatureTypeandComplexFeatureFieldclasses, using the Django model data.By default, The
basetype is detected as<gml:AbstractFeatureType>, when there is a geometry element in the definition.- __init__(name: str, namespace: str | None = None, elements: list[XsdElement] = <factory>, attributes: list[XsdAttribute] = <factory>, base: XsdAnyType | None = None, source: type[Model] | None = None) None¶
- property all_complex_elements: list[_XsdElement_WithComplexType]¶
Shortcut to get all elements with children. This mainly exists to provide a structure to mimic what’s used when PROPERTYNAME is part of the request.
- attributes: list[XsdAttribute]¶
All attributes in this class
- base: XsdAnyType | None = None¶
The base class of this type. Typically gml:AbstractFeatureType, which provides the <gml:name> and <gml:boundedBy> elements.
- property complex_elements: list[_XsdElement_WithComplexType]¶
Shortcut to get all elements with a complex type. To get all complex elements recursively, read
all_complex_elements.
- elements: list[XsdElement]¶
All local elements in this class
- property elements_including_base: list[XsdElement]¶
The local and inherited elements of this XSD type.
- property flattened_elements: list[XsdElement]¶
Shortcut to get all elements with a flattened model attribute
- property geometry_elements: list[GeometryXsdElement]¶
Shortcut to get all geometry elements
- resolve_element_path(xpath: str, ns_aliases: dict[str, str]) list[XsdNode] | None¶
Resolve a xpath reference to the actual node. This returns the whole path, including in-between relations, if a match was found.
This is used by
resolve_element()to convert a request XPath element into the ORM attributes for database queries.
- property xml_name¶
Name in the XMLSchema (e.g. {http://example.org/namespace}:SomeClass).
XML Schema Elements¶
- class gisserver.types.XsdNode(name: str, type: XsdAnyType, namespace: xmlns | str | None, *, source: models.Field | models.ForeignObjectRel | None = None, model_attribute: str | None = None, absolute_model_attribute: str | None = None, feature_type: FeatureType | None = None)¶
Base class for
XsdElementandXsdAttribute.This contains all common mapping/resolving that both elements and attributes share. For instance, how XML nodes are mapped into ORM paths, converted into ORM filters, parse query input and read model attributes to write as output.
- __init__(name: str, type: XsdAnyType, namespace: xmlns | str | None, *, source: models.Field | models.ForeignObjectRel | None = None, model_attribute: str | None = None, absolute_model_attribute: str | None = None, feature_type: FeatureType | None = None)¶
- Parameters:
name – The local name of the element.
type – The XML Schema type of the element, can also be a XsdComplexType.
namespace – XML namespace URI.
source – Original Model field, which can provide more metadata/parsing.
model_attribute – The Django model path that this element accesses.
absolute_model_attribute – The full path, including parent elements.
feature_type – Typically assigned in
bind(), needed by someget_value()functions.
- build_lhs_part(compiler: CompiledQuery, match: ORMPath)¶
Give the ORM part when this element is used as left-hand-side of a comparison. This is needed for queries like “<element> == <value>”
- build_rhs_part(compiler: CompiledQuery, match: ORMPath)¶
Give the ORM part when this element would be used as right-hand-side. This is needed for queries like “<value> == <element>” or “<element> == <element>”.
- feature_type: FeatureType | None¶
A link back to the parent that described the feature this node is a part of. This helps to perform additional filtering in side meth:get_value: based on user policies.
- format_raw_value(value)¶
Allow to apply some final transformations on a value. This is mainly used to support @gml:id which includes a prefix.
- is_attribute = False¶
Whether this node is an
XsdAttribute(avoids slowisinstance()checks)
- is_many = False¶
Whether this node can occur multiple times.
- model_attribute: str | None¶
Which field to read from the model to get the value This supports dot notation to access related attributes.
- property orm_field: str¶
The direct ORM field that provides this property; the first relative level. Typically, this is the same as the field name.
- property orm_relation: tuple[str | None, str]¶
The ORM field and parent relation. Note this isn’t something like “self.parent.orm_path”, as this mode may have a dotted-path to its source attribute.
- relative_orm_path(parent: XsdElement | None = None) str¶
The ORM field lookup to perform, relative to the parent element.
- source: models.Field | models.ForeignObjectRel | None¶
Which field to read from the model to get the value This supports dot notation to access related attributes.
- to_python(raw_value: str)¶
Convert a raw value to the Python data type for this element type. :raises ValidationError: When the value isn’t allowed for the field type.
- type: XsdAnyType¶
The data type of the element/attribute, both
XsdComplexTypeandXsdTypesare allowed.
- validate_comparison(raw_value: str, lookup, tag=None)¶
Validate whether the input value can be used in a comparison. This avoids comparing a database DATETIME object to an integer.
The raw string value can be passed here. Auto-cased values could raise an TypeError due to being unsupported by the validation.
- Parameters:
raw_value – The string value taken from the XML node.
lookup – The ORM lookup (e.g.
equalsorfes_like).tag – The filter operator tag name, e.g.
PropertyIsEqualTo.
- Returns:
The parsed Python value.
- property xml_name¶
The XML element/attribute name.
- class gisserver.types.XsdElement(name: str, type: XsdAnyType, namespace: xmlns | str | None, *, nillable: bool | None = None, min_occurs: int | None = None, max_occurs: int | Literal['unbounded'] | None = None, source: models.Field | models.ForeignObjectRel | None = None, model_attribute: str | None = None, absolute_model_attribute: str | None = None, feature_type: FeatureType | None = None)¶
Bases:
XsdNodeDeclare an XSD element.
Typically, this maps into a Django model field.
This holds the definition for a single property in the WFS server. It’s used in
DescribeFeatureTypeto output the field metadata, and used inGetFeatureto access the actual value from the object. OverridingXsdNode.get_value()allows to override this logic.The
namemay differ from the underlyingXsdNode.model_attribute, so the WFS server can use other field names then the underlying model.A dotted-path notation can be used for
XsdNode.model_attributeto access a related field. For the WFS client, the data appears to be flattened.- __init__(name: str, type: XsdAnyType, namespace: xmlns | str | None, *, nillable: bool | None = None, min_occurs: int | None = None, max_occurs: int | Literal['unbounded'] | None = None, source: models.Field | models.ForeignObjectRel | None = None, model_attribute: str | None = None, absolute_model_attribute: str | None = None, feature_type: FeatureType | None = None)¶
- Parameters:
name – The local name of the element.
type – The XML Schema type of the element, can also be a XsdComplexType.
namespace – XML namespace URI.
source – Original Model field, which can provide more metadata/parsing.
model_attribute – The Django model path that this element accesses.
absolute_model_attribute – The full path, including parent elements.
feature_type – Typically assigned in
bind(), needed by someget_value()functions.
- property is_many: bool¶
Tell whether the XML element can be rendered multiple times. Note this happens both with array fields and “…_to_many” relations.
- class gisserver.types.XsdAttribute(name: str, type: XsdAnyType = XsdTypes.string, *, namespace: xmlns | str | None = None, use: str = 'optional', source: models.Field | models.ForeignObjectRel | None = None, model_attribute: str | None = None, absolute_model_attribute: str | None = None, feature_type: FeatureType | None = None)¶
Bases:
XsdNodeDeclare an XSD attribute.
Typically, this maps into a Django model field.
Most fields are mapped into XML Elements (
XsdElement). However, WFS also supports XML attributes, and queries against them. This class is uses to support filters against attributes like “gml:id”.- __init__(name: str, type: XsdAnyType = XsdTypes.string, *, namespace: xmlns | str | None = None, use: str = 'optional', source: models.Field | models.ForeignObjectRel | None = None, model_attribute: str | None = None, absolute_model_attribute: str | None = None, feature_type: FeatureType | None = None)¶
- Parameters:
name – The local name of the element.
type – The XML Schema type of the element, can also be a XsdComplexType.
namespace – XML namespace URI.
source – Original Model field, which can provide more metadata/parsing.
model_attribute – The Django model path that this element accesses.
absolute_model_attribute – The full path, including parent elements.
feature_type – Typically assigned in
bind(), needed by someget_value()functions.
- is_attribute = True¶
Whether this node is an
XsdAttribute(avoids slowisinstance()checks)
- type: XsdTypes¶
The data type of the element/attribute, both
XsdComplexTypeandXsdTypesare allowed.
Specialized Schema Elements¶
- class gisserver.types.GeometryXsdElement(name: str, type: XsdAnyType, namespace: xmlns | str | None, *, nillable: bool | None = None, min_occurs: int | None = None, max_occurs: int | Literal['unbounded'] | None = None, source: models.Field | models.ForeignObjectRel | None = None, model_attribute: str | None = None, absolute_model_attribute: str | None = None, feature_type: FeatureType | None = None)¶
Bases:
XsdElementA subtype for the
XsdElementthat provides access to geometry data.This declares an element such as:
<app:geometry> <gml:Point>...</gml:Point> </app:geometry>
Hence, the
namespaceof this element isn’t the GML namespace, only the type it points to is geometry data.The
sourceis guaranteed to point to aGeometryField, and can be aGeneratedFieldin Django 5 as long as itsoutput_fieldpoints to aGeometryField.- source: GeometryField | models.GeneratedField¶
Which field to read from the model to get the value This supports dot notation to access related attributes.
- class gisserver.types.GmlIdAttribute(type_name: str, source: models.Field | models.ForeignObjectRel | None = None, model_attribute='pk', absolute_model_attribute=None, feature_type: FeatureType | None = None)¶
Bases:
XsdAttributeA virtual
gml:id="..."attribute that can be queried. This subclass has overwrittenget_value()logic to format the value.- __init__(type_name: str, source: models.Field | models.ForeignObjectRel | None = None, model_attribute='pk', absolute_model_attribute=None, feature_type: FeatureType | None = None)¶
- Parameters:
name – The local name of the element.
type – The XML Schema type of the element, can also be a XsdComplexType.
namespace – XML namespace URI.
source – Original Model field, which can provide more metadata/parsing.
model_attribute – The Django model path that this element accesses.
absolute_model_attribute – The full path, including parent elements.
feature_type – Typically assigned in
bind(), needed by someget_value()functions.
- format_raw_value(value)¶
Format the value as retrieved from the database.
- class gisserver.types.GmlNameElement(model_attribute: str, source: Field | ForeignObjectRel | None = None, feature_type=None)¶
Bases:
XsdElementA subclass to handle the
<gml:name>element. This displays a human-readable title for the object.Currently, this just reads a single attribute, but it can be extended to support formatted names (although that would make comparisons on
element@gml:namemore complex).- __init__(model_attribute: str, source: Field | ForeignObjectRel | None = None, feature_type=None)¶
- Parameters:
name – The local name of the element.
type – The XML Schema type of the element, can also be a XsdComplexType.
namespace – XML namespace URI.
source – Original Model field, which can provide more metadata/parsing.
model_attribute – The Django model path that this element accesses.
absolute_model_attribute – The full path, including parent elements.
feature_type – Typically assigned in
bind(), needed by someget_value()functions.
- class gisserver.types.GmlBoundedByElement(feature_type)¶
Bases:
XsdElementA subclass to handle the
<gml:boundedBy>element.This override makes sure this non-model element data can be included in the XML tree like every other element. Its value is the complete bounding box of the feature type data.
- __init__(feature_type)¶
- Parameters:
name – The local name of the element.
type – The XML Schema type of the element, can also be a XsdComplexType.
namespace – XML namespace URI.
source – Original Model field, which can provide more metadata/parsing.
model_attribute – The Django model path that this element accesses.
absolute_model_attribute – The full path, including parent elements.
feature_type – Typically assigned in
bind(), needed by someget_value()functions.
- build_lhs_part(compiler: CompiledQuery, match: ORMPath)¶
Give the ORM part when this element is used as left-hand-side of a comparison.
- build_rhs_part(compiler: CompiledQuery, match: ORMPath)¶
Give the ORM part when this element would be used as right-hand-side
- get_value(instance: Model, crs: CRS | None = None) BoundingBox | None¶
Provide the value of the <gml:boundedBy> field, which is the bounding box for a single instance.
This is only used for native Python rendering. When the database rendering is enabled (GISSERVER_USE_DB_RENDERING=True), the calculation is entirely performed within the query.
XPath Resolving¶
- class gisserver.types.ORMPath(orm_path: str, orm_filters: Q | None = None, is_many=False)¶
Base class to provide raw XPath results.
This base class is designed to allow other query types (besides XPath) too, and allows inserting raw data directly to the query compiler (for unit testing).
- __init__(orm_path: str, orm_filters: Q | None = None, is_many=False)¶
Base constructor just assigns items. Overwritten classes likely replace this with properties.
- build_lhs(compiler: CompiledQuery)¶
Give the ORM part when this element is used as left-hand-side of a comparison. For example:
path == value.
- build_rhs(compiler: CompiledQuery)¶
Give the ORM part when this element would be used as right-hand-side. For example:
path1 == path2orvalue == path.
- class gisserver.types.XPathMatch(feature_type: FeatureType, nodes: list[XsdNode], query: str)¶
Bases:
ORMPathThe ORM path result from am XPath query.
This result object defines how to resolve an XPath to an ORM object.
- __init__(feature_type: FeatureType, nodes: list[XsdNode], query: str)¶
Base constructor just assigns items. Overwritten classes likely replace this with properties.
- build_lhs(compiler: CompiledQuery)¶
Give the ORM part when this element is used as left-hand-side of a comparison. For example:
path == value.
- build_rhs(compiler: CompiledQuery)¶
Give the ORM part when this element would be used as right-hand-side. For example:
path1 == path2orvalue == path.