diff -Nru zorba-geo-module-2.9.1/NOTICE.txt zorba-geo-module-3.0.0/NOTICE.txt
--- zorba-geo-module-2.9.1/NOTICE.txt 1970-01-01 00:00:00.000000000 +0000
+++ zorba-geo-module-3.0.0/NOTICE.txt 2013-11-07 17:13:41.000000000 +0000
@@ -0,0 +1,6 @@
+How to build geo module:
+
+- You need GEOS library from here http://trac.osgeo.org/geos/ . Make sure it is version 3.2.2, or better 3.3.0 or above.
+- After installing or compiling GEOS, on Windows you need to set the cmake variables GEOS_INCLUDE_DIR and GEOS_LIBRARY.
+
+note: On Linux the variables are set automatically by cmake.
\ No newline at end of file
diff -Nru zorba-geo-module-2.9.1/debian/bzr-builder.manifest zorba-geo-module-3.0.0/debian/bzr-builder.manifest
--- zorba-geo-module-2.9.1/debian/bzr-builder.manifest 2013-05-30 16:35:20.000000000 +0000
+++ zorba-geo-module-3.0.0/debian/bzr-builder.manifest 2013-11-07 17:13:44.000000000 +0000
@@ -1,3 +1,3 @@
-# bzr-builder format 0.3 deb-version {debupstream}-1
-lp:zorba/geo-module revid:chillery+buildbot@lambda.nu-20121214162458-olse4j3pf36f126k
-nest-part debian_rules lp:~zorba-coders/zorba/debian_control_files debian_files/zorba-geo-module_debian_rules/debian debian revid:juan457@gmail.com-20130529150701-m2co1uzthg4pkjy5
+# bzr-builder format 0.3 deb-version 3.0.0-0
+lp:zorba/geo-module revid:jenkins@lambda.nu-20130809122652-hiuytsrasnza4huj
+nest-part debian_rules lp:~zorba-coders/zorba/debian_control_files debian_files/zorba-geo-module_debian_rules/debian debian revid:juan457@gmail.com-20131031190552-9p76o0q432489tw2
diff -Nru zorba-geo-module-2.9.1/debian/changelog zorba-geo-module-3.0.0/debian/changelog
--- zorba-geo-module-2.9.1/debian/changelog 2013-05-30 16:35:20.000000000 +0000
+++ zorba-geo-module-3.0.0/debian/changelog 2013-11-07 17:13:44.000000000 +0000
@@ -1,12 +1,6 @@
-zorba-geo-module (2.9.1-1~quantal1) quantal; urgency=low
+zorba-geo-module (3.0.0-0~ubuntu12.10.1) quantal; urgency=low
* Auto build.
- -- Juan Zacarias Thu, 30 May 2013 16:35:20 +0000
-
-zorba-geo-module (2.9.1) unstable; urgency=low
-
- *Updated to current Version
-
- -- Juan Zacarias Wed, 29 May 2013 08:06:37 -0700
+ -- Juan Zacarias Thu, 07 Nov 2013 17:13:44 +0000
diff -Nru zorba-geo-module-2.9.1/debian/copyright zorba-geo-module-3.0.0/debian/copyright
--- zorba-geo-module-2.9.1/debian/copyright 2013-05-30 16:35:19.000000000 +0000
+++ zorba-geo-module-3.0.0/debian/copyright 2013-11-07 17:13:44.000000000 +0000
@@ -1,5 +1,4 @@
This package was debianized by Juan Zacarias on
-Wed, 29 May 2013 08:06:37 -0700
It was downloaded from http://www.zorba-xquery.com
diff -Nru zorba-geo-module-2.9.1/src/CMakeLists.txt zorba-geo-module-3.0.0/src/CMakeLists.txt
--- zorba-geo-module-2.9.1/src/CMakeLists.txt 2013-05-30 16:35:16.000000000 +0000
+++ zorba-geo-module-3.0.0/src/CMakeLists.txt 2013-11-07 17:13:41.000000000 +0000
@@ -12,9 +12,27 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# all external module libraries are generated in the directory
-# of the corresponding .xq file
-MESSAGE(STATUS "Add org")
-ADD_SUBDIRECTORY(org)
+#
+#Geos
+#
+IF (ZORBA_SUPPRESS_GEOS)
+ MESSAGE (STATUS "ZORBA_SUPPRESS_GEOS is true - not searching for Geos.")
+ELSE (ZORBA_SUPPRESS_GEOS)
-MESSAGE(STATUS "End modules")
+ MESSAGE (STATUS "Looking for Geos")
+ FIND_PACKAGE(Geos)
+
+ IF(GEOS_FOUND)
+ MESSAGE (STATUS "Found Geos library -- " ${GEOS_LIBRARIES})
+ SET (GEO_LINK_LIBRARIES ${GEOS_LIBRARIES})
+
+ INCLUDE_DIRECTORIES(${GEOS_INCLUDE_DIR})
+ INCLUDE_DIRECTORIES("geo.xq.src")
+ DECLARE_ZORBA_MODULE (URI "http://expath.org/ns/geo" VERSION 1.0 FILE "geo.xq" LINK_LIBRARIES "${GEOS_LIBRARIES}")
+
+ ADD_TEST_DIRECTORY("${PROJECT_SOURCE_DIR}/test")
+ ELSE(GEOS_FOUND)
+ MESSAGE(STATUS "Geos Library Not Found. You need to install Geos library in order to compile the Geo Module.")
+ ENDIF(GEOS_FOUND)
+ENDIF (ZORBA_SUPPRESS_GEOS)
+MESSAGE(STATUS "")
\ No newline at end of file
diff -Nru zorba-geo-module-2.9.1/src/geo.xq zorba-geo-module-3.0.0/src/geo.xq
--- zorba-geo-module-2.9.1/src/geo.xq 1970-01-01 00:00:00.000000000 +0000
+++ zorba-geo-module-3.0.0/src/geo.xq 2013-11-07 17:13:41.000000000 +0000
@@ -0,0 +1,1347 @@
+xquery version "1.0";
+
+(:
+ : Copyright 2006-2009 The FLWOR Foundation.
+ :
+ : Licensed under the Apache License, Version 2.0 (the "License");
+ : you may not use this file except in compliance with the License.
+ : You may obtain a copy of the License at
+ :
+ : http://www.apache.org/licenses/LICENSE-2.0
+ :
+ : Unless required by applicable law or agreed to in writing, software
+ : distributed under the License is distributed on an "AS IS" BASIS,
+ : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ : See the License for the specific language governing permissions and
+ : limitations under the License.
+:)
+
+(:~
+ : Function library providing geo processing using Simple Features api API GMLSF format.
+ : It uses the GEOS third party library, license LGPL. Version 3.2.2 or above is required.
+ :
+ : The data format supported is GML SF profile 0/1.
+ : This is a subset of GML, and covers the basic geometries of Point, Line and Surface and collections of those.
+ : GMLSF nodes have the namespace "http://www.opengis.net/gml".
+ :
+ : Possible GMLSF geometric structures are:
+ :
+ : - Point
+ :
+ : double_x double_y
+ : ]]>
+ : - LineString
+ :
+ : double_x1 double_y1 double_x2 double_y2 ...
+ : ]]>
+ : - Curve
+ :
+ :
+ : [
+ : double_x1 double_y1 double_x2 double_y2 ... ;
+ : ]*
+ :
+ : ]]>
+ : - LinearRing
+ :
+ : double_x1 double_y1 double_x2 double_y2 ...
+ : ]]>
+ : - Surface
+ :
+ :
+ : [
+ :
+ : ...
+ :
+ :
+ : ...
+ : ]*
+ : ]*
+ :
+ : ]]>
+ : - Polygon
+ :
+ :
+ : ...
+ :
+ : [
+ : ...
+ : ]*
+ : ]]>
+ : - MultiPoint
+ :
+ : [ ... ]*
+ : ]]>
+ : - MultiCurve
+ :
+ : [ ... ]*
+ : ]]>
+ : - MultiSurface
+ :
+ : [ ... ]*
+ :
+ : ]]>
+ : - MultiGeometry (this is from GML 3 schema)
+ :
+ : [
+ : ...one geometry...
+ : ]*
+ : [
+ : ...a list of geometries...
+ : ]?
+ : ]]>
+ :
+ : Note: When using gml:posList, it is possible to replace this element with a list of gml:pos.
+ : Note: XLink referencing is not supported.
+ : Note: The srsDimension optional attribute specifies the coordinate dimension. The default value is 2 (for 2D).
+ : Another possible value is 3 (for 3D) in which case every point has to have three double values (x, y, z).
+ : This is an extension borrowed from GML 3 spec.
+ : The operations made on 3D objects work only on x-y coordinates, the z coordinate is not taken into account.
+ : When returning the result, the original z-coordinates of the points are preserved.
+ : For computed points, the z-coordinate is interpolated.
+ :
+ : The coordinates values have to be in cartesian coordinates, not in polar coordinates.
+ : Converting between coordinate systems and doing projections from polar to cartesian is outside the scope of this geo module.
+ :
+ : For operations between two geometries, the DE-9IM matrix is used. The DE-9IM matrix is defined like this:
+ :
+ :
+ : |
+ : Interior |
+ : Boundary |
+ : Exterior |
+ :
+ :
+ : Interior |
+ : dim(intersection of interior1 and interior2) |
+ : dim(intersection of interior1 and boundary2) |
+ : dim(intersection of interior1 and exterior2) |
+ :
+ :
+ : Boundary |
+ : dim(intersection of boundary1 and interior2) |
+ : dim(intersection of boundary1 and boundary2) |
+ : dim(intersection of boundary1 and exterior2) |
+ :
+ :
+ : Exterior |
+ : dim(intersection of exterior1 and interior2) |
+ : dim(intersection of exterior1 and boundary2) |
+ : dim(intersection of exterior1 and exterior2) |
+ :
+ :
+ :
+ : The values in the DE-9IM can be T, F, *, 0, 1, 2.
+ : - T means the intersection gives a non-empty result.
+ : - F means the intersection gives an empty result.
+ : - * means any result.
+ : - 0, 1, 2 gives the expected dimension of the result (point, curve, surface)
+ :
+ :
+ : @author Daniel Turcanu
+ :
+ : @see http://expath.org/spec/geo
+ : @see http://www.opengeospatial.org/standards/sfa
+ : @see http://www.opengeospatial.org/standards/gml
+ : @see http://trac.osgeo.org/geos/
+ : @library GEOS (Geometry Engine - Open Source)
+ : @project EXPath/EXPath Geo Module
+ :)
+module namespace geo = "http://expath.org/ns/geo";
+
+(:~
+ : Declare the namespace for the gml geometry objects.
+ :)
+declare namespace gml="http://www.opengis.net/gml";
+
+(:~
+ : Declare the expath errors namespace.
+ :)
+declare namespace geo-err="http://expath.org/ns/error";
+
+declare namespace ver = "http://zorba.io/options/versioning";
+declare option ver:module-version "1.0";
+
+
+(:~
+ : Return the dimension of the geo object.
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return 0 for point, 1 for line, 2 for surface.
+ : @error geo-err:UnrecognizedGeoObject
+ : @example test/Queries/geo/dimension1.xq
+ : @example test/Queries/geo/dimension2.xq
+ : @example test/Queries/geo/dimension3.xq
+ : @example test/Queries/geo/dimension4.xq
+ : @example test/Queries/geo/dimension5.xq
+ : @example test/Queries/geo/dimension6.xq
+ : @example test/Queries/geo/dimension7.xq
+ : @example test/Queries/geo/dimension8.xq
+ : @example test/Queries/geo/dimension9.xq
+ : @example test/Queries/geo/dimension10.xq
+:)
+declare function geo:dimension( $geometry as element()) as xs:integer external;
+
+(:~
+ : Return the coordinate dimension of the geo object, as specified in the srsDimension attribute.
+ : Only two-dimensional and three-dimensional coordinates are supported.
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return 2 for 2D, 3 for 3D.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/coordinate_dimension1.xq
+ : @example test/Queries/geo/coordinate_dimension2.xq
+ : @example test/Queries/geo/coordinate_dimension3.xq
+ : @example test/Queries/geo/coordinate_dimension4.xq
+ : @example test/Queries/geo/coordinate_dimension5.xq
+ : @example test/Queries/geo/coordinate_dimension6.xq
+:)
+declare function geo:coordinate-dimension( $geometry as element()) as xs:integer external;
+
+(:~
+ : Return the qname type of geo object.
+ : Returns empty sequence if the geometry is not recognized.
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return "gml:Point" for Point, "gml:LineString" for LineString, "gml:Curve" for Curve, "gml:LineString" for LinearRing,
+ : "gml:Surface" for Surface, "gml:Polygon" for Polygon and PolygonPatch,
+ : "gml:MultiPoint" for MultiPoint, "gml:MultiCurve" for MultiCurve,
+ : "gml:MultiSurface" for MultiSurface, "gml:MultiGeometry" for MultiGeometry
+ : @error geo-err:UnrecognizedGeoObject
+ : @example test/Queries/geo/geometry_type1.xq
+ : @example test/Queries/geo/geometry_type2.xq
+ : @example test/Queries/geo/geometry_type3.xq
+ : @example test/Queries/geo/geometry_type4.xq
+ : @example test/Queries/geo/geometry_type5.xq
+ : @example test/Queries/geo/geometry_type6.xq
+ : @example test/Queries/geo/geometry_type7.xq
+ : @example test/Queries/geo/geometry_type8.xq
+ : @example test/Queries/geo/geometry_type9.xq
+ : @example test/Queries/geo/geometry_type10.xq
+ : @example test/Queries/geo/geometry_type11.xq
+:)
+declare function geo:geometry-type( $geometry as element()) as xs:QName? external;
+
+(:~
+ : Return the srid URI of geo object.
+ : SRID is contained in the srsName attribute in the geo element, or one of the parents,
+ : or in the boundedBy/Envelope element in one of the parents.
+ : This function searches recursively from this element up to the top-most parent.
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return the SRID if it is found
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/srid1.xq
+ : @example test/Queries/geo/srid2.xq
+ : @example test/Queries/geo/srid3.xq
+ : @example test/Queries/geo/srid4.xq
+ : @example test/Queries/geo/srid5.xq
+:)
+declare function geo:srid( $geometry as element()) as xs:anyURI? external;
+
+(:~
+ : Return the number of geometries in the collection, or 1 for non-collection.
+ : For gml:Point, gml:LineString, gml:LinearRing, gml:Polygon, return 1.
+ : For gml:Curve and gml:Surface, they are treated as geometric collections.
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return number of geometries in collection
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/num-geometries1.xq
+ : @example test/Queries/geo/num-geometries2.xq
+ : @example test/Queries/geo/num-geometries3.xq
+:)
+declare function geo:num-geometries( $geometry as element()) as xs:unsignedInt external;
+
+(:~
+ : Return the n-th geometry in the collection.
+ : Return this geometry if it is not a collection.
+ : For gml:Point, gml:LineString, gml:LinearRing, gml:Polygon, return this item if n is zero, otherwise error.
+ : For gml:Curve and gml:Surface, they are treated as geometric collections.
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $n zero-based index in the collection
+ : @return n-th geometry in collection. The node is the original node, not a copy.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/geometry-n1.xq
+ : @example test/Queries/geo/geometry-n2.xq
+ : @example test/Queries/geo/geometry-n3.xq
+ : @example test/Queries/geo/geometry-n4.xq
+:)
+declare function geo:geometry-n( $geometry as element(), $n as xs:unsignedInt) as element() external;
+
+(:~
+ : The envelope is the minimum bounding box of this geometry.
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return An gml:Envelope element with content
+ : <gml:Envelope>
+ : <gml:lowerCorner>minx miny</gml:lowerCorner>
+ : <gml:upperCorner>maxx maxy</gml:upperCorner>
+ : </gml:Envelope>
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/envelope1.xq
+ : @example test/Queries/geo/envelope2.xq
+ : @example test/Queries/geo/envelope3.xq
+ : @example test/Queries/geo/envelope4.xq
+ : @example test/Queries/geo/envelope5.xq
+ : @example test/Queries/geo/envelope6.xq
+ : @example test/Queries/geo/envelope7.xq
+ : @example test/Queries/geo/envelope8.xq
+ : @example test/Queries/geo/envelope9.xq
+ : @example test/Queries/geo/envelope11.xq
+ : @example test/Queries/geo/envelope12.xq
+:)
+declare function geo:envelope( $geometry as element()) as element(gml:Envelope) external;
+
+(:~
+ : Return the Well-known Text Representation of Geometry.
+ : This is defined in the Simple Features spec from OGC.
+ : gml:Curve is represented as MultiLineString.
+ : gml:Surface is represented as MultiPolygon.
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return the Well-known Text Representation for the geo object.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/as_text1.xq
+ : @example test/Queries/geo/as_text2.xq
+ : @example test/Queries/geo/as_text3.xq
+ : @example test/Queries/geo/as_text4.xq
+ : @example test/Queries/geo/as_text5.xq
+ : @example test/Queries/geo/as_text6.xq
+ : @example test/Queries/geo/as_text7.xq
+ : @example test/Queries/geo/as_text8.xq
+ : @example test/Queries/geo/as_text9.xq
+:)
+declare function geo:as-text( $geometry as element()) as xs:string external;
+
+(:~
+ : Return the Well-known Binary Representation of Geometry.
+ : This is defined in the Simple Features spec from OGC.
+ : gml:Curve is represented as MultiLineString.
+ : gml:Surface is represented as MultiPolygon.
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return the Well-known Binary Representation for the geo object as base64.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/as_binary1.xq
+:)
+declare function geo:as-binary( $geometry as element()) as xs:base64Binary external;
+
+(:~
+ : Checks if the argument is empty or not and if it is a valid geometry or not.
+ : A geometry is considered empty if it has no points.
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return true if $geometry is not a valid gmlsf object or if is empty.
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/is_empty1.xq
+ : @example test/Queries/geo/is_empty2.xq
+ : @example test/Queries/geo/is_empty3.xq
+ : @example test/Queries/geo/is_empty4.xq
+ : @example test/Queries/geo/is_empty5.xq
+:)
+declare function geo:is-empty( $geometry as element()?) as xs:boolean external;
+
+(:~
+ : Checks if this geometric object has no anomalous geometric points, such
+ : as self intersection or self tangency.
+ : Does not work for gml:Surface and gml:MultiGeometry.
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString,
+ : gml:LinearRing, gml:Curve, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface
+ : @return true if $geometry is simple.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/is_simple1.xq
+ : @example test/Queries/geo/is_simple2.xq
+ : @example test/Queries/geo/is_simple3.xq
+ : @example test/Queries/geo/is_simple4.xq
+ : @example test/Queries/geo/is_simple5.xq
+ : @example test/Queries/geo/is_simple6.xq
+ : @example test/Queries/geo/is_simple7.xq
+ : @example test/Queries/geo/is_simple8.xq
+ : @example test/Queries/geo/is_simple9.xq
+ : @example test/Queries/geo/is_simple10.xq
+ : @example test/Queries/geo/is_simple11.xq
+ : @example test/Queries/geo/is_simple12.xq
+ : @example test/Queries/geo/is_simple13.xq
+ : @example test/Queries/geo/is_simple14.xq
+:)
+declare function geo:is-simple( $geometry as element()) as xs:boolean external;
+
+(:~
+ : Checks if this geometric object is 2D or 3D, as specified in srsDimension optional attribute.
+ :
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return true if $geometry is 3D.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/is_3D1.xq
+ : @example test/Queries/geo/is_3D2.xq
+:)
+declare function geo:is-3d( $geometry as element()) as xs:boolean external;
+
+(:~
+ : Checks if this geometric object has measurements.
+ : Measurements is not supported in this geo module, so the function returns false.
+ :
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return false.
+ : @error geo-err:UnrecognizedGeoObject
+ : @example test/Queries/geo/is_measured1.xq
+:)
+declare function geo:is-measured( $geometry as element()) as xs:boolean external;
+
+(:~
+ : A boundary is a set that represents the limit of an geometry.
+ : For a Point or MultiPoint, the boundary is the empty geometry, nothing is returned.
+ : For a LineString, the boundary is the MultiPoint set of start point and end point.
+ : For a LinearRing, the boundary is empty MultiPoint.
+ : For a Curve, it is treated as a MultiCurve.
+ : For a Polygon, the boundary is the MultiCurve set of exterior and interior rings.
+ : For a Surface, the boundary is the MultiCurve set formed from the exterior ring of all patches
+ : seen as a single surface and all the interior rings from all patches.
+ : For MultiCurve, the boundary is the MultiPoint set of all start and end points that appear
+ : in an odd number of linestrings.
+ : For MultiGeometry, a sequence of boundaries is returned, corresponding to each child geometry.
+ :
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:LinearRing,
+ : gml:Curve, gml:Polygon, gml:Surface, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return the boundary of a Geometry as a set of Geometries of the next lower dimension.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/boundary1.xq
+ : @example test/Queries/geo/boundary2.xq
+ : @example test/Queries/geo/boundary3.xq
+ : @example test/Queries/geo/boundary4.xq
+ : @example test/Queries/geo/boundary5.xq
+ : @example test/Queries/geo/boundary6.xq
+ : @example test/Queries/geo/boundary7.xq
+ : @example test/Queries/geo/boundary8.xq
+ : @example test/Queries/geo/boundary9.xq
+ : @example test/Queries/geo/boundary10.xq
+ : @example test/Queries/geo/boundary11.xq
+ : @example test/Queries/geo/boundary12.xq
+ : @example test/Queries/geo/boundary13.xq
+ : @example test/Queries/geo/boundary14.xq
+:)
+declare function geo:boundary( $geometry as element()) as element()* external;
+
+
+
+
+
+(:~
+ : Checks if the two geometries are equal.
+ :
+ : Note: Does not work for gml:Surface and gml:MultiSurface if they have multiple Polygons.
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return true if the DE-9IM intersection matrix for the two Geometrys is T*F**FFF*.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/equals1.xq
+ : @example test/Queries/geo/equals2.xq
+ : @example test/Queries/geo/equals3.xq
+ : @example test/Queries/geo/equals4.xq
+ : @example test/Queries/geo/equals5.xq
+ : @example test/Queries/geo/equals6.xq
+ : @example test/Queries/geo/equals7.xq
+ : @example test/Queries/geo/equals8.xq
+ : @example test/Queries/geo/equals9.xq
+:)
+declare function geo:equals( $geometry1 as element(), $geometry2 as element()) as xs:boolean external;
+
+(:~
+ : Checks if geometry1 covers geometry2.
+ : It has to fulfill one of these conditions:
+ : - every point of geometry2 is a point of geometry1.
+ : - the DE-9IM Intersection Matrix for the two geometries is
+ : T*****FF* or *T****FF* or ***T**FF* or ****T*FF*.
+ :
+ : Unlike contains it does not distinguish between points in the boundary and in the interior of geometries.
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return true if geometry1 covers geometry2.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/covers6.xq
+:)
+declare function geo:covers( $geometry1 as element(), $geometry2 as element()) as xs:boolean external;
+
+(:~
+ : Checks if geometry1 does not touch or intersects geometry2.
+ : It has to fulfill these conditions:
+ : - they have no point in common
+ : - the DE-9IM Intersection Matrix for the two geometries is
+ : FF*FF****.
+ : - geometry1 does not intersect geometry2.
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return true if geometry1 and geometry2 are disjoint.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/disjoint1.xq
+ : @example test/Queries/geo/disjoint2.xq
+ : @example test/Queries/geo/disjoint3.xq
+ : @example test/Queries/geo/disjoint4.xq
+ : @example test/Queries/geo/disjoint5.xq
+ : @example test/Queries/geo/disjoint6.xq
+ : @example test/Queries/geo/disjoint7.xq
+ : @example test/Queries/geo/disjoint8.xq
+ : @example test/Queries/geo/disjoint9.xq
+:)
+declare function geo:disjoint( $geometry1 as element(), $geometry2 as element()) as xs:boolean external;
+
+(:~
+ : Checks if geometry1 intersects geometry2.
+ : This is true if disjoint returns false.
+ :
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return true if geometry1 and geometry2 are not disjoint.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/intersects1.xq
+ : @example test/Queries/geo/intersects2.xq
+ : @example test/Queries/geo/intersects3.xq
+ : @example test/Queries/geo/intersects4.xq
+ : @example test/Queries/geo/intersects5.xq
+ : @example test/Queries/geo/intersects6.xq
+ : @example test/Queries/geo/intersects6_3d.xq
+ : @example test/Queries/geo/intersects7.xq
+ : @example test/Queries/geo/intersects8.xq
+ : @example test/Queries/geo/intersects9.xq
+:)
+declare function geo:intersects( $geometry1 as element(), $geometry2 as element()) as xs:boolean external;
+
+(:~
+ : Checks if geometry1 touches geometry2.
+ : Returns true if the DE-9IM intersection matrix for the two
+ : geometries is FT*******, F**T***** or F***T****.
+ :
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return true if geometry1 touches geometry2.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/touches1.xq
+ : @example test/Queries/geo/touches2.xq
+ : @example test/Queries/geo/touches3.xq
+ : @example test/Queries/geo/touches4.xq
+ : @example test/Queries/geo/touches5.xq
+ : @example test/Queries/geo/touches6.xq
+ : @example test/Queries/geo/touches7.xq
+ : @example test/Queries/geo/touches8.xq
+ : @example test/Queries/geo/touches9.xq
+:)
+declare function geo:touches( $geometry1 as element(), $geometry2 as element()) as xs:boolean external;
+
+(:~
+ : Checks if geometry1 crosses geometry2.
+ : That is if the geometries have some but not all interior points in common.
+ : Returns true if the DE-9IM intersection matrix for the two
+ : geometries is:
+ : T*T****** (for P/L, P/A, and L/A situations).
+ : T*****T** (for L/P, A/P, and A/L situations).
+ : 0******** (for L/L situations).
+ :
+ : This applies for situations: P/L, P/A, L/L, L/A, L/P, A/P and A/L.
+ : For other situations it returns false.
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return true if geometry1 crosses geometry2.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/crosses1.xq
+ : @example test/Queries/geo/crosses2.xq
+ : @example test/Queries/geo/crosses3.xq
+ : @example test/Queries/geo/crosses4.xq
+ : @example test/Queries/geo/crosses5.xq
+ : @example test/Queries/geo/crosses6.xq
+ : @example test/Queries/geo/crosses7.xq
+ : @example test/Queries/geo/crosses8.xq
+ : @example test/Queries/geo/crosses9.xq
+ : @example test/Queries/geo/crosses10.xq
+:)
+declare function geo:crosses( $geometry1 as element(), $geometry2 as element()) as xs:boolean external;
+
+(:~
+ : Checks if geometry1 is within geometry2.
+ : Returns true if the DE-9IM intersection matrix for the two
+ : geometries is T*F**F***.
+ :
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return true if geometry1 is within geometry2.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/within1.xq
+ : @example test/Queries/geo/within2.xq
+ : @example test/Queries/geo/within3.xq
+ : @example test/Queries/geo/within4.xq
+ : @example test/Queries/geo/within5.xq
+ : @example test/Queries/geo/within6.xq
+ : @example test/Queries/geo/within7.xq
+ : @example test/Queries/geo/within8.xq
+ : @example test/Queries/geo/within9.xq
+:)
+declare function geo:within( $geometry1 as element(), $geometry2 as element()) as xs:boolean external;
+
+(:~
+ : Checks if geometry1 contains geometry2.
+ : Returns true if within(geometry2, geometry1) is true.
+ :
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return true if geometry1 contains geometry2.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/contains1.xq
+ : @example test/Queries/geo/contains2.xq
+ : @example test/Queries/geo/contains3.xq
+ : @example test/Queries/geo/contains4.xq
+ : @example test/Queries/geo/contains5.xq
+ : @example test/Queries/geo/contains6.xq
+ : @example test/Queries/geo/contains7.xq
+ : @example test/Queries/geo/contains8.xq
+ : @example test/Queries/geo/contains9.xq
+ : @example test/Queries/geo/contains10.xq
+:)
+declare function geo:contains( $geometry1 as element(), $geometry2 as element()) as xs:boolean external;
+
+(:~
+ : Checks if geometry1 overlaps with geometry2.
+ : Returns true if DE-9IM intersection matrix for the two
+ : geometries is T*T***T** (for two points or two surfaces)
+ : or * 1*T***T** (for two curves).
+ :
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return true if geometry1 overlaps geometry2.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/overlaps1.xq
+ : @example test/Queries/geo/overlaps2.xq
+ : @example test/Queries/geo/overlaps3.xq
+ : @example test/Queries/geo/overlaps4.xq
+ : @example test/Queries/geo/overlaps5.xq
+ : @example test/Queries/geo/overlaps6.xq
+ : @example test/Queries/geo/overlaps7.xq
+ : @example test/Queries/geo/overlaps8.xq
+ : @example test/Queries/geo/overlaps9.xq
+ : @example test/Queries/geo/overlaps10.xq
+ : @example test/Queries/geo/overlaps11.xq
+ : @example test/Queries/geo/overlaps12.xq
+:)
+declare function geo:overlaps( $geometry1 as element(), $geometry2 as element()) as xs:boolean external;
+
+(:~
+ : Checks if geometry1 relates with geometry2 relative to a DE-9IM matrix.
+ : The DE-9IM matrix is defined like this:
+ :
+ :
+ : |
+ : Interior |
+ : Boundary |
+ : Exterior |
+ :
+ :
+ : Interior |
+ : dim(intersection of interior1 and interior2) |
+ : dim(intersection of interior1 and boundary2) |
+ : dim(intersection of interior1 and exterior2) |
+ :
+ :
+ : Boundary |
+ : dim(intersection of boundary1 and interior2) |
+ : dim(intersection of boundary1 and boundary2) |
+ : dim(intersection of boundary1 and exterior2) |
+ :
+ :
+ : Exterior |
+ : dim(intersection of exterior1 and interior2) |
+ : dim(intersection of exterior1 and boundary2) |
+ : dim(intersection of exterior1 and exterior2) |
+ :
+ :
+ :
+ : The values in the DE-9IM can be T, F, *, 0, 1, 2 .
+ : - T means the intersection gives a non-empty result.
+ : - F means the intersection gives an empty result.
+ : - * means any result.
+ : - 0, 1, 2 gives the expected dimension of the result (point, curve, surface)
+ :
+ : For example, the matrix of "T*T***T**" checks for intersections of interior1 with interior2,
+ : interior1 with exterior2 and exterior1 with interior2.
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString,
+ : gml:LinearRing, gml:Polygon
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString,
+ : gml:LinearRing, gml:Polygon
+ : @param $intersection_matrix the DE-9IM matrix, with nine chars, three chars for each line in DE-9IM matrix.
+ : @return true if geometry1 relates to geometry2 according to the intersection matrix.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/relate1.xq
+ : @example test/Queries/geo/relate2.xq
+ : @example test/Queries/geo/relate3.xq
+ : @example test/Queries/geo/relate4.xq
+:)
+declare function geo:relate( $geometry1 as element(), $geometry2 as element(), $intersection_matrix as xs:string) as xs:boolean external;
+
+
+
+
+(:~
+ : Compute the shortest distance between any two Points in geometry1 and geometry2.
+ :
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return minimum distance as xs:double.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/distance1.xq
+:)
+declare function geo:distance( $geometry1 as element(), $geometry2 as element()) as xs:double external;
+
+(:~
+ : Returns a polygon that represents all Points whose distance
+ : from this geometric object is less than or equal to distance.
+ :
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $distance the distance from geometry, expressed in units of the current coordinate system
+ : @return new geometry surrounding the input geometry.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/buffer1.xq
+ : @example test/Queries/geo/buffer2.xq
+ : @example test/Queries/geo/buffer3.xq
+ : @example test/Queries/geo/buffer4.xq
+ : @example test/Queries/geo/buffer5.xq
+ : @example test/Queries/geo/buffer6.xq
+ : @example test/Queries/geo/buffer7.xq
+ : @example test/Queries/geo/buffer8.xq
+ : @example test/Queries/geo/buffer9.xq
+ : @example test/Queries/geo/buffer10.xq
+:)
+declare function geo:buffer( $geometry as element(), $distance as xs:double) as element() external;
+
+(:~
+ : Returns the smallest convex Polygon that contains all the points in the Geometry.
+ : Actually returns the object of smallest dimension possible (possible Point or LineString).
+ :
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return the convex polygon node.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/convex-hull1.xq
+ : @example test/Queries/geo/convex-hull2.xq
+ : @example test/Queries/geo/convex-hull3.xq
+ : @example test/Queries/geo/convex-hull3_3d.xq
+ : @example test/Queries/geo/convex-hull4.xq
+ : @example test/Queries/geo/convex-hull5.xq
+ : @example test/Queries/geo/convex-hull6.xq
+ : @example test/Queries/geo/convex-hull7.xq
+ : @example test/Queries/geo/convex-hull8.xq
+ : @example test/Queries/geo/convex-hull9.xq
+ : @example test/Queries/geo/convex-hull10.xq
+:)
+declare function geo:convex-hull( $geometry as element()) as element() external;
+
+(:~
+ : Returns a geometric object that represents the Point set intersection of
+ : geometry1 and geometry2.
+ : For intersection of two polygons interiors, returns a polygon.
+ : If intersection is void, empty sequence is returned.
+ :
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return point set geometry node.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/intersection1.xq
+ : @example test/Queries/geo/intersection2.xq
+ : @example test/Queries/geo/intersection3.xq
+ : @example test/Queries/geo/intersection4.xq
+ : @example test/Queries/geo/intersection5.xq
+ : @example test/Queries/geo/intersection6.xq
+ : @example test/Queries/geo/intersection7.xq
+ : @example test/Queries/geo/intersection8.xq
+ : @example test/Queries/geo/intersection8_3d.xq
+ : @example test/Queries/geo/intersection9.xq
+ : @example test/Queries/geo/intersection10.xq
+:)
+declare function geo:intersection( $geometry1 as element(), $geometry2 as element()) as element()? external;
+
+(:~
+ : Returns a geometric object that represents the Point set union of
+ : geometry1 and geometry2.
+ :
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return point set geometry node.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/union1.xq
+ : @example test/Queries/geo/union2.xq
+ : @example test/Queries/geo/union3.xq
+ : @example test/Queries/geo/union4.xq
+ : @example test/Queries/geo/union5.xq
+ : @example test/Queries/geo/union5_3d.xq
+ : @example test/Queries/geo/union6.xq
+ : @example test/Queries/geo/union7.xq
+ : @example test/Queries/geo/union8.xq
+ : @example test/Queries/geo/union9.xq
+:)
+declare function geo:union( $geometry1 as element(), $geometry2 as element()) as element() external;
+
+(:~
+ : Returns a geometric object that represents the Point set difference of
+ : geometry1 and geometry2. Points that are in geometry1 and are not in geometry2.
+ : If difference is empty geometry, empty sequence is returned.
+ :
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return point set geometry node.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/difference1.xq
+ : @example test/Queries/geo/difference2.xq
+ : @example test/Queries/geo/difference3.xq
+ : @example test/Queries/geo/difference4.xq
+ : @example test/Queries/geo/difference5.xq
+ : @example test/Queries/geo/difference6.xq
+ : @example test/Queries/geo/difference7.xq
+ : @example test/Queries/geo/difference8.xq
+ : @example test/Queries/geo/difference9.xq
+ : @example test/Queries/geo/difference10.xq
+:)
+declare function geo:difference( $geometry1 as element(), $geometry2 as element()) as element()? external;
+
+(:~
+ : Returns a geometric object that represents the Point set symmetric difference of
+ : geometry1 and geometry2. Points that are in geometry1 and are not in geometry2
+ : and points that are in geometry2 and are not in geometry1.
+ : If difference is empty geometry, empty sequence is returned.
+ :
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return point set geometry node.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/sym-difference1.xq
+ : @example test/Queries/geo/sym-difference2.xq
+ : @example test/Queries/geo/sym-difference3.xq
+ : @example test/Queries/geo/sym-difference4.xq
+ : @example test/Queries/geo/sym-difference5.xq
+ : @example test/Queries/geo/sym-difference6.xq
+ : @example test/Queries/geo/sym-difference7.xq
+ : @example test/Queries/geo/sym-difference8.xq
+ : @example test/Queries/geo/sym-difference9.xq
+:)
+declare function geo:sym-difference( $geometry1 as element(), $geometry2 as element()) as element()? external;
+
+
+
+
+(:~
+ : Returns the area of this geometry.
+ : Returns zero for Point and Lines.
+ :
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return geometry area as xs:double.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/area1.xq
+ : @example test/Queries/geo/area2.xq
+ : @example test/Queries/geo/area3.xq
+ : @example test/Queries/geo/area4.xq
+ : @example test/Queries/geo/area5.xq
+ : @example test/Queries/geo/area6.xq
+ : @example test/Queries/geo/area7.xq
+ : @example test/Queries/geo/area8.xq
+ : @example test/Queries/geo/area9.xq
+ : @example test/Queries/geo/area10.xq
+:)
+declare function geo:area( $geometry as element()) as xs:double external;
+
+(:~
+ : Returns the length of the lines of this geometry.
+ : Returns zero for Points.
+ :
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return geometry length as xs:double.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/length1.xq
+ : @example test/Queries/geo/length2.xq
+ : @example test/Queries/geo/length3.xq
+ : @example test/Queries/geo/length4.xq
+ : @example test/Queries/geo/length5.xq
+ : @example test/Queries/geo/length6.xq
+ : @example test/Queries/geo/length7.xq
+ : @example test/Queries/geo/length8.xq
+ : @example test/Queries/geo/length9.xq
+ : @example test/Queries/geo/length10.xq
+:)
+declare function geo:length( $geometry as element()) as xs:double external;
+
+(:~
+ : Checks if geometry2 is within a certain distance of geometry1.
+ :
+ :
+ : @param $geometry1 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $geometry2 node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @param $distance the distance from geometry1, expressed in units of the current coordinate system
+ : @return true if distance from geometry1 to geometry2 is less than $distance.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:SRSNotIdenticalInBothGeometries
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/is-within-distance1.xq
+ : @example test/Queries/geo/is-within-distance2.xq
+ : @example test/Queries/geo/is-within-distance3.xq
+ : @example test/Queries/geo/is-within-distance4.xq
+ : @example test/Queries/geo/is-within-distance5.xq
+ : @example test/Queries/geo/is-within-distance6.xq
+ : @example test/Queries/geo/is-within-distance7.xq
+ : @example test/Queries/geo/is-within-distance8.xq
+ : @example test/Queries/geo/is-within-distance9.xq
+:)
+declare function geo:is-within-distance( $geometry1 as element(), $geometry2 as element(), $distance as xs:double) as xs:boolean external;
+
+(:~
+ : Returns a Point that is the mathematical centroid of this geometry.
+ : The result is not guaranteed to be on the surface.
+ :
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return centroid Point.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/centroid1.xq
+ : @example test/Queries/geo/centroid2.xq
+ : @example test/Queries/geo/centroid3.xq
+ : @example test/Queries/geo/centroid4.xq
+ : @example test/Queries/geo/centroid5.xq
+ : @example test/Queries/geo/centroid6.xq
+ : @example test/Queries/geo/centroid7.xq
+ : @example test/Queries/geo/centroid8.xq
+ : @example test/Queries/geo/centroid9.xq
+ : @example test/Queries/geo/centroid10.xq
+:)
+declare function geo:centroid( $geometry as element()) as element(gml:Point) external;
+
+(:~
+ : Returns a Point that is interior of this geometry.
+ : If it cannot be inside the geometry, then it will be on the boundary.
+ :
+ :
+ : @param $geometry node of one of GMLSF objects: gml:Point, gml:LineString, gml:Curve, gml:LinearRing,
+ : gml:Surface, gml:Polygon, gml:MultiPoint, gml:MultiCurve, gml:MultiSurface, gml:MultiGeometry
+ : @return a Point inside the geometry.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/interior-point1.xq
+ : @example test/Queries/geo/interior-point2.xq
+ : @example test/Queries/geo/interior-point3.xq
+ : @example test/Queries/geo/interior-point4.xq
+ : @example test/Queries/geo/interior-point5.xq
+ : @example test/Queries/geo/interior-point6.xq
+ : @example test/Queries/geo/interior-point7.xq
+ : @example test/Queries/geo/interior-point8.xq
+ : @example test/Queries/geo/interior-point9.xq
+ : @example test/Queries/geo/interior-point10.xq
+:)
+declare function geo:point-on-surface( $geometry as element()) as element(gml:Point) external;
+
+
+
+
+
+
+(:~
+ : Returns the X coordinate of a Point.
+ :
+ :
+ : @param $point node of one of GMLSF objects: gml:Point
+ : @return the X coordinate
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/point_xyz1.xq
+ : @example test/Queries/geo/point_xyz4.xq
+:)
+declare function geo:x( $point as element(gml:Point)) as xs:double external;
+
+(:~
+ : Returns the Y coordinate of a Point.
+ :
+ :
+ : @param $point node of one of GMLSF objects: gml:Point
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @return the Y coordinate
+ : @example test/Queries/geo/point_xyz2.xq
+:)
+declare function geo:y( $point as element(gml:Point)) as xs:double external;
+
+(:~
+ : Returns the Z coordinate of a Point, if is 3D.
+ :
+ :
+ : @param $point node of one of GMLSF objects: gml:Point
+ : @return the Z coordinate, or empty sequence if 2D
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/point_xyz3.xq
+ : @example test/Queries/geo/point_xyz5.xq
+:)
+declare function geo:z( $point as element(gml:Point)) as xs:double? external;
+
+(:~
+ : Should return the Measure of a Point, but is not implemented,
+ : because it is not specified in GMLSF.
+ :
+ :
+ : @param $point node of one of GMLSF objects: gml:Point
+ : @return always empty sequence
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @example test/Queries/geo/point_xyz6.xq
+:)
+declare function geo:m( $point as element(gml:Point)) as xs:double? external;
+
+
+
+
+
+
+
+(:~
+ : Returns the start Point of a line.
+ :
+ :
+ : @param $line node of one of GMLSF objects: gml:LineString, gml:LinearRing, gml:Curve
+ : @return the starting gml:Point, constructed with the first coordinates in the line.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/start-point1.xq
+ : @example test/Queries/geo/start-point2.xq
+ : @example test/Queries/geo/start-point3.xq
+:)
+declare function geo:start-point( $line as element()) as element(gml:Point) external;
+
+(:~
+ : Returns the end Point of a line.
+ :
+ :
+ : @param $line node of one of GMLSF objects: gml:LineString, gml:LinearRing, gml:Curve
+ : @return the end gml:Point, constructed with the last coordinates in the line.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/end-point1.xq
+:)
+declare function geo:end-point( $line as element()) as element(gml:Point) external;
+
+(:~
+ : Checks if the line is closed loop. That is, if the start Point is same with end Point.
+ : For gml:Curve, checks if the start point of the first segment is the same with the
+ : last point of the last segment. It also checks that all the segments are connected together,
+ : and returns false if they aren't.
+ : For gml:MultiCurve, checks recursively for each LineString.
+ : For gml:Surface, checks if the exterior boundary of each patch touches completely other patches,
+ : so the Surface encloses a solid.
+ : For this to happen there is a need for 3D objects, and full 3D processing is not supported in GEOS library,
+ : so the function always returns false in this case.
+ :
+ :
+ : @param $geom node of one of GMLSF objects: gml:LineString, gml:LinearRing, gml:Curve,
+ : gml:MultiCurve, gml:Surface
+ : @return true if the line or surface is closed.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/is-closed1.xq
+ : @example test/Queries/geo/is-closed2.xq
+ : @example test/Queries/geo/is-closed3.xq
+ : @example test/Queries/geo/is-closed4.xq
+ : @example test/Queries/geo/is-closed5.xq
+ : @example test/Queries/geo/is-closed6.xq
+:)
+declare function geo:is-closed( $geom as element()) as xs:boolean external;
+
+(:~
+ : Checks if the line is a ring. That is, if the line is closed and simple.
+ :
+ :
+ : @param $line node of one of GMLSF objects: gml:LineString, gml:LinearRing, gml:Curve
+ : @return true if the line is a closed ring.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/is-ring1.xq
+ : @example test/Queries/geo/is-ring2.xq
+ : @example test/Queries/geo/is-ring3.xq
+ : @example test/Queries/geo/is-ring4.xq
+:)
+declare function geo:is-ring( $line as element()) as xs:boolean external;
+
+(:~
+ : Return the number of Points in a line.
+ :
+ :
+ : @param $line node of one of GMLSF objects: gml:LineString, gml:LinearRing, gml:Curve,
+ : gml:MultiCurve
+ : @return number of points in the line
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/num-points1.xq
+ : @example test/Queries/geo/num-points2.xq
+ : @example test/Queries/geo/num-points3.xq
+:)
+declare function geo:num-points( $line as element()) as xs:unsignedInt external;
+
+(:~
+ : Return the n-th Point in a line.
+ :
+ : @param $line node of one of GMLSF objects: gml:LineString, gml:LinearRing, gml:Curve,
+ : gml:MultiCurve
+ : @param $n index in the list of coordinates, zero based.
+ : @return n-th point in the line, zero-based. The node is gml:Point constructed with n-th coordinate from line.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/point-n1.xq
+ : @example test/Queries/geo/point-n2.xq
+ : @example test/Queries/geo/point-n3.xq
+:)
+declare function geo:point-n( $line as element(), $n as xs:unsignedInt) as element(gml:Point) external;
+
+
+
+
+
+
+(:~
+ : Return the exterior ring of a Polygon.
+ :
+ :
+ : @param $polygon node of one of GMLSF objects: gml:Polygon
+ : @return the original gml:LinearRing node for exterior ring
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/exterior-ring1.xq
+ : @example test/Queries/geo/exterior-ring2.xq
+:)
+declare function geo:exterior-ring( $polygon as element(gml:Polygon)) as element(gml:LinearRing) external;
+
+(:~
+ : Return the number of interior rings of a Polygon.
+ :
+ :
+ : @param $polygon node of one of GMLSF objects: gml:Polygon
+ : @return the number of interior rings
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/num-interior-ring1.xq
+:)
+declare function geo:num-interior-ring( $polygon as element(gml:Polygon)) as xs:unsignedInt external;
+
+(:~
+ : Return the n-th interior ring of a Polygon.
+ :
+ :
+ : @param $polygon node of one of GMLSF objects: gml:Polygon
+ : @param $n index in the list of interior rings, zero based.
+ : @return n-th interior ring. The node is the original node, not a copy.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:IndexOutsideRange
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/interior-ring-n1.xq
+:)
+declare function geo:interior-ring-n( $polygon as element(gml:Polygon), $n as xs:unsignedInt) as element(gml:LinearRing) external;
+
+(:~
+ : Return the number of surface patches inside a gml:Surface.
+ : This function has the same effect as num-geometries(), only it is restricted to gml:Surface.
+ :
+ :
+ : @param $polyhedral-surface node of one of GMLSF objects: gml:Surface
+ : @return the number of surface patches
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/num-patches1.xq
+ : @example test/Queries/geo/num-patches2.xq
+:)
+declare function geo:num-patches($polyhedral-surface as element(gml:Surface)) as xs:integer external;
+
+(:~
+ : Return the n-th Surface patch of a Surface.
+ : Only polygonal Surfaces are supported, so a gml:PolygonPatch is returned.
+ : The gml:PolygonPatch has the same content as gml:Polygon.
+ : This function has the same effect as geometry-n(), only it is restricted to gml:Surface.
+ :
+ :
+ : @param $polyhedral-surface node of one of GMLSF objects: gml:Surface
+ : @param $n index in the list of surface patches, zero based.
+ : @return n-th polygon patch. The node is the original node, not a copy.
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:IndexOutsideRange
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/patch-n1.xq
+ : @example test/Queries/geo/patch-n2.xq
+:)
+declare function geo:patch-n($polyhedral-surface as element(gml:Surface),
+ $n as xs:unsignedInt) as element(gml:PolygonPatch) external;
+
+
+(:~
+ : Return the list of PolygonPatches that share a boundary with the given $polygon.
+ : The gml:PolygonPatch has the same content as gml:Polygon.
+ : This function tests the exterior ring of each polygon patch if it overlaps
+ : with the exterior ring of the given polygon.
+ :
+ :
+ : @param $polyhedral-surface node of one of GMLSF objects: gml:Surface
+ : @param $polygon, of type gml:Polygon or gml:PolygonPatch
+ : @return the list of neibourghing gml:PolygonPatch-es
+ : @error geo-err:UnrecognizedGeoObject
+ : @error geo-err:UnsupportedSRSDimensionValue
+ : @error geo-err:GEOSError
+ : @example test/Queries/geo/bounding-polygons1.xq
+ : @example test/Queries/geo/bounding-polygons2.xq
+ : @example test/Queries/geo/bounding-polygons3.xq
+:)
+declare function geo:bounding-polygons($polyhedral-surface as element(gml:Surface),
+ $polygon as element()) as element(gml:PolygonPatch)* external;
diff -Nru zorba-geo-module-2.9.1/src/geo.xq.src/geo_functions.cpp zorba-geo-module-3.0.0/src/geo.xq.src/geo_functions.cpp
--- zorba-geo-module-2.9.1/src/geo.xq.src/geo_functions.cpp 1970-01-01 00:00:00.000000000 +0000
+++ zorba-geo-module-3.0.0/src/geo.xq.src/geo_functions.cpp 2013-11-07 17:13:41.000000000 +0000
@@ -0,0 +1,4512 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include
+#include
+#include
+#include
+
+#include "geo_functions.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "geo_module.h"
+
+ #if GEOS_VERSION_MAJOR < 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 2)
+#error Zorba geo module can be linked only with GEOS version 3.2.2 or above, preferably 3.3
+#endif
+
+#define DONT_CHECK_FOR_CURVE_SURFACE true
+
+#define RETURN_RESULT_ITEM return result_item.isNull() ? ItemSequence_t(NULL) : ItemSequence_t(new SingletonItemSequence(result_item))
+
+namespace zorba { namespace geomodule {
+
+GeoFunction::GeoFunction(const GeoModule* aModule)
+ : theModule(aModule)
+{
+// geo_factory = NULL;
+}
+
+GeoFunction::~GeoFunction()
+{
+// delete geo_factory;
+}
+
+String
+GeoFunction::getURI() const
+{
+ return theModule->getURI();
+}
+
+void
+GeoFunction::throwError(
+ const char *err_localname,
+ const std::string aErrorMessage)
+{
+ Item errWrongParamQName;
+ String errNS("http://expath.org/ns/error");
+ String errName(err_localname);
+ Item errQName = GeoModule::getItemFactory()->createQName(errNS, errName);
+ String errDescription(aErrorMessage);
+ throw USER_EXCEPTION(errQName, errDescription);
+}
+
+enum GeoFunction::gmlsf_types GeoFunction::getGmlSFGeometricType(Item item) const
+{
+ Item item_qname;
+ item.getNodeName(item_qname);
+ String item_namespace = item_qname.getNamespace();
+ if(item_namespace != "http://www.opengis.net/gml")
+ return GMLSF_INVALID;
+ String localname = item_qname.getLocalName();
+
+ if(localname == "Point")
+ return GMLSF_POINT;
+ else if(localname == "LineString")
+ return GMLSF_LINESTRING;
+ else if(localname == "Curve")
+ return GMLSF_CURVE;
+ else if(localname == "LinearRing")
+ return GMLSF_LINEARRING;
+ else if(localname == "Surface")
+ return GMLSF_SURFACE;
+ else if(localname == "Polygon")
+ return GMLSF_POLYGON;
+ else if(localname == "PolygonPatch")
+ return GMLSF_POLYGON;
+ else if(localname == "MultiPoint")
+ return GMLSF_MULTIPOINT;
+ else if(localname == "MultiCurve")
+ return GMLSF_MULTICURVE;
+ else if(localname == "MultiSurface")
+ return GMLSF_MULTISURFACE;
+ else if(localname == "MultiGeometry")///from GML3
+ return GMLSF_MULTIGEOMETRY;
+ else
+ return GMLSF_INVALID;
+}
+
+enum GeoFunction::gmlsf_types GeoFunction::getGeometryNodeType(const ExternalFunction::Arguments_t& args,
+ int arg_pos, zorba::Item &lItem) const
+{
+ Iterator_t args_iter = args[arg_pos]->getIterator();
+ args_iter->open();
+ if (!args_iter->next(lItem))
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "An empty-sequence is not allowed as parameter";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+
+ if(!lItem.isNode() || (lItem.getNodeKind() != store::StoreConsts::elementNode))
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Argument must be a geometric node ";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ args_iter->close();
+ return getGmlSFGeometricType(lItem);
+}
+
+bool GeoFunction::getChild(zorba::Item &lItem, const char *localname, const char *ns,
+ zorba::Item &child_item) const
+{
+ Iterator_t children;
+ children = lItem.getChildren();
+ children->open();
+ bool retval = getChild(children, localname, ns, child_item);
+ children->close();
+ return retval;
+}
+
+bool GeoFunction::getChild(zorba::Iterator_t children, const char *localname, const char *ns,
+ zorba::Item &child_item) const
+{
+ while(children->next(child_item))
+ {
+ if(child_item.getNodeKind() != store::StoreConsts::elementNode)
+ continue;
+ Item child_name;
+ child_item.getNodeName(child_name);
+ String item_namespace = child_name.getNamespace();
+ if(item_namespace != ns)
+ {
+ continue;//next child
+ }
+ String item_name = child_name.getLocalName();
+ if(item_name != localname)
+ {
+ continue;//next child
+ }
+ return true;
+ }
+ return false;
+}
+
+bool GeoFunction::getAttribute( zorba::Item &item,
+ const char *name,
+ const char *ns,
+ zorba::Item &attr_item) const
+{
+ Iterator_t children;
+ children = item.getAttributes();
+ children->open();
+ while(children->next(attr_item))
+ {
+ zorba::Item attr_qname;
+ attr_item.getNodeName(attr_qname);
+ String attr_name = attr_qname.getLocalName();
+ if(attr_name != name)
+ {
+ continue;//next attr
+ }
+ if(!ns)
+ {
+ children->close();
+ return true;
+ }
+ String attr_ns= attr_qname.getNamespace();
+ if(attr_ns == ns)
+ {
+ children->close();
+ return true;
+ }
+ }
+ children->close();
+ return false;
+}
+
+bool GeoFunction::checkOptionalAttribute(zorba::Item &item,
+ const char *name,
+ const char *ns,
+ const char *value) const
+{
+ zorba::Item attr_item;
+ if(!getAttribute( item,
+ name,
+ ns,
+ attr_item))
+ return true;
+ String attr_value = attr_item.getStringValue();
+ return attr_value == value;
+}
+
+int GeoFunction::get_srsDimension(zorba::Item &item, int prev_srsdimension) const
+{
+ zorba::Item attr_item;
+ if(getAttribute(item,
+ "srsDimension",
+ NULL,
+ attr_item))
+ {
+ String attr_value = attr_item.getStringValue();
+ zfn::trim( attr_value );
+ int srs_dim = atoi(attr_value.c_str());
+ if((srs_dim != 2) && (srs_dim != 3))
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Geo module's supported values for srsDimension in GML are 2 and 3.";
+ throwError("UnsupportedSRSDimensionValue", lErrorMessage.str());
+ }
+ return srs_dim;
+ }
+ return prev_srsdimension;
+}
+
+const geos::geom::GeometryFactory *GeoFunction::get_geometryFactory() const
+{
+// if(!geo_factory)
+// geo_factory = new geos::geom::GeometryFactory;
+// return geo_factory;
+ return geos::geom::GeometryFactory::getDefaultInstance();
+}
+
+void GeoFunction::readPointPosCoordinates(zorba::Item &lItem,
+ double *x,
+ double *y,
+ double *z,
+ int &srs_dim) const
+{
+ Iterator_t children;
+ children = lItem.getChildren();
+ children->open();
+ bool retval = readPointPosCoordinates(children, x, y, z, srs_dim);
+ children->close();
+ if(!retval)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "gml node must have a gml:pos child";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+}
+
+bool GeoFunction::readPointPosCoordinates(zorba::Iterator_t children,
+ double *x,
+ double *y,
+ double *z,
+ int &srs_dim) const
+{
+ zorba::Item pos_item;
+ if(!getChild(children, "pos", "http://www.opengis.net/gml", pos_item))
+ {//get upset
+ //std::stringstream lErrorMessage;
+ //lErrorMessage << "gml:Point node must have a gml:pos child";
+ //throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ return false;
+ }
+ srs_dim = get_srsDimension(pos_item, srs_dim);
+
+ String pos_string;
+ pos_string = pos_item.getStringValue();
+ *x = 0;
+ *y = 0;
+ *z = 0;
+ const char *str = pos_string.c_str();
+ while(((*str == ' ') ||
+ (*str == '\t') ||
+ (*str == '\n') ||
+ (*str == '\r')) &&
+ (*str != 0))
+ str++;
+ sscanf(str, "%lf", x);
+ while((*str != ' ') &&
+ (*str != '\t') &&
+ (*str != '\n') &&
+ (*str != '\r') &&
+ (*str != 0))
+ str++;
+ while(((*str == ' ') ||
+ (*str == '\t') ||
+ (*str == '\n') ||
+ (*str == '\r')) &&
+ (*str != 0))
+ str++;
+ sscanf(str, "%lf", y);
+ if(srs_dim == 3)
+ {
+ while((*str != ' ') &&
+ (*str != '\t') &&
+ (*str != '\n') &&
+ (*str != '\r') &&
+ (*str != 0))
+ str++;
+ while(((*str == ' ') ||
+ (*str == '\t') ||
+ (*str == '\n') ||
+ (*str == '\r')) &&
+ (*str != 0))
+ str++;
+ sscanf(str, "%lf", z);
+ }
+ return true;
+}
+
+void GeoFunction::readPosListCoordinates(zorba::Item &lItem,
+ geos::geom::CoordinateSequence *&cl,
+ int &srs_dim) const
+{
+ zorba::Item poslist_item;
+ if(srs_dim != 3)
+ srs_dim = 2;
+ if(getChild(lItem, "posList", "http://www.opengis.net/gml", poslist_item))
+ {
+ srs_dim = get_srsDimension(poslist_item, srs_dim);
+ if(!cl)
+ cl = geos::geom::CoordinateArraySequenceFactory::instance()->create((std::size_t)0, srs_dim);
+
+ String poslist_string;
+ poslist_string = poslist_item.getStringValue();
+ double x, y, z;
+ int load_x = 0;
+ const char *str_poslist = poslist_string.c_str();
+ while(((*str_poslist == ' ') ||
+ (*str_poslist == '\t') ||
+ (*str_poslist == '\n') ||
+ (*str_poslist == '\r')) &&
+ (*str_poslist != 0))
+ str_poslist++;
+ x = 0; y = 0; z = 0;
+ while(str_poslist[0])
+ {
+ if(load_x == 0)
+ x = atof(str_poslist);
+ else if(load_x == 1)
+ {
+ y = atof(str_poslist);
+ if(srs_dim == 2)
+ {
+ cl->add(geos::geom::Coordinate(x, y));
+ x = 0; y = 0;
+ }
+ }
+ else if(load_x == 2)
+ {
+ z = atof(str_poslist);
+ cl->add(geos::geom::Coordinate(x, y, z));
+ x = 0; y = 0; z = 0;
+ }
+ load_x = (load_x + 1)%srs_dim;
+ while((*str_poslist != ' ') &&
+ (*str_poslist != '\t') &&
+ (*str_poslist != '\n') &&
+ (*str_poslist != '\r') &&
+ (*str_poslist != 0))
+ str_poslist++;
+ while(((*str_poslist == ' ') ||
+ (*str_poslist == '\t') ||
+ (*str_poslist == '\n') ||
+ (*str_poslist == '\r')) &&
+ (*str_poslist != 0))
+ str_poslist++;
+ }
+ }
+ else if(getChild(lItem, "pos", "http://www.opengis.net/gml", poslist_item))
+ {
+ Iterator_t children;
+ children = lItem.getChildren();
+ children->open();
+ double x = 0, y = 0, z = 0;
+ while(readPointPosCoordinates(children, &x, &y, &z, srs_dim))
+ {
+ if(!cl)
+ cl = geos::geom::CoordinateArraySequenceFactory::instance()->create((std::size_t)0, srs_dim);
+
+ if(srs_dim == 3)
+ {
+ cl->add(geos::geom::Coordinate(x, y, z));
+ }
+ else
+ {
+ cl->add(geos::geom::Coordinate(x, y));
+ }
+ x = 0; y = 0; z = 0;
+ }
+ children->close();
+ }
+ else
+ {//get upset
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << item_qname.getLocalName() << " node must have a gml:posList child";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+
+}
+
+int GeoFunction::getCoordinateDimension(const geos::geom::Geometry *geos_geometry) const
+{
+ if(!geos_geometry)
+ return 2;
+ switch(geos_geometry->getGeometryTypeId())
+ {
+ case geos::geom::GEOS_POINT:
+ {
+ const geos::geom::Coordinate *c;
+ c = geos_geometry->getCoordinate();
+ if(!ISNAN(c->z))
+ return 3;
+ else
+ return 2;
+ }
+ /// a linestring
+ case geos::geom::GEOS_LINESTRING:
+ /// a linear ring (linestring with 1st point == last point)
+ case geos::geom::GEOS_LINEARRING:
+ {
+ std::auto_ptr cs;
+ cs.reset(geos_geometry->getCoordinates());
+ size_t cs_size = cs->getSize();
+ for(size_t i=0;igetAt(i).z;
+ if(!ISNAN(z))
+ return 3;
+ }
+ return 2;
+ }
+ /// a polygon
+ case geos::geom::GEOS_POLYGON:
+ {
+ const geos::geom::LineString* exterior_ring;
+ const geos::geom::Polygon *polygon = dynamic_cast(geos_geometry);
+ exterior_ring = polygon->getExteriorRing();
+ int exterior_dim = getCoordinateDimension(exterior_ring);
+ if(exterior_dim == 3)
+ return 3;
+
+ size_t interior_rings = polygon->getNumInteriorRing();
+ for(size_t i=0;igetInteriorRingN(i);
+ int interior_dim = getCoordinateDimension(interior_ring);
+ if(interior_dim == 3)
+ return 3;
+ }
+ return 2;
+ }
+ /// a collection of points
+ case geos::geom::GEOS_MULTIPOINT:
+ {
+ size_t nr_geoms = geos_geometry->getNumGeometries();
+ for(size_t i=0;igetGeometryN(i);
+ if(getCoordinateDimension(point) == 3)
+ return 3;
+ }
+ return 2;
+ }
+ /// a collection of linestrings
+ case geos::geom::GEOS_MULTILINESTRING:
+ {
+ size_t nr_geoms = geos_geometry->getNumGeometries();
+ for(size_t i=0;igetGeometryN(i);
+ if(getCoordinateDimension(linestring) == 3)
+ return 3;
+ }
+ return 2;
+ }
+ /// a collection of polygons
+ case geos::geom::GEOS_MULTIPOLYGON:
+ {
+ size_t nr_geoms = geos_geometry->getNumGeometries();
+ for(size_t i=0;igetGeometryN(i);
+ if(getCoordinateDimension(polygon) == 3)
+ return 3;
+ }
+ return 2;
+ }
+ /// a collection of heterogeneus geometries
+ case geos::geom::GEOS_GEOMETRYCOLLECTION:
+ {
+ //can be either gml:Surface or gml:Curve
+ size_t nr_geoms = geos_geometry->getNumGeometries();
+ if(!nr_geoms)
+ return 2;//unreachable
+ for(size_t i=0;igetGeometryN(i);
+ if(getCoordinateDimension(child) == 3)
+ return 3;
+ }
+ return 2;
+ }
+ default:
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Geometry type " << geos_geometry->getGeometryType() << " is not supported";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ }
+
+ return 2;
+}
+
+void GeoFunction::getSrsName(zorba::Item lItem, zorba::Item &srs_uri) const
+{
+ zorba::Item attr_item;
+ if(getAttribute(lItem,
+ "srsName",
+ NULL,
+ attr_item))
+ {
+ String attr_value = attr_item.getStringValue();
+ srs_uri = theModule->getItemFactory()->createAnyURI(attr_value);
+ return;
+ }
+
+ zorba::Item parent_item = lItem.getParent();
+ if(parent_item.isNull())
+ return;
+ zorba::Item bounded_item;
+ zorba::Item envelope_item;
+ if(getChild(parent_item, "boundedBy", "http://www.opengis.net/gml", bounded_item) &&
+ getChild(bounded_item, "Envelope", "http://www.opengis.net/gml", envelope_item))
+ {
+ getSrsName(envelope_item, srs_uri);
+ if(!srs_uri.isNull())
+ return;
+ }
+ getSrsName(parent_item, srs_uri);
+ if(!srs_uri.isNull())
+ return;
+}
+
+geos::geom::Geometry *GeoFunction::buildGeosGeometryFromItem(zorba::Item &lItem,
+ enum GeoFunction::gmlsf_types geometric_type,
+ int srs_dim,
+ zorba::Item *srs_uri,
+ enum GeoFunction::action_item what_action,
+ uint32_t *optional_child_index_or_count,
+ zorba::Item *result_item) const
+{
+ srs_dim = get_srsDimension(lItem, srs_dim);
+ if(srs_uri)
+ getSrsName(lItem, *srs_uri);
+ geos::geom::Geometry *result;
+
+ switch(geometric_type)
+ {
+ case GMLSF_POINT:
+ {
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ double x, y, z;
+ readPointPosCoordinates(lItem, &x, &y, &z, srs_dim);
+ geos::geom::Coordinate c(x, y);
+ if(srs_dim == 3)
+ c.z = z;
+ try{
+ result = get_geometryFactory()->createPoint(c);
+ result->setUserData((void*)GMLSF_POINT);
+ return result;
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function createPoint : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+ else if(what_action == COUNT_CHILDREN)
+ (*optional_child_index_or_count) = 1;
+ else if(what_action == GET_NTH_CHILD)
+ {
+ if((*optional_child_index_or_count) == 0)
+ *result_item = lItem;
+ }
+ else
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GMLSF_POINT";
+ throwError("InternalError", lErrorMessage.str());
+ }
+ }break;
+ case GMLSF_LINESTRING:
+ {
+ geos::geom::CoordinateSequence *cl = NULL;//new geos::geom::CoordinateArraySequence();
+ readPosListCoordinates(lItem, cl, srs_dim);
+ uint32_t last_index = (uint32_t)cl->size()-1;
+ if(what_action == GET_END_POINT)
+ {
+ optional_child_index_or_count = &last_index;
+ what_action = GET_NTH_POINT;
+ }
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ try{
+ result = get_geometryFactory()->createLineString(cl);
+ result->setUserData((void*)GMLSF_LINESTRING);
+ return result;
+ }catch(std::exception &excep)
+ {
+ //delete cl;
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function createLineString : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+ else if((what_action == COUNT_CHILDREN) || (what_action == GET_NUM_POINTS))
+ {
+ (*optional_child_index_or_count) = (uint32_t)cl->size();
+ delete cl;
+ }
+ else if((what_action == GET_NTH_CHILD) || (what_action == GET_NTH_POINT))
+ {
+ if((*optional_child_index_or_count) < cl->size())
+ {
+ Item item_name;
+ Item item_type;
+ zorba::Item null_parent;
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "Point");
+ NsBindings ns_binding;
+ ns_binding.push_back(std::pair("gml", "http://www.opengis.net/gml"));
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ *result_item = theModule->getItemFactory()->createElementNode(null_parent, item_name, item_type, false, false, ns_binding);
+
+
+ zorba::Item pos_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "pos");
+ addNewLineIndentText(*result_item, 2);
+ pos_item = theModule->getItemFactory()->createElementNode(*result_item, item_name, item_type, false, false, ns_binding);
+
+ if(srs_dim == 3)
+ {
+ zorba::Item attr_value_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "srsDimension");
+ char strdim[10];
+ sprintf(strdim, "%d", srs_dim);
+ zorba::String strvalue(strdim);
+ attr_value_item = theModule->getItemFactory()->createString(strvalue);
+ theModule->getItemFactory()->createAttributeNode(pos_item, item_name, item_type, attr_value_item);
+ }
+ char strtemp[100];
+ if(srs_dim == 3)
+ {
+ if(!ISNAN(cl->getAt((*optional_child_index_or_count)).z))
+ sprintf(strtemp, "%lf %lf %lf", cl->getAt((*optional_child_index_or_count)).x,
+ cl->getAt((*optional_child_index_or_count)).y,
+ cl->getAt((*optional_child_index_or_count)).z);
+ else
+ sprintf(strtemp, "%lf %lf 0", cl->getAt((*optional_child_index_or_count)).x,
+ cl->getAt((*optional_child_index_or_count)).y);
+ }
+ else
+ {
+ sprintf(strtemp, "%lf %lf", cl->getAt((*optional_child_index_or_count)).x,
+ cl->getAt((*optional_child_index_or_count)).y);
+ }
+
+ zorba::Item text_item;
+ text_item = theModule->getItemFactory()->createTextNode(pos_item, strtemp);
+ addNewLineIndentText(*result_item, 0);
+ }
+ delete cl;
+ }
+ else
+ {
+ delete cl;
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GMLSF_LINESTRING";
+ throwError("InternalError", lErrorMessage.str());
+ }
+ }break;
+ case GMLSF_CURVE:
+ { //not supported in GEOS; emulate through MultiLineString
+ zorba::Item segments_item;
+ if(!getChild(lItem, "segments", "http://www.opengis.net/gml", segments_item))
+ {//get upset
+ std::stringstream lErrorMessage;
+ lErrorMessage << "gml:Curve node must have a gml:segments child";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ if((what_action == COUNT_CHILDREN) || (what_action == GET_NUM_POINTS))
+ {
+ (*optional_child_index_or_count) = 0;
+ }
+ unsigned int child_nr = 0;
+ Iterator_t segments_children;
+ Item line_segment_item;
+ std::vector *segments_vector = NULL;
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ segments_vector = new std::vector;
+ }
+ segments_children = segments_item.getChildren();
+ segments_children->open();
+ while(segments_children->next(line_segment_item))
+ {
+ if(line_segment_item.getNodeKind() != store::StoreConsts::elementNode)
+ continue;
+ Item item_qname;
+ line_segment_item.getNodeName(item_qname);
+ String item_namespace = item_qname.getNamespace();
+ if(item_namespace != "http://www.opengis.net/gml")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Children of gml:Curve/gml:segments must be of type gml:LineStringSegment only";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ String local_name = item_qname.getLocalName();
+ if(local_name != "LineStringSegment")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Children of gml:Curve/gml:segments must be of type gml:LineStringSegment only";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ if(!checkOptionalAttribute(line_segment_item, "interpolation", "http://www.opengis.net/gml", "linear"))
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "gml:Curve/gml:segments/gml:LineStringSegment supports only linear interpolation";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ segments_vector->push_back(buildGeosGeometryFromItem(line_segment_item, GMLSF_LINESTRING, srs_dim));
+ }
+ else if(what_action == COUNT_CHILDREN)
+ {
+ (*optional_child_index_or_count)++;
+ }
+ else if(what_action == GET_NUM_POINTS)
+ {
+ uint32_t nr_points;
+ buildGeosGeometryFromItem(line_segment_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NUM_POINTS, &nr_points);
+ (*optional_child_index_or_count) += nr_points;
+ }
+ else if(what_action == GET_NTH_CHILD)
+ {
+ if((*optional_child_index_or_count) == child_nr)
+ {
+ *result_item = line_segment_item;
+ return NULL;
+ }
+ }
+ else if(what_action == GET_NTH_POINT)
+ {
+ buildGeosGeometryFromItem(line_segment_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NTH_POINT, optional_child_index_or_count, result_item);
+ if(!result_item->isNull())
+ return NULL;
+ uint32_t nr_points;
+ buildGeosGeometryFromItem(line_segment_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NUM_POINTS, &nr_points);
+ (*optional_child_index_or_count) -= nr_points;
+ }
+ else
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GMLSF_CURVE";
+ throwError("InternalError", lErrorMessage.str());
+ }
+ child_nr++;
+ }
+
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ try{
+ result = get_geometryFactory()->createMultiLineString(segments_vector);
+ result->setUserData((void*)GMLSF_CURVE);
+ return result;
+ }catch(std::exception &excep)
+ {
+ std::vector::iterator vec_it;
+ for(vec_it = segments_vector->begin(); vec_it != segments_vector->end(); vec_it++)
+ {
+ delete (*vec_it);
+ }
+ delete segments_vector;
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function createGeometryCollection for gml:Curve: " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+ }break;
+ case GMLSF_LINEARRING:
+ {
+ geos::geom::CoordinateSequence *cl = NULL;//new geos::geom::CoordinateArraySequence();
+ readPosListCoordinates(lItem, cl, srs_dim);
+ uint32_t last_index = (uint32_t)cl->size()-1;
+ if(what_action == GET_END_POINT)
+ {
+ optional_child_index_or_count = &last_index;
+ what_action = GET_NTH_POINT;
+ }
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ try{
+ result = get_geometryFactory()->createLinearRing(cl);
+ result->setUserData((void*)GMLSF_LINEARRING);
+ return result;
+ }catch(std::exception &excep)
+ {
+ //delete cl;
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function createLinearRing : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+ else if((what_action == COUNT_CHILDREN) || (what_action == GET_NUM_POINTS))
+ {
+ (*optional_child_index_or_count) = (uint32_t)cl->size();
+ delete cl;
+ }
+ else if((what_action == GET_NTH_CHILD) || (what_action == GET_NTH_POINT))
+ {
+ if((*optional_child_index_or_count) < cl->size())
+ {
+ Item item_name;
+ Item item_type;
+ zorba::Item null_parent;
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "Point");
+ NsBindings ns_binding;
+ ns_binding.push_back(std::pair("gml", "http://www.opengis.net/gml"));
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ *result_item = theModule->getItemFactory()->createElementNode(null_parent, item_name, item_type, false, false, ns_binding);
+
+ zorba::Item pos_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "pos");
+ addNewLineIndentText(*result_item, 2);
+ pos_item = theModule->getItemFactory()->createElementNode(*result_item, item_name, item_type, false, false, ns_binding);
+
+ if(srs_dim == 3)
+ {
+ zorba::Item attr_value_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "srsDimension");
+ char strdim[10];
+ sprintf(strdim, "%d", srs_dim);
+ zorba::String strvalue(strdim);
+ attr_value_item = theModule->getItemFactory()->createString(strvalue);
+ theModule->getItemFactory()->createAttributeNode(pos_item, item_name, item_type, attr_value_item);
+ }
+ char strtemp[100];
+ if(srs_dim == 3)
+ {
+ if(!ISNAN(cl->getAt((*optional_child_index_or_count)).z))
+ sprintf(strtemp, "%lf %lf %lf", cl->getAt((*optional_child_index_or_count)).x,
+ cl->getAt((*optional_child_index_or_count)).y,
+ cl->getAt((*optional_child_index_or_count)).z);
+ else
+ sprintf(strtemp, "%lf %lf 0", cl->getAt((*optional_child_index_or_count)).x,
+ cl->getAt((*optional_child_index_or_count)).y);
+ }
+ else
+ {
+ sprintf(strtemp, "%lf %lf", cl->getAt((*optional_child_index_or_count)).x,
+ cl->getAt((*optional_child_index_or_count)).y);
+ }
+
+ zorba::Item text_item;
+ text_item = theModule->getItemFactory()->createTextNode(pos_item, strtemp);
+ addNewLineIndentText(*result_item, 0);
+ }
+ delete cl;
+ }
+ else
+ {
+ delete cl;
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GMLSF_LINEARRING";
+ throwError("InternalError", lErrorMessage.str());
+ }
+ }break;
+ case GMLSF_SURFACE:
+ { //not supported in GEOS; emulate through MultiPolygon
+ zorba::Item patches_item;
+ if(!getChild(lItem, "patches", "http://www.opengis.net/gml", patches_item))
+ {//get upset
+ std::stringstream lErrorMessage;
+ lErrorMessage << "gml:Surface node must have a gml:patches child";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ if(what_action == COUNT_CHILDREN)
+ {
+ (*optional_child_index_or_count) = 0;
+ }
+ unsigned int child_nr = 0;
+ Iterator_t patches_children;
+ Item polygon_patch_item;
+ std::vector *polygon_vector = NULL;
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ polygon_vector = new std::vector;
+ }
+ patches_children = patches_item.getChildren();
+ patches_children->open();
+ while(patches_children->next(polygon_patch_item))
+ {
+ if(polygon_patch_item.getNodeKind() != store::StoreConsts::elementNode)
+ continue;
+ Item item_qname;
+ polygon_patch_item.getNodeName(item_qname);
+ String item_namespace = item_qname.getNamespace();
+ if(item_namespace != "http://www.opengis.net/gml")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Children of gml:Surface/gml:patches must be of type gml:PolygonPatch only";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ String item_name = item_qname.getLocalName();
+ if(item_name != "PolygonPatch")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Children of gml:Surface/gml:patches must be of type gml:PolygonPatch only";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ polygon_vector->push_back(buildGeosGeometryFromItem(polygon_patch_item, GMLSF_POLYGON, srs_dim));
+ }
+ else if(what_action == COUNT_CHILDREN)
+ {
+ (*optional_child_index_or_count)++;
+ }
+ else if(what_action == GET_NTH_CHILD)
+ {
+ if((*optional_child_index_or_count) == child_nr)
+ {
+ *result_item = polygon_patch_item;
+ return NULL;
+ }
+ }
+ else
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GMLSF_CURVE";
+ throwError("InternalError", lErrorMessage.str());
+ }
+ child_nr++;
+ }
+
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ try{
+ result = get_geometryFactory()->createMultiPolygon(polygon_vector);
+ result->setUserData((void*)GMLSF_SURFACE);
+ return result;
+ }catch(std::exception &excep)
+ {
+ std::vector::iterator vec_it;
+ for(vec_it = polygon_vector->begin(); vec_it != polygon_vector->end(); vec_it++)
+ {
+ delete (*vec_it);
+ }
+ delete polygon_vector;
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function createGeometryCollection for gml:Surface : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+ }break;
+ case GMLSF_POLYGON:
+ {
+ Iterator_t polygon_children;
+ Item extint_item;
+ unsigned int nr_child = 0;
+ geos::geom::LinearRing *exterior = NULL;
+ std::vector *interior_vector = NULL;
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ interior_vector = new std::vector;
+ }
+ else if(what_action == COUNT_CHILDREN)
+ {
+ (*optional_child_index_or_count) = 0;
+ }
+ polygon_children = lItem.getChildren();
+ polygon_children->open();
+ while(polygon_children->next(extint_item))
+ {
+ if(extint_item.getNodeKind() != store::StoreConsts::elementNode)
+ continue;
+ Item item_qname;
+ extint_item.getNodeName(item_qname);
+ String item_namespace = item_qname.getNamespace();
+ if(item_namespace != "http://www.opengis.net/gml")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Children of gml:Polygon must be gml:exterior or gml:interior";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ String item_name = item_qname.getLocalName();
+ if(nr_child == 0)
+ {
+ if(item_name != "exterior")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "First child of gml:Polygon must be gml:exterior";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ zorba::Item linearring_item;
+ if(!getChild(extint_item, "LinearRing", "http://www.opengis.net/gml", linearring_item))
+ {//get upset
+ std::stringstream lErrorMessage;
+ lErrorMessage << "gml:Polygon/gml:exterior node must have a gml:LinearRing child";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ exterior = dynamic_cast(buildGeosGeometryFromItem(linearring_item, GMLSF_LINEARRING, srs_dim));
+ }
+ else if(what_action == GET_EXTERIOR_RING)
+ {
+ *result_item = linearring_item;
+ return NULL;
+ }
+ }
+ else
+ {
+ if(item_name != "interior")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Non-first child of gml:Polygon must be gml:interior";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ zorba::Item linearring_item;
+ if(!getChild(extint_item, "LinearRing", "http://www.opengis.net/gml", linearring_item))
+ {//get upset
+ std::stringstream lErrorMessage;
+ lErrorMessage << "gml:Polygon/gml:interior node must have a gml:LinearRing child";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ interior_vector->push_back(buildGeosGeometryFromItem(linearring_item, GMLSF_LINEARRING, srs_dim));
+ }
+ else if(what_action == COUNT_CHILDREN)
+ {
+ (*optional_child_index_or_count)++;
+ }
+ else if(what_action == GET_NTH_CHILD)
+ {
+ if((*optional_child_index_or_count) == (nr_child-1))
+ {
+ *result_item = linearring_item;
+ return NULL;
+ }
+ }
+ else
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GMLSF_POLYGON";
+ throwError("InternalError", lErrorMessage.str());
+ }
+ }
+ nr_child++;
+ }
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ try{
+ result = get_geometryFactory()->createPolygon(exterior, interior_vector);
+ result->setUserData((void*)GMLSF_POLYGON);
+ return result;
+ }catch(std::exception &excep)
+ {
+ delete exterior;
+ std::vector::iterator vec_it;
+ for(vec_it = interior_vector->begin(); vec_it != interior_vector->end(); vec_it++)
+ {
+ delete (*vec_it);
+ }
+ delete interior_vector;
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function createPolygon : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+ }break;
+ case GMLSF_MULTIPOINT:
+ {
+ Iterator_t multipoint_children;
+ Item point_item;
+ std::vector *point_vector = NULL;
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ point_vector = new std::vector;
+ }
+ else if(what_action == COUNT_CHILDREN)
+ {
+ (*optional_child_index_or_count) = 0;
+ }
+ unsigned int nr_child = 0;
+ multipoint_children = lItem.getChildren();
+ multipoint_children->open();
+ while(multipoint_children->next(point_item))
+ {
+ if(point_item.getNodeKind() != store::StoreConsts::elementNode)
+ continue;
+ Item item_qname;
+ point_item.getNodeName(item_qname);
+ String item_namespace = item_qname.getNamespace();
+ if(item_namespace != "http://www.opengis.net/gml")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Children of gml:MultiPoint must be gml:Point";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ String item_name = item_qname.getLocalName();
+ if(item_name != "Point")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "First child of gml:MultiPoint must be gml:Point";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ point_vector->push_back(buildGeosGeometryFromItem(point_item, GMLSF_POINT, srs_dim));
+ }
+ else if(what_action == COUNT_CHILDREN)
+ {
+ (*optional_child_index_or_count)++;
+ }
+ else if(what_action == GET_NTH_CHILD)
+ {
+ if((*optional_child_index_or_count) == nr_child)
+ {
+ *result_item = point_item;
+ return NULL;
+ }
+ }
+ else
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GMLSF_MULTIPOINT";
+ throwError("InternalError", lErrorMessage.str());
+ }
+ nr_child++;
+ }
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ try{
+ result = get_geometryFactory()->createMultiPoint(point_vector);
+ result->setUserData((void*)GMLSF_MULTIPOINT);
+ return result;
+ }catch(std::exception &excep)
+ {
+ std::vector::iterator vec_it;
+ for(vec_it = point_vector->begin(); vec_it != point_vector->end(); vec_it++)
+ {
+ delete (*vec_it);
+ }
+ delete point_vector;
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function createMultiPoint : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+ }break;
+ case GMLSF_MULTICURVE:
+ {
+ Iterator_t multicurve_children;
+ Item curve_item;
+ std::vector *curve_vector = NULL;
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ curve_vector = new std::vector;
+ }
+ else if((what_action == COUNT_CHILDREN) || (what_action == GET_NUM_POINTS))
+ {
+ (*optional_child_index_or_count) = 0;
+ }
+ unsigned int nr_child = 0;
+ multicurve_children = lItem.getChildren();
+ multicurve_children->open();
+ while(multicurve_children->next(curve_item))
+ {
+ if(curve_item.getNodeKind() != store::StoreConsts::elementNode)
+ continue;
+ Item item_qname;
+ curve_item.getNodeName(item_qname);
+ String item_namespace = item_qname.getNamespace();
+ if(item_namespace != "http://www.opengis.net/gml")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Children of gml:MultiCurve must be gml:LineString";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ String item_name = item_qname.getLocalName();
+ if(item_name != "LineString")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Children of gml:MultiCurve must be gml:LineString";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ curve_vector->push_back(buildGeosGeometryFromItem(curve_item, GMLSF_LINESTRING, srs_dim));
+ }
+ else if(what_action == COUNT_CHILDREN)
+ {
+ (*optional_child_index_or_count)++;
+ }
+ else if(what_action == GET_NUM_POINTS)
+ {
+ uint32_t nr_points;
+ buildGeosGeometryFromItem(curve_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NUM_POINTS, &nr_points);
+ (*optional_child_index_or_count) += nr_points;
+ }
+ else if(what_action == GET_NTH_CHILD)
+ {
+ if((*optional_child_index_or_count) == nr_child)
+ {
+ *result_item = curve_item;
+ return NULL;
+ }
+ }
+ else if(what_action == GET_NTH_POINT)
+ {
+ buildGeosGeometryFromItem(curve_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NTH_POINT, optional_child_index_or_count, result_item);
+ if(!result_item->isNull())
+ return NULL;
+ uint32_t nr_points;
+ buildGeosGeometryFromItem(curve_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NUM_POINTS, &nr_points);
+ (*optional_child_index_or_count) -= nr_points;
+ }
+ else
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GMLSF_MULTICURVE";
+ throwError("InternalError", lErrorMessage.str());
+ }
+ nr_child++;
+ }
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ try{
+ result = get_geometryFactory()->createMultiLineString(curve_vector);
+ result->setUserData((void*)GMLSF_MULTICURVE);
+ return result;
+ }catch(std::exception &excep)
+ {
+ std::vector::iterator vec_it;
+ for(vec_it = curve_vector->begin(); vec_it != curve_vector->end(); vec_it++)
+ {
+ delete (*vec_it);
+ }
+ delete curve_vector;
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function createMultiLineString : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+ }break;
+ case GMLSF_MULTISURFACE:
+ {
+ Iterator_t multisurface_children;
+ Item surface_item;
+ std::vector *surface_vector = NULL;
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ surface_vector = new std::vector;
+ }
+ else if(what_action == COUNT_CHILDREN)
+ {
+ (*optional_child_index_or_count) = 0;
+ }
+ unsigned int nr_child = 0;
+ multisurface_children = lItem.getChildren();
+ multisurface_children->open();
+ while(multisurface_children->next(surface_item))
+ {
+ if(surface_item.getNodeKind() != store::StoreConsts::elementNode)
+ continue;
+ Item item_qname;
+ surface_item.getNodeName(item_qname);
+ String item_namespace = item_qname.getNamespace();
+ if(item_namespace != "http://www.opengis.net/gml")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Children of gml:MultiSurface must be gml:Polygon";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ String item_name = item_qname.getLocalName();
+ if(item_name != "Polygon")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Children of gml:MultiSurface must be gml:Polygon";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ surface_vector->push_back(buildGeosGeometryFromItem(surface_item, GMLSF_POLYGON, srs_dim));
+ }
+ else if(what_action == COUNT_CHILDREN)
+ {
+ (*optional_child_index_or_count)++;
+ }
+ else if(what_action == GET_NTH_CHILD)
+ {
+ if((*optional_child_index_or_count) == nr_child)
+ {
+ *result_item = surface_item;
+ return NULL;
+ }
+ }
+ else
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GMLSF_MULTICURVE";
+ throwError("InternalError", lErrorMessage.str());
+ }
+ nr_child++;
+ }
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ try{
+ result = get_geometryFactory()->createMultiPolygon(surface_vector);
+ result->setUserData((void*)GMLSF_MULTISURFACE);
+ return result;
+ }catch(std::exception &excep)
+ {
+ std::vector::iterator vec_it;
+ for(vec_it = surface_vector->begin(); vec_it != surface_vector->end(); vec_it++)
+ {
+ delete (*vec_it);
+ }
+ delete surface_vector;
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function createMultiPolygon : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+ }break;
+ case GMLSF_MULTIGEOMETRY:
+ {
+ Iterator_t multigeometry_children;
+ Item geometry_item;
+ std::vector *geometry_vector = NULL;
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ geometry_vector = new std::vector;
+ }
+ else if(what_action == COUNT_CHILDREN)
+ {
+ (*optional_child_index_or_count) = 0;
+ }
+ unsigned int nr_child = 0;
+ multigeometry_children = lItem.getChildren();
+ multigeometry_children->open();
+ while(multigeometry_children->next(geometry_item))
+ {
+ if(geometry_item.getNodeKind() != store::StoreConsts::elementNode)
+ continue;
+ Item item_qname;
+ geometry_item.getNodeName(item_qname);
+ String item_namespace = item_qname.getNamespace();
+ if(item_namespace != "http://www.opengis.net/gml")
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Children of gml:MultiGeometry must be gml:geometryMember or gml:geometryMembers";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ String item_name = item_qname.getLocalName();
+ if(item_name == "geometryMember" || item_name == "geometryMembers")
+ {
+ Iterator_t member_children;
+ Item member_item;
+ member_children = geometry_item.getChildren();
+ member_children->open();
+ while(member_children->next(member_item))
+ {
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ geometry_vector->push_back(buildGeosGeometryFromItem(member_item, getGmlSFGeometricType(member_item), srs_dim));
+ }
+ else if(what_action == COUNT_CHILDREN)
+ {
+ (*optional_child_index_or_count)++;
+ }
+ else if(what_action == GET_NTH_CHILD)
+ {
+ if((*optional_child_index_or_count) == nr_child)
+ {
+ *result_item = member_item;
+ return NULL;
+ }
+ }
+ else
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GMLSF_MULTIGEOMETRY";
+ throwError("InternalError", lErrorMessage.str());
+ }
+ nr_child++;
+ }
+ }
+ else
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Children of gml:MultiGeometry must be gml:geometryMember or gml:geometryMembers";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ }
+ if(what_action == BUILD_GEOS_GEOMETRY)
+ {
+ try{
+ result = get_geometryFactory()->createGeometryCollection(geometry_vector);
+ result->setUserData((void*)GMLSF_MULTIGEOMETRY);
+ return result;
+ }catch(std::exception &excep)
+ {
+ std::vector::iterator vec_it;
+ for(vec_it = geometry_vector->begin(); vec_it != geometry_vector->end(); vec_it++)
+ {
+ delete (*vec_it);
+ }
+ delete geometry_vector;
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function createGeometryCollection : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+ }break;
+ case GMLSF_INVALID:
+ default:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"< 100)
+ indent = 100;
+ char *strtemp;
+ strtemp = new char[indent+10];
+ strtemp[0] = '\n';
+ memset(strtemp+1, ' ', indent);
+ strtemp[1+indent] = 0;
+ text_item = theModule->getItemFactory()->createTextNode(parent, strtemp);
+ delete[] strtemp;
+*/
+}
+
+void GeoFunction::appendIndent(char *&strtemp2, unsigned int indent) const
+{
+ strtemp2[0] = '\n';
+ memset(strtemp2+1, ' ', indent);
+ strtemp2 += indent+1;
+ strtemp2[0] = 0;
+}
+
+zorba::Item GeoFunction::getGMLItemFromGeosGeometry(zorba::Item &parent,
+ const geos::geom::Geometry *geos_geometry,
+ const zorba::Item *srs_uri,
+ unsigned int indent,
+ const char *tag_name,
+ bool dont_check_for_curve_surface
+ ) const
+{
+ zorba::Item result_item;
+ zorba::Item item_name;
+ zorba::Item item_type;
+ NsBindings ns_binding;
+ ns_binding.push_back(std::pair("gml", "http://www.opengis.net/gml"));
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+
+ if(!parent.isNull())
+ addNewLineIndentText(parent, indent);
+
+ switch(geos_geometry->getGeometryTypeId())
+ {
+ case geos::geom::GEOS_POINT:
+ {
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "Point");
+ result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
+
+ zorba::Item pos_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "pos");
+ addNewLineIndentText(result_item, indent+2);
+ pos_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
+
+ char strtemp[100];
+ const geos::geom::Coordinate *c;
+ c = geos_geometry->getCoordinate();
+#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
+ if(geos_geometry->getCoordinateDimension() == 3)
+#else
+ if(getCoordinateDimension(geos_geometry) == 3)
+#endif
+ {
+ zorba::Item attr_value_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "srsDimension");
+ zorba::String strvalue("3");
+ attr_value_item = theModule->getItemFactory()->createString(strvalue);
+ theModule->getItemFactory()->createAttributeNode(pos_item, item_name, item_type, attr_value_item);
+ if(!ISNAN(c->z))
+ sprintf(strtemp, "%lf %lf %lf", c->x, c->y, c->z);
+ else
+ sprintf(strtemp, "%lf %lf 0", c->x, c->y);
+ }
+ else
+ sprintf(strtemp, "%lf %lf", c->x, c->y);
+
+ zorba::Item text_item;
+ text_item = theModule->getItemFactory()->createTextNode(pos_item, strtemp);
+ addNewLineIndentText(result_item, indent);
+ break;
+ }
+ /// a linestring
+ case geos::geom::GEOS_LINESTRING:
+ /// a linear ring (linestring with 1st point == last point)
+ case geos::geom::GEOS_LINEARRING:
+ {
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml",
+ tag_name ? tag_name : ((geos_geometry->getGeometryTypeId() == geos::geom::GEOS_LINESTRING) ? "LineString" : "LinearRing"));
+ result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
+
+ zorba::Item pos_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "posList");
+ addNewLineIndentText(result_item, indent+2);
+ pos_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
+
+#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
+ int coord_dim = geos_geometry->getCoordinateDimension();
+#else
+ int coord_dim = getCoordinateDimension(geos_geometry);
+#endif
+ if(coord_dim == 3)
+ {
+ zorba::Item attr_value_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "srsDimension");
+ zorba::String strvalue("3");
+ attr_value_item = theModule->getItemFactory()->createString(strvalue);
+ theModule->getItemFactory()->createAttributeNode(pos_item, item_name, item_type, attr_value_item);
+ }
+ char *strtemp;
+ std::auto_ptr cs;
+ cs.reset(geos_geometry->getCoordinates());
+ size_t cs_size = cs->getSize();
+ strtemp = (char*)malloc((50+indent)*(cs_size+1) + 1);
+ strtemp[0] = 0;
+ char *strtemp2 = strtemp;
+ for(size_t i=0;igetAt(i).z))
+ sprintf(strtemp2, "%lf %lf %lf", cs->getAt(i).x, cs->getAt(i).y, cs->getAt(i).z);
+ else
+ sprintf(strtemp2, "%lf %lf 0", cs->getAt(i).x, cs->getAt(i).y);
+ }
+ else
+ sprintf(strtemp2, "%lf %lf", cs->getAt(i).x, cs->getAt(i).y);
+ strtemp2 += strlen(strtemp2);
+ }
+
+ if(cs_size)
+ {
+ appendIndent(strtemp2, indent+2);
+ zorba::Item text_item;
+ text_item = theModule->getItemFactory()->createTextNode(pos_item, strtemp);
+ addNewLineIndentText(result_item, indent);
+ }
+ free(strtemp);
+ break;
+ }
+ /// a polygon
+ case geos::geom::GEOS_POLYGON:
+ {
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", tag_name ? tag_name : "Polygon");
+ result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
+
+ const geos::geom::LineString* exterior_ring;
+ const geos::geom::Polygon *polygon = dynamic_cast(geos_geometry);
+ exterior_ring = polygon->getExteriorRing();
+ if(exterior_ring)
+ {
+ zorba::Item exterior_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "exterior");
+ addNewLineIndentText(result_item, indent+2);
+ exterior_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
+ getGMLItemFromGeosGeometry(exterior_item, exterior_ring, NULL, indent+4);
+ addNewLineIndentText(exterior_item, indent+2);
+ }
+ size_t interior_rings = polygon->getNumInteriorRing();
+ for(size_t i=0;igetInteriorRingN(i);
+
+ zorba::Item interior_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "interior");
+ addNewLineIndentText(result_item, indent+2);
+ interior_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
+ getGMLItemFromGeosGeometry(interior_item, interior_ring, NULL, indent+4);
+ addNewLineIndentText(interior_item, indent+2);
+ }
+ if(exterior_ring || interior_rings)
+ addNewLineIndentText(result_item, indent);
+ break;
+ }
+ /// a collection of points
+ case geos::geom::GEOS_MULTIPOINT:
+ {
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "MultiPoint");
+ result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
+
+ size_t nr_geoms = geos_geometry->getNumGeometries();
+ for(size_t i=0;igetGeometryN(i);
+ getGMLItemFromGeosGeometry(result_item, point, NULL, indent+2);
+ }
+ if(nr_geoms)
+ addNewLineIndentText(result_item, indent);
+ break;
+ }
+ /// a collection of linestrings
+ case geos::geom::GEOS_MULTILINESTRING:
+ {
+ const geos::geom::MultiLineString *multiline = dynamic_cast(geos_geometry);
+ if(!dont_check_for_curve_surface && isCurve(multiline))
+ {
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "Curve");
+ result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
+ zorba::Item segments_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "segments");
+ addNewLineIndentText(result_item, indent+2);
+ segments_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
+
+ size_t nr_geoms = multiline->getNumGeometries();
+ for(size_t i=0;igetGeometryN(i);
+
+ zorba::Item linestring_item;
+ linestring_item = getGMLItemFromGeosGeometry(segments_item, linestring, NULL, indent+4, "LineStringSegment");
+
+ zorba::Item attr_value_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "interpolation");
+ zorba::String strvalue("liniar");
+ attr_value_item = theModule->getItemFactory()->createString(strvalue);
+ theModule->getItemFactory()->createAttributeNode(linestring_item, item_name, item_type, attr_value_item);
+ }
+ if(nr_geoms)
+ addNewLineIndentText(segments_item, indent+2);
+ addNewLineIndentText(result_item, indent);
+ }
+ else
+ {
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "MultiCurve");
+ result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
+
+ size_t nr_geoms = geos_geometry->getNumGeometries();
+ for(size_t i=0;igetGeometryN(i);
+ getGMLItemFromGeosGeometry(result_item, linestring, NULL, indent+2);
+ }
+ if(nr_geoms)
+ addNewLineIndentText(result_item, indent);
+ }
+ break;
+ }
+ /// a collection of polygons
+ case geos::geom::GEOS_MULTIPOLYGON:
+ {
+ const geos::geom::MultiPolygon *multipoly = dynamic_cast(geos_geometry);
+ if(!dont_check_for_curve_surface && isSurface(multipoly))
+ {
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "Surface");
+ result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
+ zorba::Item patches_item;
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "patches");
+ addNewLineIndentText(result_item, indent+2);
+ patches_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
+
+ size_t nr_geoms = multipoly->getNumGeometries();
+ for(size_t i=0;igetGeometryN(i);
+
+ zorba::Item polygon_item;
+ polygon_item = getGMLItemFromGeosGeometry(patches_item, polygon, NULL, indent+4, "PolygonPatch");
+ }
+ if(nr_geoms)
+ addNewLineIndentText(patches_item, indent+2);
+ addNewLineIndentText(result_item, indent);
+ }
+ else
+ {
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "MultiSurface");
+ result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
+
+ size_t nr_geoms = geos_geometry->getNumGeometries();
+ for(size_t i=0;igetGeometryN(i);
+ getGMLItemFromGeosGeometry(result_item, polygon, NULL, indent+2);
+ }
+ if(nr_geoms)
+ addNewLineIndentText(result_item, indent);
+ }
+ break;
+ }
+ /// a collection of heterogeneus geometries
+ case geos::geom::GEOS_GEOMETRYCOLLECTION:
+ {
+ size_t nr_geoms = geos_geometry->getNumGeometries();
+ if(!nr_geoms)
+ break;
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "MultiGeometry");
+ result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
+
+ for(size_t i=0;igetItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "geometryMember");
+ addNewLineIndentText(result_item, indent+2);
+ geometryMember_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
+ const geos::geom::Geometry *member;
+ member = geos_geometry->getGeometryN(i);
+
+ zorba::Item geometry_item;
+ geometry_item = getGMLItemFromGeosGeometry(geometryMember_item, member, NULL, indent+4 );
+ if(!geometry_item.isNull())
+ addNewLineIndentText(geometryMember_item, indent+2);
+ }
+ if(nr_geoms)
+ addNewLineIndentText(result_item, indent);
+ break;
+ }
+ default:
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Geometry type " << geos_geometry->getGeometryType() << " is not supported";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ }
+
+ if(!result_item.isNull() && srs_uri && !srs_uri->isNull())
+ {
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("", "srsName");
+ zorba::String strvalue = srs_uri->getStringValue();
+ zorba::Item attr_value_item = theModule->getItemFactory()->createString(strvalue);
+ theModule->getItemFactory()->createAttributeNode(result_item, item_name, item_type, attr_value_item);
+ }
+
+// if(!parent.isNull())
+// addNewLineIndentText(parent, indent);
+ return result_item;
+}
+
+/*see if the end point from one segment is the start point for the next segment*/
+bool GeoFunction::isCurve(const geos::geom::MultiLineString *multiline) const
+{
+ geos::geom::MultiLineString::const_iterator line_it;
+ std::auto_ptr end_point;
+ for(line_it = multiline->begin(); line_it != multiline->end(); line_it++)
+ {
+ const geos::geom::LineString *linestring = dynamic_cast(*line_it);
+ if(end_point.get())
+ {
+ std::auto_ptr start_point;
+ start_point.reset(linestring->getStartPoint());
+ if(start_point->compareTo(end_point.get()))
+ return false;
+ }
+ end_point.reset(linestring->getEndPoint());
+ }
+ return true;
+}
+
+bool GeoFunction::isClosedCurve(const geos::geom::Geometry *geos_geometry) const
+{
+ //Curve is a MultiLineString
+ const geos::geom::MultiLineString *curve = dynamic_cast(geos_geometry);
+ unsigned int num_segments = (unsigned int)curve->getNumGeometries();
+ if(!num_segments)
+ return false;
+ unsigned int i;
+ //see if last point of a segment is the first of the next
+ const geos::geom::LineString *segment1 = dynamic_cast(curve->getGeometryN(0));
+ std::auto_ptr coords1(segment1->getCoordinates());
+ const geos::geom::LineString *segment2;
+ std::auto_ptr coords2;
+ for(i=1;i(curve->getGeometryN(i));
+ coords2.reset(segment2->getCoordinates());
+ if(coords1->getAt(coords1->size()-1) != coords2->getAt(0))
+ return false;
+ coords1 = coords2;
+ segment1 = segment2;
+ }
+ //check if last point is the same as the first point of the curve
+ segment2 = dynamic_cast(curve->getGeometryN(0));
+ coords2.reset(segment2->getCoordinates());
+ if(coords1->getAt(coords1->size()-1) != coords2->getAt(0))
+ return false;
+
+ return true;
+}
+
+geos::geom::LineString *GeoFunction::curveToLineString(const geos::geom::Geometry *geos_geometry) const
+{
+ const geos::geom::MultiLineString *curve = dynamic_cast(geos_geometry);
+ if(!isCurve(curve))
+ return NULL;
+ unsigned int num_segments = (unsigned int)curve->getNumGeometries();
+ if(!num_segments)
+ return NULL;
+ const geos::geom::LineString *segment;
+ std::auto_ptr coords;
+ geos::geom::CoordinateSequence *linestring_coords = geos::geom::CoordinateArraySequenceFactory::instance()->create((std::size_t)0, 2);
+ unsigned int i;
+ for(i=0;i(curve->getGeometryN(i));
+ coords.reset(segment->getCoordinates());
+ linestring_coords->add(coords.get(), true, true);
+ }
+ geos::geom::LineString *linestring = get_geometryFactory()->createLineString(linestring_coords);
+ linestring->setUserData((void*)GMLSF_LINESTRING);
+
+ return linestring;
+}
+
+bool GeoFunction::isRingCurve(const geos::geom::Geometry *geos_geometry) const
+{
+ geos::geom::LineString *linestring;
+ linestring = curveToLineString(geos_geometry);
+ if(!linestring)
+ return false;
+ //use GEOS
+ bool retval;
+ retval = linestring->isRing();
+ delete linestring;
+
+ return retval;
+}
+
+bool GeoFunction::isSimpleCurve(const geos::geom::Geometry *geos_geometry) const
+{
+ geos::geom::LineString *linestring;
+ linestring = curveToLineString(geos_geometry);
+ if(!linestring)
+ return false;
+ //use GEOS
+ bool retval;
+ retval = linestring->isSimple();
+ delete linestring;
+
+ return retval;
+}
+
+/*see if each polygon touches another polygon by at least a segment of external line and they are all connected together*/
+bool GeoFunction::isSurface(const geos::geom::MultiPolygon *multipolygon,
+ bool *is_closed,
+ geos::geom::LinearRing **exterior_boundary) const
+{
+/*
+ struct _tline
+ {
+ double x1, y1, x2, y2;
+ //bool taken;
+ };
+ struct _tpoly
+ {
+ std::vector lines;
+ bool processed, touched;
+ };
+ std::vector polys;
+ int p = 0;
+ //init the data
+ if(!multipolygon->getNumGeometries())
+ return false;
+ polys.reserve(multipolygon->getNumGeometries());
+ geos::geom::MultiPolygon::const_iterator poly_it;
+ for(poly_it = multipolygon->begin(); poly_it != multipolygon->end(); poly_it++, p++)
+ {
+ polys[p].processed = false;
+ polys[p].touched = false;
+ const geos::geom::Polygon *polygon = dynamic_cast(*poly_it);
+ const geos::geom::LineString* exterior_ring;
+ int l, nr_points;
+ const geos::geom::Point *point;
+ exterior_ring = polygon->getExteriorRing();
+ nr_points = exterior_ring->getNumPoints();
+ polys[p].lines.reserve(nr_points);
+ for(l=0; l(exterior_ring->getGeometryN(l));
+ //polys[p].lines[l].taken = false;
+ polys[p].lines[l].x1 = point->getX();
+ polys[p].lines[l].y1 = point->getY();
+ if(l)
+ {
+ polys[p].lines[l-1].x2 = point->getX();
+ polys[p].lines[l-1].y2 = point->getY();
+ }
+ else
+ {
+ polys[p].lines[nr_points-1].x2 = point->getX();
+ polys[p].lines[nr_points-1].y2 = point->getY();
+ }
+ }
+ }
+
+ //now check
+ std::vector::iterator tpoly_it;
+ bool first_round = true;
+ while(1)
+ {
+ if(first_round)
+ tpoly_it = polys.begin();
+ else
+ {
+ int total = 0;
+ int processed = 0;
+ for(tpoly_it = polys.begin(); tpoly_it != polys.end(); tpoly_it++)
+ {
+ total++;
+ if((*tpoly_it).processed)
+ processed++;
+ else if((*tpoly_it).touched)
+ break;
+ }
+ if(tpoly_it == polys.end())
+ {
+ if(total == processed)
+ return true;
+ else
+ return false;
+ }
+ }
+ first_round = false;
+ (*tpoly_it).processed = true;
+ //for every line, check there is at most one match with other line from other polygon
+ std::vector::iterator line_it;
+ int all_matches = 0;
+ for(line_it = (*tpoly_it).lines.begin(); line_it != (*tpoly_it).lines.end(); line_it++)
+ {
+ int matches = 0;
+ std::vector::iterator tpoly_it2;
+ for(tpoly_it2 = polys.begin(); tpoly_it2 != polys.end(); tpoly_it2++)
+ {
+ if((*tpoly_it2).processed)
+ continue;
+ std::vector::iterator line_it2;
+ for(line_it2 = (*tpoly_it2).lines.begin(); line_it2 != (*tpoly_it2).lines.end(); line_it2++)
+ {
+ if(((*line_it2).x1 == (*line_it).x1) && ((*line_it2).y1 == (*line_it).y1) &&
+ ((*line_it2).x2 == (*line_it).x2) && ((*line_it2).y2 == (*line_it).y2) ||
+ ((*line_it2).x1 == (*line_it).x2) && ((*line_it2).y1 == (*line_it).y2) &&
+ ((*line_it2).x2 == (*line_it).x1) && ((*line_it2).y2 == (*line_it).y1))
+ {
+ (*tpoly_it2).touched = true;
+ matches++;
+ }
+ }
+ }
+ if(matches > 1)
+ return false;
+ all_matches += matches;
+ }
+ if(!all_matches)
+ return false;
+ }
+ return true;
+*/
+
+ //another approach, using LineString::overlaps and LineString::intersection
+ //test each polygon if it touches another polygon and if they form a united surface
+ //all common boundaries should be disjoint
+
+ std::vector ids;
+ unsigned int i;
+ unsigned int nr_patches = (unsigned int)multipolygon->getNumGeometries();
+ if(!nr_patches)
+ return false;
+ ids.resize(nr_patches);
+ for(i=0;i boundary_segments;//for computing exterior_boundary
+ bool is_united;
+
+ ids[0] = -1;
+ while(1)
+ {
+ is_united = true;
+ for(i=0;i 0)
+ is_united = false;
+ else if(ids[i] < 0)
+ break;
+ if(i == nr_patches)
+ break;
+ ids[i] = 0;
+ std::vector common_segments;
+ const geos::geom::Polygon *patch1 = dynamic_cast(multipolygon->getGeometryN(i));
+ const geos::geom::LineString *ring1 = patch1->getExteriorRing();
+
+ for(unsigned int j=0;(j(multipolygon->getGeometryN(j));
+ const geos::geom::LineString *ring2 = patch2->getExteriorRing();
+ geos::geom::Geometry* segment;
+ segment = ring1->intersection(ring2);
+ if(segment)
+ {
+ for(unsigned int s=0;sgetNumGeometries();s++)
+ {
+ const geos::geom::Geometry *seg_piece = segment->getGeometryN(s);
+
+ if((seg_piece->getGeometryTypeId() == geos::geom::GEOS_LINESTRING) ||
+ (seg_piece->getGeometryTypeId() == geos::geom::GEOS_MULTILINESTRING))
+ {
+ if(ids[j] > 0)
+ ids[j] = -1;
+ for(unsigned int k=0;koverlaps(common_segments[k]))
+ {
+ delete segment;
+ for(unsigned int c=0;cclone());
+ }
+ }
+ delete segment;
+ }//end if(segment)
+ }
+ if((is_closed && *is_closed) || exterior_boundary)
+ {
+ if(!common_segments.size())
+ {
+ if(is_closed)
+ *is_closed = false;
+ }
+ else
+ {
+ geos::geom::Geometry *segment_union;
+ geos::geom::Geometry *temp_union;
+ segment_union = common_segments[0]->clone();
+ for(unsigned int c=1;cUnion(common_segments[c]);
+ delete segment_union;
+ segment_union = temp_union;
+ }
+ if(segment_union != ring1)
+ {
+ if(is_closed)
+ *is_closed = false;
+ if(exterior_boundary)
+ {
+ geos::geom::Geometry *diff;
+ diff = ring1->difference(segment_union);
+ boundary_segments.push_back(diff);
+ }
+ }
+ delete segment_union;
+ }
+ }
+ for(unsigned int c=0;c points;
+ geos::geom::CoordinateSequence *cl = NULL;
+
+ std::vector segments;
+ size_t nr_segments = 0;
+ for(unsigned int b=0;bgetNumGeometries();
+ }
+ //points.reserve(nr_segments*4);
+ segments.reserve(nr_segments);
+ for(unsigned int b=0;bgetNumGeometries();s++)
+ {
+ const geos::geom::Geometry* part = segm->getGeometryN(s);
+ if(part->getGeometryTypeId() == geos::geom::GEOS_LINESTRING)
+ {
+ segments.push_back(dynamic_cast(part));
+ }
+ }
+ }
+ const geos::geom::Geometry* part = segments[0];
+ if(!cl)
+ {
+ int srs_dim;
+#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
+ srs_dim = part->getCoordinateDimension();
+#else
+ srs_dim = getCoordinateDimension(part);
+#endif
+ cl = geos::geom::CoordinateArraySequenceFactory::instance()->create((std::size_t)0, srs_dim);
+ }
+ std::auto_ptr coords(part->getCoordinates());
+ cl->add(coords.get(), false, true);
+
+ segments[0] = NULL;
+ while(1)
+ {
+ const geos::geom::Coordinate &last_point = cl->getAt(cl->size()-1);
+ bool added_points = false;
+ for(unsigned int s=1;s coords(segmn->getCoordinates());
+ geos::geom::Coordinate point = coords->getAt(0);
+ if(last_point == point)
+ {
+ cl->add(coords.get(), false, true);
+ segments[s] = NULL;
+ added_points = true;
+ break;
+ }
+ else
+ {
+ point = coords->getAt(coords->size()-1);
+ if(last_point == point)
+ {
+ cl->add(coords.get(), false, false);
+ segments[s] = NULL;
+ added_points = true;
+ break;
+ }
+ }
+ }
+ if(!added_points)
+ break;
+ }
+ cl->add(cl->getAt(0), false);
+ *exterior_boundary = get_geometryFactory()->createLinearRing(cl);
+ (*exterior_boundary)->setUserData((void*)GMLSF_LINEARRING);
+ for(unsigned int b=0;b geos_geometry(buildGeosGeometryFromItem(lItem, geometric_type, -1));
+
+ geos::geom::Dimension::DimensionType dim_type = geos::geom::Dimension::DONTCARE;
+ try{
+ dim_type = geos_geometry->getDimension();
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function getDimension : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createInteger((int)dim_type)));
+}
+
+///////////////////////////////////////////////////////////////////////
+ItemSequence_t
+SFCoordinateDimensionFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"< geos_geometry(buildGeosGeometryFromItem(lItem, geometric_type, -1));
+
+#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
+ int coord_dim = geos_geometry->getCoordinateDimension();
+#else
+ int coord_dim = getCoordinateDimension(geos_geometry.get());
+#endif
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createInteger(coord_dim)));
+}
+
+///////////////////////////////////////////////////////////////////////
+ItemSequence_t
+SFGeometryTypeFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ zorba::String type_string;
+ switch(geometric_type)
+ {
+ case GMLSF_POINT:
+ type_string = "Point";break;
+ case GMLSF_LINESTRING:
+ type_string = "LineString";break;
+ case GMLSF_CURVE:
+ type_string = "Curve";break;
+ case GMLSF_LINEARRING:
+ type_string = "LineString";break;
+ case GMLSF_SURFACE:
+ type_string = "Surface";break;
+ case GMLSF_POLYGON:
+ //case GMLSF_POLYGONPATCH:
+ type_string = "Polygon";break;
+ case GMLSF_MULTIPOINT:
+ type_string = "MultiPoint";break;
+ case GMLSF_MULTICURVE:
+ type_string = "MultiCurve";break;
+ case GMLSF_MULTISURFACE:
+ type_string = "MultiSurface";break;
+ case GMLSF_MULTIGEOMETRY:
+ type_string = "MultiGeometry";break;
+
+ case GMLSF_INVALID:
+ default:
+ /* {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"<getItemFactory()->createQName(gmlns, gmlprefix, type_string)));
+ }
+ else
+ {
+ return ItemSequence_t(NULL);//new EmptySequence());
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+ItemSequence_t
+SFNumGeometriesFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_POINT:
+ case GMLSF_LINESTRING:
+ //case GMLSF_CURVE:
+ case GMLSF_LINEARRING:
+ //case GMLSF_SURFACE:
+ case GMLSF_POLYGON:
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createUnsignedInt(1)));
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"<getItemFactory()->createUnsignedInt(num_geos)));
+}
+
+ItemSequence_t
+SFGeometryNFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem1;
+ gmlsf_types geometric_type1;
+ geometric_type1 = getGeometryNodeType(args, 0, lItem1);
+
+ switch(geometric_type1)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname1;
+ lItem1.getNodeName(item_qname1);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname1.getPrefix() <<":"<getIterator();
+ arg1_iter->open();
+ if (!arg1_iter->next(lItem2))
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "An empty-sequence is not allowed as second parameter";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ arg1_iter->close();
+
+ uint32_t n;
+ n = lItem2.getUnsignedIntValue();
+
+ switch(geometric_type1)
+ {
+ case GMLSF_POINT:
+ case GMLSF_LINESTRING:
+ //case GMLSF_CURVE:
+ case GMLSF_LINEARRING:
+ //case GMLSF_SURFACE:
+ case GMLSF_POLYGON:
+ if(n == 0)
+ return ItemSequence_t(new SingletonItemSequence(lItem1));
+ else
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Index n (" << n << ") is outside the range ";
+ throwError("IndexOutsideRange", lErrorMessage.str());
+ }
+ break;
+ default:break;
+ }
+
+ Item nth_child;
+ buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_CHILD, &n, &nth_child);
+
+ if(nth_child.isNull())
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Index n (" << n << ") is outside the range ";
+ throwError("IndexOutsideRange", lErrorMessage.str());
+ }
+ return ItemSequence_t(new SingletonItemSequence(nth_child));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////
+#define DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_GEOMETRY(sfclass_name, geos_function_name) \
+ItemSequence_t \
+sfclass_name::evaluate(const ExternalFunction::Arguments_t& args, \
+ const StaticContext* aSctxCtx, \
+ const DynamicContext* aDynCtx) const \
+{ \
+ Item lItem; \
+ gmlsf_types geometric_type; \
+ geometric_type = getGeometryNodeType(args, 0, lItem); \
+ \
+ switch(geometric_type) \
+ { \
+ case GMLSF_INVALID: \
+ { \
+ std::stringstream lErrorMessage; \
+ zorba::Item item_qname; \
+ lItem.getNodeName(item_qname); \
+ lErrorMessage << "Unrecognized geometric type for element " \
+ << item_qname.getPrefix() <<":"< geos_geometry(buildGeosGeometryFromItem(lItem, geometric_type, -1, &srs_uri)); \
+ \
+ std::auto_ptr geos_result; \
+ try{ \
+ geos_result.reset(geos_geometry->geos_function_name()); \
+ }catch(std::exception &excep) \
+ { \
+ std::stringstream lErrorMessage; \
+ lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what(); \
+ throwError("GEOSError", lErrorMessage.str()); \
+ } \
+ \
+ zorba::Item null_parent; \
+ zorba::Item result_item; \
+ result_item = getGMLItemFromGeosGeometry(null_parent, geos_result.get(), &srs_uri); \
+ \
+ RETURN_RESULT_ITEM; \
+}
+
+//DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_GEOMETRY(SFBoundaryFunction, getBoundary)
+DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_GEOMETRY(SFConvexHullFunction, convexHull)
+DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_GEOMETRY(SFCentroidFunction, getCentroid)
+DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_GEOMETRY(SFPointOnSurfaceFunction, getInteriorPoint)
+
+zorba::Item GeoFunction::getBoundary(geos::geom::Geometry *geos_geometry, zorba::Item srs_uri) const
+{
+ std::auto_ptr geos_result;
+ if(geos_geometry->getUserData() == (void*)GMLSF_SURFACE)
+ {
+ geos::geom::LinearRing *exterior_ring;
+ geos::geom::MultiPolygon* surface = dynamic_cast(geos_geometry);
+ if(!isSurface(surface, NULL, &exterior_ring))
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in Surface : the patches do not form a polyhedral surface";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ std::vector *rings = new std::vector;
+ rings->push_back(exterior_ring);
+ for(unsigned int i=0;igetNumGeometries();i++)
+ {
+ const geos::geom::Polygon* polygon = dynamic_cast(geos_geometry->getGeometryN(i));
+ for(unsigned int r=0;rgetNumInteriorRing();r++)
+ {
+ rings->push_back((geos::geom::LineString*)polygon->getInteriorRingN(r));
+ }
+ }
+ geos_result.reset(get_geometryFactory()->createMultiLineString(rings));
+ }
+ /*else if(geometric_type == GMLSF_CURVE)
+ {
+ geos::geom::LineString *linestring = curveToLineString(geos_geometry);
+ try{
+ geos_result = linestring->getBoundary();
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function getBoundary : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ delete linestring;
+ }
+ */
+ else
+ {
+ try{
+ geos_result.reset(geos_geometry->getBoundary());
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function getBoundary : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+
+ zorba::Item null_parent;
+ zorba::Item result_item;
+ result_item = getGMLItemFromGeosGeometry(null_parent, geos_result.get(), &srs_uri, 0, NULL, DONT_CHECK_FOR_CURVE_SURFACE);
+ return result_item;
+}
+
+void GeoFunction::getMultiGeometryBoundary(geos::geom::Geometry *geos_geometry,
+ std::vector *boundaries,
+ zorba::Item srs_uri) const
+{
+ for(unsigned int i=0;igetNumGeometries();i++)
+ {
+ geos::geom::Geometry *geom = (geos::geom::Geometry *)geos_geometry->getGeometryN(i);
+ if(geom->getGeometryTypeId() == geos::geom::GEOS_GEOMETRYCOLLECTION)
+ getMultiGeometryBoundary(geom, boundaries, srs_uri);
+ else
+ {
+ zorba::Item boundary;
+ boundary = getBoundary(geom, srs_uri);
+ if(!boundary.isNull())
+ boundaries->push_back(boundary);
+ }
+ }
+}
+
+ItemSequence_t
+SFBoundaryFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"< geos_geometry;
+ zorba::Item srs_uri;
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1, &srs_uri));
+
+ if(geometric_type != GMLSF_MULTIGEOMETRY)
+ {
+ zorba::Item result_item;
+ result_item = getBoundary(geos_geometry.get(), srs_uri);
+ RETURN_RESULT_ITEM;
+ }
+ else
+ {
+ std::vector boundaries;
+ getMultiGeometryBoundary(geos_geometry.get(), &boundaries, srs_uri);
+ return ItemSequence_t(new VectorItemSequence(boundaries));
+ }
+
+}
+
+///////////////////////////////////////////////////////////////////////
+ItemSequence_t
+SFSridFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"< geos_geometry;
+ zorba::Item srs_uri;
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1, &srs_uri));
+
+ if(!srs_uri.isNull())
+ return ItemSequence_t(new SingletonItemSequence(srs_uri));
+ else
+ return ItemSequence_t(NULL);
+}
+
+///////////////////////////////////////////////////////////////////////
+ItemSequence_t
+SFEnvelopeFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"< geos_geometry;
+ zorba::Item srs_uri;
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1, &srs_uri));
+
+ const geos::geom::Envelope *envelope = NULL;
+ try{
+ envelope = geos_geometry->getEnvelopeInternal();
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function getEnvelopeInternal : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+
+
+ zorba::Item envelope_item;
+ zorba::Item corner_item;
+ zorba::Item item_name;
+ zorba::Item item_type;
+ zorba::Item null_parent;
+ zorba::NsBindings ns_binding;
+ char strtemp[100];
+ ns_binding.push_back(std::pair("gml", "http://www.opengis.net/gml"));
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "Envelope");
+ envelope_item = theModule->getItemFactory()->createElementNode(null_parent, item_name, item_type, false, false, ns_binding);
+
+ if(!srs_uri.isNull())
+ {
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("", "srsName");
+ zorba::String strvalue = srs_uri.getStringValue();
+ zorba::Item attr_value_item = theModule->getItemFactory()->createString(strvalue);
+ theModule->getItemFactory()->createAttributeNode(envelope_item, item_name, item_type, attr_value_item);
+ }
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "lowerCorner");
+ addNewLineIndentText(envelope_item, 2);
+ corner_item = theModule->getItemFactory()->createElementNode(envelope_item, item_name, item_type, false, false, ns_binding);
+
+ sprintf(strtemp, "%lf %lf", envelope->getMinX(), envelope->getMinY());
+ theModule->getItemFactory()->createTextNode(corner_item, strtemp);
+
+ item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
+ item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "upperCorner");
+ addNewLineIndentText(envelope_item, 2);
+ corner_item = theModule->getItemFactory()->createElementNode(envelope_item, item_name, item_type, false, false, ns_binding);
+
+ sprintf(strtemp, "%lf %lf", envelope->getMaxX(), envelope->getMaxY());
+ theModule->getItemFactory()->createTextNode(corner_item, strtemp);
+ addNewLineIndentText(envelope_item, 0);
+
+ return ItemSequence_t(new SingletonItemSequence(envelope_item));
+}
+
+///////////////////////////////////////////////////////////////////////
+ItemSequence_t
+SFAsTextFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"< geos_geometry;
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
+
+ std::string as_text;
+ as_text = geos_geometry->toString();
+
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createString(as_text)));
+}
+
+unsigned char GeoFunction::hex_to_bin(char hex) const
+{
+ if((hex >= '0') && (hex <= '9'))
+ return hex-'0';
+ else if((hex >= 'a') && (hex <= 'f'))
+ return hex-'a'+10;
+ else if((hex >= 'A') && (hex <= 'F'))
+ return hex-'A'+10;
+ else
+ return 0;
+}
+///////////////////////////////////////////////////////////////////////
+ItemSequence_t
+SFAsBinaryFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"< geos_geometry;
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
+
+ std::ostringstream as_binary;
+ as_binary << *geos_geometry;
+
+ std::string binary_hex = as_binary.str();
+ size_t binary_len = binary_hex.size() / 2;
+ const char *hex_str = binary_hex.c_str();
+ unsigned char *binary_bin = new unsigned char[binary_len];
+ for(size_t i=0;igetItemFactory()->createBase64Binary(
+ reinterpret_cast(binary_bin), binary_len, false
+ )
+ );
+ delete[] binary_bin;
+
+ return ItemSequence_t(new SingletonItemSequence(base64_item));
+}
+
+///////////////////////////////////////////////////////////////////////
+ItemSequence_t
+SFIsEmptyFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ Iterator_t arg0_iter = args[0]->getIterator();
+ arg0_iter->open();
+ if (!arg0_iter->next(lItem))
+ {
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createBoolean(true)));
+ }
+ arg0_iter->close();
+
+ if(!lItem.isNode() || (lItem.getNodeKind() != store::StoreConsts::elementNode))
+ {
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createBoolean(true)));
+ }
+
+ GeoFunction::gmlsf_types geotype = getGmlSFGeometricType(lItem);
+ if(geotype == GMLSF_INVALID)
+ {
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createBoolean(true)));
+ }
+
+ std::auto_ptr geos_geometry;
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geotype, -1));
+
+ bool is_empty = false;
+ try{
+ is_empty = (geos_geometry->getNumPoints() == 0);
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function getNumGeometries : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createBoolean(is_empty)));
+}
+
+///////////////////////////////////////////////////////////////////////
+ItemSequence_t
+SFIsSimpleFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"< geos_geometry;
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
+
+ bool is_simple = false;
+ if(geometric_type == GMLSF_CURVE)
+ {
+ is_simple = isSimpleCurve(geos_geometry.get());
+ }
+ else
+ {
+ try{
+ is_simple = geos_geometry->isSimple();
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function isSimple : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createBoolean(is_simple)));
+}
+
+///////////////////////////////////////////////////////////////////////
+ItemSequence_t
+SFIs3DFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"< geos_geometry;
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
+
+#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
+ bool is_3D = (geos_geometry->getCoordinateDimension() == 3);
+#else
+ bool is_3D = (getCoordinateDimension(geos_geometry.get()) == 3);//for GEOS 3.2.2
+#endif
+
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createBoolean(is_3D)));
+}
+
+///////////////////////////////////////////////////////////////////////
+ItemSequence_t
+SFIsMeasuredFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"<getItemFactory()->createBoolean(false)));
+}
+
+///////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////
+#define DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(sfclass_name, geos_function_name) \
+ItemSequence_t \
+sfclass_name::evaluate(const ExternalFunction::Arguments_t& args, \
+ const StaticContext* aSctxCtx, \
+ const DynamicContext* aDynCtx) const \
+{ \
+ Item lItem1; \
+ gmlsf_types geometric_type1; \
+ geometric_type1 = getGeometryNodeType(args, 0, lItem1); \
+ \
+ switch(geometric_type1) \
+ { \
+ case GMLSF_INVALID: \
+ { \
+ std::stringstream lErrorMessage; \
+ zorba::Item item_qname1; \
+ lItem1.getNodeName(item_qname1); \
+ lErrorMessage << "Unrecognized geometric type for element " \
+ << item_qname1.getPrefix() <<":"< geos_geometry1; \
+ zorba::Item srs_uri1; \
+ geos_geometry1.reset(buildGeosGeometryFromItem(lItem1, geometric_type1, -1, &srs_uri1)); \
+ \
+ std::auto_ptr geos_geometry2; \
+ zorba::Item srs_uri2; \
+ geos_geometry2.reset(buildGeosGeometryFromItem(lItem2, geometric_type2, -1, &srs_uri2)); \
+ \
+ if(!srs_uri1.isNull() && !srs_uri2.isNull() && \
+ srs_uri1.getStringValue() != srs_uri2.getStringValue()) \
+ { \
+ std::stringstream lErrorMessage; \
+ lErrorMessage << "SrsName is not the same in the two geometries: " << \
+ srs_uri1.getStringValue() << " vs. " << srs_uri2.getStringValue(); \
+ throwError("SRSNotIdenticalInBothGeometries", lErrorMessage.str()); \
+ } \
+ \
+ bool retval = false; \
+ try{ \
+ retval = geos_geometry1->geos_function_name(geos_geometry2.get()); \
+ }catch(std::exception &excep) \
+ { \
+ std::stringstream lErrorMessage; \
+ lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what(); \
+ throwError("GEOSError", lErrorMessage.str()); \
+ } \
+ \
+ \
+ return ItemSequence_t(new SingletonItemSequence( \
+ theModule->getItemFactory()->createBoolean(retval))); \
+}
+
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFEqualsFunction, equals)
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFCoversFunction, covers)
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFDisjointFunction, disjoint)
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFIntersectsFunction, intersects)
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFTouchesFunction, touches)
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFCrossesFunction, crosses)
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFWithinFunction, within)
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFContainsFunction, contains)
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFOverlapsFunction, overlaps)
+
+///////////////////////////////////////////////////////////////////////
+#define DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_GEOMETRY(sfclass_name, geos_function_name) \
+ItemSequence_t \
+sfclass_name::evaluate(const ExternalFunction::Arguments_t& args, \
+ const StaticContext* aSctxCtx, \
+ const DynamicContext* aDynCtx) const \
+{ \
+ Item lItem1; \
+ gmlsf_types geometric_type1; \
+ geometric_type1 = getGeometryNodeType(args, 0, lItem1); \
+ \
+ switch(geometric_type1) \
+ { \
+ case GMLSF_INVALID: \
+ { \
+ std::stringstream lErrorMessage; \
+ zorba::Item item_qname1; \
+ lItem1.getNodeName(item_qname1); \
+ lErrorMessage << "Unrecognized geometric type for element " \
+ << item_qname1.getPrefix() <<":"< geos_geometry1; \
+ zorba::Item srs_uri1; \
+ geos_geometry1.reset(buildGeosGeometryFromItem(lItem1, geometric_type1, -1, &srs_uri1)); \
+ \
+ std::auto_ptr geos_geometry2; \
+ zorba::Item srs_uri2; \
+ geos_geometry2.reset(buildGeosGeometryFromItem(lItem2, geometric_type2, -1, &srs_uri2)); \
+ \
+ if(!srs_uri1.isNull() && !srs_uri2.isNull() && \
+ srs_uri1.getStringValue() == srs_uri2.getStringValue()) \
+ { \
+ std::stringstream lErrorMessage; \
+ lErrorMessage << "SrsName is not the same in the two geometries: " << \
+ srs_uri1.getStringValue() << " vs. " << srs_uri2.getStringValue(); \
+ throwError("SRSNotIdenticalInBothGeometries", lErrorMessage.str()); \
+ } \
+ \
+ std::auto_ptr geos_result; \
+ try{ \
+ geos_result.reset(geos_geometry1->geos_function_name(geos_geometry2.get())); \
+ }catch(std::exception &excep) \
+ { \
+ std::stringstream lErrorMessage; \
+ lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what(); \
+ throwError("GEOSError", lErrorMessage.str()); \
+ } \
+ \
+ \
+ if(srs_uri1.isNull()) \
+ srs_uri1 = srs_uri2; \
+ zorba::Item null_parent; \
+ zorba::Item result_item; \
+ result_item = getGMLItemFromGeosGeometry(null_parent, geos_result.get(), &srs_uri1); \
+ \
+ RETURN_RESULT_ITEM; \
+}
+
+
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_GEOMETRY(SFIntersectionFunction, intersection)
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_GEOMETRY(SFUnionFunction, Union)
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_GEOMETRY(SFDifferenceFunction, difference)
+DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_GEOMETRY(SFSymDifferenceFunction, symDifference)
+
+
+///////////////////////////////////////////////////////////////////////
+#define DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_DOUBLE(sfclass_name, geos_function_name) \
+ItemSequence_t \
+sfclass_name::evaluate(const ExternalFunction::Arguments_t& args, \
+ const StaticContext* aSctxCtx, \
+ const DynamicContext* aDynCtx) const \
+{ \
+ Item lItem; \
+ gmlsf_types geometric_type; \
+ geometric_type = getGeometryNodeType(args, 0, lItem); \
+ \
+ switch(geometric_type) \
+ { \
+ case GMLSF_INVALID: \
+ { \
+ std::stringstream lErrorMessage; \
+ zorba::Item item_qname; \
+ lItem.getNodeName(item_qname); \
+ lErrorMessage << "Unrecognized geometric type for element " \
+ << item_qname.getPrefix() <<":"< geos_geometry; \
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1)); \
+ \
+ double retval = 0; \
+ try{ \
+ retval = geos_geometry->geos_function_name(); \
+ }catch(std::exception &excep) \
+ { \
+ std::stringstream lErrorMessage; \
+ lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what(); \
+ throwError("GEOSError", lErrorMessage.str()); \
+ } \
+ \
+ return ItemSequence_t(new SingletonItemSequence( \
+ theModule->getItemFactory()->createDouble(retval))); \
+}
+
+DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_DOUBLE(SFAreaFunction, getArea)
+DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_DOUBLE(SFLengthFunction, getLength)
+
+ItemSequence_t
+SFRelateFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem1;
+ gmlsf_types geometric_type1;
+ geometric_type1 = getGeometryNodeType(args, 0, lItem1);
+
+ switch(geometric_type1)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname1;
+ lItem1.getNodeName(item_qname1);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname1.getPrefix() <<":"< geos_geometry1;
+ zorba::Item srs_uri1;
+ geos_geometry1.reset(buildGeosGeometryFromItem(lItem1, geometric_type1, -1, &srs_uri1));
+
+ std::auto_ptr geos_geometry2;
+ zorba::Item srs_uri2;
+ geos_geometry2.reset(buildGeosGeometryFromItem(lItem2, geometric_type2, -1, &srs_uri2));
+
+ if(!srs_uri1.isNull() && !srs_uri2.isNull() &&
+ srs_uri1.getStringValue()== srs_uri2.getStringValue())
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "SrsName is not the same in the two geometries: " <<
+ srs_uri1.getStringValue() << " vs. " << srs_uri2.getStringValue();
+ throwError("SRSNotIdenticalInBothGeometries", lErrorMessage.str());
+ }
+
+
+ Item lItem3;
+ Iterator_t arg2_iter = args[2]->getIterator();
+ arg2_iter->open();
+ if (!arg2_iter->next(lItem3))
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "An empty-sequence is not allowed as parameter";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ arg2_iter->close();
+
+ zorba::String intersection_matrix;
+ intersection_matrix = lItem3.getStringValue();
+
+ bool is_relate = false;
+ try{
+ is_relate = geos_geometry1->relate(geos_geometry2.get(), intersection_matrix.c_str());
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS relate function: " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createBoolean(is_relate)));
+}
+
+ItemSequence_t
+SFIsWithinDistanceFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem1;
+ gmlsf_types geometric_type1;
+ geometric_type1 = getGeometryNodeType(args, 0, lItem1);
+
+ switch(geometric_type1)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname1;
+ lItem1.getNodeName(item_qname1);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname1.getPrefix() <<":"< geos_geometry1;
+ zorba::Item srs_uri1;
+ geos_geometry1.reset(buildGeosGeometryFromItem(lItem1, geometric_type1, -1, &srs_uri1));
+
+ std::auto_ptr geos_geometry2;
+ zorba::Item srs_uri2;
+ geos_geometry2.reset(buildGeosGeometryFromItem(lItem2, geometric_type2, -1, &srs_uri2));
+
+ if(!srs_uri1.isNull() && !srs_uri2.isNull() &&
+ srs_uri1.getStringValue() == srs_uri2.getStringValue())
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "SrsName is not the same in the two geometries: " <<
+ srs_uri1.getStringValue() << " vs. " << srs_uri2.getStringValue();
+ throwError("SRSNotIdenticalInBothGeometries", lErrorMessage.str());
+ }
+
+ Item lItem3;
+ Iterator_t arg2_iter = args[2]->getIterator();
+ arg2_iter->open();
+ if (!arg2_iter->next(lItem3))
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "An empty-sequence is not allowed as third parameter";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ arg2_iter->close();
+
+ double distance;
+ distance = lItem3.getDoubleValue();
+
+ bool is_within_distance = false;
+ try{
+ is_within_distance = geos_geometry1->isWithinDistance(geos_geometry2.get(), distance);
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function isWithinDistance : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createBoolean(is_within_distance)));
+}
+
+ItemSequence_t
+SFDistanceFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem1;
+ gmlsf_types geometric_type1;
+ geometric_type1 = getGeometryNodeType(args, 0, lItem1);
+
+ switch(geometric_type1)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname1;
+ lItem1.getNodeName(item_qname1);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname1.getPrefix() <<":"< geos_geometry1;
+ zorba::Item srs_uri1;
+ geos_geometry1.reset(buildGeosGeometryFromItem(lItem1, geometric_type1, -1, &srs_uri1));
+
+ std::auto_ptr geos_geometry2;
+ zorba::Item srs_uri2;
+ geos_geometry2.reset(buildGeosGeometryFromItem(lItem2, geometric_type2, -1, &srs_uri2));
+
+ if(!srs_uri1.isNull() && !srs_uri2.isNull() &&
+ srs_uri1.getStringValue() == srs_uri2.getStringValue())
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "SrsName is not the same in the two geometries: " <<
+ srs_uri1.getStringValue() << " vs. " << srs_uri2.getStringValue();
+ throwError("SRSNotIdenticalInBothGeometries", lErrorMessage.str());
+ }
+
+ double min_distance = 0;
+ try{
+ min_distance = geos_geometry1->distance(geos_geometry2.get());
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function distance : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createDouble(min_distance)));
+}
+
+ItemSequence_t
+SFBufferFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem1;
+ gmlsf_types geometric_type1;
+ geometric_type1 = getGeometryNodeType(args, 0, lItem1);
+
+ switch(geometric_type1)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname1;
+ lItem1.getNodeName(item_qname1);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname1.getPrefix() <<":"< geos_geometry1;
+ zorba::Item srs_uri;
+ geos_geometry1.reset(buildGeosGeometryFromItem(lItem1, geometric_type1, -1, &srs_uri));
+
+
+ Item lItem2;
+ Iterator_t arg1_iter = args[1]->getIterator();
+ arg1_iter->open();
+ if (!arg1_iter->next(lItem2))
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "An empty-sequence is not allowed as second parameter";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ arg1_iter->close();
+
+ double distance;
+ distance = lItem2.getDoubleValue();
+
+ std::auto_ptr geos_result;
+ try{
+ geos_result.reset(geos_geometry1->buffer(distance));
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function buffer : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+
+ zorba::Item null_parent;
+ zorba::Item result_item;
+ result_item = getGMLItemFromGeosGeometry(null_parent, geos_result.get(), &srs_uri);
+
+ RETURN_RESULT_ITEM;
+}
+
+///////////////////////////////////////////////////////////////////////
+#define DEFINE_EVALUATE_ONE_POINT_RETURN_DOUBLE(sfclass_name, geos_function_name) \
+ItemSequence_t \
+sfclass_name::evaluate(const ExternalFunction::Arguments_t& args, \
+ const StaticContext* aSctxCtx, \
+ const DynamicContext* aDynCtx) const \
+{ \
+ Item lItem; \
+ gmlsf_types geometric_type; \
+ geometric_type = getGeometryNodeType(args, 0, lItem); \
+ \
+ switch(geometric_type) \
+ { \
+ case GMLSF_INVALID: \
+ { \
+ std::stringstream lErrorMessage; \
+ zorba::Item item_qname; \
+ lItem.getNodeName(item_qname); \
+ lErrorMessage << "Unrecognized geometric type for element " \
+ << item_qname.getPrefix() <<":"< geos_geometry; \
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1)); \
+ geos::geom::Point *geos_point = dynamic_cast(geos_geometry.get()); \
+ \
+ double retval = 0; \
+ try{ \
+ retval = geos_point->geos_function_name(); \
+ }catch(std::exception &excep) \
+ { \
+ std::stringstream lErrorMessage; \
+ lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what(); \
+ throwError("GEOSError", lErrorMessage.str()); \
+ } \
+ \
+ return ItemSequence_t(new SingletonItemSequence( \
+ theModule->getItemFactory()->createDouble(retval))); \
+}
+
+DEFINE_EVALUATE_ONE_POINT_RETURN_DOUBLE(SFXFunction, getX)
+DEFINE_EVALUATE_ONE_POINT_RETURN_DOUBLE(SFYFunction, getY)
+
+ItemSequence_t
+SFZFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"< geos_geometry;
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
+
+ const geos::geom::Coordinate *c;
+ c = geos_geometry->getCoordinate();
+#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
+ if(geos_geometry->getCoordinateDimension() == 3)
+#else
+ if(getCoordinateDimension(geos_geometry.get()) == 3)
+#endif
+ {
+ double z = c->z;
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createDouble(z)));
+ }
+ else
+ {
+ return zorba::ItemSequence_t(NULL);
+ }
+
+}
+
+ItemSequence_t
+SFMFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"< geos_geometry;
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
+
+ bool retval = 0;
+ if(geometric_type == GMLSF_SURFACE)
+ {
+ if(!isSurface(dynamic_cast(geos_geometry.get()), &retval))
+ retval = false;
+ }
+ else if(geometric_type == GMLSF_CURVE)
+ {
+ retval = isClosedCurve(geos_geometry.get());
+ }
+ else
+ {
+ try{
+ if(geometric_type != GMLSF_MULTICURVE)
+ {
+ geos::geom::LineString *geos_line = dynamic_cast(geos_geometry.get());
+ retval = geos_line->isClosed();
+ }
+ else
+ {
+ geos::geom::MultiLineString *geos_multiline = dynamic_cast(geos_geometry.get());
+ retval = geos_multiline->isClosed();
+ }
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function SFIsClosedFunction : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createBoolean(retval)));
+}
+
+ItemSequence_t
+SFIsRingFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"< geos_geometry;
+ geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
+
+ bool retval = 0;
+ if(geometric_type != GMLSF_CURVE)
+ {
+ try{
+ geos::geom::LineString *geos_line = dynamic_cast(geos_geometry.get());
+ retval = geos_line->isClosed();
+ }catch(std::exception &excep)
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Error in GEOS function isClosed : " << excep.what();
+ throwError("GEOSError", lErrorMessage.str());
+ }
+ }
+ else
+ {
+ retval = isRingCurve(geos_geometry.get());
+ }
+ return ItemSequence_t(new SingletonItemSequence(
+ theModule->getItemFactory()->createBoolean(retval)));
+}
+
+ItemSequence_t
+SFNumPointsFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"<getItemFactory()->createUnsignedInt(num_children)));
+}
+
+ItemSequence_t
+SFPointNFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem1;
+ gmlsf_types geometric_type1;
+ geometric_type1 = getGeometryNodeType(args, 0, lItem1);
+
+ switch(geometric_type1)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname1;
+ lItem1.getNodeName(item_qname1);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname1.getPrefix() <<":"<getIterator();
+ arg1_iter->open();
+ if (!arg1_iter->next(lItem2))
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "An empty-sequence is not allowed as second parameter";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ arg1_iter->close();
+
+ uint32_t n;
+ n = lItem2.getUnsignedIntValue();
+
+ Item nth_child;
+ buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_POINT, &n, &nth_child);
+
+ if(nth_child.isNull())
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Index n (" << n << ") is outside the range ";
+ throwError("IndexOutsideRange", lErrorMessage.str());
+ }
+
+ return ItemSequence_t(new SingletonItemSequence(nth_child));
+}
+
+///////////////////////////////////////////////////////////////////////
+ItemSequence_t
+SFExteriorRingFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"<getItemFactory()->createUnsignedInt(num_children)));
+}
+
+ItemSequence_t
+SFInteriorRingNFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem1;
+ gmlsf_types geometric_type1;
+ geometric_type1 = getGeometryNodeType(args, 0, lItem1);
+
+ switch(geometric_type1)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname1;
+ lItem1.getNodeName(item_qname1);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname1.getPrefix() <<":"<getIterator();
+ arg1_iter->open();
+ if (!arg1_iter->next(lItem2))
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "An empty-sequence is not allowed as second parameter";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ arg1_iter->close();
+
+ uint32_t n;
+ n = lItem2.getUnsignedIntValue();
+
+ Item nth_child;
+ buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_CHILD, &n, &nth_child);
+
+ if(nth_child.isNull())
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Index n (" << n << ") is outside the range ";
+ throwError("IndexOutsideRange", lErrorMessage.str());
+ }
+
+ return ItemSequence_t(new SingletonItemSequence(nth_child));
+}
+
+ItemSequence_t
+SFNumPatchesFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem;
+ gmlsf_types geometric_type;
+ geometric_type = getGeometryNodeType(args, 0, lItem);
+
+ switch(geometric_type)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname;
+ lItem.getNodeName(item_qname);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname.getPrefix() <<":"<getItemFactory()->createUnsignedInt(num_children)));
+}
+
+ItemSequence_t
+SFPatchNFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem1;
+ gmlsf_types geometric_type1;
+ geometric_type1 = getGeometryNodeType(args, 0, lItem1);
+
+ switch(geometric_type1)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname1;
+ lItem1.getNodeName(item_qname1);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname1.getPrefix() <<":"<getIterator();
+ arg1_iter->open();
+ if (!arg1_iter->next(lItem2))
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "An empty-sequence is not allowed as second parameter";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+ arg1_iter->close();
+
+ uint32_t n;
+ n = lItem2.getUnsignedIntValue();
+
+ Item nth_child;
+ buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_CHILD, &n, &nth_child);
+
+ if(nth_child.isNull())
+ {
+ std::stringstream lErrorMessage;
+ lErrorMessage << "Index n (" << n << ") is outside the range ";
+ throwError("IndexOutsideRange", lErrorMessage.str());
+ }
+
+ return ItemSequence_t(new SingletonItemSequence(nth_child));
+}
+
+
+ItemSequence_t
+SFBoundingPolygonsFunction::evaluate(const ExternalFunction::Arguments_t& args,
+ const StaticContext* aSctxCtx,
+ const DynamicContext* aDynCtx) const
+{
+ Item lItem1;
+ gmlsf_types geometric_type1;
+ geometric_type1 = getGeometryNodeType(args, 0, lItem1);
+
+ switch(geometric_type1)
+ {
+ case GMLSF_INVALID:
+ {
+ std::stringstream lErrorMessage;
+ zorba::Item item_qname1;
+ lItem1.getNodeName(item_qname1);
+ lErrorMessage << "Unrecognized geometric type for element "
+ << item_qname1.getPrefix() <<":"< result;
+ zorba::Item patches_item;
+ if(!getChild(lItem1, "patches", "http://www.opengis.net/gml", patches_item))
+ {//get upset
+ std::stringstream lErrorMessage;
+ lErrorMessage << "gml:Surface node must have a gml:patches child";
+ throwError("UnrecognizedGeoObject", lErrorMessage.str());
+ }
+
+ Iterator_t patches_children;
+ Item polygon_patch_item;
+
+ patches_children = patches_item.getChildren();
+ patches_children->open();
+ unsigned int patch_nr = 0;
+
+ std::auto_ptr geos_geometry1(buildGeosGeometryFromItem(lItem1, geometric_type1, -1));
+ std::auto_ptr geos_geometry2(buildGeosGeometryFromItem(lItem2, GMLSF_POLYGON, -1));
+
+ const geos::geom::MultiPolygon *surface = dynamic_cast(geos_geometry1.get());
+ const geos::geom::Polygon *polygon = dynamic_cast(geos_geometry2.get());
+ const geos::geom::LineString *exterior_ring = polygon->getExteriorRing();
+ //const geos::geom::CoordinateSequence *coords = exterior_ring->getCoordinates();
+
+
+ unsigned int nr_patches = (unsigned int)surface->getNumGeometries();
+ unsigned int i;
+ for(i=0;i(surface->getGeometryN(i));
+ const geos::geom::LineString *patch_exterior_ring = patch->getExteriorRing();
+ //const geos::geom::CoordinateSequence *patch_coords = patch_exterior_ring->getCoordinates();
+ //see if this patch touches the input polygon
+ bool is_touching = false;
+ /*
+ for(unsigned int j=0;jsize();j++)
+ {
+ for(unsigned int k=0;ksize();k++)
+ {
+ if(coords->getAt(k) == patch_coords->getAt(j))
+ {
+ geos::geom::Coordinate next1;
+ geos::geom::Coordinate next2;
+ if(k == (coords->size()-1))
+ next1 = coords->getAt(0);
+ else
+ next1 = coords->getAt(k+1);
+ if(j == (patch_coords->size()-1))
+ next2 = patch_coords->getAt(0);
+ else
+ next2 = patch_coords->getAt(j+1);
+ if(next1 == next2)
+ {
+ is_touching = true;
+ break;
+ }
+ if(j == 0)
+ next2 = patch_coords->getAt(patch_coords->size()-1);
+ else
+ next2 = patch_coords->getAt(j-1);
+ if(next1 == next2)
+ {
+ is_touching = true;
+ break;
+ }
+ }
+ }
+ if(is_touching)
+ break;
+ }
+ */
+ if(patch_exterior_ring->overlaps(exterior_ring))
+ is_touching = true;
+ if(is_touching)
+ {
+ //add the coresponding patch item to the list
+ while(patch_nr <= i)
+ {
+ patches_children->next(polygon_patch_item);
+ patch_nr++;
+ }
+ result.push_back(polygon_patch_item);
+ }
+ }
+
+ return ItemSequence_t(new VectorItemSequence(result));
+}
+
+
+} /* namespace geomodule */
+} /* namespace zorba */
+/* vim:set et sw=2 ts=2: */
diff -Nru zorba-geo-module-2.9.1/src/geo.xq.src/geo_functions.h zorba-geo-module-3.0.0/src/geo.xq.src/geo_functions.h
--- zorba-geo-module-2.9.1/src/geo.xq.src/geo_functions.h 1970-01-01 00:00:00.000000000 +0000
+++ zorba-geo-module-3.0.0/src/geo.xq.src/geo_functions.h 2013-11-07 17:13:41.000000000 +0000
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ZORBA_GEOMODULE_GEOFUNCTION_H
+#define ZORBA_GEOMODULE_GEOFUNCTION_H
+
+
+#include
+#include
+#include
+
+namespace geos{
+namespace geom{
+class GeometryFactory;
+class Geometry;
+class CoordinateSequence;
+class MultiLineString;
+class MultiPolygon;
+class LineString;
+class LinearRing;
+}}
+
+namespace zorba { namespace geomodule {
+
+ class GeoModule;
+
+ class GeoFunction : public ContextualExternalFunction
+ {
+ protected:
+ const GeoModule* theModule;
+ //geos::geom::GeometryFactory *geo_factory;
+
+ static void
+ throwError(
+ const char *err_localname,
+ const std::string aErrorMessage);
+
+
+ public:
+ enum gmlsf_types{
+ GMLSF_POINT,
+ GMLSF_LINESTRING,
+ GMLSF_CURVE,
+ GMLSF_LINEARRING,
+ GMLSF_SURFACE,
+ GMLSF_POLYGON,
+ //GMLSF_POLYGONPATCH,
+ GMLSF_MULTIPOINT,
+ GMLSF_MULTICURVE,
+ GMLSF_MULTISURFACE,
+ GMLSF_MULTIGEOMETRY,
+
+ GMLSF_INVALID
+ };
+
+ enum action_item{
+ BUILD_GEOS_GEOMETRY,
+ COUNT_CHILDREN,
+ GET_NTH_CHILD,
+ GET_EXTERIOR_RING,
+ GET_NUM_POINTS,
+ GET_NTH_POINT,
+ GET_END_POINT
+ };
+ protected:
+ bool getChild(zorba::Item &lItem, const char *localname, const char *ns,
+ zorba::Item &child_item) const;
+ bool getChild(zorba::Iterator_t children, const char *localname, const char *ns,
+ zorba::Item &child_item) const;
+ bool getAttribute( zorba::Item &item,
+ const char *name,
+ const char *ns,
+ zorba::Item &attr_item) const;
+ bool checkOptionalAttribute(zorba::Item &item, const char *attr_name, const char *ns, const char *attr_value) const;
+ int get_srsDimension(zorba::Item &item, int prev_srsdimension) const;
+ const geos::geom::GeometryFactory *get_geometryFactory() const;
+ void readPointPosCoordinates(zorba::Item &lItem, double *x, double *y, double *z, int &srs_dim) const;
+ bool readPointPosCoordinates(zorba::Iterator_t children, double *x, double *y, double *z, int &srs_dim) const;
+ void readPosListCoordinates(zorba::Item &lItem, geos::geom::CoordinateSequence *&cl, int &srs_dim) const;
+ int getCoordinateDimension(const geos::geom::Geometry *geos_geometry) const;
+ void getSrsName(zorba::Item lItem, zorba::Item &srs_uri) const;
+ bool isCurve(const geos::geom::MultiLineString *multiline) const;
+ bool isSurface(const geos::geom::MultiPolygon *multipolygon,
+ bool *is_closed = NULL,
+ geos::geom::LinearRing **exterior_boundary = NULL) const;
+ geos::geom::LineString *curveToLineString(const geos::geom::Geometry *geos_geometry) const;
+ bool isClosedCurve(const geos::geom::Geometry *geos_geometry) const;
+ bool isRingCurve(const geos::geom::Geometry *geos_geometry) const;
+ bool isSimpleCurve(const geos::geom::Geometry *geos_geometry) const;
+
+ zorba::Item getBoundary(geos::geom::Geometry *geos_geometry, zorba::Item srs_uri) const;
+ void getMultiGeometryBoundary(geos::geom::Geometry *geos_geometry,
+ std::vector *boundaries,
+ zorba::Item srs_uri) const;
+ void addNewLineIndentText(zorba::Item &parent, unsigned int indent) const;
+ void appendIndent(char *&strtemp2, unsigned int indent) const;
+ unsigned char hex_to_bin(char hex) const;
+
+ public:
+ GeoFunction(const GeoModule* module);
+ virtual ~GeoFunction();
+
+ virtual String
+ getURI() const;
+
+ enum gmlsf_types getGmlSFGeometricType(Item item) const;
+ enum gmlsf_types getGeometryNodeType(const ExternalFunction::Arguments_t& args, int arg_pos, zorba::Item &lItem) const;
+
+ geos::geom::Geometry *buildGeosGeometryFromItem(zorba::Item &lItem,
+ enum GeoFunction::gmlsf_types geometric_type,
+ int srs_dim,
+ zorba::Item *srs_uri = NULL,
+ enum GeoFunction::action_item what_action = BUILD_GEOS_GEOMETRY,
+ uint32_t *optional_child_index_or_count = NULL,
+ zorba::Item *result_item = NULL) const;
+ zorba::Item getGMLItemFromGeosGeometry(zorba::Item &parent,
+ const geos::geom::Geometry *geos_geometry,
+ const zorba::Item *srs_uri = NULL,
+ unsigned int indent = 0,
+ const char *tag_name = NULL,
+ bool dont_check_for_curve_surface = false) const;
+ };
+
+
+//*****************************************************************************
+#define DECLARE_GEOFUNCTION_CLASS(geoclass_name, function_name) \
+ class geoclass_name : public GeoFunction \
+ { \
+ public: \
+ geoclass_name(const GeoModule* aModule) : GeoFunction(aModule) {} \
+ \
+ virtual String \
+ getLocalName() const { return #function_name; } \
+ \
+ virtual ItemSequence_t \
+ evaluate(const ExternalFunction::Arguments_t& args, \
+ const StaticContext* aSctxCtx, \
+ const DynamicContext* aDynCtx) const; \
+ };
+
+DECLARE_GEOFUNCTION_CLASS(SFDimensionFunction, dimension)
+DECLARE_GEOFUNCTION_CLASS(SFCoordinateDimensionFunction, coordinate-dimension)
+DECLARE_GEOFUNCTION_CLASS(SFGeometryTypeFunction, geometry-type)
+DECLARE_GEOFUNCTION_CLASS(SFSridFunction, srid)
+DECLARE_GEOFUNCTION_CLASS(SFNumGeometriesFunction, num-geometries)
+DECLARE_GEOFUNCTION_CLASS(SFGeometryNFunction, geometry-n)
+DECLARE_GEOFUNCTION_CLASS(SFEnvelopeFunction, envelope)
+DECLARE_GEOFUNCTION_CLASS(SFAsTextFunction, as-text)
+DECLARE_GEOFUNCTION_CLASS(SFAsBinaryFunction, as-binary)
+DECLARE_GEOFUNCTION_CLASS(SFIsEmptyFunction, is-empty)
+DECLARE_GEOFUNCTION_CLASS(SFIsSimpleFunction, is-simple)
+DECLARE_GEOFUNCTION_CLASS(SFIs3DFunction, is-3d)
+DECLARE_GEOFUNCTION_CLASS(SFIsMeasuredFunction, is-measured)
+DECLARE_GEOFUNCTION_CLASS(SFBoundaryFunction, boundary)
+DECLARE_GEOFUNCTION_CLASS(SFEqualsFunction, equals)
+DECLARE_GEOFUNCTION_CLASS(SFCoversFunction, covers)
+DECLARE_GEOFUNCTION_CLASS(SFDisjointFunction, disjoint)
+DECLARE_GEOFUNCTION_CLASS(SFIntersectsFunction, intersects)
+DECLARE_GEOFUNCTION_CLASS(SFTouchesFunction, touches)
+DECLARE_GEOFUNCTION_CLASS(SFCrossesFunction, crosses)
+DECLARE_GEOFUNCTION_CLASS(SFWithinFunction, within)
+DECLARE_GEOFUNCTION_CLASS(SFContainsFunction, contains)
+DECLARE_GEOFUNCTION_CLASS(SFOverlapsFunction, overlaps)
+DECLARE_GEOFUNCTION_CLASS(SFRelateFunction, relate)
+DECLARE_GEOFUNCTION_CLASS(SFDistanceFunction, distance)
+DECLARE_GEOFUNCTION_CLASS(SFBufferFunction, buffer)
+DECLARE_GEOFUNCTION_CLASS(SFConvexHullFunction, convex-hull)
+DECLARE_GEOFUNCTION_CLASS(SFIntersectionFunction, intersection)
+DECLARE_GEOFUNCTION_CLASS(SFUnionFunction, union)
+DECLARE_GEOFUNCTION_CLASS(SFDifferenceFunction, difference)
+DECLARE_GEOFUNCTION_CLASS(SFSymDifferenceFunction, sym-difference)
+DECLARE_GEOFUNCTION_CLASS(SFAreaFunction, area)
+DECLARE_GEOFUNCTION_CLASS(SFLengthFunction, length)
+DECLARE_GEOFUNCTION_CLASS(SFIsWithinDistanceFunction, is-within-distance)
+DECLARE_GEOFUNCTION_CLASS(SFCentroidFunction, centroid)
+DECLARE_GEOFUNCTION_CLASS(SFPointOnSurfaceFunction, point-on-surface)
+
+DECLARE_GEOFUNCTION_CLASS(SFXFunction, x)
+DECLARE_GEOFUNCTION_CLASS(SFYFunction, y)
+DECLARE_GEOFUNCTION_CLASS(SFZFunction, z)
+DECLARE_GEOFUNCTION_CLASS(SFMFunction, m)
+
+DECLARE_GEOFUNCTION_CLASS(SFStartPointFunction, start-point)
+DECLARE_GEOFUNCTION_CLASS(SFEndPointFunction, end-point)
+DECLARE_GEOFUNCTION_CLASS(SFIsClosedFunction, is-closed)
+DECLARE_GEOFUNCTION_CLASS(SFIsRingFunction, is-ring)
+DECLARE_GEOFUNCTION_CLASS(SFNumPointsFunction, num-points)
+DECLARE_GEOFUNCTION_CLASS(SFPointNFunction, point-n)
+
+DECLARE_GEOFUNCTION_CLASS(SFExteriorRingFunction, exterior-ring)
+DECLARE_GEOFUNCTION_CLASS(SFNumInteriorRingFunction, num-interior-ring)
+DECLARE_GEOFUNCTION_CLASS(SFInteriorRingNFunction, interior-ring-n)
+
+DECLARE_GEOFUNCTION_CLASS(SFNumPatchesFunction, num-patches)
+DECLARE_GEOFUNCTION_CLASS(SFPatchNFunction, patch-n)
+DECLARE_GEOFUNCTION_CLASS(SFBoundingPolygonsFunction, bounding-polygons)
+} /* namespace geomodule */
+} /* namespace zorba */
+
+#endif /* ZORBA_FILEMODULE_FILEFUNCTION_H */
diff -Nru zorba-geo-module-2.9.1/src/geo.xq.src/geo_module.cpp zorba-geo-module-3.0.0/src/geo.xq.src/geo_module.cpp
--- zorba-geo-module-2.9.1/src/geo.xq.src/geo_module.cpp 1970-01-01 00:00:00.000000000 +0000
+++ zorba-geo-module-3.0.0/src/geo.xq.src/geo_module.cpp 2013-11-07 17:13:41.000000000 +0000
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "geo_module.h"
+#include "geo_functions.h"
+
+namespace zorba { namespace geomodule {
+
+ ItemFactory* GeoModule::theFactory = 0;
+
+#ifdef WIN32
+# define DLL_EXPORT __declspec(dllexport)
+#else
+# define DLL_EXPORT __attribute__ ((visibility("default")))
+#endif
+
+extern "C" DLL_EXPORT zorba::ExternalModule* createModule() {
+ return new zorba::geomodule::GeoModule();
+}
+
+GeoModule::~GeoModule()
+{
+ for (FuncMap_t::const_iterator lIter = theFunctions.begin();
+ lIter != theFunctions.end(); ++lIter) {
+ delete lIter->second;
+ }
+ theFunctions.clear();
+}
+
+ExternalFunction*
+GeoModule::getExternalFunction(const String& aLocalname)
+{
+ ExternalFunction*& lFunc = theFunctions[aLocalname];
+ if (!lFunc) {
+ if (1 == 0) {
+
+ }
+ else if (aLocalname == "dimension") {
+ lFunc = new SFDimensionFunction(this);
+ }
+ else if (aLocalname == "coordinate-dimension") {
+ lFunc = new SFCoordinateDimensionFunction(this);
+ }
+ else if (aLocalname == "geometry-type") {
+ lFunc = new SFGeometryTypeFunction(this);
+ }
+ else if (aLocalname == "srid") {
+ lFunc = new SFSridFunction(this);
+ }
+ else if (aLocalname == "num-geometries") {
+ lFunc = new SFNumGeometriesFunction(this);
+ }
+ else if (aLocalname == "geometry-n") {
+ lFunc = new SFGeometryNFunction(this);
+ }
+ else if (aLocalname == "envelope") {
+ lFunc = new SFEnvelopeFunction(this);
+ }
+ else if (aLocalname == "as-text") {
+ lFunc = new SFAsTextFunction(this);
+ }
+ else if (aLocalname == "as-binary") {
+ lFunc = new SFAsBinaryFunction(this);
+ }
+ else if (aLocalname == "is-empty") {
+ lFunc = new SFIsEmptyFunction(this);
+ }
+ else if (aLocalname == "is-simple") {
+ lFunc = new SFIsSimpleFunction(this);
+ }
+ else if (aLocalname == "is-3d") {
+ lFunc = new SFIs3DFunction(this);
+ }
+ else if (aLocalname == "is-measured") {
+ lFunc = new SFIsMeasuredFunction(this);
+ }
+ else if (aLocalname == "boundary") {
+ lFunc = new SFBoundaryFunction(this);
+ }
+ else if (aLocalname == "equals") {
+ lFunc = new SFEqualsFunction(this);
+ }
+ else if (aLocalname == "covers") {
+ lFunc = new SFCoversFunction(this);
+ }
+ else if (aLocalname == "disjoint") {
+ lFunc = new SFDisjointFunction(this);
+ }
+ else if (aLocalname == "intersects") {
+ lFunc = new SFIntersectsFunction(this);
+ }
+ else if (aLocalname == "touches") {
+ lFunc = new SFTouchesFunction(this);
+ }
+ else if (aLocalname == "crosses") {
+ lFunc = new SFCrossesFunction(this);
+ }
+ else if (aLocalname == "within") {
+ lFunc = new SFWithinFunction(this);
+ }
+ else if (aLocalname == "contains") {
+ lFunc = new SFContainsFunction(this);
+ }
+ else if (aLocalname == "overlaps") {
+ lFunc = new SFOverlapsFunction(this);
+ }
+ else if (aLocalname == "relate") {
+ lFunc = new SFRelateFunction(this);
+ }
+ else if (aLocalname == "distance") {
+ lFunc = new SFDistanceFunction(this);
+ }
+ else if (aLocalname == "buffer") {
+ lFunc = new SFBufferFunction(this);
+ }
+ else if (aLocalname == "convex-hull") {
+ lFunc = new SFConvexHullFunction(this);
+ }
+ else if (aLocalname == "intersection") {
+ lFunc = new SFIntersectionFunction(this);
+ }
+ else if (aLocalname == "union") {
+ lFunc = new SFUnionFunction(this);
+ }
+ else if (aLocalname == "difference") {
+ lFunc = new SFDifferenceFunction(this);
+ }
+ else if (aLocalname == "sym-difference") {
+ lFunc = new SFSymDifferenceFunction(this);
+ }
+ else if (aLocalname == "area") {
+ lFunc = new SFAreaFunction(this);
+ }
+ else if (aLocalname == "length") {
+ lFunc = new SFLengthFunction(this);
+ }
+ else if (aLocalname == "is-within-distance") {
+ lFunc = new SFIsWithinDistanceFunction(this);
+ }
+ else if (aLocalname == "centroid") {
+ lFunc = new SFCentroidFunction(this);
+ }
+ else if (aLocalname == "point-on-surface") {
+ lFunc = new SFPointOnSurfaceFunction(this);
+ }
+ else if (aLocalname == "x") {
+ lFunc = new SFXFunction(this);
+ }
+ else if (aLocalname == "y") {
+ lFunc = new SFYFunction(this);
+ }
+ else if (aLocalname == "z") {
+ lFunc = new SFZFunction(this);
+ }
+ else if (aLocalname == "m") {
+ lFunc = new SFMFunction(this);
+ }
+ else if (aLocalname == "start-point") {
+ lFunc = new SFStartPointFunction(this);
+ }
+ else if (aLocalname == "end-point") {
+ lFunc = new SFEndPointFunction(this);
+ }
+ else if (aLocalname == "is-closed") {
+ lFunc = new SFIsClosedFunction(this);
+ }
+ else if (aLocalname == "is-ring") {
+ lFunc = new SFIsRingFunction(this);
+ }
+ else if (aLocalname == "num-points") {
+ lFunc = new SFNumPointsFunction(this);
+ }
+ else if (aLocalname == "point-n") {
+ lFunc = new SFPointNFunction(this);
+ }
+ else if (aLocalname == "exterior-ring") {
+ lFunc = new SFExteriorRingFunction(this);
+ }
+ else if (aLocalname == "num-interior-ring") {
+ lFunc = new SFNumInteriorRingFunction(this);
+ }
+ else if (aLocalname == "interior-ring-n") {
+ lFunc = new SFInteriorRingNFunction(this);
+ }
+ else if (aLocalname == "num-patches") {
+ lFunc = new SFNumPatchesFunction(this);
+ }
+ else if (aLocalname == "patch-n") {
+ lFunc = new SFPatchNFunction(this);
+ }
+ else if (aLocalname == "bounding-polygons") {
+ lFunc = new SFBoundingPolygonsFunction(this);
+ }
+ }
+ return lFunc;
+}
+
+void
+GeoModule::destroy()
+{
+ if (!dynamic_cast(this)) {
+ return;
+ }
+ delete this;
+}
+
+} /* namespace GeoModule */ } /* namespace zorba */
diff -Nru zorba-geo-module-2.9.1/src/geo.xq.src/geo_module.h zorba-geo-module-3.0.0/src/geo.xq.src/geo_module.h
--- zorba-geo-module-2.9.1/src/geo.xq.src/geo_module.h 1970-01-01 00:00:00.000000000 +0000
+++ zorba-geo-module-3.0.0/src/geo.xq.src/geo_module.h 2013-11-07 17:13:41.000000000 +0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ZORBA_GEOMODULE_GEOMODULE_H
+#define ZORBA_GEOMODULE_GEOMODULE_H
+
+#include