Translating WFS Query to
SQL/XML Query
Vânia Vidal
Fernando Lemos
Fábio Feitosa
Departamento de Computação
Universidade Federal do Ceará
Outline
WFS Specification
Contributions
Feature Type Specification
Extension of Feature Type
Translating WFS Query to SQL/XML Query
Conclusions
WFS Specification
OpenGis Consortium
promotes
the development and use of
advanced open system standards and techniques
in the geoprocessing area and
related information technologies
WFS
publishes
GML views of geographic features
stored in data sources
users can query and update data stores
through a feature type schema
WFS Specification
WFS request
GetCapabilities
DescribeFeatureType
GetFeature
Transaction
LockFeature
Contributions
Correspondence Assertions
specify
the mappings between
feature type schemas and relational schemas
TranslateWFSQuery Algorithm
translates
a WFS query over a feature type schema
into a SQL/XML query over the relational schema
translation is based on the correspondence assertions
WFS GetFeature Request
Deegree WFS
SQL Query Q1
…
WFS Query
GML
Deegree
WFS Server
SQL Query Qn
result of Q1
BDR
…
result of Qn
Our approach
WFS Query
SQL/XML Query
GML Publisher
WFS Server
GML
BDR
GML
Feature Type Specification
Feature Type F over a relational schema S
F = <T, R, A>
where
T is the XML Schema type for feature instances
R is the name of the master relation schema,
which contains the geometric attribute
A is the set of correspondence assertions,
which fully specifies T in terms of R
Example
XML Schema type for
Relational Schema DB_Station
Feature Type F_Station
TStation
code
geometry
name
address (TAddress)
street
city (TCity)
name
area
zipcode
Pluviometry* (TPluviometry)
month
value
agency
Master Relation Schema
Station_rel
CODE
GEOM_POINT
NAME
STREET
ZIPCODE
CODECITY (FK)
CODEAGENCY (FK)
Pluviometry_rel
CODESTATION (FK)
MONTH
VALUE
City_rel
CODECITY
NAME
AREA
Agency_rel
CODEAGENCY
NAME
PHONE
FAX
Correspondence Assertions of F_Station
TStation
code (integer)
Master Relation Schema
1:[TStation/code][Station_rel/CODE]
geometry (abstractgeometry) 2:[TStation/geometry][Station_rel/GEOM_POINT]
name (string)
3:[TStation/name][Station_rel/NAME]
address (TAddress)
4:[TStation/address][Station_rel/NULL]
street (string)
city (TCity)
5:[TAddress/street][Station_rel/STREET]
6:[TAddress/city][Station_rel/FK1]
name (string)
7:[TCity/name][City_rel/NAME]
area (number)
8:[TCity/area][City_rel/ARE
A]
9:[TAddress/zipcode][Station_rel/ZIPCODE]
zipcode (string)
pluviometry (TPluviometry)
10:[TStation/pluviometry][Station_rel/FK2-1]
month (integer)
11:[TPluviometry/month][Pluviometry_rel/MONTH]
value (number)
12:[TPluviometry/value][Pluviometry_rel/VALUE]
agency (string)
13:[TStation/agency][Station_rel/FK3/NAME]
Station_rel
CODE (number)
GEOM_POINT (sdo_geometry)
NAME (varchar2)
OBSERVER (varchar2)
STREET (varchar2)
ZIPCODE (varchar2)
PHONE (varchar2)
CODECITY (number)
CODEAGENCY (number)
FK1 (City_rel)
CODECITY (number)
NAME (varchar2)
AREA (number)
FK2-1 (Pluviometry_rel)
CODESTATION (number)
MONTH (number)
VALUE (number)
FK3 (Agency_rel)
CODEAGENCY (number)
NAME (varchar2)
PHONE (varchar2)
FAX (varchar2)
Extension of a Feature Type
Extension of F = <T, R, A> for an instance s of schema S
a sequence of F-elements of type T,
such that each F-element matches a tuple of s(R)
F = { $f | $f is an instance of T and rs(R) such that $fAr}
SQL/XML query definition of an extension of F
F = SELECT
XMLELEMENT( "Extension_of_F ",
XMLAGG( XMLELEMENT( "F", [RT](r) ))
FROM R r
[RT](r) constructs the content for an instance $f of T
such that $f A r as specified by the CAs of F
SQL/XML Definition for Extension of F_Station
SELECT XMLELEMENT( "Extension_of_F_Station", XMLAGG(
XMLELEMENT( "F_Station",
[TStation / code] [Station_rel / CODE]
XMLFOREST(S.CODE AS "code"),
[TStation / geometry] [Station_rel / GEOM_POINT]
XMLFOREST(
SDO_UTIL.TO_GMLGEOMETRY(S.GEOM_POINT) AS "geometry"),
[TStation / name] [Station_rel / NAME]
XMLFOREST(S.NAME AS "name"),
XMLELEMENT( "address",
[TStation / address] [Station_rel / NULL]
XMLFOREST(S.STREET AS "street"),
[TAddress / street] [Station_rel / STREET]
XMLELEMENT( "city",
[TAddress / city] [Station_rel / FK1]
(SELECT XMLCONCAT(
[TCity / name] [City_rel / NAME]
XMLFOREST(C.NAME AS "name"),
XMLFOREST(C.AREA AS "area"))
[TCity / area] [City_rel / AREA]
FROM City_rel C WHERE C.CODECITY = S.CODECITY) ),
XMLFOREST(S.ZIPCODE AS "zipcode") ),
[TAddress / zipcode] [Station_rel / ZIPCODE]
(SELECT XMLAGG(XMLELEMENT( "pluviometry",
[TStation / pluviometry] [Station_rel / FK2-1]
XMLFOREST(PL.MONTH AS "month"),
[TPluviometry / month] [Pluviometry_rel / MONTH]
XMLFOREST(PL.VALUE AS "value") ) )
[TPluviometry / area] [Pluviometry_rel / AREA]
FROM Pluviometry_rel PL WHERE S.CODE = PL.CODESTATION),
[TStation / agency] [Station_rel / FK3 / NAME]
XMLFOREST( (SELECT A.NAME FROM Agency_rel A
WHERE A.CODEAGENCY = S.CODEAGENCY) AS "agency")
)))
FROM Station_rel S;
An Instance of DB_Station
Station_rel
CODE
NAME
STREET
ZIPCODE
GEOM_POINT
CODE CODECITY
AGENCY
164
Serragem R. Prinicpal s/n
62755000
-4.45,-38.5
1
2309458
165
Arisco
Sitio Penha
62755000
-4.65,-38.55
2
2309458
481
Arruda
R. São Francisco,606 62113000
-3.85,-40.66
1
2312908
Pluviometry_rel
Agency_rel
CODEAGENCY
NAME
PHONE
FAX
CODESTATION MONTH
VALUE
1
FUNCEME 31011088
31011093
164
01
87.8
2
SUDENE
34339045
164
02
171.6
165
01
50.4
481
03
150
34339031
City_rel
CODECITY
NAME
AREA
2309458
OCARA
1450
2312908
SOBRAL
19820
Extension of F_Station
Station_rel
CODE
NAME
STREET
ZIPCODE
GEOM_POINT
CODE CODECITY
AGENCY
164
Serragem R. Prinicpal s/n
62755000 -4.45,-38.5
1
2309458
165
Arisco
Sitio Penha
62755000 -4.65,-38.55
2
2309458
481
Arruda
R. São Francisco,606 62113000 -3.85,-40.66
1
2312908
<Extension_of_F_Station>
<F_Station>
<F_Station>
<F_Station>
<code>165</code>
<code>481</code>
<code>164</code>
<gml:Point>
<gml:Point>
<geometry>
<gml:coordinates cs=","
<gml:coordinates cs=","
<gml:Point>
decimal="." ts="">
decimal="." ts="">
<gml:coordinates cs=","
-4.65,-38.55
-3.85,-40.66
decimal="." ts="">
</gml:coordinates>
</gml:coordinates>
-4.45,-38.5
</gml:Point>
</gml:Point>
</gml:coordinates>
<name>Arisco</name>
<name>Arruda</name>
</gml:Point>
<address>
<address>
</geometry>
<street>Sitio Penha</street>
<street>R. Sao Francisco, 606</street>
<name>Serragem</name>
<city>…</city>
<city>…</city>
<address>
<zipcode>62755000</zipcode>
<zipcode>62113000</zipcode>
<street>R. Principal s/n</street> </address>
</address>
<city>…</city>
<pluviometry>…</pluviometry>
<pluviometry>…</pluviometry>
<zipcode>62755000</zipcode> <agency>…</agency>
<agency>…</agency>
</address>
</F_Station>
</F_Station>
<pluviometry>…</pluviometry>
</Extension_of_F_Station>
<pluviometry>…</pluviometry>
<agency>…</agency>
</F_Station>
Extension of F_Station
Agency_rel
CODEAGENCY
NAME
PHONE
FAX
1
FUNCEME 31011088
31011093
2
SUDENE
34339045
34339031
<Extension_of_F_Station>
<F_Station>
<F_Station>
<F_Station>
<code>165</code>
<code>481</code>
<code>164</code>
<geometry>…</geometry>
<geometry>…</geometry>
<geometry>…</geometry>
<name>Arisco</name>
<name>Arruda</name>
<name>Serragem</name>
<address>…</address>
<address>…</address>
<address>…</address>
<pluviometry>
<pluviometry>
<pluviometry>
<month>1</month>
<month>3</month>
<month>1</month>
<value>50.4</value>
<value>150</value>
<value>87.8</value>
</pluviometry>
</pluviometry>
</pluviometry>
<agency>SUDENE</agency> <agency>FUNCEME</agency>
<pluviometry>
</F_Station>
</F_Station>
<month>2</month>
</Extension_of_F_Station>
<value>171.6</value>
</pluviometry>
<agency>FUNCEME</agency>
</F_Station>
Extension of F_Station
Pluviometry_rel
CODESTATION MONTH
VALUE
164
01
87.8
164
02
171.6
165
01
50.4
481
03
150
<Extension_of_F_Station>
<F_Station>
<F_Station>
<F_Station>
<code>165</code>
<code>481</code>
<code>164</code>
<geometry>…</geometry>
<geometry>…</geometry>
<geometry>…</geometry>
<name>Arisco</name>
<name>Arruda</name>
<name>Serragem</name>
<address>…</address>
<address>…</address>
<address>…</address>
<pluviometry>
<pluviometry>
<pluviometry>
<month>1</month>
<month>3</month>
<month>1</month>
<value>50.4</value>
<value>150</value>
<value>87.8</value>
</pluviometry>
</pluviometry>
</pluviometry>
<agency>SUDENE</agency> <agency>FUNCEME</agency>
<pluviometry>
</F_Station>
</F_Station>
<month>2</month>
</Extension_of_F_Station>
<value>171.6</value>
</pluviometry>
<agency>FUNCEME</agency>
</F_Station>
Extension of F_Station
City_rel
CODECITY
NAME
AREA
2309458
OCARA
1450
2312908
SOBRAL
19820
<Extension_of_F_Station>
<F_Station>
<code>164</code>
<geometry>…</geometry>
<name>Serragem</name>
<address>
<street>…</street>
<city>
<name>OCARA</name>
<area>1450</area>
</city>
<zipcode>62755000</zipcode>
</address>
<pluviometry>…</pluviometry>
<pluviometry>…</pluviometry>
<agency>…</agency>
</F_Station>
<F_Station>
<F_Station>
<code>165</code>
<code>481</code>
<geometry>…</geometry>
<geometry>…</geometry>
<name>Arisco</name>
<name>Arruda</name>
<address>
<address>
<street>…</street>
<street>…</street>
<city>
<city>
<name>OCARA</name>
<name>SOBRAL</name>
<area>1450</area>
<area>19820</area>
</city>
</city>
<zipcode>62755000</zipcode>
<zipcode>62113000</zipcode>
</address>
</address>
<pluviometry>…</pluviometry>
<pluviometry>…</pluviometry>
<agency>…</agency>
<agency>…</agency>
</F_Station>
</F_Station>
</Extension_of_F_Station>
WFS Query
<Query> element of a GetFeature request:
delivers feature instances of a given feature type,
where each feature instance matches a tuple of the Master Table
<Query> element contains:
a mandatory attribute typeName
a sequence of zero or more <wfs:PropertyName> elements
used to indicate the name of the feature type to be queried
used to specify what properties to retrieve
the value of each <wfs:PropertyName> element is an XPath expression that
references a property or sub-property of the relevant feature type
an optional <Filter> element
used to define spatial and non-spatial constraints on a query
encoded as described in the OGC Filter Encoding Implementation Spec
QW : WFS Query over F_Station
<wfs:Query typeName="F_Station">
<wfs:PropertyName>name</wfs:PropertyName>
<wfs:PropertyName>address / city</wfs:PropertyName>
<wfs:PropertyName>pluviometry</wfs:PropertyName>
<wfs:PropertyName>geometry</wfs:PropertyName>
<ogc:Filter>
<ogc:And> <ogc:PropertyIsEqualTo>
<ogc:PropertyName>agency</ogc:PropertyName>
<ogc:Literal>FUNCEME</ogc:Literal>
</ogc:PropertyIsEqualTo>
<ogc:BBox>
<ogc:PropertyName>geometry</ogc:PropertyName>
<gml:Envelope>
<gml:lowercorner>-5.2 -42.5</gml:lowercorner>
<gml:upperCorner>-2.5 -38.7</gml:upperCorner>
</gml:Envelope> </ogc:BBox> </ogc:And>
</ogc:Filter>
</wfs:Query>
QX : Canonical XQuery for QW
FOR $f in document("F")/Station
WHERE $f satisfies the filter of QW
RETURN <gml:featureMember>{
<F_Station> {
$f/name,
$f/address/city,
$f/pluviometry,
$f/geometry
}</F_Station>
}<gml:featureMember>
The result of Qw is the result of evaluating QX on
an extension of F_Station
XML fragment resulting from QW
QW : WFS Query
<wfs:Query typeName="F_Station">
<wfs:PropertyName>name</wfs:PropertyName>
<wfs:PropertyName>address / city</wfs:PropertyName>
<wfs:PropertyName>pluviometry</wfs:PropertyName>
<wfs:PropertyName>geometry</wfs:PropertyName>
<ogc:Filter>
<ogc:And> <ogc:PropertyIsEqualTo>
<ogc:PropertyName>agency</ogc:PropertyName>
<ogc:Literal>FUNCEME</ogc:Literal>
</ogc:PropertyIsEqualTo>
<ogc:BBox>
<ogc:PropertyName>geometry</ogc:PropertyName>
<gml:Envelope>
<gml:lowercorner>-5.2 -42.5</gml:lowercorner>
<gml:upperCorner>-2.5 -38.7</gml:upperCorner>
</gml:Envelope> </ogc:BBox> </ogc:And>
</ogc:Filter>
</wfs:Query>
<gml:FeatureMember>
<F_Station>
<name>Serragem</name>
<city> <name>OCARA</name>
<area>1450</area> </city>
<pluviometry> <month>1</month>
<value>87.8</value> </pluviometry>
<pluviometry> <month>2</month>
<value>171.6</value> </pluviometry>
<geometry>
<gml:Point>
<gml:coordinates cs="," decimal="." ts="">
-4.45,-38.5</gml:coordinates> </gml:Point>
</geometry>
</F_Station>
</gml:FeatureMember>
<gml:FeatureMember>
<F_Station>
<name>Arruda</name>
<city> <name>SOBRAL</name>
<area>19820</area> </city>
<pluviometry> <month>3</month>
<value>150</value> </pluviometry>
<geometry>
<gml:Point>
<gml:coordinates cs="," decimal="." ts="">
-3.85,-40.66</gml:coordinates> </gml:Point>
</geometry>
</F_Station>
</gml:FeatureMember>
WFS Query
Definition:
Let
QW be a WFS Query over feature type F
Qx be the canonical XQuery for QW
QS be a SQL/XML query over S which returns a set of
<gml:featureMember> elements.
Then, we say that QS is a correct translation for QW iff,
for any instance S of S,
if F is the extension of F on S
S1 is the set of <gml:featureMember> elements
resulting from evaluating QS on S and
S2 is the set of <gml:featureMember> elements
resulting from evaluating QX on F
then S1 = S2
TranslateWFSQuery Algorithm
Input: WFS query QW
Output: SQL/XML query QS
Let <P,L > := TranslateFilter( f ), where f is the filter of QW
In case of
Case 1: QW has no <wfs:PropertyName> elements
Qs = SELECT
XMLELEMENT( "gml:featureMember",
XMLELEMENT( "F",
[RT][r]
))
FROM R r, L
WHERE P
TranslateWFSQuery Algorithm
Case 2: QW has n <wfs:PropertyName> elements
Let Pathi be the value of i-th <wfs:PropertyName> element of QW.
Let Qi [r] := TranslatePath(Pathi)
Qs = SELECT
XMLELEMENT( " gml:featureMember ",
XMLELEMENT( " F ",
Q1 [r]
…
Qn [r]
))
FROM R r, L
WHERE P
TranslateWFSQuery Algorithm
TranslateFilter( f )
returns a tuple <P,L>
where
P is an SQL conditional expression
L is a list of relations names required to process P
such that,
for any instance $t of T if $t A r, where r is a tuple of R,
then $t satisfies f iff r satisfies P
TranslatePath(F) Algorithm
Input: a path F = p1 /…/ pn of type T
Output: SQL/XML subquery Q[r] that computes the value of path F
Theorem:
For any instance $t of Extension of F, where $t Ar,
then Q[r] returns a set S of pn-elements where S = $t/ p1 /…/ pn
Translation for QW
QW : WFS Query
<wfs:Query typeName="F_Station">
<wfs:PropertyName>name</wfs:PropertyName>
<wfs:PropertyName>address / city</wfs:PropertyName>
<wfs:PropertyName>pluviometry</wfs:PropertyName>
<wfs:PropertyName>geometry</wfs:PropertyName>
<ogc:Filter>
<ogc:And> <ogc:PropertyIsEqualTo>
<ogc:PropertyName>agency</ogc:PropertyName>
<ogc:Literal>FUNCEME</ogc:Literal>
</ogc:PropertyIsEqualTo>
<ogc:BBox>
<ogc:PropertyName>geometry</ogc:PropertyName>
<gml:Envelope>
<gml:lowercorner>-5.2 -42.5</gml:lowercorner>
<gml:upperCorner>-2.5 -38.7</gml:upperCorner>
</gml:Envelope> </ogc:BBox> </ogc:And>
</ogc:Filter>
</wfs:Query>
QX : Canonical XQuery for QW
FOR $f in document("F")/Station
WHERE $f satisfies the filter of QW
RETURN <gml:featureMember>{
<F_Station> {
$f / name,
$f / address/city,
$f / pluviometry,
$f / geometry
}</F_Station>
}<gml:featureMember>
Translation for QW
SQL/XML Query
SELECT XMLELEMENT("gml:FeatureMember",
XMLELEMENT("Station",
Q1[S], .........…..…………………..TranslatePath( name )
Q2[S],……........................TranslatePath( address / city)
Q3[S],…………….…………TranslatePath( pluviometry )
Q4[S]…………………………..TranslatePath( geometry )
))
FROM Station_rel S, L
WHERE P
Translation for QW
SQL/XML Query
SELECT XMLELEMENT("gml:FeatureMember",
XMLELEMENT("Station")
XMLFOREST(S.NAME AS "name"),
Q2[S],
Q3[S],
Q4[S]
TranslatePath( name )
)
FROM Station_rel S, L
WHERE P
[TStation / name] [Station_rel / NAME]
Translation for QW
SQL/XML Query
SELECT XMLELEMENT("gml:FeatureMember",
XMLELEMENT("Station")
XMLFOREST(S.NAME AS "name"),
XMLELEMENT( "city",
(SELECT XMLCONCAT(
XMLFOREST(C.NAME AS "name"),
XMLFOREST(C.AREA AS "area") )
FROM City_rel C
WHERE C.CODECITY = S.CODECITY)),
Q3[S],
Q4[S]
TranslatePath( address / city )
)
FROM Station_rel S, L
WHERE P
[TStation / address] [Station_rel / NULL]
+ [TAddress / city] [Station_rel / FK1]
+ [TCity / name] [City_rel / NAME]
+ [TCity / area] [City_rel / AREA]
Translation for QW
SQL/XML Query
SELECT XMLELEMENT("gml:FeatureMember",
XMLELEMENT("Station")
XMLFOREST(S.NAME AS "name"),
[TStation / pluviometry] [Station_rel / FK2-1]
XMLELEMENT( "city",
+ [TPluviomety / month] [Pluviometry_rel / MONTH]
(SELECT XMLCONCAT(
+ [TPluviomety / value] [Pluviometry_rel / VALUE]
XMLFOREST(C.NAME AS "name"),
XMLFOREST(C.AREA AS "area") )
FROM City_rel C
WHERE C.CODECITY = S.CODECITY)),
(SELECT XMLAGG(XMLELEMENT("pluviometry",
XMLFOREST(PL.MONTH AS "month"),
XMLFOREST(PL.VALUE AS "value") ) )
FROM Pluviometry_rel PL
WHERE S.CODE = PL.CODESTATION),
Q[ S ]
)
FROM Station_rel S, L
WHERE P
TranslatePath( pluviometry )
Translation for QW
SQL/XML Query
SELECT XMLELEMENT("gml:FeatureMember",
XMLELEMENT("Station")
XMLFOREST(S.NAME AS "name"),
XMLELEMENT( "city",
[TStation / geometry] [Station_rel / GEOM_POINT]
(SELECT XMLCONCAT(
XMLFOREST(C.NAME AS "name"),
XMLFOREST(C.AREA AS "area") )
FROM City_rel C
WHERE C.CODECITY = S.CODECITY)),
(SELECT XMLAGG(XMLELEMENT("pluviometry",
XMLFOREST(PL.MONTH AS "month"),
XMLFOREST(PL.VALUE AS "value") ) )
TranslatePath( geometry )
FROM Pluviometry_rel PL
WHERE S.CODE = PL.CODESTATION),
XMLFOREST(SDO_UTIL.TO_GMLGEOMETRY(S.GEOM_POINT) AS "geometry")
)
FROM Station_rel S, L
WHERE P
Translation for QW
SQL/XML Query
SELECT XMLELEMENT("gml:FeatureMember",
XMLELEMENT("Station")
XMLFOREST(S.NAME AS "name"),
XMLELEMENT( "city",
(SELECT XMLCONCAT(
XMLFOREST(C.NAME AS "name"),
XMLFOREST(C.AREA AS "area") )
FROM City_rel C
WHERE C.CODECITY = S.CODECITY)),
(SELECT XMLAGG(XMLELEMENT("pluviometry",
XMLFOREST(PL.MONTH AS "month"),
XMLFOREST(PL.VALUE AS "value") ) )
FROM Pluviometry_rel PL
WHERE S.CODE = PL.CODESTATION),
XMLFOREST(SDO_UTIL.TO_GMLGEOMETRY(S.GEOM_POINT) AS "geometry")
)
FROM Station_rel S, Agency_rel A
WHERE S.CODEAGENCY = A.CODEAGENCY AND A.NAME = 'FUNCEME' AND
mdsys.sdo_relate( S.GEOM_POINT, mdsys.sdo_geometry(2003, NULL, NULL,
mdsys.sdo_elem_info_array(1, 1003, 3),
mdsys.sdo_ordinate_array(-5.2, -42.5, –2.5, -38.7)),
'mask=ANYINTERACT querytype=WINDOW') = 'TRUE'
<P,L > := TraslateFilter(f )
TranslateWFSQuery Algorithm
Theorem:
Let
Qw be a WFS Query over F
QX be a canonical XQuery for QW
QS be a SQL/XML query over S generated by TranslateWFSQuery
S1 be a set of <featureMember> elements resulting from QX on F
S2 be a set of <featureMember> elements resulting from QS on S
Then
S1 = S2
Conclusions
Contributions:
a formalism to specify the mapping between
a feature type schema and a relational database schema
an algorithm that translates
a WFS query over a feature type schema into
a SQL/XML query over the relational database schema,
based on feature type's correspondence assertions.
Future work:
development of GML Publisher, a framework for publishing
geographic data stored in relational databases as GML