2
* Copyright 2006-2008 The FLWOR Foundation.
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
21
#include "geo_functions.h"
23
#include <geos/geom/PrecisionModel.h>
24
#include <geos/geom/GeometryFactory.h>
25
#include <geos/geom/Geometry.h>
26
#include <geos/geom/Point.h>
27
#include <geos/geom/LinearRing.h>
28
#include <geos/geom/LineString.h>
29
#include <geos/geom/Polygon.h>
30
#include <geos/geom/GeometryCollection.h>
31
#include <geos/geom/MultiPoint.h>
32
#include <geos/geom/MultiLineString.h>
33
#include <geos/geom/MultiPolygon.h>
34
#include <geos/geom/Coordinate.h>
35
#include <geos/geom/CoordinateSequence.h>
36
#include <geos/geom/CoordinateArraySequence.h>
37
#include <geos/geom/CoordinateArraySequenceFactory.h>
38
#include <geos/geom/IntersectionMatrix.h>
39
#include <geos/io/WKBReader.h>
40
#include <geos/io/WKBWriter.h>
41
#include <geos/io/WKTWriter.h>
42
#include <geos/util/GeometricShapeFactory.h>
43
#include <geos/util/GEOSException.h>
44
#include <geos/util/IllegalArgumentException.h>
45
#include <geos/opLinemerge.h>
46
#include <geos/opPolygonize.h>
47
#include <geos/version.h>
52
#include <zorba/zorba.h>
53
#include <zorba/store_consts.h>
54
#include <zorba/singleton_item_sequence.h>
55
#include <zorba/vector_item_sequence.h>
56
#include <zorba/empty_sequence.h>
58
#include "geo_module.h"
60
#if GEOS_VERSION_MAJOR < 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 2) || \
61
(GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR == 2 && GEOS_VERSION_PATCH < 2)
62
#error Zorba geo module can be linked only with GEOS version 3.2.2 or above, preferably 3.3
65
#define DONT_CHECK_FOR_CURVE_SURFACE true
67
#define RETURN_RESULT_ITEM return result_item.isNull() ? ItemSequence_t(NULL) : ItemSequence_t(new SingletonItemSequence(result_item))
69
namespace zorba { namespace geomodule {
71
GeoFunction::GeoFunction(const GeoModule* aModule)
74
// geo_factory = NULL;
77
GeoFunction::~GeoFunction()
79
// delete geo_factory;
83
GeoFunction::getURI() const
85
return theModule->getURI();
89
GeoFunction::throwError(
90
const char *err_localname,
91
const std::string aErrorMessage)
93
Item errWrongParamQName;
94
String errNS("http://expath.org/ns/error");
95
String errName(err_localname);
96
Item errQName = GeoModule::getItemFactory()->createQName(errNS, errName);
97
String errDescription(aErrorMessage);
98
ExternalFunctionData::error(errQName, errDescription);
101
enum GeoFunction::gmlsf_types GeoFunction::getGmlSFGeometricType(Item item) const
104
item.getNodeName(item_qname);
105
String item_namespace = item_qname.getNamespace();
106
if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
107
return GMLSF_INVALID;
108
String localname = item_qname.getLocalName();
110
if(localname.byteEqual("Point", 5))
112
else if(localname.byteEqual("LineString", 10))
113
return GMLSF_LINESTRING;
114
else if(localname.byteEqual("Curve", 5))
116
else if(localname.byteEqual("LinearRing", 10))
117
return GMLSF_LINEARRING;
118
else if(localname.byteEqual("Surface", 7))
119
return GMLSF_SURFACE;
120
else if(localname.byteEqual("Polygon", 7))
121
return GMLSF_POLYGON;
122
else if(localname.byteEqual("PolygonPatch", 12))
123
return GMLSF_POLYGON;
124
else if(localname.byteEqual("MultiPoint", 10))
125
return GMLSF_MULTIPOINT;
126
else if(localname.byteEqual("MultiCurve", 10))
127
return GMLSF_MULTICURVE;
128
else if(localname.byteEqual("MultiSurface", 12))
129
return GMLSF_MULTISURFACE;
130
else if(localname.byteEqual("MultiGeometry", 13))///from GML3
131
return GMLSF_MULTIGEOMETRY;
133
return GMLSF_INVALID;
136
enum GeoFunction::gmlsf_types GeoFunction::getGeometryNodeType(const StatelessExternalFunction::Arguments_t& args,
137
int arg_pos, zorba::Item &lItem) const
139
Iterator_t args_iter = args[arg_pos]->getIterator();
141
if (!args_iter->next(lItem))
143
std::stringstream lErrorMessage;
144
lErrorMessage << "An empty-sequence is not allowed as parameter";
145
throwError("UnrecognizedGeoObject", lErrorMessage.str());
148
if(!lItem.isNode() || (lItem.getNodeKind() != store::StoreConsts::elementNode))
150
std::stringstream lErrorMessage;
151
lErrorMessage << "Argument must be a geometric node ";
152
throwError("UnrecognizedGeoObject", lErrorMessage.str());
155
return getGmlSFGeometricType(lItem);
158
bool GeoFunction::getChild(zorba::Item &lItem, const char *localname, const char *ns,
159
zorba::Item &child_item) const
162
children = lItem.getChildren();
164
bool retval = getChild(children, localname, ns, child_item);
169
bool GeoFunction::getChild(zorba::Iterator_t children, const char *localname, const char *ns,
170
zorba::Item &child_item) const
172
while(children->next(child_item))
174
if(child_item.getNodeKind() != store::StoreConsts::elementNode)
177
child_item.getNodeName(child_name);
178
String item_namespace = child_name.getNamespace();
179
if(!item_namespace.byteEqual(ns, (unsigned int)strlen(ns)))
181
continue;//next child
183
String item_name = child_name.getLocalName();
184
if(!item_name.byteEqual(localname, (unsigned int)strlen(localname)))
186
continue;//next child
193
bool GeoFunction::getAttribute( zorba::Item &item,
196
zorba::Item &attr_item) const
199
children = item.getAttributes();
201
while(children->next(attr_item))
203
zorba::Item attr_qname;
204
attr_item.getNodeName(attr_qname);
205
String attr_name = attr_qname.getLocalName();
206
if(!attr_name.byteEqual(name, (unsigned int)strlen(name)))
215
String attr_ns= attr_qname.getNamespace();
216
if(attr_ns.byteEqual(ns, (unsigned int)strlen(ns)))
226
bool GeoFunction::checkOptionalAttribute(zorba::Item &item,
229
const char *value) const
231
zorba::Item attr_item;
232
if(!getAttribute( item,
237
String attr_value = attr_item.getStringValue();
238
return attr_value.byteEqual(value, (unsigned int)strlen(value));
241
int GeoFunction::get_srsDimension(zorba::Item &item, int prev_srsdimension) const
243
zorba::Item attr_item;
244
if(getAttribute(item,
249
String attr_value = attr_item.getStringValue();
250
String trimed_value = attr_value.trim();
251
int srs_dim = atoi(trimed_value.c_str());
252
if((srs_dim != 2) && (srs_dim != 3))
254
std::stringstream lErrorMessage;
255
lErrorMessage << "Geo module's supported values for srsDimension in GML are 2 and 3.";
256
throwError("UnsupportedSRSDimensionValue", lErrorMessage.str());
260
return prev_srsdimension;
263
const geos::geom::GeometryFactory *GeoFunction::get_geometryFactory() const
266
// geo_factory = new geos::geom::GeometryFactory;
267
// return geo_factory;
268
return geos::geom::GeometryFactory::getDefaultInstance();
271
void GeoFunction::readPointPosCoordinates(zorba::Item &lItem,
278
children = lItem.getChildren();
280
bool retval = readPointPosCoordinates(children, x, y, z, srs_dim);
284
std::stringstream lErrorMessage;
285
lErrorMessage << "gml node must have a gml:pos child";
286
throwError("UnrecognizedGeoObject", lErrorMessage.str());
290
bool GeoFunction::readPointPosCoordinates(zorba::Iterator_t children,
296
zorba::Item pos_item;
297
if(!getChild(children, "pos", "http://www.opengis.net/gml", pos_item))
299
//std::stringstream lErrorMessage;
300
//lErrorMessage << "gml:Point node must have a gml:pos child";
301
//throwError("UnrecognizedGeoObject", lErrorMessage.str());
304
srs_dim = get_srsDimension(pos_item, srs_dim);
307
pos_string = pos_item.getStringValue();
311
const char *str = pos_string.c_str();
312
while(((*str == ' ') ||
318
sscanf(str, "%lf", x);
319
while((*str != ' ') &&
325
while(((*str == ' ') ||
331
sscanf(str, "%lf", y);
334
while((*str != ' ') &&
340
while(((*str == ' ') ||
346
sscanf(str, "%lf", z);
351
void GeoFunction::readPosListCoordinates(zorba::Item &lItem,
352
geos::geom::CoordinateSequence *&cl,
355
zorba::Item poslist_item;
358
if(getChild(lItem, "posList", "http://www.opengis.net/gml", poslist_item))
360
srs_dim = get_srsDimension(poslist_item, srs_dim);
362
cl = geos::geom::CoordinateArraySequenceFactory::instance()->create((std::size_t)0, srs_dim);
364
String poslist_string;
365
poslist_string = poslist_item.getStringValue();
368
const char *str_poslist = poslist_string.c_str();
369
while(((*str_poslist == ' ') ||
370
(*str_poslist == '\t') ||
371
(*str_poslist == '\n') ||
372
(*str_poslist == '\r')) &&
376
while(str_poslist[0])
379
x = atof(str_poslist);
382
y = atof(str_poslist);
385
cl->add(geos::geom::Coordinate(x, y));
391
z = atof(str_poslist);
392
cl->add(geos::geom::Coordinate(x, y, z));
395
load_x = (load_x + 1)%srs_dim;
396
while((*str_poslist != ' ') &&
397
(*str_poslist != '\t') &&
398
(*str_poslist != '\n') &&
399
(*str_poslist != '\r') &&
402
while(((*str_poslist == ' ') ||
403
(*str_poslist == '\t') ||
404
(*str_poslist == '\n') ||
405
(*str_poslist == '\r')) &&
410
else if(getChild(lItem, "pos", "http://www.opengis.net/gml", poslist_item))
413
children = lItem.getChildren();
415
double x = 0, y = 0, z = 0;
416
while(readPointPosCoordinates(children, &x, &y, &z, srs_dim))
419
cl = geos::geom::CoordinateArraySequenceFactory::instance()->create((std::size_t)0, srs_dim);
423
cl->add(geos::geom::Coordinate(x, y, z));
427
cl->add(geos::geom::Coordinate(x, y));
435
std::stringstream lErrorMessage;
436
zorba::Item item_qname;
437
lItem.getNodeName(item_qname);
438
lErrorMessage << item_qname.getLocalName() << " node must have a gml:posList child";
439
throwError("UnrecognizedGeoObject", lErrorMessage.str());
444
int GeoFunction::getCoordinateDimension(const geos::geom::Geometry *geos_geometry) const
448
switch(geos_geometry->getGeometryTypeId())
450
case geos::geom::GEOS_POINT:
452
const geos::geom::Coordinate *c;
453
c = geos_geometry->getCoordinate();
460
case geos::geom::GEOS_LINESTRING:
461
/// a linear ring (linestring with 1st point == last point)
462
case geos::geom::GEOS_LINEARRING:
464
std::auto_ptr<geos::geom::CoordinateSequence> cs;
465
cs.reset(geos_geometry->getCoordinates());
466
size_t cs_size = cs->getSize();
467
for(size_t i=0;i<cs_size;i++)
469
if(!ISNAN(cs->getAt(i).z))
475
case geos::geom::GEOS_POLYGON:
477
const geos::geom::LineString* exterior_ring;
478
const geos::geom::Polygon *polygon = dynamic_cast<const geos::geom::Polygon*>(geos_geometry);
479
exterior_ring = polygon->getExteriorRing();
480
int exterior_dim = getCoordinateDimension(exterior_ring);
481
if(exterior_dim == 3)
484
size_t interior_rings = polygon->getNumInteriorRing();
485
for(size_t i=0;i<interior_rings;i++)
487
const geos::geom::LineString* interior_ring;
488
interior_ring = polygon->getInteriorRingN(i);
489
int interior_dim = getCoordinateDimension(interior_ring);
490
if(interior_dim == 3)
495
/// a collection of points
496
case geos::geom::GEOS_MULTIPOINT:
498
size_t nr_geoms = geos_geometry->getNumGeometries();
499
for(size_t i=0;i<nr_geoms;i++)
501
const geos::geom::Geometry *point;
502
point = geos_geometry->getGeometryN(i);
503
if(getCoordinateDimension(point) == 3)
508
/// a collection of linestrings
509
case geos::geom::GEOS_MULTILINESTRING:
511
size_t nr_geoms = geos_geometry->getNumGeometries();
512
for(size_t i=0;i<nr_geoms;i++)
514
const geos::geom::Geometry *linestring;
515
linestring = geos_geometry->getGeometryN(i);
516
if(getCoordinateDimension(linestring) == 3)
521
/// a collection of polygons
522
case geos::geom::GEOS_MULTIPOLYGON:
524
size_t nr_geoms = geos_geometry->getNumGeometries();
525
for(size_t i=0;i<nr_geoms;i++)
527
const geos::geom::Geometry *polygon;
528
polygon = geos_geometry->getGeometryN(i);
529
if(getCoordinateDimension(polygon) == 3)
534
/// a collection of heterogeneus geometries
535
case geos::geom::GEOS_GEOMETRYCOLLECTION:
537
//can be either gml:Surface or gml:Curve
538
size_t nr_geoms = geos_geometry->getNumGeometries();
540
return 2;//unreachable
541
for(size_t i=0;i<nr_geoms;i++)
543
const geos::geom::Geometry *child;
544
child = geos_geometry->getGeometryN(i);
545
if(getCoordinateDimension(child) == 3)
552
std::stringstream lErrorMessage;
553
lErrorMessage << "Geometry type " << geos_geometry->getGeometryType() << " is not supported";
554
throwError("UnrecognizedGeoObject", lErrorMessage.str());
561
void GeoFunction::getSrsName(zorba::Item lItem, zorba::Item &srs_uri) const
563
zorba::Item attr_item;
564
if(getAttribute(lItem,
569
String attr_value = attr_item.getStringValue();
570
srs_uri = theModule->getItemFactory()->createAnyURI(attr_value);
574
zorba::Item parent_item = lItem.getParent();
575
if(parent_item.isNull())
577
zorba::Item bounded_item;
578
zorba::Item envelope_item;
579
if(getChild(parent_item, "boundedBy", "http://www.opengis.net/gml", bounded_item) &&
580
getChild(bounded_item, "Envelope", "http://www.opengis.net/gml", envelope_item))
582
getSrsName(envelope_item, srs_uri);
583
if(!srs_uri.isNull())
586
getSrsName(parent_item, srs_uri);
587
if(!srs_uri.isNull())
591
geos::geom::Geometry *GeoFunction::buildGeosGeometryFromItem(zorba::Item &lItem,
592
enum GeoFunction::gmlsf_types geometric_type,
594
zorba::Item *srs_uri,
595
enum GeoFunction::action_item what_action,
596
uint32_t *optional_child_index_or_count,
597
zorba::Item *result_item) const
599
srs_dim = get_srsDimension(lItem, srs_dim);
601
getSrsName(lItem, *srs_uri);
602
geos::geom::Geometry *result;
604
switch(geometric_type)
608
if(what_action == BUILD_GEOS_GEOMETRY)
611
readPointPosCoordinates(lItem, &x, &y, &z, srs_dim);
612
geos::geom::Coordinate c(x, y);
616
result = get_geometryFactory()->createPoint(c);
617
result->setUserData((void*)GMLSF_POINT);
619
}catch(std::exception &excep)
621
std::stringstream lErrorMessage;
622
lErrorMessage << "Error in GEOS function createPoint : " << excep.what();
623
throwError("GEOSError", lErrorMessage.str());
626
else if(what_action == COUNT_CHILDREN)
627
(*optional_child_index_or_count) = 1;
628
else if(what_action == GET_NTH_CHILD)
630
if((*optional_child_index_or_count) == 0)
631
*result_item = lItem;
635
std::stringstream lErrorMessage;
636
lErrorMessage << "Error in GMLSF_POINT";
637
throwError("InternalError", lErrorMessage.str());
640
case GMLSF_LINESTRING:
642
geos::geom::CoordinateSequence *cl = NULL;//new geos::geom::CoordinateArraySequence();
643
readPosListCoordinates(lItem, cl, srs_dim);
644
uint32_t last_index = (uint32_t)cl->size()-1;
645
if(what_action == GET_END_POINT)
647
optional_child_index_or_count = &last_index;
648
what_action = GET_NTH_POINT;
650
if(what_action == BUILD_GEOS_GEOMETRY)
653
result = get_geometryFactory()->createLineString(cl);
654
result->setUserData((void*)GMLSF_LINESTRING);
656
}catch(std::exception &excep)
659
std::stringstream lErrorMessage;
660
lErrorMessage << "Error in GEOS function createLineString : " << excep.what();
661
throwError("GEOSError", lErrorMessage.str());
664
else if((what_action == COUNT_CHILDREN) || (what_action == GET_NUM_POINTS))
666
(*optional_child_index_or_count) = (uint32_t)cl->size();
669
else if((what_action == GET_NTH_CHILD) || (what_action == GET_NTH_POINT))
671
if((*optional_child_index_or_count) < cl->size())
675
zorba::Item null_parent;
676
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "Point");
677
std::vector<std::pair<String, String> > ns_binding;
678
ns_binding.push_back(std::pair<String, String>("gml", "http://www.opengis.net/gml"));
679
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
680
*result_item = theModule->getItemFactory()->createElementNode(null_parent, item_name, item_type, false, false, ns_binding);
683
zorba::Item pos_item;
684
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
685
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "pos");
686
addNewLineIndentText(*result_item, 2);
687
pos_item = theModule->getItemFactory()->createElementNode(*result_item, item_name, item_type, false, false, ns_binding);
691
zorba::Item attr_value_item;
692
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
693
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "srsDimension");
695
sprintf(strdim, "%d", srs_dim);
696
zorba::String strvalue(strdim);
697
attr_value_item = theModule->getItemFactory()->createString(strvalue);
698
theModule->getItemFactory()->createAttributeNode(pos_item, item_name, item_type, attr_value_item);
703
if(!ISNAN(cl->getAt((*optional_child_index_or_count)).z))
704
sprintf(strtemp, "%lf %lf %lf", cl->getAt((*optional_child_index_or_count)).x,
705
cl->getAt((*optional_child_index_or_count)).y,
706
cl->getAt((*optional_child_index_or_count)).z);
708
sprintf(strtemp, "%lf %lf 0", cl->getAt((*optional_child_index_or_count)).x,
709
cl->getAt((*optional_child_index_or_count)).y);
713
sprintf(strtemp, "%lf %lf", cl->getAt((*optional_child_index_or_count)).x,
714
cl->getAt((*optional_child_index_or_count)).y);
717
zorba::Item text_item;
718
text_item = theModule->getItemFactory()->createTextNode(pos_item, strtemp);
719
addNewLineIndentText(*result_item, 0);
726
std::stringstream lErrorMessage;
727
lErrorMessage << "Error in GMLSF_LINESTRING";
728
throwError("InternalError", lErrorMessage.str());
732
{ //not supported in GEOS; emulate through MultiLineString
733
zorba::Item segments_item;
734
if(!getChild(lItem, "segments", "http://www.opengis.net/gml", segments_item))
736
std::stringstream lErrorMessage;
737
lErrorMessage << "gml:Curve node must have a gml:segments child";
738
throwError("UnrecognizedGeoObject", lErrorMessage.str());
740
if((what_action == COUNT_CHILDREN) || (what_action == GET_NUM_POINTS))
742
(*optional_child_index_or_count) = 0;
744
unsigned int child_nr = 0;
745
Iterator_t segments_children;
746
Item line_segment_item;
747
std::vector<geos::geom::Geometry*> *segments_vector = NULL;
748
if(what_action == BUILD_GEOS_GEOMETRY)
750
segments_vector = new std::vector<geos::geom::Geometry*>;
752
segments_children = segments_item.getChildren();
753
segments_children->open();
754
while(segments_children->next(line_segment_item))
756
if(line_segment_item.getNodeKind() != store::StoreConsts::elementNode)
759
line_segment_item.getNodeName(item_qname);
760
String item_namespace = item_qname.getNamespace();
761
if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
763
std::stringstream lErrorMessage;
764
lErrorMessage << "Children of gml:Curve/gml:segments must be of type gml:LineStringSegment only";
765
throwError("UnrecognizedGeoObject", lErrorMessage.str());
767
String local_name = item_qname.getLocalName();
768
if(!local_name.byteEqual("LineStringSegment", 17))
770
std::stringstream lErrorMessage;
771
lErrorMessage << "Children of gml:Curve/gml:segments must be of type gml:LineStringSegment only";
772
throwError("UnrecognizedGeoObject", lErrorMessage.str());
774
if(!checkOptionalAttribute(line_segment_item, "interpolation", "http://www.opengis.net/gml", "linear"))
776
std::stringstream lErrorMessage;
777
lErrorMessage << "gml:Curve/gml:segments/gml:LineStringSegment supports only linear interpolation";
778
throwError("UnrecognizedGeoObject", lErrorMessage.str());
781
if(what_action == BUILD_GEOS_GEOMETRY)
783
segments_vector->push_back(buildGeosGeometryFromItem(line_segment_item, GMLSF_LINESTRING, srs_dim));
785
else if(what_action == COUNT_CHILDREN)
787
(*optional_child_index_or_count)++;
789
else if(what_action == GET_NUM_POINTS)
792
buildGeosGeometryFromItem(line_segment_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NUM_POINTS, &nr_points);
793
(*optional_child_index_or_count) += nr_points;
795
else if(what_action == GET_NTH_CHILD)
797
if((*optional_child_index_or_count) == child_nr)
799
*result_item = line_segment_item;
803
else if(what_action == GET_NTH_POINT)
805
buildGeosGeometryFromItem(line_segment_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NTH_POINT, optional_child_index_or_count, result_item);
806
if(!result_item->isNull())
809
buildGeosGeometryFromItem(line_segment_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NUM_POINTS, &nr_points);
810
(*optional_child_index_or_count) -= nr_points;
814
std::stringstream lErrorMessage;
815
lErrorMessage << "Error in GMLSF_CURVE";
816
throwError("InternalError", lErrorMessage.str());
821
if(what_action == BUILD_GEOS_GEOMETRY)
824
result = get_geometryFactory()->createMultiLineString(segments_vector);
825
result->setUserData((void*)GMLSF_CURVE);
827
}catch(std::exception &excep)
829
std::vector<geos::geom::Geometry*>::iterator vec_it;
830
for(vec_it = segments_vector->begin(); vec_it != segments_vector->end(); vec_it++)
834
delete segments_vector;
835
std::stringstream lErrorMessage;
836
lErrorMessage << "Error in GEOS function createGeometryCollection for gml:Curve: " << excep.what();
837
throwError("GEOSError", lErrorMessage.str());
841
case GMLSF_LINEARRING:
843
geos::geom::CoordinateSequence *cl = NULL;//new geos::geom::CoordinateArraySequence();
844
readPosListCoordinates(lItem, cl, srs_dim);
845
uint32_t last_index = (uint32_t)cl->size()-1;
846
if(what_action == GET_END_POINT)
848
optional_child_index_or_count = &last_index;
849
what_action = GET_NTH_POINT;
851
if(what_action == BUILD_GEOS_GEOMETRY)
854
result = get_geometryFactory()->createLinearRing(cl);
855
result->setUserData((void*)GMLSF_LINEARRING);
857
}catch(std::exception &excep)
860
std::stringstream lErrorMessage;
861
lErrorMessage << "Error in GEOS function createLinearRing : " << excep.what();
862
throwError("GEOSError", lErrorMessage.str());
865
else if((what_action == COUNT_CHILDREN) || (what_action == GET_NUM_POINTS))
867
(*optional_child_index_or_count) = (uint32_t)cl->size();
870
else if((what_action == GET_NTH_CHILD) || (what_action == GET_NTH_POINT))
872
if((*optional_child_index_or_count) < cl->size())
876
zorba::Item null_parent;
877
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "Point");
878
std::vector<std::pair<String, String> > ns_binding;
879
ns_binding.push_back(std::pair<String, String>("gml", "http://www.opengis.net/gml"));
880
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
881
*result_item = theModule->getItemFactory()->createElementNode(null_parent, item_name, item_type, false, false, ns_binding);
883
zorba::Item pos_item;
884
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
885
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "pos");
886
addNewLineIndentText(*result_item, 2);
887
pos_item = theModule->getItemFactory()->createElementNode(*result_item, item_name, item_type, false, false, ns_binding);
891
zorba::Item attr_value_item;
892
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
893
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "srsDimension");
895
sprintf(strdim, "%d", srs_dim);
896
zorba::String strvalue(strdim);
897
attr_value_item = theModule->getItemFactory()->createString(strvalue);
898
theModule->getItemFactory()->createAttributeNode(pos_item, item_name, item_type, attr_value_item);
903
if(!ISNAN(cl->getAt((*optional_child_index_or_count)).z))
904
sprintf(strtemp, "%lf %lf %lf", cl->getAt((*optional_child_index_or_count)).x,
905
cl->getAt((*optional_child_index_or_count)).y,
906
cl->getAt((*optional_child_index_or_count)).z);
908
sprintf(strtemp, "%lf %lf 0", cl->getAt((*optional_child_index_or_count)).x,
909
cl->getAt((*optional_child_index_or_count)).y);
913
sprintf(strtemp, "%lf %lf", cl->getAt((*optional_child_index_or_count)).x,
914
cl->getAt((*optional_child_index_or_count)).y);
917
zorba::Item text_item;
918
text_item = theModule->getItemFactory()->createTextNode(pos_item, strtemp);
919
addNewLineIndentText(*result_item, 0);
926
std::stringstream lErrorMessage;
927
lErrorMessage << "Error in GMLSF_LINEARRING";
928
throwError("InternalError", lErrorMessage.str());
932
{ //not supported in GEOS; emulate through MultiPolygon
933
zorba::Item patches_item;
934
if(!getChild(lItem, "patches", "http://www.opengis.net/gml", patches_item))
936
std::stringstream lErrorMessage;
937
lErrorMessage << "gml:Surface node must have a gml:patches child";
938
throwError("UnrecognizedGeoObject", lErrorMessage.str());
940
if(what_action == COUNT_CHILDREN)
942
(*optional_child_index_or_count) = 0;
944
unsigned int child_nr = 0;
945
Iterator_t patches_children;
946
Item polygon_patch_item;
947
std::vector<geos::geom::Geometry*> *polygon_vector = NULL;
948
if(what_action == BUILD_GEOS_GEOMETRY)
950
polygon_vector = new std::vector<geos::geom::Geometry*>;
952
patches_children = patches_item.getChildren();
953
patches_children->open();
954
while(patches_children->next(polygon_patch_item))
956
if(polygon_patch_item.getNodeKind() != store::StoreConsts::elementNode)
959
polygon_patch_item.getNodeName(item_qname);
960
String item_namespace = item_qname.getNamespace();
961
if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
963
std::stringstream lErrorMessage;
964
lErrorMessage << "Children of gml:Surface/gml:patches must be of type gml:PolygonPatch only";
965
throwError("UnrecognizedGeoObject", lErrorMessage.str());
967
String item_name = item_qname.getLocalName();
968
if(!item_name.byteEqual("PolygonPatch", 12))
970
std::stringstream lErrorMessage;
971
lErrorMessage << "Children of gml:Surface/gml:patches must be of type gml:PolygonPatch only";
972
throwError("UnrecognizedGeoObject", lErrorMessage.str());
975
if(what_action == BUILD_GEOS_GEOMETRY)
977
polygon_vector->push_back(buildGeosGeometryFromItem(polygon_patch_item, GMLSF_POLYGON, srs_dim));
979
else if(what_action == COUNT_CHILDREN)
981
(*optional_child_index_or_count)++;
983
else if(what_action == GET_NTH_CHILD)
985
if((*optional_child_index_or_count) == child_nr)
987
*result_item = polygon_patch_item;
993
std::stringstream lErrorMessage;
994
lErrorMessage << "Error in GMLSF_CURVE";
995
throwError("InternalError", lErrorMessage.str());
1000
if(what_action == BUILD_GEOS_GEOMETRY)
1003
result = get_geometryFactory()->createMultiPolygon(polygon_vector);
1004
result->setUserData((void*)GMLSF_SURFACE);
1006
}catch(std::exception &excep)
1008
std::vector<geos::geom::Geometry*>::iterator vec_it;
1009
for(vec_it = polygon_vector->begin(); vec_it != polygon_vector->end(); vec_it++)
1013
delete polygon_vector;
1014
std::stringstream lErrorMessage;
1015
lErrorMessage << "Error in GEOS function createGeometryCollection for gml:Surface : " << excep.what();
1016
throwError("GEOSError", lErrorMessage.str());
1022
Iterator_t polygon_children;
1024
unsigned int nr_child = 0;
1025
geos::geom::LinearRing *exterior = NULL;
1026
std::vector<geos::geom::Geometry*> *interior_vector = NULL;
1027
if(what_action == BUILD_GEOS_GEOMETRY)
1029
interior_vector = new std::vector<geos::geom::Geometry*>;
1031
else if(what_action == COUNT_CHILDREN)
1033
(*optional_child_index_or_count) = 0;
1035
polygon_children = lItem.getChildren();
1036
polygon_children->open();
1037
while(polygon_children->next(extint_item))
1039
if(extint_item.getNodeKind() != store::StoreConsts::elementNode)
1042
extint_item.getNodeName(item_qname);
1043
String item_namespace = item_qname.getNamespace();
1044
if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
1046
std::stringstream lErrorMessage;
1047
lErrorMessage << "Children of gml:Polygon must be gml:exterior or gml:interior";
1048
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1050
String item_name = item_qname.getLocalName();
1053
if(!item_name.byteEqual("exterior", 8))
1055
std::stringstream lErrorMessage;
1056
lErrorMessage << "First child of gml:Polygon must be gml:exterior";
1057
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1059
zorba::Item linearring_item;
1060
if(!getChild(extint_item, "LinearRing", "http://www.opengis.net/gml", linearring_item))
1062
std::stringstream lErrorMessage;
1063
lErrorMessage << "gml:Polygon/gml:exterior node must have a gml:LinearRing child";
1064
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1066
if(what_action == BUILD_GEOS_GEOMETRY)
1068
exterior = dynamic_cast<geos::geom::LinearRing*>(buildGeosGeometryFromItem(linearring_item, GMLSF_LINEARRING, srs_dim));
1070
else if(what_action == GET_EXTERIOR_RING)
1072
*result_item = linearring_item;
1078
if(!item_name.byteEqual("interior", 8))
1080
std::stringstream lErrorMessage;
1081
lErrorMessage << "Non-first child of gml:Polygon must be gml:interior";
1082
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1084
zorba::Item linearring_item;
1085
if(!getChild(extint_item, "LinearRing", "http://www.opengis.net/gml", linearring_item))
1087
std::stringstream lErrorMessage;
1088
lErrorMessage << "gml:Polygon/gml:interior node must have a gml:LinearRing child";
1089
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1091
if(what_action == BUILD_GEOS_GEOMETRY)
1093
interior_vector->push_back(buildGeosGeometryFromItem(linearring_item, GMLSF_LINEARRING, srs_dim));
1095
else if(what_action == COUNT_CHILDREN)
1097
(*optional_child_index_or_count)++;
1099
else if(what_action == GET_NTH_CHILD)
1101
if((*optional_child_index_or_count) == (nr_child-1))
1103
*result_item = linearring_item;
1109
std::stringstream lErrorMessage;
1110
lErrorMessage << "Error in GMLSF_POLYGON";
1111
throwError("InternalError", lErrorMessage.str());
1116
if(what_action == BUILD_GEOS_GEOMETRY)
1119
result = get_geometryFactory()->createPolygon(exterior, interior_vector);
1120
result->setUserData((void*)GMLSF_POLYGON);
1122
}catch(std::exception &excep)
1125
std::vector<geos::geom::Geometry*>::iterator vec_it;
1126
for(vec_it = interior_vector->begin(); vec_it != interior_vector->end(); vec_it++)
1130
delete interior_vector;
1131
std::stringstream lErrorMessage;
1132
lErrorMessage << "Error in GEOS function createPolygon : " << excep.what();
1133
throwError("GEOSError", lErrorMessage.str());
1137
case GMLSF_MULTIPOINT:
1139
Iterator_t multipoint_children;
1141
std::vector<geos::geom::Geometry*> *point_vector = NULL;
1142
if(what_action == BUILD_GEOS_GEOMETRY)
1144
point_vector = new std::vector<geos::geom::Geometry*>;
1146
else if(what_action == COUNT_CHILDREN)
1148
(*optional_child_index_or_count) = 0;
1150
unsigned int nr_child = 0;
1151
multipoint_children = lItem.getChildren();
1152
multipoint_children->open();
1153
while(multipoint_children->next(point_item))
1155
if(point_item.getNodeKind() != store::StoreConsts::elementNode)
1158
point_item.getNodeName(item_qname);
1159
String item_namespace = item_qname.getNamespace();
1160
if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
1162
std::stringstream lErrorMessage;
1163
lErrorMessage << "Children of gml:MultiPoint must be gml:Point";
1164
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1166
String item_name = item_qname.getLocalName();
1167
if(!item_name.byteEqual("Point", 5))
1169
std::stringstream lErrorMessage;
1170
lErrorMessage << "First child of gml:MultiPoint must be gml:Point";
1171
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1173
if(what_action == BUILD_GEOS_GEOMETRY)
1175
point_vector->push_back(buildGeosGeometryFromItem(point_item, GMLSF_POINT, srs_dim));
1177
else if(what_action == COUNT_CHILDREN)
1179
(*optional_child_index_or_count)++;
1181
else if(what_action == GET_NTH_CHILD)
1183
if((*optional_child_index_or_count) == nr_child)
1185
*result_item = point_item;
1191
std::stringstream lErrorMessage;
1192
lErrorMessage << "Error in GMLSF_MULTIPOINT";
1193
throwError("InternalError", lErrorMessage.str());
1197
if(what_action == BUILD_GEOS_GEOMETRY)
1200
result = get_geometryFactory()->createMultiPoint(point_vector);
1201
result->setUserData((void*)GMLSF_MULTIPOINT);
1203
}catch(std::exception &excep)
1205
std::vector<geos::geom::Geometry*>::iterator vec_it;
1206
for(vec_it = point_vector->begin(); vec_it != point_vector->end(); vec_it++)
1210
delete point_vector;
1211
std::stringstream lErrorMessage;
1212
lErrorMessage << "Error in GEOS function createMultiPoint : " << excep.what();
1213
throwError("GEOSError", lErrorMessage.str());
1217
case GMLSF_MULTICURVE:
1219
Iterator_t multicurve_children;
1221
std::vector<geos::geom::Geometry*> *curve_vector = NULL;
1222
if(what_action == BUILD_GEOS_GEOMETRY)
1224
curve_vector = new std::vector<geos::geom::Geometry*>;
1226
else if((what_action == COUNT_CHILDREN) || (what_action == GET_NUM_POINTS))
1228
(*optional_child_index_or_count) = 0;
1230
unsigned int nr_child = 0;
1231
multicurve_children = lItem.getChildren();
1232
multicurve_children->open();
1233
while(multicurve_children->next(curve_item))
1235
if(curve_item.getNodeKind() != store::StoreConsts::elementNode)
1238
curve_item.getNodeName(item_qname);
1239
String item_namespace = item_qname.getNamespace();
1240
if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
1242
std::stringstream lErrorMessage;
1243
lErrorMessage << "Children of gml:MultiCurve must be gml:LineString";
1244
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1246
String item_name = item_qname.getLocalName();
1247
if(!item_name.byteEqual("LineString", 10))
1249
std::stringstream lErrorMessage;
1250
lErrorMessage << "Children of gml:MultiCurve must be gml:LineString";
1251
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1253
if(what_action == BUILD_GEOS_GEOMETRY)
1255
curve_vector->push_back(buildGeosGeometryFromItem(curve_item, GMLSF_LINESTRING, srs_dim));
1257
else if(what_action == COUNT_CHILDREN)
1259
(*optional_child_index_or_count)++;
1261
else if(what_action == GET_NUM_POINTS)
1264
buildGeosGeometryFromItem(curve_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NUM_POINTS, &nr_points);
1265
(*optional_child_index_or_count) += nr_points;
1267
else if(what_action == GET_NTH_CHILD)
1269
if((*optional_child_index_or_count) == nr_child)
1271
*result_item = curve_item;
1275
else if(what_action == GET_NTH_POINT)
1277
buildGeosGeometryFromItem(curve_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NTH_POINT, optional_child_index_or_count, result_item);
1278
if(!result_item->isNull())
1281
buildGeosGeometryFromItem(curve_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NUM_POINTS, &nr_points);
1282
(*optional_child_index_or_count) -= nr_points;
1286
std::stringstream lErrorMessage;
1287
lErrorMessage << "Error in GMLSF_MULTICURVE";
1288
throwError("InternalError", lErrorMessage.str());
1292
if(what_action == BUILD_GEOS_GEOMETRY)
1295
result = get_geometryFactory()->createMultiLineString(curve_vector);
1296
result->setUserData((void*)GMLSF_MULTICURVE);
1298
}catch(std::exception &excep)
1300
std::vector<geos::geom::Geometry*>::iterator vec_it;
1301
for(vec_it = curve_vector->begin(); vec_it != curve_vector->end(); vec_it++)
1305
delete curve_vector;
1306
std::stringstream lErrorMessage;
1307
lErrorMessage << "Error in GEOS function createMultiLineString : " << excep.what();
1308
throwError("GEOSError", lErrorMessage.str());
1312
case GMLSF_MULTISURFACE:
1314
Iterator_t multisurface_children;
1316
std::vector<geos::geom::Geometry*> *surface_vector = NULL;
1317
if(what_action == BUILD_GEOS_GEOMETRY)
1319
surface_vector = new std::vector<geos::geom::Geometry*>;
1321
else if(what_action == COUNT_CHILDREN)
1323
(*optional_child_index_or_count) = 0;
1325
unsigned int nr_child = 0;
1326
multisurface_children = lItem.getChildren();
1327
multisurface_children->open();
1328
while(multisurface_children->next(surface_item))
1330
if(surface_item.getNodeKind() != store::StoreConsts::elementNode)
1333
surface_item.getNodeName(item_qname);
1334
String item_namespace = item_qname.getNamespace();
1335
if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
1337
std::stringstream lErrorMessage;
1338
lErrorMessage << "Children of gml:MultiSurface must be gml:Polygon";
1339
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1341
String item_name = item_qname.getLocalName();
1342
if(!item_name.byteEqual("Polygon", 7))
1344
std::stringstream lErrorMessage;
1345
lErrorMessage << "Children of gml:MultiSurface must be gml:Polygon";
1346
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1348
if(what_action == BUILD_GEOS_GEOMETRY)
1350
surface_vector->push_back(buildGeosGeometryFromItem(surface_item, GMLSF_POLYGON, srs_dim));
1352
else if(what_action == COUNT_CHILDREN)
1354
(*optional_child_index_or_count)++;
1356
else if(what_action == GET_NTH_CHILD)
1358
if((*optional_child_index_or_count) == nr_child)
1360
*result_item = surface_item;
1366
std::stringstream lErrorMessage;
1367
lErrorMessage << "Error in GMLSF_MULTICURVE";
1368
throwError("InternalError", lErrorMessage.str());
1372
if(what_action == BUILD_GEOS_GEOMETRY)
1375
result = get_geometryFactory()->createMultiPolygon(surface_vector);
1376
result->setUserData((void*)GMLSF_MULTISURFACE);
1378
}catch(std::exception &excep)
1380
std::vector<geos::geom::Geometry*>::iterator vec_it;
1381
for(vec_it = surface_vector->begin(); vec_it != surface_vector->end(); vec_it++)
1385
delete surface_vector;
1386
std::stringstream lErrorMessage;
1387
lErrorMessage << "Error in GEOS function createMultiPolygon : " << excep.what();
1388
throwError("GEOSError", lErrorMessage.str());
1392
case GMLSF_MULTIGEOMETRY:
1394
Iterator_t multigeometry_children;
1396
std::vector<geos::geom::Geometry*> *geometry_vector = NULL;
1397
if(what_action == BUILD_GEOS_GEOMETRY)
1399
geometry_vector = new std::vector<geos::geom::Geometry*>;
1401
else if(what_action == COUNT_CHILDREN)
1403
(*optional_child_index_or_count) = 0;
1405
unsigned int nr_child = 0;
1406
multigeometry_children = lItem.getChildren();
1407
multigeometry_children->open();
1408
while(multigeometry_children->next(geometry_item))
1410
if(geometry_item.getNodeKind() != store::StoreConsts::elementNode)
1413
geometry_item.getNodeName(item_qname);
1414
String item_namespace = item_qname.getNamespace();
1415
if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
1417
std::stringstream lErrorMessage;
1418
lErrorMessage << "Children of gml:MultiGeometry must be gml:geometryMember or gml:geometryMembers";
1419
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1421
String item_name = item_qname.getLocalName();
1422
if(item_name.byteEqual("geometryMember", 14) || item_name.byteEqual("geometryMembers", 15))
1424
Iterator_t member_children;
1426
member_children = geometry_item.getChildren();
1427
member_children->open();
1428
while(member_children->next(member_item))
1430
if(what_action == BUILD_GEOS_GEOMETRY)
1432
geometry_vector->push_back(buildGeosGeometryFromItem(member_item, getGmlSFGeometricType(member_item), srs_dim));
1434
else if(what_action == COUNT_CHILDREN)
1436
(*optional_child_index_or_count)++;
1438
else if(what_action == GET_NTH_CHILD)
1440
if((*optional_child_index_or_count) == nr_child)
1442
*result_item = member_item;
1448
std::stringstream lErrorMessage;
1449
lErrorMessage << "Error in GMLSF_MULTIGEOMETRY";
1450
throwError("InternalError", lErrorMessage.str());
1457
std::stringstream lErrorMessage;
1458
lErrorMessage << "Children of gml:MultiGeometry must be gml:geometryMember or gml:geometryMembers";
1459
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1462
if(what_action == BUILD_GEOS_GEOMETRY)
1465
result = get_geometryFactory()->createGeometryCollection(geometry_vector);
1466
result->setUserData((void*)GMLSF_MULTIGEOMETRY);
1468
}catch(std::exception &excep)
1470
std::vector<geos::geom::Geometry*>::iterator vec_it;
1471
for(vec_it = geometry_vector->begin(); vec_it != geometry_vector->end(); vec_it++)
1475
delete geometry_vector;
1476
std::stringstream lErrorMessage;
1477
lErrorMessage << "Error in GEOS function createGeometryCollection : " << excep.what();
1478
throwError("GEOSError", lErrorMessage.str());
1485
std::stringstream lErrorMessage;
1486
zorba::Item item_qname;
1487
lItem.getNodeName(item_qname);
1488
lErrorMessage << "Unrecognized geometric type for element "
1489
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
1490
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1498
void GeoFunction::addNewLineIndentText(zorba::Item &parent, unsigned int indent) const
1500
/* zorba::Item text_item;
1504
strtemp = new char[indent+10];
1506
memset(strtemp+1, ' ', indent);
1507
strtemp[1+indent] = 0;
1508
text_item = theModule->getItemFactory()->createTextNode(parent, strtemp);
1513
void GeoFunction::appendIndent(char *&strtemp2, unsigned int indent) const
1516
memset(strtemp2+1, ' ', indent);
1517
strtemp2 += indent+1;
1521
zorba::Item GeoFunction::getGMLItemFromGeosGeometry(zorba::Item &parent,
1522
const geos::geom::Geometry *geos_geometry,
1523
const zorba::Item *srs_uri,
1524
unsigned int indent,
1525
const char *tag_name,
1526
bool dont_check_for_curve_surface
1529
zorba::Item result_item;
1530
zorba::Item item_name;
1531
zorba::Item item_type;
1532
std::vector<std::pair<String, String> > ns_binding;
1533
ns_binding.push_back(std::pair<String, String>("gml", "http://www.opengis.net/gml"));
1534
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
1536
if(!parent.isNull())
1537
addNewLineIndentText(parent, indent);
1539
switch(geos_geometry->getGeometryTypeId())
1541
case geos::geom::GEOS_POINT:
1543
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "Point");
1544
result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
1546
zorba::Item pos_item;
1547
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
1548
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "pos");
1549
addNewLineIndentText(result_item, indent+2);
1550
pos_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
1553
const geos::geom::Coordinate *c;
1554
c = geos_geometry->getCoordinate();
1555
#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
1556
if(geos_geometry->getCoordinateDimension() == 3)
1558
if(getCoordinateDimension(geos_geometry) == 3)
1561
zorba::Item attr_value_item;
1562
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
1563
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "srsDimension");
1564
zorba::String strvalue("3");
1565
attr_value_item = theModule->getItemFactory()->createString(strvalue);
1566
theModule->getItemFactory()->createAttributeNode(pos_item, item_name, item_type, attr_value_item);
1568
sprintf(strtemp, "%lf %lf %lf", c->x, c->y, c->z);
1570
sprintf(strtemp, "%lf %lf 0", c->x, c->y);
1573
sprintf(strtemp, "%lf %lf", c->x, c->y);
1575
zorba::Item text_item;
1576
text_item = theModule->getItemFactory()->createTextNode(pos_item, strtemp);
1577
addNewLineIndentText(result_item, indent);
1581
case geos::geom::GEOS_LINESTRING:
1582
/// a linear ring (linestring with 1st point == last point)
1583
case geos::geom::GEOS_LINEARRING:
1585
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml",
1586
tag_name ? tag_name : ((geos_geometry->getGeometryTypeId() == geos::geom::GEOS_LINESTRING) ? "LineString" : "LinearRing"));
1587
result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
1589
zorba::Item pos_item;
1590
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
1591
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "posList");
1592
addNewLineIndentText(result_item, indent+2);
1593
pos_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
1595
#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
1596
int coord_dim = geos_geometry->getCoordinateDimension();
1598
int coord_dim = getCoordinateDimension(geos_geometry);
1602
zorba::Item attr_value_item;
1603
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
1604
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "srsDimension");
1605
zorba::String strvalue("3");
1606
attr_value_item = theModule->getItemFactory()->createString(strvalue);
1607
theModule->getItemFactory()->createAttributeNode(pos_item, item_name, item_type, attr_value_item);
1610
std::auto_ptr<geos::geom::CoordinateSequence> cs;
1611
cs.reset(geos_geometry->getCoordinates());
1612
size_t cs_size = cs->getSize();
1613
strtemp = (char*)malloc((50+indent)*(cs_size+1) + 1);
1615
char *strtemp2 = strtemp;
1616
for(size_t i=0;i<cs_size;i++)
1618
appendIndent(strtemp2, indent+4);
1621
if(!ISNAN(cs->getAt(i).z))
1622
sprintf(strtemp2, "%lf %lf %lf", cs->getAt(i).x, cs->getAt(i).y, cs->getAt(i).z);
1624
sprintf(strtemp2, "%lf %lf 0", cs->getAt(i).x, cs->getAt(i).y);
1627
sprintf(strtemp2, "%lf %lf", cs->getAt(i).x, cs->getAt(i).y);
1628
strtemp2 += strlen(strtemp2);
1633
appendIndent(strtemp2, indent+2);
1634
zorba::Item text_item;
1635
text_item = theModule->getItemFactory()->createTextNode(pos_item, strtemp);
1636
addNewLineIndentText(result_item, indent);
1642
case geos::geom::GEOS_POLYGON:
1644
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", tag_name ? tag_name : "Polygon");
1645
result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
1647
const geos::geom::LineString* exterior_ring;
1648
const geos::geom::Polygon *polygon = dynamic_cast<const geos::geom::Polygon*>(geos_geometry);
1649
exterior_ring = polygon->getExteriorRing();
1652
zorba::Item exterior_item;
1653
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
1654
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "exterior");
1655
addNewLineIndentText(result_item, indent+2);
1656
exterior_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
1657
getGMLItemFromGeosGeometry(exterior_item, exterior_ring, NULL, indent+4);
1658
addNewLineIndentText(exterior_item, indent+2);
1660
size_t interior_rings = polygon->getNumInteriorRing();
1661
for(size_t i=0;i<interior_rings;i++)
1663
const geos::geom::LineString* interior_ring;
1664
interior_ring = polygon->getInteriorRingN(i);
1666
zorba::Item interior_item;
1667
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
1668
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "interior");
1669
addNewLineIndentText(result_item, indent+2);
1670
interior_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
1671
getGMLItemFromGeosGeometry(interior_item, interior_ring, NULL, indent+4);
1672
addNewLineIndentText(interior_item, indent+2);
1674
if(exterior_ring || interior_rings)
1675
addNewLineIndentText(result_item, indent);
1678
/// a collection of points
1679
case geos::geom::GEOS_MULTIPOINT:
1681
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "MultiPoint");
1682
result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
1684
size_t nr_geoms = geos_geometry->getNumGeometries();
1685
for(size_t i=0;i<nr_geoms;i++)
1687
const geos::geom::Geometry *point;
1688
point = geos_geometry->getGeometryN(i);
1689
getGMLItemFromGeosGeometry(result_item, point, NULL, indent+2);
1692
addNewLineIndentText(result_item, indent);
1695
/// a collection of linestrings
1696
case geos::geom::GEOS_MULTILINESTRING:
1698
const geos::geom::MultiLineString *multiline = dynamic_cast<const geos::geom::MultiLineString*>(geos_geometry);
1699
if(!dont_check_for_curve_surface && isCurve(multiline))
1701
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "Curve");
1702
result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
1703
zorba::Item segments_item;
1704
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
1705
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "segments");
1706
addNewLineIndentText(result_item, indent+2);
1707
segments_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
1709
size_t nr_geoms = multiline->getNumGeometries();
1710
for(size_t i=0;i<nr_geoms;i++)
1712
const geos::geom::Geometry *linestring;
1713
linestring = multiline->getGeometryN(i);
1715
zorba::Item linestring_item;
1716
linestring_item = getGMLItemFromGeosGeometry(segments_item, linestring, NULL, indent+4, "LineStringSegment");
1718
zorba::Item attr_value_item;
1719
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
1720
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "interpolation");
1721
zorba::String strvalue("liniar");
1722
attr_value_item = theModule->getItemFactory()->createString(strvalue);
1723
theModule->getItemFactory()->createAttributeNode(linestring_item, item_name, item_type, attr_value_item);
1726
addNewLineIndentText(segments_item, indent+2);
1727
addNewLineIndentText(result_item, indent);
1731
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "MultiCurve");
1732
result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
1734
size_t nr_geoms = geos_geometry->getNumGeometries();
1735
for(size_t i=0;i<nr_geoms;i++)
1737
const geos::geom::Geometry *linestring;
1738
linestring = geos_geometry->getGeometryN(i);
1739
getGMLItemFromGeosGeometry(result_item, linestring, NULL, indent+2);
1742
addNewLineIndentText(result_item, indent);
1746
/// a collection of polygons
1747
case geos::geom::GEOS_MULTIPOLYGON:
1749
const geos::geom::MultiPolygon *multipoly = dynamic_cast<const geos::geom::MultiPolygon*>(geos_geometry);
1750
if(!dont_check_for_curve_surface && isSurface(multipoly))
1752
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "Surface");
1753
result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
1754
zorba::Item patches_item;
1755
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
1756
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "patches");
1757
addNewLineIndentText(result_item, indent+2);
1758
patches_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
1760
size_t nr_geoms = multipoly->getNumGeometries();
1761
for(size_t i=0;i<nr_geoms;i++)
1763
const geos::geom::Geometry *polygon;
1764
polygon = multipoly->getGeometryN(i);
1766
zorba::Item polygon_item;
1767
polygon_item = getGMLItemFromGeosGeometry(patches_item, polygon, NULL, indent+4, "PolygonPatch");
1770
addNewLineIndentText(patches_item, indent+2);
1771
addNewLineIndentText(result_item, indent);
1775
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "MultiSurface");
1776
result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
1778
size_t nr_geoms = geos_geometry->getNumGeometries();
1779
for(size_t i=0;i<nr_geoms;i++)
1781
const geos::geom::Geometry *polygon;
1782
polygon = geos_geometry->getGeometryN(i);
1783
getGMLItemFromGeosGeometry(result_item, polygon, NULL, indent+2);
1786
addNewLineIndentText(result_item, indent);
1790
/// a collection of heterogeneus geometries
1791
case geos::geom::GEOS_GEOMETRYCOLLECTION:
1793
size_t nr_geoms = geos_geometry->getNumGeometries();
1796
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "MultiGeometry");
1797
result_item = theModule->getItemFactory()->createElementNode(parent, item_name, item_type, false, false, ns_binding);
1799
for(size_t i=0;i<nr_geoms;i++)
1801
zorba::Item geometryMember_item;
1802
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
1803
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "geometryMember");
1804
addNewLineIndentText(result_item, indent+2);
1805
geometryMember_item = theModule->getItemFactory()->createElementNode(result_item, item_name, item_type, false, false, ns_binding);
1806
const geos::geom::Geometry *member;
1807
member = geos_geometry->getGeometryN(i);
1809
zorba::Item geometry_item;
1810
geometry_item = getGMLItemFromGeosGeometry(geometryMember_item, member, NULL, indent+4 );
1811
if(!geometry_item.isNull())
1812
addNewLineIndentText(geometryMember_item, indent+2);
1815
addNewLineIndentText(result_item, indent);
1820
std::stringstream lErrorMessage;
1821
lErrorMessage << "Geometry type " << geos_geometry->getGeometryType() << " is not supported";
1822
throwError("UnrecognizedGeoObject", lErrorMessage.str());
1826
if(!result_item.isNull() && srs_uri && !srs_uri->isNull())
1828
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
1829
item_name = theModule->getItemFactory()->createQName("", "srsName");
1830
zorba::String strvalue = srs_uri->getStringValue();
1831
zorba::Item attr_value_item = theModule->getItemFactory()->createString(strvalue);
1832
theModule->getItemFactory()->createAttributeNode(result_item, item_name, item_type, attr_value_item);
1835
// if(!parent.isNull())
1836
// addNewLineIndentText(parent, indent);
1840
/*see if the end point from one segment is the start point for the next segment*/
1841
bool GeoFunction::isCurve(const geos::geom::MultiLineString *multiline) const
1843
geos::geom::MultiLineString::const_iterator line_it;
1844
std::auto_ptr<geos::geom::Point> end_point;
1845
for(line_it = multiline->begin(); line_it != multiline->end(); line_it++)
1847
const geos::geom::LineString *linestring = dynamic_cast<const geos::geom::LineString*>(*line_it);
1850
std::auto_ptr<geos::geom::Point> start_point;
1851
start_point.reset(linestring->getStartPoint());
1852
if(start_point->compareTo(end_point.get()))
1855
end_point.reset(linestring->getEndPoint());
1860
bool GeoFunction::isClosedCurve(const geos::geom::Geometry *geos_geometry) const
1862
//Curve is a MultiLineString
1863
const geos::geom::MultiLineString *curve = dynamic_cast<const geos::geom::MultiLineString *>(geos_geometry);
1864
unsigned int num_segments = (unsigned int)curve->getNumGeometries();
1868
//see if last point of a segment is the first of the next
1869
const geos::geom::LineString *segment1 = dynamic_cast<const geos::geom::LineString *>(curve->getGeometryN(0));
1870
std::auto_ptr<const geos::geom::CoordinateSequence> coords1(segment1->getCoordinates());
1871
const geos::geom::LineString *segment2;
1872
std::auto_ptr<const geos::geom::CoordinateSequence> coords2;
1873
for(i=1;i<num_segments;i++)
1875
segment2 = dynamic_cast<const geos::geom::LineString *>(curve->getGeometryN(i));
1876
coords2.reset(segment2->getCoordinates());
1877
if(!coords1->getAt(coords1->size()-1).equals(coords2->getAt(0)))
1880
segment1 = segment2;
1882
//check if last point is the same as the first point of the curve
1883
segment2 = dynamic_cast<const geos::geom::LineString *>(curve->getGeometryN(0));
1884
coords2.reset(segment2->getCoordinates());
1885
if(!coords1->getAt(coords1->size()-1).equals(coords2->getAt(0)))
1891
geos::geom::LineString *GeoFunction::curveToLineString(const geos::geom::Geometry *geos_geometry) const
1893
const geos::geom::MultiLineString *curve = dynamic_cast<const geos::geom::MultiLineString *>(geos_geometry);
1896
unsigned int num_segments = (unsigned int)curve->getNumGeometries();
1899
const geos::geom::LineString *segment;
1900
std::auto_ptr<const geos::geom::CoordinateSequence> coords;
1901
geos::geom::CoordinateSequence *linestring_coords = geos::geom::CoordinateArraySequenceFactory::instance()->create((std::size_t)0, 2);
1903
for(i=0;i<num_segments;i++)
1905
segment = dynamic_cast<const geos::geom::LineString *>(curve->getGeometryN(i));
1906
coords.reset(segment->getCoordinates());
1907
linestring_coords->add(coords.get(), true, true);
1909
geos::geom::LineString *linestring = get_geometryFactory()->createLineString(linestring_coords);
1910
linestring->setUserData((void*)GMLSF_LINESTRING);
1915
bool GeoFunction::isRingCurve(const geos::geom::Geometry *geos_geometry) const
1917
geos::geom::LineString *linestring;
1918
linestring = curveToLineString(geos_geometry);
1923
retval = linestring->isRing();
1929
bool GeoFunction::isSimpleCurve(const geos::geom::Geometry *geos_geometry) const
1931
geos::geom::LineString *linestring;
1932
linestring = curveToLineString(geos_geometry);
1937
retval = linestring->isSimple();
1943
/*see if each polygon touches another polygon by at least a segment of external line and they are all connected together*/
1944
bool GeoFunction::isSurface(const geos::geom::MultiPolygon *multipolygon,
1946
geos::geom::LinearRing **exterior_boundary) const
1951
double x1, y1, x2, y2;
1956
std::vector<struct _tline> lines;
1957
bool processed, touched;
1959
std::vector<struct _tpoly> polys;
1962
if(!multipolygon->getNumGeometries())
1964
polys.reserve(multipolygon->getNumGeometries());
1965
geos::geom::MultiPolygon::const_iterator poly_it;
1966
for(poly_it = multipolygon->begin(); poly_it != multipolygon->end(); poly_it++, p++)
1968
polys[p].processed = false;
1969
polys[p].touched = false;
1970
const geos::geom::Polygon *polygon = dynamic_cast<const geos::geom::Polygon*>(*poly_it);
1971
const geos::geom::LineString* exterior_ring;
1973
const geos::geom::Point *point;
1974
exterior_ring = polygon->getExteriorRing();
1975
nr_points = exterior_ring->getNumPoints();
1976
polys[p].lines.reserve(nr_points);
1977
for(l=0; l<nr_points; l++)
1979
point = dynamic_cast<const geos::geom::Point*>(exterior_ring->getGeometryN(l));
1980
//polys[p].lines[l].taken = false;
1981
polys[p].lines[l].x1 = point->getX();
1982
polys[p].lines[l].y1 = point->getY();
1985
polys[p].lines[l-1].x2 = point->getX();
1986
polys[p].lines[l-1].y2 = point->getY();
1990
polys[p].lines[nr_points-1].x2 = point->getX();
1991
polys[p].lines[nr_points-1].y2 = point->getY();
1997
std::vector<struct _tpoly>::iterator tpoly_it;
1998
bool first_round = true;
2002
tpoly_it = polys.begin();
2007
for(tpoly_it = polys.begin(); tpoly_it != polys.end(); tpoly_it++)
2010
if((*tpoly_it).processed)
2012
else if((*tpoly_it).touched)
2015
if(tpoly_it == polys.end())
2017
if(total == processed)
2023
first_round = false;
2024
(*tpoly_it).processed = true;
2025
//for every line, check there is at most one match with other line from other polygon
2026
std::vector<struct _tline>::iterator line_it;
2027
int all_matches = 0;
2028
for(line_it = (*tpoly_it).lines.begin(); line_it != (*tpoly_it).lines.end(); line_it++)
2031
std::vector<struct _tpoly>::iterator tpoly_it2;
2032
for(tpoly_it2 = polys.begin(); tpoly_it2 != polys.end(); tpoly_it2++)
2034
if((*tpoly_it2).processed)
2036
std::vector<struct _tline>::iterator line_it2;
2037
for(line_it2 = (*tpoly_it2).lines.begin(); line_it2 != (*tpoly_it2).lines.end(); line_it2++)
2039
if(((*line_it2).x1 == (*line_it).x1) && ((*line_it2).y1 == (*line_it).y1) &&
2040
((*line_it2).x2 == (*line_it).x2) && ((*line_it2).y2 == (*line_it).y2) ||
2041
((*line_it2).x1 == (*line_it).x2) && ((*line_it2).y1 == (*line_it).y2) &&
2042
((*line_it2).x2 == (*line_it).x1) && ((*line_it2).y2 == (*line_it).y1))
2044
(*tpoly_it2).touched = true;
2051
all_matches += matches;
2059
//another approach, using LineString::overlaps and LineString::intersection
2060
//test each polygon if it touches another polygon and if they form a united surface
2061
//all common boundaries should be disjoint
2063
std::vector<int> ids;
2065
unsigned int nr_patches = (unsigned int)multipolygon->getNumGeometries();
2068
ids.resize(nr_patches);
2069
for(i=0;i<nr_patches;i++)
2071
ids[i] = 1;//will be set -i-1 if it is touched by another polygon, and to zero when processed
2076
if(exterior_boundary)
2077
*exterior_boundary = NULL;
2079
std::vector<geos::geom::Geometry*> boundary_segments;//for computing exterior_boundary
2086
for(i=0;i<nr_patches;i++)
2094
std::vector<geos::geom::Geometry*> common_segments;
2095
const geos::geom::Polygon *patch1 = dynamic_cast<const geos::geom::Polygon *>(multipolygon->getGeometryN(i));
2096
const geos::geom::LineString *ring1 = patch1->getExteriorRing();
2098
for(unsigned int j=0;(j<nr_patches);j++)
2102
const geos::geom::Polygon *patch2 = dynamic_cast<const geos::geom::Polygon *>(multipolygon->getGeometryN(j));
2103
const geos::geom::LineString *ring2 = patch2->getExteriorRing();
2104
geos::geom::Geometry* segment;
2105
segment = ring1->intersection(ring2);
2108
for(unsigned int s=0;s<segment->getNumGeometries();s++)
2110
const geos::geom::Geometry *seg_piece = segment->getGeometryN(s);
2112
if((seg_piece->getGeometryTypeId() == geos::geom::GEOS_LINESTRING) ||
2113
(seg_piece->getGeometryTypeId() == geos::geom::GEOS_MULTILINESTRING))
2117
for(unsigned int k=0;k<common_segments.size();k++)
2119
if(seg_piece->overlaps(common_segments[k]))
2122
for(unsigned int c=0;c<common_segments.size();c++)
2123
delete common_segments[c];
2124
for(unsigned int b=0;b<boundary_segments.size();b++)
2125
delete boundary_segments[b];
2129
common_segments.push_back(seg_piece->clone());
2135
if((is_closed && *is_closed) || exterior_boundary)
2137
if(!common_segments.size())
2144
geos::geom::Geometry *segment_union;
2145
geos::geom::Geometry *temp_union;
2146
segment_union = common_segments[0]->clone();
2147
for(unsigned int c=1;c<common_segments.size();c++)
2149
temp_union = segment_union->Union(common_segments[c]);
2150
delete segment_union;
2151
segment_union = temp_union;
2153
if(!segment_union->equals(ring1))
2157
if(exterior_boundary)
2159
geos::geom::Geometry *diff;
2160
diff = ring1->difference(segment_union);
2161
boundary_segments.push_back(diff);
2164
delete segment_union;
2167
for(unsigned int c=0;c<common_segments.size();c++)
2168
delete common_segments[c];
2169
common_segments.clear();
2172
if(is_united && exterior_boundary)
2174
//do manual union of boundary_segments
2175
//std::vector<const geos::geom::Point *> points;
2176
geos::geom::CoordinateSequence *cl = NULL;
2178
std::vector<const geos::geom::LineString *> segments;
2179
size_t nr_segments = 0;
2180
for(unsigned int b=0;b<boundary_segments.size();b++)
2182
nr_segments += boundary_segments[b]->getNumGeometries();
2184
//points.reserve(nr_segments*4);
2185
segments.reserve(nr_segments);
2186
for(unsigned int b=0;b<boundary_segments.size();b++)
2188
geos::geom::Geometry* segm = boundary_segments[b];
2189
for(unsigned int s=0;s<segm->getNumGeometries();s++)
2191
const geos::geom::Geometry* part = segm->getGeometryN(s);
2192
if(part->getGeometryTypeId() == geos::geom::GEOS_LINESTRING)
2194
segments.push_back(dynamic_cast<const geos::geom::LineString *>(part));
2198
const geos::geom::Geometry* part = segments[0];
2202
#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
2203
srs_dim = part->getCoordinateDimension();
2205
srs_dim = getCoordinateDimension(part);
2207
cl = geos::geom::CoordinateArraySequenceFactory::instance()->create((std::size_t)0, srs_dim);
2209
std::auto_ptr<const geos::geom::CoordinateSequence> coords(part->getCoordinates());
2210
cl->add(coords.get(), false, true);
2215
const geos::geom::Coordinate &last_point = cl->getAt(cl->size()-1);
2216
bool added_points = false;
2217
for(unsigned int s=1;s<segments.size();s++)
2221
const geos::geom::Geometry *segmn = segments[s];
2222
std::auto_ptr<geos::geom::CoordinateSequence> coords(segmn->getCoordinates());
2223
geos::geom::Coordinate point = coords->getAt(0);
2224
if(last_point.equals(point))
2226
cl->add(coords.get(), false, true);
2228
added_points = true;
2233
point = coords->getAt(coords->size()-1);
2234
if(last_point.equals(point))
2236
cl->add(coords.get(), false, false);
2238
added_points = true;
2246
cl->add(cl->getAt(0), false);
2247
*exterior_boundary = get_geometryFactory()->createLinearRing(cl);
2248
(*exterior_boundary)->setUserData((void*)GMLSF_LINEARRING);
2249
for(unsigned int b=0;b<boundary_segments.size();b++)
2250
delete boundary_segments[b];
2255
///////////////////////////////////////////////////////////////////////
2257
SFDimensionFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2258
const StaticContext* aSctxCtx,
2259
const DynamicContext* aDynCtx) const
2262
gmlsf_types geometric_type;
2263
geometric_type = getGeometryNodeType(args, 0, lItem);
2265
std::auto_ptr<geos::geom::Geometry> geos_geometry(buildGeosGeometryFromItem(lItem, geometric_type, -1));
2267
geos::geom::Dimension::DimensionType dim_type = geos::geom::Dimension::DONTCARE;
2269
dim_type = geos_geometry->getDimension();
2270
}catch(std::exception &excep)
2272
std::stringstream lErrorMessage;
2273
lErrorMessage << "Error in GEOS function getDimension : " << excep.what();
2274
throwError("GEOSError", lErrorMessage.str());
2277
return ItemSequence_t(new SingletonItemSequence(
2278
theModule->getItemFactory()->createInteger((int)dim_type)));
2281
///////////////////////////////////////////////////////////////////////
2283
SFCoordinateDimensionFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2284
const StaticContext* aSctxCtx,
2285
const DynamicContext* aDynCtx) const
2288
gmlsf_types geometric_type;
2289
geometric_type = getGeometryNodeType(args, 0, lItem);
2291
switch(geometric_type)
2295
std::stringstream lErrorMessage;
2296
zorba::Item item_qname;
2297
lItem.getNodeName(item_qname);
2298
lErrorMessage << "Unrecognized geometric type for element "
2299
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
2300
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2307
std::auto_ptr<geos::geom::Geometry> geos_geometry(buildGeosGeometryFromItem(lItem, geometric_type, -1));
2309
#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
2310
int coord_dim = geos_geometry->getCoordinateDimension();
2312
int coord_dim = getCoordinateDimension(geos_geometry.get());
2314
return ItemSequence_t(new SingletonItemSequence(
2315
theModule->getItemFactory()->createInteger(coord_dim)));
2318
///////////////////////////////////////////////////////////////////////
2320
SFGeometryTypeFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2321
const StaticContext* aSctxCtx,
2322
const DynamicContext* aDynCtx) const
2325
gmlsf_types geometric_type;
2326
geometric_type = getGeometryNodeType(args, 0, lItem);
2328
zorba::String type_string;
2329
switch(geometric_type)
2332
type_string = "Point";break;
2333
case GMLSF_LINESTRING:
2334
type_string = "LineString";break;
2336
type_string = "Curve";break;
2337
case GMLSF_LINEARRING:
2338
type_string = "LineString";break;
2340
type_string = "Surface";break;
2342
//case GMLSF_POLYGONPATCH:
2343
type_string = "Polygon";break;
2344
case GMLSF_MULTIPOINT:
2345
type_string = "MultiPoint";break;
2346
case GMLSF_MULTICURVE:
2347
type_string = "MultiCurve";break;
2348
case GMLSF_MULTISURFACE:
2349
type_string = "MultiSurface";break;
2350
case GMLSF_MULTIGEOMETRY:
2351
type_string = "MultiGeometry";break;
2356
std::stringstream lErrorMessage;
2357
zorba::Item item_qname;
2358
lItem.getNodeName(item_qname);
2359
lErrorMessage << "Unrecognized geometric type for element "
2360
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
2361
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2366
if(!type_string.empty())
2368
String gmlns("http://www.opengis.net/gml");
2369
String gmlprefix("gml");
2370
return ItemSequence_t(new SingletonItemSequence(
2371
theModule->getItemFactory()->createQName(gmlns, gmlprefix, type_string)));
2375
return ItemSequence_t(NULL);//new EmptySequence());
2379
///////////////////////////////////////////////////////////////////////
2381
SFNumGeometriesFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2382
const StaticContext* aSctxCtx,
2383
const DynamicContext* aDynCtx) const
2386
gmlsf_types geometric_type;
2387
geometric_type = getGeometryNodeType(args, 0, lItem);
2389
switch(geometric_type)
2392
case GMLSF_LINESTRING:
2394
case GMLSF_LINEARRING:
2395
//case GMLSF_SURFACE:
2397
return ItemSequence_t(new SingletonItemSequence(
2398
theModule->getItemFactory()->createUnsignedInt(1)));
2401
std::stringstream lErrorMessage;
2402
zorba::Item item_qname;
2403
lItem.getNodeName(item_qname);
2404
lErrorMessage << "Unrecognized geometric type for element "
2405
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
2406
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2413
uint32_t num_geos = 0;
2414
buildGeosGeometryFromItem(lItem, geometric_type, -1, NULL, COUNT_CHILDREN, &num_geos);
2416
return ItemSequence_t(new SingletonItemSequence(
2417
theModule->getItemFactory()->createUnsignedInt(num_geos)));
2421
SFGeometryNFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2422
const StaticContext* aSctxCtx,
2423
const DynamicContext* aDynCtx) const
2426
gmlsf_types geometric_type1;
2427
geometric_type1 = getGeometryNodeType(args, 0, lItem1);
2429
switch(geometric_type1)
2433
std::stringstream lErrorMessage;
2434
zorba::Item item_qname1;
2435
lItem1.getNodeName(item_qname1);
2436
lErrorMessage << "Unrecognized geometric type for element "
2437
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter.";
2438
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2446
Iterator_t arg1_iter = args[1]->getIterator();
2448
if (!arg1_iter->next(lItem2))
2450
std::stringstream lErrorMessage;
2451
lErrorMessage << "An empty-sequence is not allowed as second parameter";
2452
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2457
n = lItem2.getUnsignedIntValue();
2459
switch(geometric_type1)
2462
case GMLSF_LINESTRING:
2464
case GMLSF_LINEARRING:
2465
//case GMLSF_SURFACE:
2468
return ItemSequence_t(new SingletonItemSequence(lItem1));
2471
std::stringstream lErrorMessage;
2472
lErrorMessage << "Index n (" << n << ") is outside the range ";
2473
throwError("IndexOutsideRange", lErrorMessage.str());
2480
buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_CHILD, &n, &nth_child);
2482
if(nth_child.isNull())
2484
std::stringstream lErrorMessage;
2485
lErrorMessage << "Index n (" << n << ") is outside the range ";
2486
throwError("IndexOutsideRange", lErrorMessage.str());
2488
return ItemSequence_t(new SingletonItemSequence(nth_child));
2493
///////////////////////////////////////////////////////////////////////
2494
#define DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_GEOMETRY(sfclass_name, geos_function_name) \
2496
sfclass_name::evaluate(const StatelessExternalFunction::Arguments_t& args, \
2497
const StaticContext* aSctxCtx, \
2498
const DynamicContext* aDynCtx) const \
2501
gmlsf_types geometric_type; \
2502
geometric_type = getGeometryNodeType(args, 0, lItem); \
2504
switch(geometric_type) \
2506
case GMLSF_INVALID: \
2508
std::stringstream lErrorMessage; \
2509
zorba::Item item_qname; \
2510
lItem.getNodeName(item_qname); \
2511
lErrorMessage << "Unrecognized geometric type for element " \
2512
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << "."; \
2513
throwError("UnrecognizedGeoObject", lErrorMessage.str()); \
2520
zorba::Item srs_uri; \
2521
std::auto_ptr<geos::geom::Geometry> geos_geometry(buildGeosGeometryFromItem(lItem, geometric_type, -1, &srs_uri)); \
2523
std::auto_ptr<geos::geom::Geometry> geos_result; \
2525
geos_result.reset(geos_geometry->geos_function_name()); \
2526
}catch(std::exception &excep) \
2528
std::stringstream lErrorMessage; \
2529
lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what(); \
2530
throwError("GEOSError", lErrorMessage.str()); \
2533
zorba::Item null_parent; \
2534
zorba::Item result_item; \
2535
result_item = getGMLItemFromGeosGeometry(null_parent, geos_result.get(), &srs_uri); \
2537
RETURN_RESULT_ITEM; \
2540
//DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_GEOMETRY(SFBoundaryFunction, getBoundary)
2541
DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_GEOMETRY(SFConvexHullFunction, convexHull)
2542
DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_GEOMETRY(SFCentroidFunction, getCentroid)
2543
DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_GEOMETRY(SFPointOnSurfaceFunction, getInteriorPoint)
2545
zorba::Item GeoFunction::getBoundary(geos::geom::Geometry *geos_geometry, zorba::Item srs_uri) const
2547
std::auto_ptr<geos::geom::Geometry> geos_result;
2548
if(geos_geometry->getUserData() == (void*)GMLSF_SURFACE)
2550
geos::geom::LinearRing *exterior_ring;
2551
geos::geom::MultiPolygon* surface = dynamic_cast<geos::geom::MultiPolygon*>(geos_geometry);
2552
if(!isSurface(surface, NULL, &exterior_ring))
2554
std::stringstream lErrorMessage;
2555
lErrorMessage << "Error in Surface : the patches do not form a polyhedral surface";
2556
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2558
std::vector<geos::geom::Geometry*> *rings = new std::vector<geos::geom::Geometry*>;
2559
rings->push_back(exterior_ring);
2560
for(unsigned int i=0;i<surface->getNumGeometries();i++)
2562
const geos::geom::Polygon* polygon = dynamic_cast<const geos::geom::Polygon*>(geos_geometry->getGeometryN(i));
2563
for(unsigned int r=0;r<polygon->getNumInteriorRing();r++)
2565
rings->push_back((geos::geom::LineString*)polygon->getInteriorRingN(r));
2568
geos_result.reset(get_geometryFactory()->createMultiLineString(rings));
2570
/*else if(geometric_type == GMLSF_CURVE)
2572
geos::geom::LineString *linestring = curveToLineString(geos_geometry);
2574
geos_result = linestring->getBoundary();
2575
}catch(std::exception &excep)
2577
std::stringstream lErrorMessage;
2578
lErrorMessage << "Error in GEOS function getBoundary : " << excep.what();
2579
throwError("GEOSError", lErrorMessage.str());
2587
geos_result.reset(geos_geometry->getBoundary());
2588
}catch(std::exception &excep)
2590
std::stringstream lErrorMessage;
2591
lErrorMessage << "Error in GEOS function getBoundary : " << excep.what();
2592
throwError("GEOSError", lErrorMessage.str());
2596
zorba::Item null_parent;
2597
zorba::Item result_item;
2598
result_item = getGMLItemFromGeosGeometry(null_parent, geos_result.get(), &srs_uri, 0, NULL, DONT_CHECK_FOR_CURVE_SURFACE);
2602
void GeoFunction::getMultiGeometryBoundary(geos::geom::Geometry *geos_geometry,
2603
std::vector<zorba::Item> *boundaries,
2604
zorba::Item srs_uri) const
2606
for(unsigned int i=0;i<geos_geometry->getNumGeometries();i++)
2608
geos::geom::Geometry *geom = (geos::geom::Geometry *)geos_geometry->getGeometryN(i);
2609
if(geom->getGeometryTypeId() == geos::geom::GEOS_GEOMETRYCOLLECTION)
2610
getMultiGeometryBoundary(geom, boundaries, srs_uri);
2613
zorba::Item boundary;
2614
boundary = getBoundary(geom, srs_uri);
2615
if(!boundary.isNull())
2616
boundaries->push_back(boundary);
2622
SFBoundaryFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2623
const StaticContext* aSctxCtx,
2624
const DynamicContext* aDynCtx) const
2627
gmlsf_types geometric_type;
2628
geometric_type = getGeometryNodeType(args, 0, lItem);
2630
switch(geometric_type)
2634
std::stringstream lErrorMessage;
2635
zorba::Item item_qname;
2636
lItem.getNodeName(item_qname);
2637
lErrorMessage << "Unrecognized geometric type for element "
2638
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
2639
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2646
std::auto_ptr<geos::geom::Geometry> geos_geometry;
2647
zorba::Item srs_uri;
2648
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1, &srs_uri));
2650
if(geometric_type != GMLSF_MULTIGEOMETRY)
2652
zorba::Item result_item;
2653
result_item = getBoundary(geos_geometry.get(), srs_uri);
2658
std::vector<zorba::Item> boundaries;
2659
getMultiGeometryBoundary(geos_geometry.get(), &boundaries, srs_uri);
2660
return ItemSequence_t(new VectorItemSequence(boundaries));
2665
///////////////////////////////////////////////////////////////////////
2667
SFSridFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2668
const StaticContext* aSctxCtx,
2669
const DynamicContext* aDynCtx) const
2672
gmlsf_types geometric_type;
2673
geometric_type = getGeometryNodeType(args, 0, lItem);
2675
switch(geometric_type)
2679
std::stringstream lErrorMessage;
2680
zorba::Item item_qname;
2681
lItem.getNodeName(item_qname);
2682
lErrorMessage << "Unrecognized geometric type for element "
2683
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
2684
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2691
std::auto_ptr<geos::geom::Geometry> geos_geometry;
2692
zorba::Item srs_uri;
2693
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1, &srs_uri));
2695
if(!srs_uri.isNull())
2696
return ItemSequence_t(new SingletonItemSequence(srs_uri));
2698
return ItemSequence_t(NULL);
2701
///////////////////////////////////////////////////////////////////////
2703
SFEnvelopeFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2704
const StaticContext* aSctxCtx,
2705
const DynamicContext* aDynCtx) const
2708
gmlsf_types geometric_type;
2709
geometric_type = getGeometryNodeType(args, 0, lItem);
2711
switch(geometric_type)
2715
std::stringstream lErrorMessage;
2716
zorba::Item item_qname;
2717
lItem.getNodeName(item_qname);
2718
lErrorMessage << "Unrecognized geometric type for element "
2719
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
2720
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2727
std::auto_ptr<geos::geom::Geometry> geos_geometry;
2728
zorba::Item srs_uri;
2729
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1, &srs_uri));
2731
const geos::geom::Envelope *envelope = NULL;
2733
envelope = geos_geometry->getEnvelopeInternal();
2734
}catch(std::exception &excep)
2736
std::stringstream lErrorMessage;
2737
lErrorMessage << "Error in GEOS function getEnvelopeInternal : " << excep.what();
2738
throwError("GEOSError", lErrorMessage.str());
2742
zorba::Item envelope_item;
2743
zorba::Item corner_item;
2744
zorba::Item item_name;
2745
zorba::Item item_type;
2746
zorba::Item null_parent;
2747
std::vector<std::pair<String, String> > ns_binding;
2749
ns_binding.push_back(std::pair<String, String>("gml", "http://www.opengis.net/gml"));
2750
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
2751
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "Envelope");
2752
envelope_item = theModule->getItemFactory()->createElementNode(null_parent, item_name, item_type, false, false, ns_binding);
2754
if(!srs_uri.isNull())
2756
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
2757
item_name = theModule->getItemFactory()->createQName("", "srsName");
2758
zorba::String strvalue = srs_uri.getStringValue();
2759
zorba::Item attr_value_item = theModule->getItemFactory()->createString(strvalue);
2760
theModule->getItemFactory()->createAttributeNode(envelope_item, item_name, item_type, attr_value_item);
2762
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
2763
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "lowerCorner");
2764
addNewLineIndentText(envelope_item, 2);
2765
corner_item = theModule->getItemFactory()->createElementNode(envelope_item, item_name, item_type, false, false, ns_binding);
2767
sprintf(strtemp, "%lf %lf", envelope->getMinX(), envelope->getMinY());
2768
theModule->getItemFactory()->createTextNode(corner_item, strtemp);
2770
item_type = theModule->getItemFactory()->createQName("http://www.w3.org/2001/XMLSchema", "untyped");
2771
item_name = theModule->getItemFactory()->createQName("http://www.opengis.net/gml", "gml", "upperCorner");
2772
addNewLineIndentText(envelope_item, 2);
2773
corner_item = theModule->getItemFactory()->createElementNode(envelope_item, item_name, item_type, false, false, ns_binding);
2775
sprintf(strtemp, "%lf %lf", envelope->getMaxX(), envelope->getMaxY());
2776
theModule->getItemFactory()->createTextNode(corner_item, strtemp);
2777
addNewLineIndentText(envelope_item, 0);
2779
return ItemSequence_t(new SingletonItemSequence(envelope_item));
2782
///////////////////////////////////////////////////////////////////////
2784
SFAsTextFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2785
const StaticContext* aSctxCtx,
2786
const DynamicContext* aDynCtx) const
2789
gmlsf_types geometric_type;
2790
geometric_type = getGeometryNodeType(args, 0, lItem);
2792
switch(geometric_type)
2796
std::stringstream lErrorMessage;
2797
zorba::Item item_qname;
2798
lItem.getNodeName(item_qname);
2799
lErrorMessage << "Unrecognized geometric type for element "
2800
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
2801
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2808
std::auto_ptr<geos::geom::Geometry> geos_geometry;
2809
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
2811
std::string as_text;
2812
as_text = geos_geometry->toString();
2814
return ItemSequence_t(new SingletonItemSequence(
2815
theModule->getItemFactory()->createString(as_text)));
2818
unsigned char GeoFunction::hex_to_bin(char hex) const
2820
if((hex >= '0') && (hex <= '9'))
2822
else if((hex >= 'a') && (hex <= 'f'))
2824
else if((hex >= 'A') && (hex <= 'F'))
2829
///////////////////////////////////////////////////////////////////////
2831
SFAsBinaryFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2832
const StaticContext* aSctxCtx,
2833
const DynamicContext* aDynCtx) const
2836
gmlsf_types geometric_type;
2837
geometric_type = getGeometryNodeType(args, 0, lItem);
2839
switch(geometric_type)
2843
std::stringstream lErrorMessage;
2844
zorba::Item item_qname;
2845
lItem.getNodeName(item_qname);
2846
lErrorMessage << "Unrecognized geometric type for element "
2847
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
2848
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2855
std::auto_ptr<geos::geom::Geometry> geos_geometry;
2856
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
2858
std::ostringstream as_binary;
2859
as_binary << *geos_geometry;
2861
std::string binary_hex = as_binary.str();
2862
size_t binary_len = binary_hex.size() / 2;
2863
const char *hex_str = binary_hex.c_str();
2864
unsigned char *binary_bin = new unsigned char[binary_len];
2865
for(size_t i=0;i<binary_len;i++)
2867
binary_bin[i] = ((hex_to_bin(hex_str[i*2]) << 4) | hex_to_bin(hex_str[i*2+1]));
2870
zorba::Item base64_item = theModule->getItemFactory()->createBase64Binary(binary_bin, binary_len);
2871
delete[] binary_bin;
2873
return ItemSequence_t(new SingletonItemSequence(base64_item));
2876
///////////////////////////////////////////////////////////////////////
2878
SFIsEmptyFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2879
const StaticContext* aSctxCtx,
2880
const DynamicContext* aDynCtx) const
2883
Iterator_t arg0_iter = args[0]->getIterator();
2885
if (!arg0_iter->next(lItem))
2887
return ItemSequence_t(new SingletonItemSequence(
2888
theModule->getItemFactory()->createBoolean(true)));
2892
if(!lItem.isNode() || (lItem.getNodeKind() != store::StoreConsts::elementNode))
2894
return ItemSequence_t(new SingletonItemSequence(
2895
theModule->getItemFactory()->createBoolean(true)));
2898
GeoFunction::gmlsf_types geotype = getGmlSFGeometricType(lItem);
2899
if(geotype == GMLSF_INVALID)
2901
return ItemSequence_t(new SingletonItemSequence(
2902
theModule->getItemFactory()->createBoolean(true)));
2905
std::auto_ptr<geos::geom::Geometry> geos_geometry;
2906
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geotype, -1));
2908
bool is_empty = false;
2910
is_empty = (geos_geometry->getNumPoints() == 0);
2911
}catch(std::exception &excep)
2913
std::stringstream lErrorMessage;
2914
lErrorMessage << "Error in GEOS function getNumGeometries : " << excep.what();
2915
throwError("GEOSError", lErrorMessage.str());
2918
return ItemSequence_t(new SingletonItemSequence(
2919
theModule->getItemFactory()->createBoolean(is_empty)));
2922
///////////////////////////////////////////////////////////////////////
2924
SFIsSimpleFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2925
const StaticContext* aSctxCtx,
2926
const DynamicContext* aDynCtx) const
2929
gmlsf_types geometric_type;
2930
geometric_type = getGeometryNodeType(args, 0, lItem);
2932
switch(geometric_type)
2936
std::stringstream lErrorMessage;
2937
zorba::Item item_qname;
2938
lItem.getNodeName(item_qname);
2939
lErrorMessage << "Unrecognized geometric type for element "
2940
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
2941
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2948
std::auto_ptr<geos::geom::Geometry> geos_geometry;
2949
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
2951
bool is_simple = false;
2952
if(geometric_type == GMLSF_CURVE)
2954
is_simple = isSimpleCurve(geos_geometry.get());
2959
is_simple = geos_geometry->isSimple();
2960
}catch(std::exception &excep)
2962
std::stringstream lErrorMessage;
2963
lErrorMessage << "Error in GEOS function isSimple : " << excep.what();
2964
throwError("GEOSError", lErrorMessage.str());
2968
return ItemSequence_t(new SingletonItemSequence(
2969
theModule->getItemFactory()->createBoolean(is_simple)));
2972
///////////////////////////////////////////////////////////////////////
2974
SFIs3DFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2975
const StaticContext* aSctxCtx,
2976
const DynamicContext* aDynCtx) const
2979
gmlsf_types geometric_type;
2980
geometric_type = getGeometryNodeType(args, 0, lItem);
2982
switch(geometric_type)
2986
std::stringstream lErrorMessage;
2987
zorba::Item item_qname;
2988
lItem.getNodeName(item_qname);
2989
lErrorMessage << "Unrecognized geometric type for element "
2990
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
2991
throwError("UnrecognizedGeoObject", lErrorMessage.str());
2998
std::auto_ptr<geos::geom::Geometry> geos_geometry;
2999
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
3001
#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
3002
bool is_3D = (geos_geometry->getCoordinateDimension() == 3);
3004
bool is_3D = (getCoordinateDimension(geos_geometry.get()) == 3);//for GEOS 3.2.2
3007
return ItemSequence_t(new SingletonItemSequence(
3008
theModule->getItemFactory()->createBoolean(is_3D)));
3011
///////////////////////////////////////////////////////////////////////
3013
SFIsMeasuredFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3014
const StaticContext* aSctxCtx,
3015
const DynamicContext* aDynCtx) const
3018
gmlsf_types geometric_type;
3019
geometric_type = getGeometryNodeType(args, 0, lItem);
3021
switch(geometric_type)
3025
std::stringstream lErrorMessage;
3026
zorba::Item item_qname;
3027
lItem.getNodeName(item_qname);
3028
lErrorMessage << "Unrecognized geometric type for element "
3029
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
3030
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3037
return ItemSequence_t(new SingletonItemSequence(
3038
theModule->getItemFactory()->createBoolean(false)));
3041
///////////////////////////////////////////////////////////////////////
3043
///////////////////////////////////////////////////////////////////////
3044
#define DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(sfclass_name, geos_function_name) \
3046
sfclass_name::evaluate(const StatelessExternalFunction::Arguments_t& args, \
3047
const StaticContext* aSctxCtx, \
3048
const DynamicContext* aDynCtx) const \
3051
gmlsf_types geometric_type1; \
3052
geometric_type1 = getGeometryNodeType(args, 0, lItem1); \
3054
switch(geometric_type1) \
3056
case GMLSF_INVALID: \
3058
std::stringstream lErrorMessage; \
3059
zorba::Item item_qname1; \
3060
lItem1.getNodeName(item_qname1); \
3061
lErrorMessage << "Unrecognized geometric type for element " \
3062
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter."; \
3063
throwError("UnrecognizedGeoObject", lErrorMessage.str()); \
3071
gmlsf_types geometric_type2; \
3072
geometric_type2 = getGeometryNodeType(args, 1, lItem2); \
3074
switch(geometric_type2) \
3076
case GMLSF_INVALID: \
3078
std::stringstream lErrorMessage; \
3079
zorba::Item item_qname2; \
3080
lItem2.getNodeName(item_qname2); \
3081
lErrorMessage << "Unrecognized geometric type for element " \
3082
<< item_qname2.getPrefix() <<":"<<item_qname2.getLocalName() << " in second parameter."; \
3083
throwError("UnrecognizedGeoObject", lErrorMessage.str()); \
3090
std::auto_ptr<geos::geom::Geometry> geos_geometry1; \
3091
zorba::Item srs_uri1; \
3092
geos_geometry1.reset(buildGeosGeometryFromItem(lItem1, geometric_type1, -1, &srs_uri1)); \
3094
std::auto_ptr<geos::geom::Geometry> geos_geometry2; \
3095
zorba::Item srs_uri2; \
3096
geos_geometry2.reset(buildGeosGeometryFromItem(lItem2, geometric_type2, -1, &srs_uri2)); \
3098
if(!srs_uri1.isNull() && !srs_uri2.isNull() && \
3099
!srs_uri1.getStringValue().equals(srs_uri2.getStringValue())) \
3101
std::stringstream lErrorMessage; \
3102
lErrorMessage << "SrsName is not the same in the two geometries: " << \
3103
srs_uri1.getStringValue() << " vs. " << srs_uri2.getStringValue(); \
3104
throwError("SRSNotIdenticalInBothGeometries", lErrorMessage.str()); \
3107
bool retval = false; \
3109
retval = geos_geometry1->geos_function_name(geos_geometry2.get()); \
3110
}catch(std::exception &excep) \
3112
std::stringstream lErrorMessage; \
3113
lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what(); \
3114
throwError("GEOSError", lErrorMessage.str()); \
3118
return ItemSequence_t(new SingletonItemSequence( \
3119
theModule->getItemFactory()->createBoolean(retval))); \
3122
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFEqualsFunction, equals)
3123
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFCoversFunction, covers)
3124
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFDisjointFunction, disjoint)
3125
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFIntersectsFunction, intersects)
3126
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFTouchesFunction, touches)
3127
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFCrossesFunction, crosses)
3128
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFWithinFunction, within)
3129
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFContainsFunction, contains)
3130
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(SFOverlapsFunction, overlaps)
3132
///////////////////////////////////////////////////////////////////////
3133
#define DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_GEOMETRY(sfclass_name, geos_function_name) \
3135
sfclass_name::evaluate(const StatelessExternalFunction::Arguments_t& args, \
3136
const StaticContext* aSctxCtx, \
3137
const DynamicContext* aDynCtx) const \
3140
gmlsf_types geometric_type1; \
3141
geometric_type1 = getGeometryNodeType(args, 0, lItem1); \
3143
switch(geometric_type1) \
3145
case GMLSF_INVALID: \
3147
std::stringstream lErrorMessage; \
3148
zorba::Item item_qname1; \
3149
lItem1.getNodeName(item_qname1); \
3150
lErrorMessage << "Unrecognized geometric type for element " \
3151
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter."; \
3152
throwError("UnrecognizedGeoObject", lErrorMessage.str()); \
3160
gmlsf_types geometric_type2; \
3161
geometric_type2 = getGeometryNodeType(args, 1, lItem2); \
3163
switch(geometric_type2) \
3165
case GMLSF_INVALID: \
3167
std::stringstream lErrorMessage; \
3168
zorba::Item item_qname2; \
3169
lItem2.getNodeName(item_qname2); \
3170
lErrorMessage << "Unrecognized geometric type for element " \
3171
<< item_qname2.getPrefix() <<":"<<item_qname2.getLocalName() << " in second parameter."; \
3172
throwError("UnrecognizedGeoObject", lErrorMessage.str()); \
3179
std::auto_ptr<geos::geom::Geometry> geos_geometry1; \
3180
zorba::Item srs_uri1; \
3181
geos_geometry1.reset(buildGeosGeometryFromItem(lItem1, geometric_type1, -1, &srs_uri1)); \
3183
std::auto_ptr<geos::geom::Geometry> geos_geometry2; \
3184
zorba::Item srs_uri2; \
3185
geos_geometry2.reset(buildGeosGeometryFromItem(lItem2, geometric_type2, -1, &srs_uri2)); \
3187
if(!srs_uri1.isNull() && !srs_uri2.isNull() && \
3188
!srs_uri1.getStringValue().equals(srs_uri2.getStringValue())) \
3190
std::stringstream lErrorMessage; \
3191
lErrorMessage << "SrsName is not the same in the two geometries: " << \
3192
srs_uri1.getStringValue() << " vs. " << srs_uri2.getStringValue(); \
3193
throwError("SRSNotIdenticalInBothGeometries", lErrorMessage.str()); \
3196
std::auto_ptr<geos::geom::Geometry> geos_result; \
3198
geos_result.reset(geos_geometry1->geos_function_name(geos_geometry2.get())); \
3199
}catch(std::exception &excep) \
3201
std::stringstream lErrorMessage; \
3202
lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what(); \
3203
throwError("GEOSError", lErrorMessage.str()); \
3207
if(srs_uri1.isNull()) \
3208
srs_uri1 = srs_uri2; \
3209
zorba::Item null_parent; \
3210
zorba::Item result_item; \
3211
result_item = getGMLItemFromGeosGeometry(null_parent, geos_result.get(), &srs_uri1); \
3213
RETURN_RESULT_ITEM; \
3217
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_GEOMETRY(SFIntersectionFunction, intersection)
3218
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_GEOMETRY(SFUnionFunction, Union)
3219
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_GEOMETRY(SFDifferenceFunction, difference)
3220
DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_GEOMETRY(SFSymDifferenceFunction, symDifference)
3223
///////////////////////////////////////////////////////////////////////
3224
#define DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_DOUBLE(sfclass_name, geos_function_name) \
3226
sfclass_name::evaluate(const StatelessExternalFunction::Arguments_t& args, \
3227
const StaticContext* aSctxCtx, \
3228
const DynamicContext* aDynCtx) const \
3231
gmlsf_types geometric_type; \
3232
geometric_type = getGeometryNodeType(args, 0, lItem); \
3234
switch(geometric_type) \
3236
case GMLSF_INVALID: \
3238
std::stringstream lErrorMessage; \
3239
zorba::Item item_qname; \
3240
lItem.getNodeName(item_qname); \
3241
lErrorMessage << "Unrecognized geometric type for element " \
3242
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << "."; \
3243
throwError("UnrecognizedGeoObject", lErrorMessage.str()); \
3250
std::auto_ptr<geos::geom::Geometry> geos_geometry; \
3251
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1)); \
3253
double retval = 0; \
3255
retval = geos_geometry->geos_function_name(); \
3256
}catch(std::exception &excep) \
3258
std::stringstream lErrorMessage; \
3259
lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what(); \
3260
throwError("GEOSError", lErrorMessage.str()); \
3263
return ItemSequence_t(new SingletonItemSequence( \
3264
theModule->getItemFactory()->createDouble(retval))); \
3267
DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_DOUBLE(SFAreaFunction, getArea)
3268
DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_DOUBLE(SFLengthFunction, getLength)
3271
SFRelateFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3272
const StaticContext* aSctxCtx,
3273
const DynamicContext* aDynCtx) const
3276
gmlsf_types geometric_type1;
3277
geometric_type1 = getGeometryNodeType(args, 0, lItem1);
3279
switch(geometric_type1)
3283
std::stringstream lErrorMessage;
3284
zorba::Item item_qname1;
3285
lItem1.getNodeName(item_qname1);
3286
lErrorMessage << "Unrecognized geometric type for element "
3287
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter.";
3288
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3296
gmlsf_types geometric_type2;
3297
geometric_type2 = getGeometryNodeType(args, 1, lItem2);
3299
switch(geometric_type2)
3303
std::stringstream lErrorMessage;
3304
zorba::Item item_qname2;
3305
lItem2.getNodeName(item_qname2);
3306
lErrorMessage << "Unrecognized geometric type for third element "
3307
<< item_qname2.getPrefix() <<":"<<item_qname2.getLocalName() << " in second parameter.";
3308
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3315
std::auto_ptr<geos::geom::Geometry> geos_geometry1;
3316
zorba::Item srs_uri1;
3317
geos_geometry1.reset(buildGeosGeometryFromItem(lItem1, geometric_type1, -1, &srs_uri1));
3319
std::auto_ptr<geos::geom::Geometry> geos_geometry2;
3320
zorba::Item srs_uri2;
3321
geos_geometry2.reset(buildGeosGeometryFromItem(lItem2, geometric_type2, -1, &srs_uri2));
3323
if(!srs_uri1.isNull() && !srs_uri2.isNull() &&
3324
!srs_uri1.getStringValue().equals(srs_uri2.getStringValue()))
3326
std::stringstream lErrorMessage;
3327
lErrorMessage << "SrsName is not the same in the two geometries: " <<
3328
srs_uri1.getStringValue() << " vs. " << srs_uri2.getStringValue();
3329
throwError("SRSNotIdenticalInBothGeometries", lErrorMessage.str());
3334
Iterator_t arg2_iter = args[2]->getIterator();
3336
if (!arg2_iter->next(lItem3))
3338
std::stringstream lErrorMessage;
3339
lErrorMessage << "An empty-sequence is not allowed as parameter";
3340
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3344
zorba::String intersection_matrix;
3345
intersection_matrix = lItem3.getStringValue();
3347
bool is_relate = false;
3349
is_relate = geos_geometry1->relate(geos_geometry2.get(), intersection_matrix.c_str());
3350
}catch(std::exception &excep)
3352
std::stringstream lErrorMessage;
3353
lErrorMessage << "Error in GEOS relate function: " << excep.what();
3354
throwError("GEOSError", lErrorMessage.str());
3357
return ItemSequence_t(new SingletonItemSequence(
3358
theModule->getItemFactory()->createBoolean(is_relate)));
3362
SFIsWithinDistanceFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3363
const StaticContext* aSctxCtx,
3364
const DynamicContext* aDynCtx) const
3367
gmlsf_types geometric_type1;
3368
geometric_type1 = getGeometryNodeType(args, 0, lItem1);
3370
switch(geometric_type1)
3374
std::stringstream lErrorMessage;
3375
zorba::Item item_qname1;
3376
lItem1.getNodeName(item_qname1);
3377
lErrorMessage << "Unrecognized geometric type for element "
3378
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter.";
3379
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3387
gmlsf_types geometric_type2;
3388
geometric_type2 = getGeometryNodeType(args, 1, lItem2);
3390
switch(geometric_type2)
3394
std::stringstream lErrorMessage;
3395
zorba::Item item_qname2;
3396
lItem2.getNodeName(item_qname2);
3397
lErrorMessage << "Unrecognized geometric type for element "
3398
<< item_qname2.getPrefix() <<":"<<item_qname2.getLocalName() << " in second parameter.";
3399
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3406
std::auto_ptr<geos::geom::Geometry> geos_geometry1;
3407
zorba::Item srs_uri1;
3408
geos_geometry1.reset(buildGeosGeometryFromItem(lItem1, geometric_type1, -1, &srs_uri1));
3410
std::auto_ptr<geos::geom::Geometry> geos_geometry2;
3411
zorba::Item srs_uri2;
3412
geos_geometry2.reset(buildGeosGeometryFromItem(lItem2, geometric_type2, -1, &srs_uri2));
3414
if(!srs_uri1.isNull() && !srs_uri2.isNull() &&
3415
!srs_uri1.getStringValue().equals(srs_uri2.getStringValue()))
3417
std::stringstream lErrorMessage;
3418
lErrorMessage << "SrsName is not the same in the two geometries: " <<
3419
srs_uri1.getStringValue() << " vs. " << srs_uri2.getStringValue();
3420
throwError("SRSNotIdenticalInBothGeometries", lErrorMessage.str());
3424
Iterator_t arg2_iter = args[2]->getIterator();
3426
if (!arg2_iter->next(lItem3))
3428
std::stringstream lErrorMessage;
3429
lErrorMessage << "An empty-sequence is not allowed as third parameter";
3430
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3435
distance = lItem3.getDoubleValue();
3437
bool is_within_distance = false;
3439
is_within_distance = geos_geometry1->isWithinDistance(geos_geometry2.get(), distance);
3440
}catch(std::exception &excep)
3442
std::stringstream lErrorMessage;
3443
lErrorMessage << "Error in GEOS function isWithinDistance : " << excep.what();
3444
throwError("GEOSError", lErrorMessage.str());
3447
return ItemSequence_t(new SingletonItemSequence(
3448
theModule->getItemFactory()->createBoolean(is_within_distance)));
3452
SFDistanceFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3453
const StaticContext* aSctxCtx,
3454
const DynamicContext* aDynCtx) const
3457
gmlsf_types geometric_type1;
3458
geometric_type1 = getGeometryNodeType(args, 0, lItem1);
3460
switch(geometric_type1)
3464
std::stringstream lErrorMessage;
3465
zorba::Item item_qname1;
3466
lItem1.getNodeName(item_qname1);
3467
lErrorMessage << "Unrecognized geometric type for element "
3468
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter.";
3469
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3477
gmlsf_types geometric_type2;
3478
geometric_type2 = getGeometryNodeType(args, 1, lItem2);
3480
switch(geometric_type2)
3484
std::stringstream lErrorMessage;
3485
zorba::Item item_qname2;
3486
lItem2.getNodeName(item_qname2);
3487
lErrorMessage << "Unrecognized geometric type for element "
3488
<< item_qname2.getPrefix() <<":"<<item_qname2.getLocalName() << " in second parameter.";
3489
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3496
std::auto_ptr<geos::geom::Geometry> geos_geometry1;
3497
zorba::Item srs_uri1;
3498
geos_geometry1.reset(buildGeosGeometryFromItem(lItem1, geometric_type1, -1, &srs_uri1));
3500
std::auto_ptr<geos::geom::Geometry> geos_geometry2;
3501
zorba::Item srs_uri2;
3502
geos_geometry2.reset(buildGeosGeometryFromItem(lItem2, geometric_type2, -1, &srs_uri2));
3504
if(!srs_uri1.isNull() && !srs_uri2.isNull() &&
3505
!srs_uri1.getStringValue().equals(srs_uri2.getStringValue()))
3507
std::stringstream lErrorMessage;
3508
lErrorMessage << "SrsName is not the same in the two geometries: " <<
3509
srs_uri1.getStringValue() << " vs. " << srs_uri2.getStringValue();
3510
throwError("SRSNotIdenticalInBothGeometries", lErrorMessage.str());
3513
double min_distance = 0;
3515
min_distance = geos_geometry1->distance(geos_geometry2.get());
3516
}catch(std::exception &excep)
3518
std::stringstream lErrorMessage;
3519
lErrorMessage << "Error in GEOS function distance : " << excep.what();
3520
throwError("GEOSError", lErrorMessage.str());
3523
return ItemSequence_t(new SingletonItemSequence(
3524
theModule->getItemFactory()->createDouble(min_distance)));
3528
SFBufferFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3529
const StaticContext* aSctxCtx,
3530
const DynamicContext* aDynCtx) const
3533
gmlsf_types geometric_type1;
3534
geometric_type1 = getGeometryNodeType(args, 0, lItem1);
3536
switch(geometric_type1)
3540
std::stringstream lErrorMessage;
3541
zorba::Item item_qname1;
3542
lItem1.getNodeName(item_qname1);
3543
lErrorMessage << "Unrecognized geometric type for element "
3544
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter.";
3545
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3552
std::auto_ptr<geos::geom::Geometry> geos_geometry1;
3553
zorba::Item srs_uri;
3554
geos_geometry1.reset(buildGeosGeometryFromItem(lItem1, geometric_type1, -1, &srs_uri));
3558
Iterator_t arg1_iter = args[1]->getIterator();
3560
if (!arg1_iter->next(lItem2))
3562
std::stringstream lErrorMessage;
3563
lErrorMessage << "An empty-sequence is not allowed as second parameter";
3564
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3569
distance = lItem2.getDoubleValue();
3571
std::auto_ptr<geos::geom::Geometry> geos_result;
3573
geos_result.reset(geos_geometry1->buffer(distance));
3574
}catch(std::exception &excep)
3576
std::stringstream lErrorMessage;
3577
lErrorMessage << "Error in GEOS function buffer : " << excep.what();
3578
throwError("GEOSError", lErrorMessage.str());
3581
zorba::Item null_parent;
3582
zorba::Item result_item;
3583
result_item = getGMLItemFromGeosGeometry(null_parent, geos_result.get(), &srs_uri);
3588
///////////////////////////////////////////////////////////////////////
3589
#define DEFINE_EVALUATE_ONE_POINT_RETURN_DOUBLE(sfclass_name, geos_function_name) \
3591
sfclass_name::evaluate(const StatelessExternalFunction::Arguments_t& args, \
3592
const StaticContext* aSctxCtx, \
3593
const DynamicContext* aDynCtx) const \
3596
gmlsf_types geometric_type; \
3597
geometric_type = getGeometryNodeType(args, 0, lItem); \
3599
switch(geometric_type) \
3601
case GMLSF_INVALID: \
3603
std::stringstream lErrorMessage; \
3604
zorba::Item item_qname; \
3605
lItem.getNodeName(item_qname); \
3606
lErrorMessage << "Unrecognized geometric type for element " \
3607
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << "."; \
3608
throwError("UnrecognizedGeoObject", lErrorMessage.str()); \
3615
std::stringstream lErrorMessage; \
3616
zorba::Item item_qname; \
3617
lItem.getNodeName(item_qname); \
3618
lErrorMessage << "Geometry must be a point: " \
3619
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << "."; \
3620
throwError("UnrecognizedGeoObject", lErrorMessage.str()); \
3625
std::auto_ptr<geos::geom::Geometry> geos_geometry; \
3626
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1)); \
3627
geos::geom::Point *geos_point = dynamic_cast<geos::geom::Point*>(geos_geometry.get()); \
3629
double retval = 0; \
3631
retval = geos_point->geos_function_name(); \
3632
}catch(std::exception &excep) \
3634
std::stringstream lErrorMessage; \
3635
lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what(); \
3636
throwError("GEOSError", lErrorMessage.str()); \
3639
return ItemSequence_t(new SingletonItemSequence( \
3640
theModule->getItemFactory()->createDouble(retval))); \
3643
DEFINE_EVALUATE_ONE_POINT_RETURN_DOUBLE(SFXFunction, getX)
3644
DEFINE_EVALUATE_ONE_POINT_RETURN_DOUBLE(SFYFunction, getY)
3647
SFZFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3648
const StaticContext* aSctxCtx,
3649
const DynamicContext* aDynCtx) const
3652
gmlsf_types geometric_type;
3653
geometric_type = getGeometryNodeType(args, 0, lItem);
3655
switch(geometric_type)
3659
std::stringstream lErrorMessage;
3660
zorba::Item item_qname;
3661
lItem.getNodeName(item_qname);
3662
lErrorMessage << "Unrecognized geometric type for element "
3663
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
3664
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3671
std::stringstream lErrorMessage;
3672
zorba::Item item_qname;
3673
lItem.getNodeName(item_qname);
3674
lErrorMessage << "Geometry must be a point: "
3675
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
3676
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3680
std::auto_ptr<geos::geom::Geometry> geos_geometry;
3681
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
3683
const geos::geom::Coordinate *c;
3684
c = geos_geometry->getCoordinate();
3685
#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
3686
if(geos_geometry->getCoordinateDimension() == 3)
3688
if(getCoordinateDimension(geos_geometry.get()) == 3)
3692
return ItemSequence_t(new SingletonItemSequence(
3693
theModule->getItemFactory()->createDouble(z)));
3697
return zorba::ItemSequence_t(NULL);
3703
SFMFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3704
const StaticContext* aSctxCtx,
3705
const DynamicContext* aDynCtx) const
3708
gmlsf_types geometric_type;
3709
geometric_type = getGeometryNodeType(args, 0, lItem);
3711
switch(geometric_type)
3715
std::stringstream lErrorMessage;
3716
zorba::Item item_qname;
3717
lItem.getNodeName(item_qname);
3718
lErrorMessage << "Unrecognized geometric type for element "
3719
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
3720
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3727
std::stringstream lErrorMessage;
3728
zorba::Item item_qname;
3729
lItem.getNodeName(item_qname);
3730
lErrorMessage << "Geometry must be a point: "
3731
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
3732
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3737
//don't know how to get the Measure from Point
3738
return zorba::ItemSequence_t(NULL);
3744
SFStartPointFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3745
const StaticContext* aSctxCtx,
3746
const DynamicContext* aDynCtx) const
3749
gmlsf_types geometric_type1;
3750
geometric_type1 = getGeometryNodeType(args, 0, lItem1);
3752
switch(geometric_type1)
3756
std::stringstream lErrorMessage;
3757
zorba::Item item_qname1;
3758
lItem1.getNodeName(item_qname1);
3759
lErrorMessage << "Unrecognized geometric type for element "
3760
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter.";
3761
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3764
case GMLSF_LINESTRING:
3765
case GMLSF_LINEARRING:
3770
std::stringstream lErrorMessage;
3771
zorba::Item item_qname1;
3772
lItem1.getNodeName(item_qname1);
3773
lErrorMessage << "Geometry must be a line: "
3774
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << ".";
3775
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3783
buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_POINT, &n, &nth_child);
3785
if(nth_child.isNull())
3787
std::stringstream lErrorMessage;
3788
lErrorMessage << "LineString has no points ";
3789
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3792
return ItemSequence_t(new SingletonItemSequence(nth_child));
3796
SFEndPointFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3797
const StaticContext* aSctxCtx,
3798
const DynamicContext* aDynCtx) const
3801
gmlsf_types geometric_type1;
3802
geometric_type1 = getGeometryNodeType(args, 0, lItem1);
3804
switch(geometric_type1)
3808
std::stringstream lErrorMessage;
3809
zorba::Item item_qname1;
3810
lItem1.getNodeName(item_qname1);
3811
lErrorMessage << "Unrecognized geometric type for element "
3812
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter.";
3813
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3816
case GMLSF_LINESTRING:
3817
case GMLSF_LINEARRING:
3822
std::stringstream lErrorMessage;
3823
zorba::Item item_qname1;
3824
lItem1.getNodeName(item_qname1);
3825
lErrorMessage << "Geometry must be a line: "
3826
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << ".";
3827
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3833
buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_END_POINT, NULL, &nth_child);
3835
if(nth_child.isNull())
3837
std::stringstream lErrorMessage;
3838
lErrorMessage << "LineString has no points ";
3839
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3842
return ItemSequence_t(new SingletonItemSequence(nth_child));
3845
///////////////////////////////////////////////////////////////////////
3847
SFIsClosedFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3848
const StaticContext* aSctxCtx,
3849
const DynamicContext* aDynCtx) const
3852
gmlsf_types geometric_type;
3853
geometric_type = getGeometryNodeType(args, 0, lItem);
3855
switch(geometric_type)
3859
std::stringstream lErrorMessage;
3860
zorba::Item item_qname;
3861
lItem.getNodeName(item_qname);
3862
lErrorMessage << "Unrecognized geometric type for element "
3863
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
3864
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3867
case GMLSF_LINESTRING:
3868
case GMLSF_LINEARRING:
3870
case GMLSF_MULTICURVE:
3875
std::stringstream lErrorMessage;
3876
zorba::Item item_qname;
3877
lItem.getNodeName(item_qname);
3878
lErrorMessage << "Geometry must be a line or Surface: "
3879
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
3880
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3885
std::auto_ptr<geos::geom::Geometry> geos_geometry;
3886
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
3889
if(geometric_type == GMLSF_SURFACE)
3891
if(!isSurface(dynamic_cast<geos::geom::MultiPolygon*>(geos_geometry.get()), &retval))
3894
else if(geometric_type == GMLSF_CURVE)
3896
retval = isClosedCurve(geos_geometry.get());
3901
if(geometric_type != GMLSF_MULTICURVE)
3903
geos::geom::LineString *geos_line = dynamic_cast<geos::geom::LineString*>(geos_geometry.get());
3904
retval = geos_line->isClosed();
3908
geos::geom::MultiLineString *geos_multiline = dynamic_cast<geos::geom::MultiLineString*>(geos_geometry.get());
3909
retval = geos_multiline->isClosed();
3911
}catch(std::exception &excep)
3913
std::stringstream lErrorMessage;
3914
lErrorMessage << "Error in GEOS function SFIsClosedFunction : " << excep.what();
3915
throwError("GEOSError", lErrorMessage.str());
3918
return ItemSequence_t(new SingletonItemSequence(
3919
theModule->getItemFactory()->createBoolean(retval)));
3923
SFIsRingFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3924
const StaticContext* aSctxCtx,
3925
const DynamicContext* aDynCtx) const
3928
gmlsf_types geometric_type;
3929
geometric_type = getGeometryNodeType(args, 0, lItem);
3931
switch(geometric_type)
3935
std::stringstream lErrorMessage;
3936
zorba::Item item_qname;
3937
lItem.getNodeName(item_qname);
3938
lErrorMessage << "Unrecognized geometric type for element "
3939
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
3940
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3943
case GMLSF_LINESTRING:
3944
case GMLSF_LINEARRING:
3949
std::stringstream lErrorMessage;
3950
zorba::Item item_qname;
3951
lItem.getNodeName(item_qname);
3952
lErrorMessage << "Geometry must be a line: "
3953
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
3954
throwError("UnrecognizedGeoObject", lErrorMessage.str());
3959
std::auto_ptr<geos::geom::Geometry> geos_geometry;
3960
geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
3963
if(geometric_type != GMLSF_CURVE)
3966
geos::geom::LineString *geos_line = dynamic_cast<geos::geom::LineString*>(geos_geometry.get());
3967
retval = geos_line->isClosed();
3968
}catch(std::exception &excep)
3970
std::stringstream lErrorMessage;
3971
lErrorMessage << "Error in GEOS function isClosed : " << excep.what();
3972
throwError("GEOSError", lErrorMessage.str());
3977
retval = isRingCurve(geos_geometry.get());
3979
return ItemSequence_t(new SingletonItemSequence(
3980
theModule->getItemFactory()->createBoolean(retval)));
3984
SFNumPointsFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3985
const StaticContext* aSctxCtx,
3986
const DynamicContext* aDynCtx) const
3989
gmlsf_types geometric_type;
3990
geometric_type = getGeometryNodeType(args, 0, lItem);
3992
switch(geometric_type)
3996
std::stringstream lErrorMessage;
3997
zorba::Item item_qname;
3998
lItem.getNodeName(item_qname);
3999
lErrorMessage << "Unrecognized geometric type for element "
4000
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << " in first parameter.";
4001
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4004
case GMLSF_LINESTRING:
4005
case GMLSF_LINEARRING:
4007
case GMLSF_MULTICURVE:
4011
std::stringstream lErrorMessage;
4012
zorba::Item item_qname;
4013
lItem.getNodeName(item_qname);
4014
lErrorMessage << "Geometry must be a line: "
4015
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
4016
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4021
uint32_t num_children;
4022
buildGeosGeometryFromItem(lItem, geometric_type, -1, NULL, GET_NUM_POINTS, &num_children);
4024
return ItemSequence_t(new SingletonItemSequence(
4025
theModule->getItemFactory()->createUnsignedInt(num_children)));
4029
SFPointNFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
4030
const StaticContext* aSctxCtx,
4031
const DynamicContext* aDynCtx) const
4034
gmlsf_types geometric_type1;
4035
geometric_type1 = getGeometryNodeType(args, 0, lItem1);
4037
switch(geometric_type1)
4041
std::stringstream lErrorMessage;
4042
zorba::Item item_qname1;
4043
lItem1.getNodeName(item_qname1);
4044
lErrorMessage << "Unrecognized geometric type for element "
4045
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter.";
4046
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4049
case GMLSF_LINESTRING:
4050
case GMLSF_LINEARRING:
4052
case GMLSF_MULTICURVE:
4056
std::stringstream lErrorMessage;
4057
zorba::Item item_qname1;
4058
lItem1.getNodeName(item_qname1);
4059
lErrorMessage << "Geometry must be a line: "
4060
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << ".";
4061
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4068
Iterator_t arg1_iter = args[1]->getIterator();
4070
if (!arg1_iter->next(lItem2))
4072
std::stringstream lErrorMessage;
4073
lErrorMessage << "An empty-sequence is not allowed as second parameter";
4074
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4079
n = lItem2.getUnsignedIntValue();
4082
buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_POINT, &n, &nth_child);
4084
if(nth_child.isNull())
4086
std::stringstream lErrorMessage;
4087
lErrorMessage << "Index n (" << n << ") is outside the range ";
4088
throwError("IndexOutsideRange", lErrorMessage.str());
4091
return ItemSequence_t(new SingletonItemSequence(nth_child));
4094
///////////////////////////////////////////////////////////////////////
4096
SFExteriorRingFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
4097
const StaticContext* aSctxCtx,
4098
const DynamicContext* aDynCtx) const
4101
gmlsf_types geometric_type;
4102
geometric_type = getGeometryNodeType(args, 0, lItem);
4104
switch(geometric_type)
4108
std::stringstream lErrorMessage;
4109
zorba::Item item_qname;
4110
lItem.getNodeName(item_qname);
4111
lErrorMessage << "Unrecognized geometric type for element "
4112
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
4113
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4120
std::stringstream lErrorMessage;
4121
zorba::Item item_qname;
4122
lItem.getNodeName(item_qname);
4123
lErrorMessage << "Geometry must be a polygon: "
4124
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
4125
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4131
buildGeosGeometryFromItem(lItem, geometric_type, -1, NULL, GET_EXTERIOR_RING, NULL, &result_item);
4137
SFNumInteriorRingFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
4138
const StaticContext* aSctxCtx,
4139
const DynamicContext* aDynCtx) const
4142
gmlsf_types geometric_type;
4143
geometric_type = getGeometryNodeType(args, 0, lItem);
4145
switch(geometric_type)
4149
std::stringstream lErrorMessage;
4150
zorba::Item item_qname;
4151
lItem.getNodeName(item_qname);
4152
lErrorMessage << "Unrecognized geometric type for element "
4153
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
4154
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4161
std::stringstream lErrorMessage;
4162
zorba::Item item_qname;
4163
lItem.getNodeName(item_qname);
4164
lErrorMessage << "Geometry must be a polygon: "
4165
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
4166
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4171
uint32_t num_children;
4172
buildGeosGeometryFromItem(lItem, geometric_type, -1, NULL, COUNT_CHILDREN, &num_children);
4174
return ItemSequence_t(new SingletonItemSequence(
4175
theModule->getItemFactory()->createUnsignedInt(num_children)));
4179
SFInteriorRingNFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
4180
const StaticContext* aSctxCtx,
4181
const DynamicContext* aDynCtx) const
4184
gmlsf_types geometric_type1;
4185
geometric_type1 = getGeometryNodeType(args, 0, lItem1);
4187
switch(geometric_type1)
4191
std::stringstream lErrorMessage;
4192
zorba::Item item_qname1;
4193
lItem1.getNodeName(item_qname1);
4194
lErrorMessage << "Unrecognized geometric type for element "
4195
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter.";
4196
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4203
std::stringstream lErrorMessage;
4204
zorba::Item item_qname1;
4205
lItem1.getNodeName(item_qname1);
4206
lErrorMessage << "Geometry must be a polygon: "
4207
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << ".";
4208
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4216
Iterator_t arg1_iter = args[1]->getIterator();
4218
if (!arg1_iter->next(lItem2))
4220
std::stringstream lErrorMessage;
4221
lErrorMessage << "An empty-sequence is not allowed as second parameter";
4222
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4227
n = lItem2.getUnsignedIntValue();
4230
buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_CHILD, &n, &nth_child);
4232
if(nth_child.isNull())
4234
std::stringstream lErrorMessage;
4235
lErrorMessage << "Index n (" << n << ") is outside the range ";
4236
throwError("IndexOutsideRange", lErrorMessage.str());
4239
return ItemSequence_t(new SingletonItemSequence(nth_child));
4243
SFNumPatchesFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
4244
const StaticContext* aSctxCtx,
4245
const DynamicContext* aDynCtx) const
4248
gmlsf_types geometric_type;
4249
geometric_type = getGeometryNodeType(args, 0, lItem);
4251
switch(geometric_type)
4255
std::stringstream lErrorMessage;
4256
zorba::Item item_qname;
4257
lItem.getNodeName(item_qname);
4258
lErrorMessage << "Unrecognized geometric type for element "
4259
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
4260
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4267
std::stringstream lErrorMessage;
4268
zorba::Item item_qname;
4269
lItem.getNodeName(item_qname);
4270
lErrorMessage << "Geometry must be a Surface: "
4271
<< item_qname.getPrefix() <<":"<<item_qname.getLocalName() << ".";
4272
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4277
uint32_t num_children;
4278
buildGeosGeometryFromItem(lItem, geometric_type, -1, NULL, COUNT_CHILDREN, &num_children);
4280
return ItemSequence_t(new SingletonItemSequence(
4281
theModule->getItemFactory()->createUnsignedInt(num_children)));
4285
SFPatchNFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
4286
const StaticContext* aSctxCtx,
4287
const DynamicContext* aDynCtx) const
4290
gmlsf_types geometric_type1;
4291
geometric_type1 = getGeometryNodeType(args, 0, lItem1);
4293
switch(geometric_type1)
4297
std::stringstream lErrorMessage;
4298
zorba::Item item_qname1;
4299
lItem1.getNodeName(item_qname1);
4300
lErrorMessage << "Unrecognized geometric type for element "
4301
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter.";
4302
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4309
std::stringstream lErrorMessage;
4310
zorba::Item item_qname1;
4311
lItem1.getNodeName(item_qname1);
4312
lErrorMessage << "Geometry must be a Surface: "
4313
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << ".";
4314
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4322
Iterator_t arg1_iter = args[1]->getIterator();
4324
if (!arg1_iter->next(lItem2))
4326
std::stringstream lErrorMessage;
4327
lErrorMessage << "An empty-sequence is not allowed as second parameter";
4328
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4333
n = lItem2.getUnsignedIntValue();
4336
buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_CHILD, &n, &nth_child);
4338
if(nth_child.isNull())
4340
std::stringstream lErrorMessage;
4341
lErrorMessage << "Index n (" << n << ") is outside the range ";
4342
throwError("IndexOutsideRange", lErrorMessage.str());
4345
return ItemSequence_t(new SingletonItemSequence(nth_child));
4350
SFBoundingPolygonsFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
4351
const StaticContext* aSctxCtx,
4352
const DynamicContext* aDynCtx) const
4355
gmlsf_types geometric_type1;
4356
geometric_type1 = getGeometryNodeType(args, 0, lItem1);
4358
switch(geometric_type1)
4362
std::stringstream lErrorMessage;
4363
zorba::Item item_qname1;
4364
lItem1.getNodeName(item_qname1);
4365
lErrorMessage << "Unrecognized geometric type for element "
4366
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << " in first parameter.";
4367
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4374
std::stringstream lErrorMessage;
4375
zorba::Item item_qname1;
4376
lItem1.getNodeName(item_qname1);
4377
lErrorMessage << "Parameter 1 must be a Surface: "
4378
<< item_qname1.getPrefix() <<":"<<item_qname1.getLocalName() << ".";
4379
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4385
gmlsf_types geometric_type2;
4386
geometric_type2 = getGeometryNodeType(args, 1, lItem2);
4388
switch(geometric_type2)
4392
std::stringstream lErrorMessage;
4393
zorba::Item item_qname2;
4394
lItem2.getNodeName(item_qname2);
4395
lErrorMessage << "Unrecognized geometric type for element "
4396
<< item_qname2.getPrefix() <<":"<<item_qname2.getLocalName() << " in first parameter.";
4397
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4401
//case GMLSF_POLYGONPATCH:
4405
std::stringstream lErrorMessage;
4406
zorba::Item item_qname2;
4407
lItem2.getNodeName(item_qname2);
4408
lErrorMessage << "Parameter 2 must be a Polygon or PolygonPatch: "
4409
<< item_qname2.getPrefix() <<":"<<item_qname2.getLocalName() << ".";
4410
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4415
std::vector<Item> result;
4416
zorba::Item patches_item;
4417
if(!getChild(lItem1, "patches", "http://www.opengis.net/gml", patches_item))
4419
std::stringstream lErrorMessage;
4420
lErrorMessage << "gml:Surface node must have a gml:patches child";
4421
throwError("UnrecognizedGeoObject", lErrorMessage.str());
4424
Iterator_t patches_children;
4425
Item polygon_patch_item;
4427
patches_children = patches_item.getChildren();
4428
patches_children->open();
4429
unsigned int patch_nr = 0;
4431
std::auto_ptr<geos::geom::Geometry> geos_geometry1(buildGeosGeometryFromItem(lItem1, geometric_type1, -1));
4432
std::auto_ptr<geos::geom::Geometry> geos_geometry2(buildGeosGeometryFromItem(lItem2, GMLSF_POLYGON, -1));
4434
const geos::geom::MultiPolygon *surface = dynamic_cast<const geos::geom::MultiPolygon*>(geos_geometry1.get());
4435
const geos::geom::Polygon *polygon = dynamic_cast<const geos::geom::Polygon*>(geos_geometry2.get());
4436
const geos::geom::LineString *exterior_ring = polygon->getExteriorRing();
4437
//const geos::geom::CoordinateSequence *coords = exterior_ring->getCoordinates();
4440
unsigned int nr_patches = (unsigned int)surface->getNumGeometries();
4442
for(i=0;i<nr_patches;i++)
4444
const geos::geom::Polygon *patch= dynamic_cast<const geos::geom::Polygon*>(surface->getGeometryN(i));
4445
const geos::geom::LineString *patch_exterior_ring = patch->getExteriorRing();
4446
//const geos::geom::CoordinateSequence *patch_coords = patch_exterior_ring->getCoordinates();
4447
//see if this patch touches the input polygon
4448
bool is_touching = false;
4450
for(unsigned int j=0;j<patch_coords->size();j++)
4452
for(unsigned int k=0;k<coords->size();k++)
4454
if(coords->getAt(k).equals(patch_coords->getAt(j)))
4456
geos::geom::Coordinate next1;
4457
geos::geom::Coordinate next2;
4458
if(k == (coords->size()-1))
4459
next1 = coords->getAt(0);
4461
next1 = coords->getAt(k+1);
4462
if(j == (patch_coords->size()-1))
4463
next2 = patch_coords->getAt(0);
4465
next2 = patch_coords->getAt(j+1);
4466
if(next1.equals(next2))
4472
next2 = patch_coords->getAt(patch_coords->size()-1);
4474
next2 = patch_coords->getAt(j-1);
4475
if(next1.equals(next2))
4486
if(patch_exterior_ring->overlaps(exterior_ring))
4490
//add the coresponding patch item to the list
4491
while(patch_nr <= i)
4493
patches_children->next(polygon_patch_item);
4496
result.push_back(polygon_patch_item);
4500
return ItemSequence_t(new VectorItemSequence(result));
4504
} /* namespace geomodule */ } /* namespace zorba */