throws OwsException, XPathExpressionException {
// initialize
LOGGER.finer("Parsing spatial clause for "+parent.getNodeName());
String sErr = parent.getNodeName();
Envelope envelope = spatialClause.getBoundingEnvelope();
// TODO ensure that the discoverable is a geometry
Discoverable discoverable = this.parsePropertyName(parent,xpath);
spatialClause.setTarget(discoverable);
/*
*
* gml:Envelope <attribute name="gid" type="ID" use="optional"/> <attribute
* name="srsName" type="anyURI" use="optional"/>
*
* <element name="lowerCorner" type="gml:DirectPositionType"/> <attribute
* name="gid" type="ID" use="optional"/> <attribute name="srsName"
* type="anyURI" use="optional"/> space separated x y <element
* name="upperCorner" type="gml:DirectPositionType"/> <attribute name="gid"
* type="ID" use="optional"/> <attribute name="srsName" type="anyURI"
* use="optional"/> space separated x y
*
* <element ref="gml:pos" minOccurs="2" maxOccurs="2"> both are
* type="gml:DirectPositionType" (deprecated)
*
* <element ref="gml:coord" minOccurs="2" maxOccurs="2"/> <element X> <element
* Y>
*
* <element ref="gml:coordinates"/> <attribute name="decimal" type="string"
* use="optional" default="."/> <attribute name="cs" type="string"
* use="optional" default=","/> <attribute name="ts" type="string"
* use="optional" default=" "/>
*
* gml:Box <attribute name="gid" type="ID" use="optional"/> <attribute
* name="srsName" type="anyURI" use="optional"/> <element ref="gml:coord"
* minOccurs="2" maxOccurs="2"/> <element X> <element Y> <element
* ref="gml:coordinates"/> <attribute name="decimal" type="string"
* use="optional" default="."/> <attribute name="cs" type="string"
* use="optional" default=","/> <attribute name="ts" type="string"
* use="optional" default=" "/>
*
* gml:Point <attribute name="gid" type="ID" use="optional"/> <attribute
* name="srsName" type="anyURI" use="optional"/> <element ref="gml:coord"/>
* <element X> <element Y> <element ref="gml:coordinates"/> <attribute
* name="decimal" type="string" use="optional" default="."/> <attribute
* name="cs" type="string" use="optional" default=","/> <attribute name="ts"
* type="string" use="optional" default=" "/>
*
* gml:LineString <attribute name="gid" type="ID" use="optional"/> <attribute
* name="srsName" type="anyURI" use="optional"/> <element ref="gml:coord"
* minOccurs="2" maxOccurs="unbounded"/> <element X> <element Y> <element
* ref="gml:coordinates"/> <attribute name="decimal" type="string"
* use="optional" default="."/> <attribute name="cs" type="string"
* use="optional" default=","/> <attribute name="ts" type="string"
* use="optional" default=" "/>
*/
// determine the envelope
Node ndSpatial = (Node)xpath.evaluate("gml:Envelope",parent,XPathConstants.NODE);
if (ndSpatial == null) {
ndSpatial = (Node)xpath.evaluate("gml:Box",parent,XPathConstants.NODE);
if (ndSpatial == null) {
ndSpatial = (Node)xpath.evaluate("gml:Point",parent,XPathConstants.NODE);
}
}
if (ndSpatial != null) {
LOGGER.finest("Parsing "+ndSpatial.getNodeName()+"...");
sErr += "."+ndSpatial.getNodeName();
spatialClause.setSrsName(xpath.evaluate("@srsName",ndSpatial));
Node ndLower = (Node)xpath.evaluate("gml:lowerCorner",ndSpatial,XPathConstants.NODE);
Node ndUpper = (Node)xpath.evaluate("gml:upperCorner",ndSpatial,XPathConstants.NODE);
Node ndCoords = (Node)xpath.evaluate("gml:coordinates",ndSpatial,XPathConstants.NODE);
NodeList nlCoord = (NodeList)xpath.evaluate("gml:coord",ndSpatial,XPathConstants.NODESET);
// handle a lower and upper boundary
if ((ndLower != null) && (ndUpper != null)) {
String sLower = Val.chkStr(ndLower.getTextContent());
String sUpper = Val.chkStr(ndUpper.getTextContent());
LOGGER.finest("Parsing gml:lowerCorner=\""+sLower+"\" gml:upperCorner=\""+sUpper+"\"");
String[] xyLower = Val.tokenize(sLower," ");
String[] xyUpper = Val.tokenize(sUpper," ");
if ((xyLower.length == 2) && (xyUpper.length == 2)) {
envelope.put(xyLower[0],xyLower[1],xyUpper[0],xyUpper[1]);
}
// handle a delimited list of coordinates
} else if (ndCoords != null) {
// separators: decimal, ts (between coordinate pairs), cs (between x/y values)
char cDecSep = '.';
String decSep = xpath.evaluate("@decimal",ndCoords);
if ((decSep != null) && (decSep.length() == 1)) cDecSep = decSep.charAt(0);
String tsSep = xpath.evaluate("@ts",ndCoords);
if ((tsSep == null) || (tsSep.length() != 1)) tsSep = " ";
String csSep = xpath.evaluate("@cs", ndCoords);
if ((csSep == null) || (csSep.length() != 1)) csSep = ",";
String sepMsg = "decimal=\""+cDecSep+"\" ts=\""+tsSep+"\" cs=\""+csSep+"\"";
// collect individual string values
String sCordinates = Val.chkStr(ndCoords.getTextContent());
LOGGER.finest("Parsing gml:coordinates "+sepMsg+" coordinates=\""+sCordinates+"\"");
ArrayList<String> values = new ArrayList<String>();
String[] tsValues = Val.tokenize(sCordinates,tsSep);
for (String tsValue : tsValues) {
String[] csValues = Val.tokenize(tsValue,csSep);
for (String csValue: csValues) {
LOGGER.finer("Adding coordinate value: "+csValue);
values.add(csValue.replace(cDecSep,'.'));
}
}
// determine the minimum and maximum envelope values from the coordinate list
for (int i=0; i<values.size(); i=i+2) {
try {
LOGGER.finest("Handling coordinate: "+values.get(i)+" "+values.get(i + 1));
double x = Double.parseDouble(values.get(i));
double y = Double.parseDouble(values.get(i+1));
envelope.merge(new Envelope(x,y,x,y));
} catch (NumberFormatException e) {
LOGGER.warning(e.getMessage());
}
}
// handle a collection of coordinate elements
} else if (nlCoord.getLength() > 0) {
LOGGER.finest("Parsing gml:coord elements...");
for (int i=0; i< nlCoord.getLength(); i++) {
Node ndX = (Node)xpath.evaluate("gml:X",nlCoord.item(i),XPathConstants.NODE);
Node ndY = (Node)xpath.evaluate("gml:Y",nlCoord.item(i),XPathConstants.NODE);
if ((ndX != null) && (ndY != null)) {
try {
LOGGER.finest("Handling coordinate: "+ndX.getTextContent()+" "+ndY.getTextContent());
double x = Double.parseDouble(ndX.getTextContent());
double y = Double.parseDouble(ndY.getTextContent());
envelope.merge(new Envelope(x,y,x,y));
} catch (NumberFormatException e) {
LOGGER.warning(e.getMessage());
}
}
}
}
}
// add the clause if the envelope is not empty
if (!envelope.isEmpty()) {
logicalClause.getClauses().add(spatialClause);
} else {
String msg = sErr+" - the geometry of the spatial operand was not valid.";
throw new OwsException(OwsException.OWSCODE_InvalidParameterValue,parent.getLocalName(),msg);
}