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:

+ : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + :
InteriorBoundaryExterior
Interiordim(intersection of interior1 and interior2)dim(intersection of interior1 and boundary2)dim(intersection of interior1 and exterior2)
Boundarydim(intersection of boundary1 and interior2)dim(intersection of boundary1 and boundary2)dim(intersection of boundary1 and exterior2)
Exteriordim(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:

+ : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + : + :
InteriorBoundaryExterior
Interiordim(intersection of interior1 and interior2)dim(intersection of interior1 and boundary2)dim(intersection of interior1 and exterior2)
Boundarydim(intersection of boundary1 and interior2)dim(intersection of boundary1 and boundary2)dim(intersection of boundary1 and exterior2)
Exteriordim(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 + +#include +#include + +namespace zorba { namespace geomodule { + +class GeoModule : public ExternalModule +{ +private: + static ItemFactory* theFactory; + +protected: + class ltstr + { + public: + bool operator()(const String& s1, const String& s2) const + { + return s1.compare(s2) < 0; + } + }; + + typedef std::map FuncMap_t; + + FuncMap_t theFunctions; + +public: + virtual ~GeoModule(); + + virtual String + getURI() const { return "http://expath.org/ns/geo"; } + + virtual ExternalFunction* + getExternalFunction(const String& aLocalname); + + virtual void + destroy(); + + static ItemFactory* + getItemFactory() + { + if(!theFactory) + { + theFactory = Zorba::getInstance(0)->getItemFactory(); + } + + return theFactory; + } +}; + + +} /* namespace geomodule */ +} /* namespace zorba */ + +#endif /* ZORBA_GEOMODULE_GEOMODULE_H */ + +/* + * Local variables: + * mode: c++ + * End: + */ diff -Nru zorba-geo-module-2.9.1/src/org/CMakeLists.txt zorba-geo-module-3.0.0/src/org/CMakeLists.txt --- zorba-geo-module-2.9.1/src/org/CMakeLists.txt 2013-05-30 16:35:16.000000000 +0000 +++ zorba-geo-module-3.0.0/src/org/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -# 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. -ADD_SUBDIRECTORY(expath) diff -Nru zorba-geo-module-2.9.1/src/org/expath/CMakeLists.txt zorba-geo-module-3.0.0/src/org/expath/CMakeLists.txt --- zorba-geo-module-2.9.1/src/org/expath/CMakeLists.txt 2013-05-30 16:35:16.000000000 +0000 +++ zorba-geo-module-3.0.0/src/org/expath/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -# 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. -ADD_SUBDIRECTORY(ns) diff -Nru zorba-geo-module-2.9.1/src/org/expath/ns/CMakeLists.txt zorba-geo-module-3.0.0/src/org/expath/ns/CMakeLists.txt --- zorba-geo-module-2.9.1/src/org/expath/ns/CMakeLists.txt 2013-05-30 16:35:16.000000000 +0000 +++ zorba-geo-module-3.0.0/src/org/expath/ns/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -# 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. - -# -#Geos -# -IF (ZORBA_SUPPRESS_GEOS) - MESSAGE (STATUS "ZORBA_SUPPRESS_GEOS is true - not searching for Geos.") -ELSE (ZORBA_SUPPRESS_GEOS) - - 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/org/expath/ns/geo.xq zorba-geo-module-3.0.0/src/org/expath/ns/geo.xq --- zorba-geo-module-2.9.1/src/org/expath/ns/geo.xq 2013-05-30 16:35:16.000000000 +0000 +++ zorba-geo-module-3.0.0/src/org/expath/ns/geo.xq 1970-01-01 00:00:00.000000000 +0000 @@ -1,1352 +0,0 @@ -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: - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - :
InteriorBoundaryExterior
Interiordim(intersection of interior1 and interior2)dim(intersection of interior1 and boundary2)dim(intersection of interior1 and exterior2)
Boundarydim(intersection of boundary1 and interior2)dim(intersection of boundary1 and boundary2)dim(intersection of boundary1 and exterior2)
Exteriordim(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)
- :

- : - : 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. - : On Linux the variables are set automatically by cmake. - : - : @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/Geo - :) -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://www.zorba-xquery.com/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: - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - : - :
InteriorBoundaryExterior
Interiordim(intersection of interior1 and interior2)dim(intersection of interior1 and boundary2)dim(intersection of interior1 and exterior2)
Boundarydim(intersection of boundary1 and interior2)dim(intersection of boundary1 and boundary2)dim(intersection of boundary1 and exterior2)
Exteriordim(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/org/expath/ns/geo.xq.src/geo_functions.cpp zorba-geo-module-3.0.0/src/org/expath/ns/geo.xq.src/geo_functions.cpp --- zorba-geo-module-2.9.1/src/org/expath/ns/geo.xq.src/geo_functions.cpp 2013-05-30 16:35:16.000000000 +0000 +++ zorba-geo-module-3.0.0/src/org/expath/ns/geo.xq.src/geo_functions.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,4507 +0,0 @@ -/* - * 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) || \ - (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR == 2 && GEOS_VERSION_PATCH < 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(binary_bin, binary_len); - 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 */ diff -Nru zorba-geo-module-2.9.1/src/org/expath/ns/geo.xq.src/geo_functions.h zorba-geo-module-3.0.0/src/org/expath/ns/geo.xq.src/geo_functions.h --- zorba-geo-module-2.9.1/src/org/expath/ns/geo.xq.src/geo_functions.h 2013-05-30 16:35:16.000000000 +0000 +++ zorba-geo-module-3.0.0/src/org/expath/ns/geo.xq.src/geo_functions.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,213 +0,0 @@ -/* - * 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/org/expath/ns/geo.xq.src/geo_module.cpp zorba-geo-module-3.0.0/src/org/expath/ns/geo.xq.src/geo_module.cpp --- zorba-geo-module-2.9.1/src/org/expath/ns/geo.xq.src/geo_module.cpp 2013-05-30 16:35:16.000000000 +0000 +++ zorba-geo-module-3.0.0/src/org/expath/ns/geo.xq.src/geo_module.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,220 +0,0 @@ -/* - * 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/org/expath/ns/geo.xq.src/geo_module.h zorba-geo-module-3.0.0/src/org/expath/ns/geo.xq.src/geo_module.h --- zorba-geo-module-2.9.1/src/org/expath/ns/geo.xq.src/geo_module.h 2013-05-30 16:35:16.000000000 +0000 +++ zorba-geo-module-3.0.0/src/org/expath/ns/geo.xq.src/geo_module.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -/* - * 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 - -#include -#include - -namespace zorba { namespace geomodule { - -class GeoModule : public ExternalModule -{ -private: - static ItemFactory* theFactory; - -protected: - class ltstr - { - public: - bool operator()(const String& s1, const String& s2) const - { - return s1.compare(s2) < 0; - } - }; - - typedef std::map FuncMap_t; - - FuncMap_t theFunctions; - -public: - virtual ~GeoModule(); - - virtual String - getURI() const { return "http://expath.org/ns/geo"; } - - virtual ExternalFunction* - getExternalFunction(const String& aLocalname); - - virtual void - destroy(); - - static ItemFactory* - getItemFactory() - { - if(!theFactory) - { - theFactory = Zorba::getInstance(0)->getItemFactory(); - } - - return theFactory; - } -}; - - -} /* namespace geomodule */ -} /* namespace zorba */ - -#endif /* ZORBA_GEOMODULE_GEOMODULE_H */ - -/* - * Local variables: - * mode: c++ - * End: - */