~juan457/+junk/zorba

« back to all changes in this revision

Viewing changes to modules/org/expath/ns/geo.xq.src/geo_functions.cpp

  • Committer: ceejatec
  • Date: 2011-02-23 12:49:34 UTC
  • Revision ID: svn-v4:8046edc3-af21-0410-8661-ec7318497eea:trunk/zorba:9976
Numerous changes to support externalizing modules.
1. Overhauled ZorbaConfig framework to allow easy "finding" of Zorba (either
   from source or installed binary form); consolidated all into top-level
   config/ directory.
2. Moved GENERATE_MODULE_LIBRARY() macro to ZorbaModule.cmake (which is also
   installed); updated to support out-of-core modules.
3. Fixed and improved several features regarding "make install", such as
   enabling RPath, correcting include directories, etc.
4. Consolidated some other project-configuration files into config/, such as
   debian and Fedora packaging files.
5. Added --module-path option to testdriver and testdriver_mt.
6. testdriver is now installed by "make install" (may be revisited).

And, eliminated "geo" module - now available at
  http://zorba.svn.sourceforge.net/svnroot/zorba/modules/geo/trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2006-2008 The FLWOR Foundation.
3
 
 * 
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
7
 
 * 
8
 
 * http://www.apache.org/licenses/LICENSE-2.0
9
 
 * 
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.
15
 
 */
16
 
#include <string.h>
17
 
#include <stdio.h>
18
 
#include <math.h>
19
 
#include <stdlib.h>
20
 
 
21
 
#include "geo_functions.h"
22
 
 
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>
48
 
#include <vector>
49
 
#include <sstream>
50
 
#include <iomanip>
51
 
 
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>
57
 
 
58
 
#include "geo_module.h"
59
 
 
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
63
 
#endif
64
 
 
65
 
#define DONT_CHECK_FOR_CURVE_SURFACE true
66
 
 
67
 
#define RETURN_RESULT_ITEM            return result_item.isNull() ? ItemSequence_t(NULL) : ItemSequence_t(new SingletonItemSequence(result_item))
68
 
 
69
 
namespace zorba { namespace geomodule {
70
 
 
71
 
GeoFunction::GeoFunction(const GeoModule* aModule)
72
 
        : theModule(aModule)
73
 
{
74
 
//  geo_factory = NULL;
75
 
}
76
 
 
77
 
GeoFunction::~GeoFunction()
78
 
{
79
 
//  delete geo_factory;
80
 
}
81
 
 
82
 
String
83
 
GeoFunction::getURI() const
84
 
{
85
 
  return theModule->getURI();
86
 
}
87
 
 
88
 
void
89
 
GeoFunction::throwError(
90
 
    const char *err_localname,
91
 
    const std::string aErrorMessage)
92
 
{
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);
99
 
}
100
 
 
101
 
enum GeoFunction::gmlsf_types GeoFunction::getGmlSFGeometricType(Item item) const
102
 
{
103
 
  Item  item_qname;
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();
109
 
 
110
 
  if(localname.byteEqual("Point", 5))
111
 
    return GMLSF_POINT;
112
 
  else if(localname.byteEqual("LineString", 10))
113
 
    return GMLSF_LINESTRING;
114
 
  else if(localname.byteEqual("Curve", 5))
115
 
    return GMLSF_CURVE;
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;
132
 
  else
133
 
    return GMLSF_INVALID;
134
 
}
135
 
 
136
 
enum GeoFunction::gmlsf_types GeoFunction::getGeometryNodeType(const StatelessExternalFunction::Arguments_t& args,
137
 
                                                               int arg_pos, zorba::Item &lItem) const
138
 
{
139
 
  Iterator_t args_iter = args[arg_pos]->getIterator();
140
 
  args_iter->open();
141
 
  if (!args_iter->next(lItem)) 
142
 
  {
143
 
    std::stringstream lErrorMessage;
144
 
    lErrorMessage << "An empty-sequence is not allowed as parameter";
145
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
146
 
  }
147
 
 
148
 
  if(!lItem.isNode() || (lItem.getNodeKind() != store::StoreConsts::elementNode))
149
 
  {
150
 
    std::stringstream lErrorMessage;
151
 
    lErrorMessage << "Argument must be a geometric node ";
152
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
153
 
  }
154
 
  args_iter->close();
155
 
  return getGmlSFGeometricType(lItem);
156
 
}
157
 
 
158
 
bool GeoFunction::getChild(zorba::Item &lItem, const char *localname, const char *ns, 
159
 
                           zorba::Item &child_item) const
160
 
{
161
 
  Iterator_t    children;
162
 
  children = lItem.getChildren();
163
 
  children->open();
164
 
  bool retval = getChild(children, localname, ns, child_item);
165
 
  children->close();
166
 
  return retval;
167
 
}
168
 
 
169
 
bool GeoFunction::getChild(zorba::Iterator_t children, const char *localname, const char *ns, 
170
 
                           zorba::Item &child_item) const
171
 
{
172
 
  while(children->next(child_item))
173
 
  {
174
 
    if(child_item.getNodeKind() != store::StoreConsts::elementNode)
175
 
      continue;
176
 
    Item    child_name;
177
 
    child_item.getNodeName(child_name);
178
 
    String  item_namespace = child_name.getNamespace();
179
 
    if(!item_namespace.byteEqual(ns, (unsigned int)strlen(ns)))
180
 
    {
181
 
      continue;//next child
182
 
    }
183
 
    String  item_name = child_name.getLocalName();
184
 
    if(!item_name.byteEqual(localname, (unsigned int)strlen(localname)))
185
 
    {
186
 
      continue;//next child
187
 
    }
188
 
    return true;
189
 
  }
190
 
  return false;
191
 
}
192
 
 
193
 
bool GeoFunction::getAttribute(  zorba::Item &item, 
194
 
                                 const char *name, 
195
 
                                 const char *ns,
196
 
                                 zorba::Item &attr_item) const
197
 
{
198
 
  Iterator_t    children;
199
 
  children = item.getAttributes();
200
 
  children->open();
201
 
  while(children->next(attr_item))
202
 
  {
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)))
207
 
    {
208
 
      continue;//next attr
209
 
    }
210
 
    if(!ns)
211
 
    {
212
 
      children->close();
213
 
      return true;
214
 
   }
215
 
    String  attr_ns= attr_qname.getNamespace();
216
 
    if(attr_ns.byteEqual(ns, (unsigned int)strlen(ns)))
217
 
    {
218
 
      children->close();
219
 
      return true;
220
 
    }
221
 
  }
222
 
  children->close();
223
 
  return false;
224
 
}
225
 
 
226
 
bool GeoFunction::checkOptionalAttribute(zorba::Item &item, 
227
 
                                         const char *name, 
228
 
                                         const char *ns,
229
 
                                         const char *value) const
230
 
{
231
 
  zorba::Item attr_item;
232
 
  if(!getAttribute(  item, 
233
 
                     name, 
234
 
                     ns,
235
 
                     attr_item))
236
 
     return true;
237
 
  String  attr_value = attr_item.getStringValue();
238
 
  return attr_value.byteEqual(value, (unsigned int)strlen(value));
239
 
}
240
 
 
241
 
int GeoFunction::get_srsDimension(zorba::Item &item, int prev_srsdimension) const
242
 
{
243
 
  zorba::Item attr_item;
244
 
  if(getAttribute(item, 
245
 
                   "srsDimension", 
246
 
                   NULL,
247
 
                   attr_item))
248
 
  {
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))
253
 
    {
254
 
      std::stringstream lErrorMessage;
255
 
      lErrorMessage << "Geo module's supported values for srsDimension in GML are 2 and 3.";
256
 
      throwError("UnsupportedSRSDimensionValue", lErrorMessage.str());
257
 
    }
258
 
    return srs_dim;
259
 
  }
260
 
  return prev_srsdimension;
261
 
}
262
 
 
263
 
const geos::geom::GeometryFactory   *GeoFunction::get_geometryFactory() const
264
 
{
265
 
//  if(!geo_factory)
266
 
//    geo_factory = new geos::geom::GeometryFactory;
267
 
//  return geo_factory;
268
 
  return geos::geom::GeometryFactory::getDefaultInstance();
269
 
}
270
 
 
271
 
void GeoFunction::readPointPosCoordinates(zorba::Item &lItem, 
272
 
                                          double *x, 
273
 
                                          double *y,
274
 
                                          double *z,
275
 
                                          int &srs_dim) const
276
 
{
277
 
  Iterator_t    children;
278
 
  children = lItem.getChildren();
279
 
  children->open();
280
 
  bool retval = readPointPosCoordinates(children, x, y, z, srs_dim);
281
 
  children->close();
282
 
  if(!retval)
283
 
  {
284
 
    std::stringstream lErrorMessage;
285
 
    lErrorMessage << "gml node must have a gml:pos child";
286
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
287
 
  }
288
 
}
289
 
 
290
 
bool GeoFunction::readPointPosCoordinates(zorba::Iterator_t children, 
291
 
                                          double *x, 
292
 
                                          double *y,
293
 
                                          double *z,
294
 
                                          int &srs_dim) const
295
 
{
296
 
  zorba::Item   pos_item;
297
 
  if(!getChild(children, "pos", "http://www.opengis.net/gml", pos_item))
298
 
  {//get upset
299
 
    //std::stringstream lErrorMessage;
300
 
    //lErrorMessage << "gml:Point node must have a gml:pos child";
301
 
    //throwError("UnrecognizedGeoObject", lErrorMessage.str());
302
 
    return false;
303
 
  }
304
 
  srs_dim = get_srsDimension(pos_item, srs_dim);
305
 
 
306
 
  String    pos_string;
307
 
  pos_string = pos_item.getStringValue();
308
 
  *x = 0;
309
 
  *y = 0;
310
 
  *z = 0;
311
 
  const char *str = pos_string.c_str();
312
 
  while(((*str == ' ') ||
313
 
        (*str == '\t') ||
314
 
        (*str == '\n') ||
315
 
        (*str == '\r')) &&
316
 
        (*str != 0))
317
 
     str++;
318
 
  sscanf(str, "%lf", x);
319
 
  while((*str != ' ') &&
320
 
        (*str != '\t') &&
321
 
        (*str != '\n') &&
322
 
        (*str != '\r') &&
323
 
        (*str != 0))
324
 
     str++;
325
 
  while(((*str == ' ') ||
326
 
      (*str == '\t') ||
327
 
      (*str == '\n') ||
328
 
      (*str == '\r')) &&
329
 
      (*str != 0))
330
 
     str++;
331
 
  sscanf(str, "%lf", y);
332
 
  if(srs_dim == 3)
333
 
  {
334
 
    while((*str != ' ') &&
335
 
          (*str != '\t') &&
336
 
          (*str != '\n') &&
337
 
          (*str != '\r') &&
338
 
          (*str != 0))
339
 
       str++;
340
 
    while(((*str == ' ') ||
341
 
        (*str == '\t') ||
342
 
        (*str == '\n') ||
343
 
        (*str == '\r')) &&
344
 
        (*str != 0))
345
 
       str++;
346
 
    sscanf(str, "%lf", z);
347
 
  }
348
 
  return true;
349
 
}
350
 
 
351
 
void GeoFunction::readPosListCoordinates(zorba::Item &lItem, 
352
 
                                         geos::geom::CoordinateSequence *&cl,
353
 
                                         int &srs_dim) const
354
 
{
355
 
  zorba::Item   poslist_item;
356
 
  if(srs_dim != 3)
357
 
    srs_dim = 2;
358
 
  if(getChild(lItem, "posList", "http://www.opengis.net/gml", poslist_item))
359
 
  {
360
 
    srs_dim = get_srsDimension(poslist_item, srs_dim);
361
 
    if(!cl)
362
 
      cl = geos::geom::CoordinateArraySequenceFactory::instance()->create((std::size_t)0, srs_dim);
363
 
 
364
 
    String    poslist_string;
365
 
    poslist_string = poslist_item.getStringValue();
366
 
    double x, y, z;
367
 
    int load_x = 0;
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')) &&
373
 
          (*str_poslist != 0))
374
 
       str_poslist++;
375
 
    x = 0; y = 0; z = 0;
376
 
    while(str_poslist[0])
377
 
    {
378
 
      if(load_x == 0)
379
 
        x = atof(str_poslist);
380
 
      else if(load_x == 1)
381
 
      {
382
 
        y = atof(str_poslist);
383
 
        if(srs_dim == 2)
384
 
        {
385
 
          cl->add(geos::geom::Coordinate(x, y));
386
 
          x = 0; y = 0;
387
 
        }
388
 
      }
389
 
      else if(load_x == 2)
390
 
      {
391
 
        z = atof(str_poslist);
392
 
        cl->add(geos::geom::Coordinate(x, y, z));
393
 
        x = 0; y = 0; z = 0;
394
 
      }
395
 
      load_x = (load_x + 1)%srs_dim;
396
 
      while((*str_poslist != ' ') &&
397
 
            (*str_poslist != '\t') &&
398
 
            (*str_poslist != '\n') &&
399
 
            (*str_poslist != '\r') &&
400
 
            (*str_poslist != 0))
401
 
         str_poslist++;
402
 
      while(((*str_poslist == ' ') ||
403
 
          (*str_poslist == '\t') ||
404
 
          (*str_poslist == '\n') ||
405
 
          (*str_poslist == '\r')) &&
406
 
          (*str_poslist != 0))
407
 
         str_poslist++;
408
 
    }
409
 
  }
410
 
  else if(getChild(lItem, "pos", "http://www.opengis.net/gml", poslist_item))
411
 
  {
412
 
    Iterator_t    children;
413
 
    children = lItem.getChildren();
414
 
    children->open();
415
 
    double x = 0, y = 0, z = 0;
416
 
    while(readPointPosCoordinates(children, &x, &y, &z, srs_dim))
417
 
    {
418
 
      if(!cl)
419
 
        cl = geos::geom::CoordinateArraySequenceFactory::instance()->create((std::size_t)0, srs_dim);
420
 
 
421
 
      if(srs_dim == 3)
422
 
      {
423
 
        cl->add(geos::geom::Coordinate(x, y, z));
424
 
      }
425
 
      else
426
 
      {
427
 
        cl->add(geos::geom::Coordinate(x, y));
428
 
      }
429
 
      x = 0; y = 0; z = 0;
430
 
    }
431
 
    children->close();
432
 
  }
433
 
  else
434
 
  {//get upset
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());
440
 
  }
441
 
 
442
 
}
443
 
 
444
 
int GeoFunction::getCoordinateDimension(const geos::geom::Geometry *geos_geometry) const
445
 
{
446
 
  if(!geos_geometry)
447
 
    return 2;
448
 
  switch(geos_geometry->getGeometryTypeId())
449
 
  {
450
 
  case  geos::geom::GEOS_POINT:
451
 
  {
452
 
    const geos::geom::Coordinate  *c;
453
 
    c = geos_geometry->getCoordinate();
454
 
      if(!ISNAN(c->z))
455
 
        return 3;
456
 
      else
457
 
        return 2;
458
 
  }
459
 
        /// a linestring
460
 
  case geos::geom::GEOS_LINESTRING:
461
 
        /// a linear ring (linestring with 1st point == last point)
462
 
  case geos::geom::GEOS_LINEARRING:
463
 
  {
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++)
468
 
    {
469
 
      if(!ISNAN(cs->getAt(i).z))
470
 
        return 3;
471
 
    }
472
 
    return 2;
473
 
  }
474
 
        /// a polygon
475
 
  case geos::geom::GEOS_POLYGON:
476
 
  {
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)
482
 
      return 3;
483
 
 
484
 
    size_t interior_rings = polygon->getNumInteriorRing();
485
 
    for(size_t i=0;i<interior_rings;i++)
486
 
    {
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)
491
 
        return 3;
492
 
    }
493
 
    return 2;
494
 
  }
495
 
        /// a collection of points
496
 
  case geos::geom::GEOS_MULTIPOINT:
497
 
  {
498
 
    size_t    nr_geoms = geos_geometry->getNumGeometries();
499
 
    for(size_t i=0;i<nr_geoms;i++)
500
 
    {
501
 
      const geos::geom::Geometry  *point;
502
 
      point = geos_geometry->getGeometryN(i);
503
 
      if(getCoordinateDimension(point) == 3)
504
 
        return 3;
505
 
    }
506
 
    return 2;
507
 
  }
508
 
        /// a collection of linestrings
509
 
  case geos::geom::GEOS_MULTILINESTRING:
510
 
  {
511
 
    size_t    nr_geoms = geos_geometry->getNumGeometries();
512
 
    for(size_t i=0;i<nr_geoms;i++)
513
 
    {
514
 
      const geos::geom::Geometry  *linestring;
515
 
      linestring = geos_geometry->getGeometryN(i);
516
 
      if(getCoordinateDimension(linestring) == 3)
517
 
        return 3;
518
 
    }
519
 
    return 2;
520
 
  }
521
 
        /// a collection of polygons
522
 
  case geos::geom::GEOS_MULTIPOLYGON:
523
 
  {
524
 
    size_t    nr_geoms = geos_geometry->getNumGeometries();
525
 
    for(size_t i=0;i<nr_geoms;i++)
526
 
    {
527
 
      const geos::geom::Geometry  *polygon;
528
 
      polygon = geos_geometry->getGeometryN(i);
529
 
      if(getCoordinateDimension(polygon) == 3)
530
 
        return 3;
531
 
    }
532
 
    return 2;
533
 
  }
534
 
        /// a collection of heterogeneus geometries
535
 
  case geos::geom::GEOS_GEOMETRYCOLLECTION:
536
 
  {
537
 
    //can be either gml:Surface or gml:Curve
538
 
    size_t    nr_geoms = geos_geometry->getNumGeometries();
539
 
    if(!nr_geoms)
540
 
      return 2;//unreachable
541
 
    for(size_t i=0;i<nr_geoms;i++)
542
 
    {
543
 
      const geos::geom::Geometry *child;
544
 
      child = geos_geometry->getGeometryN(i);
545
 
      if(getCoordinateDimension(child) == 3)
546
 
        return 3;
547
 
    }
548
 
    return 2;
549
 
  }
550
 
  default:
551
 
  {
552
 
    std::stringstream lErrorMessage;
553
 
    lErrorMessage << "Geometry type " << geos_geometry->getGeometryType() << " is not supported";
554
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
555
 
  }
556
 
  }
557
 
 
558
 
  return 2;
559
 
}
560
 
 
561
 
void GeoFunction::getSrsName(zorba::Item lItem, zorba::Item &srs_uri) const
562
 
{
563
 
  zorba::Item attr_item;
564
 
  if(getAttribute(lItem, 
565
 
                   "srsName", 
566
 
                   NULL,
567
 
                   attr_item))
568
 
  {
569
 
    String attr_value = attr_item.getStringValue();
570
 
    srs_uri = theModule->getItemFactory()->createAnyURI(attr_value);
571
 
    return;
572
 
  }
573
 
 
574
 
  zorba::Item parent_item = lItem.getParent();
575
 
  if(parent_item.isNull())
576
 
    return;
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))
581
 
  {
582
 
    getSrsName(envelope_item, srs_uri);
583
 
    if(!srs_uri.isNull())
584
 
      return;
585
 
  }
586
 
  getSrsName(parent_item, srs_uri);
587
 
  if(!srs_uri.isNull())
588
 
    return;
589
 
}
590
 
 
591
 
geos::geom::Geometry  *GeoFunction::buildGeosGeometryFromItem(zorba::Item &lItem, 
592
 
                                                              enum GeoFunction::gmlsf_types geometric_type,
593
 
                                                              int srs_dim,
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
598
 
{
599
 
  srs_dim = get_srsDimension(lItem, srs_dim);
600
 
  if(srs_uri)
601
 
    getSrsName(lItem, *srs_uri);
602
 
  geos::geom::Geometry *result;
603
 
 
604
 
  switch(geometric_type)
605
 
  {
606
 
  case GMLSF_POINT:
607
 
  {
608
 
    if(what_action == BUILD_GEOS_GEOMETRY)
609
 
    {
610
 
      double x, y, z;
611
 
      readPointPosCoordinates(lItem, &x, &y, &z, srs_dim);
612
 
            geos::geom::Coordinate c(x, y);
613
 
      if(srs_dim == 3)
614
 
        c.z = z;
615
 
      try{
616
 
      result = get_geometryFactory()->createPoint(c);
617
 
      result->setUserData((void*)GMLSF_POINT);
618
 
      return result;
619
 
      }catch(std::exception &excep)                                        
620
 
      {                                                                               
621
 
        std::stringstream lErrorMessage;                                              
622
 
        lErrorMessage << "Error in GEOS function createPoint : " << excep.what();  
623
 
        throwError("GEOSError", lErrorMessage.str());                                    
624
 
      }                                                                               
625
 
    }
626
 
    else if(what_action == COUNT_CHILDREN)
627
 
      (*optional_child_index_or_count) = 1;
628
 
    else if(what_action == GET_NTH_CHILD)
629
 
    {
630
 
      if((*optional_child_index_or_count) == 0)
631
 
        *result_item = lItem;
632
 
    }
633
 
    else
634
 
    {
635
 
      std::stringstream lErrorMessage;                                              
636
 
      lErrorMessage << "Error in GMLSF_POINT";  
637
 
      throwError("InternalError", lErrorMessage.str());                                    
638
 
    }
639
 
  }break;
640
 
  case GMLSF_LINESTRING:
641
 
  {
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)
646
 
    {
647
 
      optional_child_index_or_count = &last_index;
648
 
      what_action = GET_NTH_POINT;
649
 
    }
650
 
    if(what_action == BUILD_GEOS_GEOMETRY)
651
 
    {
652
 
      try{
653
 
      result = get_geometryFactory()->createLineString(cl);
654
 
      result->setUserData((void*)GMLSF_LINESTRING);
655
 
      return result;
656
 
      }catch(std::exception &excep)                                        
657
 
      {                                                                               
658
 
        //delete cl;                                                        
659
 
        std::stringstream lErrorMessage;                                              
660
 
        lErrorMessage << "Error in GEOS function createLineString : " << excep.what();  
661
 
        throwError("GEOSError", lErrorMessage.str());                                    
662
 
      }                                                                               
663
 
    }
664
 
    else if((what_action == COUNT_CHILDREN) || (what_action == GET_NUM_POINTS))
665
 
    {
666
 
      (*optional_child_index_or_count) = (uint32_t)cl->size();
667
 
      delete cl;
668
 
    }
669
 
    else if((what_action == GET_NTH_CHILD) || (what_action == GET_NTH_POINT))
670
 
    {
671
 
      if((*optional_child_index_or_count) < cl->size())
672
 
      {
673
 
        Item  item_name;
674
 
        Item  item_type;
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);
681
 
 
682
 
 
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);
688
 
        
689
 
        if(srs_dim == 3)
690
 
        {
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");
694
 
          char  strdim[10];
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);
699
 
        }
700
 
        char strtemp[100];
701
 
        if(srs_dim == 3)
702
 
        {
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);
707
 
          else
708
 
            sprintf(strtemp, "%lf %lf 0", cl->getAt((*optional_child_index_or_count)).x, 
709
 
                                          cl->getAt((*optional_child_index_or_count)).y);
710
 
        }
711
 
        else
712
 
        {
713
 
          sprintf(strtemp, "%lf %lf", cl->getAt((*optional_child_index_or_count)).x, 
714
 
                                      cl->getAt((*optional_child_index_or_count)).y);
715
 
        }
716
 
 
717
 
        zorba::Item text_item;
718
 
        text_item = theModule->getItemFactory()->createTextNode(pos_item, strtemp);
719
 
        addNewLineIndentText(*result_item, 0);
720
 
      }
721
 
      delete cl;
722
 
    }
723
 
    else
724
 
    {
725
 
      delete cl;
726
 
      std::stringstream lErrorMessage;                                              
727
 
      lErrorMessage << "Error in GMLSF_LINESTRING";  
728
 
      throwError("InternalError", lErrorMessage.str());                                    
729
 
    }
730
 
  }break;
731
 
  case GMLSF_CURVE:
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))
735
 
    {//get upset
736
 
      std::stringstream lErrorMessage;
737
 
      lErrorMessage << "gml:Curve node must have a gml:segments child";
738
 
      throwError("UnrecognizedGeoObject", lErrorMessage.str());
739
 
    }
740
 
    if((what_action == COUNT_CHILDREN) || (what_action == GET_NUM_POINTS))
741
 
    {
742
 
      (*optional_child_index_or_count) = 0;
743
 
    }
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)
749
 
    {
750
 
      segments_vector = new std::vector<geos::geom::Geometry*>;
751
 
    }
752
 
    segments_children = segments_item.getChildren();
753
 
    segments_children->open();
754
 
    while(segments_children->next(line_segment_item))
755
 
    {
756
 
      if(line_segment_item.getNodeKind() != store::StoreConsts::elementNode)
757
 
        continue;
758
 
      Item    item_qname;
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))
762
 
      {
763
 
        std::stringstream lErrorMessage;
764
 
        lErrorMessage << "Children of gml:Curve/gml:segments must be of type gml:LineStringSegment only";
765
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
766
 
      }
767
 
      String  local_name = item_qname.getLocalName();
768
 
      if(!local_name.byteEqual("LineStringSegment", 17))
769
 
      {
770
 
        std::stringstream lErrorMessage;
771
 
        lErrorMessage << "Children of gml:Curve/gml:segments must be of type gml:LineStringSegment only";
772
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
773
 
      }
774
 
      if(!checkOptionalAttribute(line_segment_item, "interpolation", "http://www.opengis.net/gml", "linear"))
775
 
      {
776
 
        std::stringstream lErrorMessage;
777
 
        lErrorMessage << "gml:Curve/gml:segments/gml:LineStringSegment supports only linear interpolation";
778
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
779
 
      }
780
 
          
781
 
      if(what_action == BUILD_GEOS_GEOMETRY)
782
 
      {
783
 
        segments_vector->push_back(buildGeosGeometryFromItem(line_segment_item, GMLSF_LINESTRING, srs_dim));
784
 
      }
785
 
      else if(what_action == COUNT_CHILDREN)
786
 
      {
787
 
        (*optional_child_index_or_count)++;
788
 
      }
789
 
      else if(what_action == GET_NUM_POINTS)
790
 
      {
791
 
        uint32_t    nr_points;
792
 
        buildGeosGeometryFromItem(line_segment_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NUM_POINTS, &nr_points);
793
 
        (*optional_child_index_or_count) += nr_points;
794
 
      }
795
 
      else if(what_action == GET_NTH_CHILD)
796
 
      {
797
 
        if((*optional_child_index_or_count) == child_nr)
798
 
        {
799
 
          *result_item = line_segment_item;
800
 
          return NULL;
801
 
        }
802
 
      }
803
 
      else if(what_action == GET_NTH_POINT)
804
 
      {
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())
807
 
          return NULL;
808
 
        uint32_t    nr_points;
809
 
        buildGeosGeometryFromItem(line_segment_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NUM_POINTS, &nr_points);
810
 
        (*optional_child_index_or_count) -= nr_points;
811
 
      }
812
 
      else
813
 
      {
814
 
        std::stringstream lErrorMessage;                                              
815
 
        lErrorMessage << "Error in GMLSF_CURVE";  
816
 
        throwError("InternalError", lErrorMessage.str());                                    
817
 
      }
818
 
      child_nr++;
819
 
   }
820
 
 
821
 
    if(what_action == BUILD_GEOS_GEOMETRY)
822
 
    {
823
 
      try{
824
 
        result = get_geometryFactory()->createMultiLineString(segments_vector);
825
 
        result->setUserData((void*)GMLSF_CURVE);
826
 
        return result;
827
 
      }catch(std::exception &excep)                                        
828
 
      {                      
829
 
        std::vector<geos::geom::Geometry*>::iterator  vec_it;
830
 
        for(vec_it = segments_vector->begin(); vec_it != segments_vector->end(); vec_it++)
831
 
        {
832
 
          delete (*vec_it);
833
 
        }
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());                                    
838
 
      }                                                                               
839
 
    }
840
 
  }break;
841
 
  case GMLSF_LINEARRING:
842
 
  {
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)
847
 
    {
848
 
      optional_child_index_or_count = &last_index;
849
 
      what_action = GET_NTH_POINT;
850
 
    }
851
 
    if(what_action == BUILD_GEOS_GEOMETRY)
852
 
    {
853
 
      try{
854
 
      result = get_geometryFactory()->createLinearRing(cl);
855
 
      result->setUserData((void*)GMLSF_LINEARRING);
856
 
      return result;
857
 
      }catch(std::exception &excep)                                        
858
 
      {                                                                               
859
 
        //delete cl;                                                        
860
 
        std::stringstream lErrorMessage;                                              
861
 
        lErrorMessage << "Error in GEOS function createLinearRing : " << excep.what();  
862
 
        throwError("GEOSError", lErrorMessage.str());                                    
863
 
      }  
864
 
    }
865
 
    else if((what_action == COUNT_CHILDREN) || (what_action == GET_NUM_POINTS))
866
 
    {
867
 
      (*optional_child_index_or_count) = (uint32_t)cl->size();
868
 
      delete cl;
869
 
    }
870
 
    else if((what_action == GET_NTH_CHILD) || (what_action == GET_NTH_POINT))
871
 
    {
872
 
      if((*optional_child_index_or_count) < cl->size())
873
 
      {
874
 
        Item  item_name;
875
 
        Item  item_type;
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);
882
 
 
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);
888
 
        
889
 
        if(srs_dim == 3)
890
 
        {
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");
894
 
          char  strdim[10];
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);
899
 
        }
900
 
        char strtemp[100];
901
 
        if(srs_dim == 3)
902
 
        {
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);
907
 
          else
908
 
            sprintf(strtemp, "%lf %lf 0", cl->getAt((*optional_child_index_or_count)).x, 
909
 
                                          cl->getAt((*optional_child_index_or_count)).y);
910
 
        }
911
 
        else
912
 
        {
913
 
          sprintf(strtemp, "%lf %lf", cl->getAt((*optional_child_index_or_count)).x, 
914
 
                                      cl->getAt((*optional_child_index_or_count)).y);
915
 
        }
916
 
 
917
 
        zorba::Item text_item;
918
 
        text_item = theModule->getItemFactory()->createTextNode(pos_item, strtemp);
919
 
        addNewLineIndentText(*result_item, 0);
920
 
      }
921
 
      delete cl;
922
 
    }
923
 
    else
924
 
    {
925
 
      delete cl;
926
 
      std::stringstream lErrorMessage;                                              
927
 
      lErrorMessage << "Error in GMLSF_LINEARRING";  
928
 
      throwError("InternalError", lErrorMessage.str());                                    
929
 
    }
930
 
  }break;
931
 
  case GMLSF_SURFACE:
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))
935
 
    {//get upset
936
 
      std::stringstream lErrorMessage;
937
 
      lErrorMessage << "gml:Surface node must have a gml:patches child";
938
 
      throwError("UnrecognizedGeoObject", lErrorMessage.str());
939
 
    }
940
 
    if(what_action == COUNT_CHILDREN)
941
 
    {
942
 
      (*optional_child_index_or_count) = 0;
943
 
    }
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)
949
 
    {
950
 
      polygon_vector = new std::vector<geos::geom::Geometry*>;
951
 
    }
952
 
    patches_children = patches_item.getChildren();
953
 
    patches_children->open();
954
 
    while(patches_children->next(polygon_patch_item))
955
 
    {
956
 
      if(polygon_patch_item.getNodeKind() != store::StoreConsts::elementNode)
957
 
        continue;
958
 
      Item    item_qname;
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))
962
 
      {
963
 
        std::stringstream lErrorMessage;
964
 
        lErrorMessage << "Children of gml:Surface/gml:patches must be of type gml:PolygonPatch only";
965
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
966
 
      }
967
 
      String  item_name = item_qname.getLocalName();
968
 
      if(!item_name.byteEqual("PolygonPatch", 12))
969
 
      {
970
 
        std::stringstream lErrorMessage;
971
 
        lErrorMessage << "Children of gml:Surface/gml:patches must be of type gml:PolygonPatch only";
972
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
973
 
      }
974
 
 
975
 
      if(what_action == BUILD_GEOS_GEOMETRY)
976
 
      {
977
 
        polygon_vector->push_back(buildGeosGeometryFromItem(polygon_patch_item, GMLSF_POLYGON, srs_dim));
978
 
      }
979
 
      else if(what_action == COUNT_CHILDREN)
980
 
      {
981
 
        (*optional_child_index_or_count)++;
982
 
      }
983
 
      else if(what_action == GET_NTH_CHILD)
984
 
      {
985
 
        if((*optional_child_index_or_count) == child_nr)
986
 
        {
987
 
          *result_item = polygon_patch_item;
988
 
          return NULL;
989
 
        }
990
 
      }
991
 
      else
992
 
      {
993
 
        std::stringstream lErrorMessage;                                              
994
 
        lErrorMessage << "Error in GMLSF_CURVE";  
995
 
        throwError("InternalError", lErrorMessage.str());                                    
996
 
      }
997
 
      child_nr++;
998
 
    }
999
 
 
1000
 
    if(what_action == BUILD_GEOS_GEOMETRY)
1001
 
    {
1002
 
      try{
1003
 
        result = get_geometryFactory()->createMultiPolygon(polygon_vector);
1004
 
        result->setUserData((void*)GMLSF_SURFACE);
1005
 
        return result;
1006
 
      }catch(std::exception &excep)                                        
1007
 
      {                                                                               
1008
 
        std::vector<geos::geom::Geometry*>::iterator  vec_it;
1009
 
        for(vec_it = polygon_vector->begin(); vec_it != polygon_vector->end(); vec_it++)
1010
 
        {
1011
 
          delete (*vec_it);
1012
 
        }
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());                                    
1017
 
      }                                                                               
1018
 
    }
1019
 
  }break;
1020
 
  case GMLSF_POLYGON:
1021
 
  {
1022
 
    Iterator_t    polygon_children;
1023
 
    Item          extint_item;
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)
1028
 
    {
1029
 
      interior_vector = new std::vector<geos::geom::Geometry*>;
1030
 
    }
1031
 
    else if(what_action == COUNT_CHILDREN)
1032
 
    {
1033
 
      (*optional_child_index_or_count) = 0;
1034
 
    }
1035
 
    polygon_children = lItem.getChildren();
1036
 
    polygon_children->open();
1037
 
    while(polygon_children->next(extint_item))
1038
 
    {
1039
 
      if(extint_item.getNodeKind() != store::StoreConsts::elementNode)
1040
 
        continue;
1041
 
      Item    item_qname;
1042
 
      extint_item.getNodeName(item_qname);
1043
 
      String  item_namespace = item_qname.getNamespace();
1044
 
      if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
1045
 
      {
1046
 
        std::stringstream lErrorMessage;
1047
 
        lErrorMessage << "Children of gml:Polygon must be gml:exterior or gml:interior";
1048
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
1049
 
      }
1050
 
      String  item_name = item_qname.getLocalName();
1051
 
      if(nr_child == 0)
1052
 
      {
1053
 
        if(!item_name.byteEqual("exterior", 8))
1054
 
        {
1055
 
          std::stringstream lErrorMessage;
1056
 
          lErrorMessage << "First child of gml:Polygon must be gml:exterior";
1057
 
          throwError("UnrecognizedGeoObject", lErrorMessage.str());
1058
 
        }
1059
 
        zorba::Item   linearring_item;
1060
 
        if(!getChild(extint_item, "LinearRing", "http://www.opengis.net/gml", linearring_item))
1061
 
        {//get upset
1062
 
          std::stringstream lErrorMessage;
1063
 
          lErrorMessage << "gml:Polygon/gml:exterior node must have a gml:LinearRing child";
1064
 
          throwError("UnrecognizedGeoObject", lErrorMessage.str());
1065
 
        }
1066
 
        if(what_action == BUILD_GEOS_GEOMETRY)
1067
 
        {
1068
 
          exterior = dynamic_cast<geos::geom::LinearRing*>(buildGeosGeometryFromItem(linearring_item, GMLSF_LINEARRING, srs_dim));
1069
 
        }
1070
 
        else if(what_action == GET_EXTERIOR_RING)
1071
 
        {
1072
 
          *result_item = linearring_item;
1073
 
          return NULL;
1074
 
        }
1075
 
      }
1076
 
      else
1077
 
      {
1078
 
        if(!item_name.byteEqual("interior", 8))
1079
 
        {
1080
 
          std::stringstream lErrorMessage;
1081
 
          lErrorMessage << "Non-first child of gml:Polygon must be gml:interior";
1082
 
          throwError("UnrecognizedGeoObject", lErrorMessage.str());
1083
 
        }
1084
 
        zorba::Item   linearring_item;
1085
 
        if(!getChild(extint_item, "LinearRing", "http://www.opengis.net/gml", linearring_item))
1086
 
        {//get upset
1087
 
          std::stringstream lErrorMessage;
1088
 
          lErrorMessage << "gml:Polygon/gml:interior node must have a gml:LinearRing child";
1089
 
          throwError("UnrecognizedGeoObject", lErrorMessage.str());
1090
 
        }
1091
 
        if(what_action == BUILD_GEOS_GEOMETRY)
1092
 
        {
1093
 
          interior_vector->push_back(buildGeosGeometryFromItem(linearring_item, GMLSF_LINEARRING, srs_dim));
1094
 
        }
1095
 
        else if(what_action == COUNT_CHILDREN)
1096
 
        {
1097
 
          (*optional_child_index_or_count)++;
1098
 
        }
1099
 
        else if(what_action == GET_NTH_CHILD)
1100
 
        {
1101
 
          if((*optional_child_index_or_count) == (nr_child-1))
1102
 
          {
1103
 
            *result_item = linearring_item;
1104
 
            return NULL;
1105
 
          }
1106
 
        }
1107
 
        else
1108
 
        {
1109
 
          std::stringstream lErrorMessage;                                              
1110
 
          lErrorMessage << "Error in GMLSF_POLYGON";  
1111
 
          throwError("InternalError", lErrorMessage.str());                                    
1112
 
        }
1113
 
      }
1114
 
      nr_child++;
1115
 
    }
1116
 
    if(what_action == BUILD_GEOS_GEOMETRY)
1117
 
    {
1118
 
      try{
1119
 
      result = get_geometryFactory()->createPolygon(exterior, interior_vector);
1120
 
      result->setUserData((void*)GMLSF_POLYGON);
1121
 
      return result;
1122
 
      }catch(std::exception &excep)                                        
1123
 
      {      
1124
 
        delete exterior;
1125
 
        std::vector<geos::geom::Geometry*>::iterator  vec_it;
1126
 
        for(vec_it = interior_vector->begin(); vec_it != interior_vector->end(); vec_it++)
1127
 
        {
1128
 
          delete (*vec_it);
1129
 
        }
1130
 
        delete interior_vector;                                                        
1131
 
        std::stringstream lErrorMessage;                                              
1132
 
        lErrorMessage << "Error in GEOS function createPolygon : " << excep.what();  
1133
 
        throwError("GEOSError", lErrorMessage.str());                                    
1134
 
      }                                                                               
1135
 
    }    
1136
 
  }break;
1137
 
  case GMLSF_MULTIPOINT:
1138
 
  {
1139
 
    Iterator_t    multipoint_children;
1140
 
    Item          point_item;
1141
 
    std::vector<geos::geom::Geometry*>    *point_vector = NULL;
1142
 
    if(what_action == BUILD_GEOS_GEOMETRY)
1143
 
    {
1144
 
      point_vector = new std::vector<geos::geom::Geometry*>;
1145
 
    }
1146
 
    else if(what_action == COUNT_CHILDREN)
1147
 
    {
1148
 
      (*optional_child_index_or_count) = 0;
1149
 
    }
1150
 
    unsigned int nr_child = 0;
1151
 
    multipoint_children = lItem.getChildren();
1152
 
    multipoint_children->open();
1153
 
    while(multipoint_children->next(point_item))
1154
 
    {
1155
 
      if(point_item.getNodeKind() != store::StoreConsts::elementNode)
1156
 
        continue;
1157
 
      Item    item_qname;
1158
 
      point_item.getNodeName(item_qname);
1159
 
      String  item_namespace = item_qname.getNamespace();
1160
 
      if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
1161
 
      {
1162
 
        std::stringstream lErrorMessage;
1163
 
        lErrorMessage << "Children of gml:MultiPoint must be gml:Point";
1164
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
1165
 
      }
1166
 
      String  item_name = item_qname.getLocalName();
1167
 
      if(!item_name.byteEqual("Point", 5))
1168
 
      {
1169
 
        std::stringstream lErrorMessage;
1170
 
        lErrorMessage << "First child of gml:MultiPoint must be gml:Point";
1171
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
1172
 
      }
1173
 
      if(what_action == BUILD_GEOS_GEOMETRY)
1174
 
      {
1175
 
        point_vector->push_back(buildGeosGeometryFromItem(point_item, GMLSF_POINT, srs_dim));
1176
 
      }
1177
 
      else if(what_action == COUNT_CHILDREN)
1178
 
      {
1179
 
        (*optional_child_index_or_count)++;
1180
 
      }
1181
 
      else if(what_action == GET_NTH_CHILD)
1182
 
      {
1183
 
        if((*optional_child_index_or_count) == nr_child)
1184
 
        {
1185
 
          *result_item = point_item;
1186
 
          return NULL;
1187
 
        }
1188
 
      }
1189
 
      else
1190
 
      {
1191
 
        std::stringstream lErrorMessage;                                              
1192
 
        lErrorMessage << "Error in GMLSF_MULTIPOINT";  
1193
 
        throwError("InternalError", lErrorMessage.str());                                    
1194
 
      }
1195
 
      nr_child++;
1196
 
    }
1197
 
    if(what_action == BUILD_GEOS_GEOMETRY)
1198
 
    {
1199
 
      try{
1200
 
      result = get_geometryFactory()->createMultiPoint(point_vector);
1201
 
      result->setUserData((void*)GMLSF_MULTIPOINT);
1202
 
      return result;
1203
 
      }catch(std::exception &excep)                                        
1204
 
      {                                                                               
1205
 
        std::vector<geos::geom::Geometry*>::iterator  vec_it;
1206
 
        for(vec_it = point_vector->begin(); vec_it != point_vector->end(); vec_it++)
1207
 
        {
1208
 
          delete (*vec_it);
1209
 
        }
1210
 
        delete point_vector;
1211
 
        std::stringstream lErrorMessage;                                              
1212
 
        lErrorMessage << "Error in GEOS function createMultiPoint : " << excep.what();  
1213
 
        throwError("GEOSError", lErrorMessage.str());                                    
1214
 
      }                                                                               
1215
 
    }
1216
 
  }break;
1217
 
  case GMLSF_MULTICURVE:
1218
 
  {
1219
 
    Iterator_t    multicurve_children;
1220
 
    Item          curve_item;
1221
 
    std::vector<geos::geom::Geometry*>    *curve_vector = NULL;
1222
 
    if(what_action == BUILD_GEOS_GEOMETRY)
1223
 
    {
1224
 
      curve_vector = new std::vector<geos::geom::Geometry*>;
1225
 
    }
1226
 
    else if((what_action == COUNT_CHILDREN) || (what_action == GET_NUM_POINTS))
1227
 
    {
1228
 
      (*optional_child_index_or_count) = 0;
1229
 
    }
1230
 
    unsigned int nr_child = 0;
1231
 
    multicurve_children = lItem.getChildren();
1232
 
    multicurve_children->open();
1233
 
    while(multicurve_children->next(curve_item))
1234
 
    {
1235
 
      if(curve_item.getNodeKind() != store::StoreConsts::elementNode)
1236
 
        continue;
1237
 
      Item    item_qname;
1238
 
      curve_item.getNodeName(item_qname);
1239
 
      String  item_namespace = item_qname.getNamespace();
1240
 
      if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
1241
 
      {
1242
 
        std::stringstream lErrorMessage;
1243
 
        lErrorMessage << "Children of gml:MultiCurve must be gml:LineString";
1244
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
1245
 
      }
1246
 
      String  item_name = item_qname.getLocalName();
1247
 
      if(!item_name.byteEqual("LineString", 10))
1248
 
      {
1249
 
        std::stringstream lErrorMessage;
1250
 
        lErrorMessage << "Children of gml:MultiCurve must be gml:LineString";
1251
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
1252
 
      }
1253
 
      if(what_action == BUILD_GEOS_GEOMETRY)
1254
 
      {
1255
 
        curve_vector->push_back(buildGeosGeometryFromItem(curve_item, GMLSF_LINESTRING, srs_dim));
1256
 
      }
1257
 
      else if(what_action == COUNT_CHILDREN)
1258
 
      {
1259
 
        (*optional_child_index_or_count)++;
1260
 
      }
1261
 
      else if(what_action == GET_NUM_POINTS)
1262
 
      {
1263
 
        uint32_t  nr_points;
1264
 
        buildGeosGeometryFromItem(curve_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NUM_POINTS, &nr_points);
1265
 
        (*optional_child_index_or_count) += nr_points;
1266
 
      }
1267
 
      else if(what_action == GET_NTH_CHILD)
1268
 
      {
1269
 
        if((*optional_child_index_or_count) == nr_child)
1270
 
        {
1271
 
          *result_item = curve_item;
1272
 
          return NULL;
1273
 
        }
1274
 
      }
1275
 
      else if(what_action == GET_NTH_POINT)
1276
 
      {
1277
 
        buildGeosGeometryFromItem(curve_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NTH_POINT, optional_child_index_or_count, result_item);
1278
 
        if(!result_item->isNull())
1279
 
          return NULL;
1280
 
        uint32_t  nr_points;
1281
 
        buildGeosGeometryFromItem(curve_item, GMLSF_LINESTRING, srs_dim, NULL, GET_NUM_POINTS, &nr_points);
1282
 
        (*optional_child_index_or_count) -= nr_points;
1283
 
      }
1284
 
      else
1285
 
      {
1286
 
        std::stringstream lErrorMessage;                                              
1287
 
        lErrorMessage << "Error in GMLSF_MULTICURVE";  
1288
 
        throwError("InternalError", lErrorMessage.str());                                    
1289
 
      }
1290
 
      nr_child++;
1291
 
    }
1292
 
    if(what_action == BUILD_GEOS_GEOMETRY)
1293
 
    {
1294
 
      try{
1295
 
      result = get_geometryFactory()->createMultiLineString(curve_vector);
1296
 
      result->setUserData((void*)GMLSF_MULTICURVE);
1297
 
      return result;
1298
 
      }catch(std::exception &excep)                                        
1299
 
      {                                                                               
1300
 
        std::vector<geos::geom::Geometry*>::iterator  vec_it;
1301
 
        for(vec_it = curve_vector->begin(); vec_it != curve_vector->end(); vec_it++)
1302
 
        {
1303
 
          delete (*vec_it);
1304
 
        }
1305
 
        delete curve_vector;
1306
 
        std::stringstream lErrorMessage;                                              
1307
 
        lErrorMessage << "Error in GEOS function createMultiLineString : " << excep.what();  
1308
 
        throwError("GEOSError", lErrorMessage.str());                                    
1309
 
      }                                                                               
1310
 
    }
1311
 
  }break;
1312
 
  case GMLSF_MULTISURFACE:
1313
 
  {
1314
 
    Iterator_t    multisurface_children;
1315
 
    Item          surface_item;
1316
 
    std::vector<geos::geom::Geometry*>    *surface_vector = NULL;
1317
 
    if(what_action == BUILD_GEOS_GEOMETRY)
1318
 
    {
1319
 
      surface_vector = new std::vector<geos::geom::Geometry*>;
1320
 
    }
1321
 
    else if(what_action == COUNT_CHILDREN)
1322
 
    {
1323
 
      (*optional_child_index_or_count) = 0;
1324
 
    }
1325
 
    unsigned int nr_child = 0;
1326
 
    multisurface_children = lItem.getChildren();
1327
 
    multisurface_children->open();
1328
 
    while(multisurface_children->next(surface_item))
1329
 
    {
1330
 
      if(surface_item.getNodeKind() != store::StoreConsts::elementNode)
1331
 
        continue;
1332
 
      Item    item_qname;
1333
 
      surface_item.getNodeName(item_qname);
1334
 
      String  item_namespace = item_qname.getNamespace();
1335
 
      if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
1336
 
      {
1337
 
        std::stringstream lErrorMessage;
1338
 
        lErrorMessage << "Children of gml:MultiSurface must be gml:Polygon";
1339
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
1340
 
      }
1341
 
      String  item_name = item_qname.getLocalName();
1342
 
      if(!item_name.byteEqual("Polygon", 7))
1343
 
      {
1344
 
        std::stringstream lErrorMessage;
1345
 
        lErrorMessage << "Children of gml:MultiSurface must be gml:Polygon";
1346
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
1347
 
      }
1348
 
      if(what_action == BUILD_GEOS_GEOMETRY)
1349
 
      {
1350
 
        surface_vector->push_back(buildGeosGeometryFromItem(surface_item, GMLSF_POLYGON, srs_dim));
1351
 
      }
1352
 
      else if(what_action == COUNT_CHILDREN)
1353
 
      {
1354
 
        (*optional_child_index_or_count)++;
1355
 
      }
1356
 
      else if(what_action == GET_NTH_CHILD)
1357
 
      {
1358
 
        if((*optional_child_index_or_count) == nr_child)
1359
 
        {
1360
 
          *result_item = surface_item;
1361
 
          return NULL;
1362
 
        }
1363
 
      }
1364
 
      else
1365
 
      {
1366
 
        std::stringstream lErrorMessage;                                              
1367
 
        lErrorMessage << "Error in GMLSF_MULTICURVE";  
1368
 
        throwError("InternalError", lErrorMessage.str());                                    
1369
 
      }
1370
 
      nr_child++;
1371
 
    }
1372
 
    if(what_action == BUILD_GEOS_GEOMETRY)
1373
 
    {
1374
 
      try{
1375
 
      result = get_geometryFactory()->createMultiPolygon(surface_vector);
1376
 
      result->setUserData((void*)GMLSF_MULTISURFACE);
1377
 
      return result;
1378
 
      }catch(std::exception &excep)                                        
1379
 
      {                                                                               
1380
 
        std::vector<geos::geom::Geometry*>::iterator  vec_it;
1381
 
        for(vec_it = surface_vector->begin(); vec_it != surface_vector->end(); vec_it++)
1382
 
        {
1383
 
          delete (*vec_it);
1384
 
        }
1385
 
        delete surface_vector;
1386
 
        std::stringstream lErrorMessage;                                              
1387
 
        lErrorMessage << "Error in GEOS function createMultiPolygon : " << excep.what();  
1388
 
        throwError("GEOSError", lErrorMessage.str());                                    
1389
 
      }                                                                               
1390
 
    }
1391
 
  }break;
1392
 
  case GMLSF_MULTIGEOMETRY:
1393
 
  {
1394
 
    Iterator_t    multigeometry_children;
1395
 
    Item          geometry_item;
1396
 
    std::vector<geos::geom::Geometry*>    *geometry_vector = NULL;
1397
 
    if(what_action == BUILD_GEOS_GEOMETRY)
1398
 
    {
1399
 
      geometry_vector = new std::vector<geos::geom::Geometry*>;
1400
 
    }
1401
 
    else if(what_action == COUNT_CHILDREN)
1402
 
    {
1403
 
      (*optional_child_index_or_count) = 0;
1404
 
    }
1405
 
    unsigned int nr_child = 0;
1406
 
    multigeometry_children = lItem.getChildren();
1407
 
    multigeometry_children->open();
1408
 
    while(multigeometry_children->next(geometry_item))
1409
 
    {
1410
 
      if(geometry_item.getNodeKind() != store::StoreConsts::elementNode)
1411
 
        continue;
1412
 
      Item    item_qname;
1413
 
      geometry_item.getNodeName(item_qname);
1414
 
      String  item_namespace = item_qname.getNamespace();
1415
 
      if(!item_namespace.byteEqual("http://www.opengis.net/gml", 26))
1416
 
      {
1417
 
        std::stringstream lErrorMessage;
1418
 
        lErrorMessage << "Children of gml:MultiGeometry must be gml:geometryMember or gml:geometryMembers";
1419
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
1420
 
      }
1421
 
      String  item_name = item_qname.getLocalName();
1422
 
      if(item_name.byteEqual("geometryMember", 14) || item_name.byteEqual("geometryMembers", 15))
1423
 
      {
1424
 
        Iterator_t    member_children;
1425
 
        Item          member_item;
1426
 
        member_children = geometry_item.getChildren();
1427
 
        member_children->open();
1428
 
        while(member_children->next(member_item))
1429
 
        {
1430
 
          if(what_action == BUILD_GEOS_GEOMETRY)
1431
 
          {
1432
 
            geometry_vector->push_back(buildGeosGeometryFromItem(member_item, getGmlSFGeometricType(member_item), srs_dim));
1433
 
          }
1434
 
          else if(what_action == COUNT_CHILDREN)
1435
 
          {
1436
 
            (*optional_child_index_or_count)++;
1437
 
          }
1438
 
          else if(what_action == GET_NTH_CHILD)
1439
 
          {
1440
 
            if((*optional_child_index_or_count) == nr_child)
1441
 
            {
1442
 
              *result_item = member_item;
1443
 
              return NULL;
1444
 
            }
1445
 
          }
1446
 
          else
1447
 
          {
1448
 
            std::stringstream lErrorMessage;                                              
1449
 
            lErrorMessage << "Error in GMLSF_MULTIGEOMETRY";  
1450
 
            throwError("InternalError", lErrorMessage.str());                                    
1451
 
          }
1452
 
          nr_child++;
1453
 
        }
1454
 
      }
1455
 
      else
1456
 
      {
1457
 
        std::stringstream lErrorMessage;
1458
 
        lErrorMessage << "Children of gml:MultiGeometry must be gml:geometryMember or gml:geometryMembers";
1459
 
        throwError("UnrecognizedGeoObject", lErrorMessage.str());
1460
 
      }
1461
 
    }
1462
 
    if(what_action == BUILD_GEOS_GEOMETRY)
1463
 
    {
1464
 
      try{
1465
 
        result = get_geometryFactory()->createGeometryCollection(geometry_vector);
1466
 
        result->setUserData((void*)GMLSF_MULTIGEOMETRY);
1467
 
        return result;
1468
 
      }catch(std::exception &excep)                                        
1469
 
      {                                                                               
1470
 
        std::vector<geos::geom::Geometry*>::iterator  vec_it;
1471
 
        for(vec_it = geometry_vector->begin(); vec_it != geometry_vector->end(); vec_it++)
1472
 
        {
1473
 
          delete (*vec_it);
1474
 
        }
1475
 
        delete geometry_vector;
1476
 
        std::stringstream lErrorMessage;                                              
1477
 
        lErrorMessage << "Error in GEOS function createGeometryCollection : " << excep.what();  
1478
 
        throwError("GEOSError", lErrorMessage.str());                                    
1479
 
      }                                                                               
1480
 
    }
1481
 
  }break;
1482
 
  case GMLSF_INVALID:
1483
 
  default:
1484
 
  {
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());
1491
 
  }
1492
 
  break;
1493
 
  }
1494
 
 
1495
 
  return NULL;
1496
 
}
1497
 
 
1498
 
void GeoFunction::addNewLineIndentText(zorba::Item &parent, unsigned int indent) const 
1499
 
{
1500
 
/*  zorba::Item text_item;
1501
 
  if(indent > 100)
1502
 
    indent = 100;
1503
 
  char *strtemp;
1504
 
  strtemp = new char[indent+10];
1505
 
  strtemp[0] = '\n';
1506
 
  memset(strtemp+1, ' ', indent);
1507
 
  strtemp[1+indent] = 0;
1508
 
  text_item = theModule->getItemFactory()->createTextNode(parent, strtemp);
1509
 
  delete[] strtemp;
1510
 
*/
1511
 
}
1512
 
 
1513
 
void GeoFunction::appendIndent(char *&strtemp2, unsigned int indent) const
1514
 
{
1515
 
  strtemp2[0] = '\n';
1516
 
  memset(strtemp2+1, ' ', indent);
1517
 
  strtemp2 += indent+1;
1518
 
  strtemp2[0] = 0;
1519
 
}
1520
 
 
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
1527
 
                                                    ) const
1528
 
{
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");
1535
 
 
1536
 
  if(!parent.isNull())
1537
 
    addNewLineIndentText(parent, indent);
1538
 
 
1539
 
  switch(geos_geometry->getGeometryTypeId())
1540
 
  {
1541
 
  case  geos::geom::GEOS_POINT:
1542
 
  {
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);
1545
 
 
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);
1551
 
    
1552
 
    char strtemp[100];
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)
1557
 
#else
1558
 
    if(getCoordinateDimension(geos_geometry) == 3)
1559
 
#endif
1560
 
    {
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);
1567
 
      if(!ISNAN(c->z))
1568
 
        sprintf(strtemp, "%lf %lf %lf", c->x, c->y, c->z);
1569
 
      else
1570
 
        sprintf(strtemp, "%lf %lf 0", c->x, c->y);
1571
 
    }
1572
 
    else
1573
 
      sprintf(strtemp, "%lf %lf", c->x, c->y);
1574
 
 
1575
 
    zorba::Item text_item;
1576
 
    text_item = theModule->getItemFactory()->createTextNode(pos_item, strtemp);
1577
 
    addNewLineIndentText(result_item, indent);
1578
 
    break;
1579
 
  }
1580
 
        /// a linestring
1581
 
  case geos::geom::GEOS_LINESTRING:
1582
 
        /// a linear ring (linestring with 1st point == last point)
1583
 
  case geos::geom::GEOS_LINEARRING:
1584
 
  {
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);
1588
 
 
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);
1594
 
    
1595
 
#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
1596
 
    int coord_dim = geos_geometry->getCoordinateDimension();
1597
 
#else
1598
 
    int coord_dim = getCoordinateDimension(geos_geometry);
1599
 
#endif
1600
 
    if(coord_dim == 3)
1601
 
    {
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);
1608
 
    }
1609
 
    char *strtemp;
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);
1614
 
    strtemp[0] = 0;
1615
 
    char  *strtemp2 = strtemp;
1616
 
    for(size_t i=0;i<cs_size;i++)
1617
 
    {
1618
 
      appendIndent(strtemp2, indent+4);
1619
 
      if(coord_dim == 3)
1620
 
      {
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);
1623
 
        else
1624
 
          sprintf(strtemp2, "%lf %lf 0", cs->getAt(i).x, cs->getAt(i).y);
1625
 
      }
1626
 
      else
1627
 
        sprintf(strtemp2, "%lf %lf", cs->getAt(i).x, cs->getAt(i).y);
1628
 
      strtemp2 += strlen(strtemp2);
1629
 
    }
1630
 
 
1631
 
    if(cs_size)
1632
 
    {
1633
 
      appendIndent(strtemp2, indent+2);
1634
 
      zorba::Item text_item;
1635
 
      text_item = theModule->getItemFactory()->createTextNode(pos_item, strtemp);
1636
 
      addNewLineIndentText(result_item, indent);
1637
 
    }
1638
 
    free(strtemp);
1639
 
    break;
1640
 
  }
1641
 
        /// a polygon
1642
 
  case geos::geom::GEOS_POLYGON:
1643
 
  {
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);
1646
 
 
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();
1650
 
    if(exterior_ring)
1651
 
    {
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);
1659
 
    }
1660
 
    size_t interior_rings = polygon->getNumInteriorRing();
1661
 
    for(size_t i=0;i<interior_rings;i++)
1662
 
    {
1663
 
      const geos::geom::LineString*   interior_ring;
1664
 
      interior_ring = polygon->getInteriorRingN(i);
1665
 
 
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);
1673
 
    }
1674
 
    if(exterior_ring || interior_rings)
1675
 
      addNewLineIndentText(result_item, indent);
1676
 
    break;
1677
 
  }
1678
 
        /// a collection of points
1679
 
  case geos::geom::GEOS_MULTIPOINT:
1680
 
  {
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);
1683
 
 
1684
 
    size_t    nr_geoms = geos_geometry->getNumGeometries();
1685
 
    for(size_t i=0;i<nr_geoms;i++)
1686
 
    {
1687
 
      const geos::geom::Geometry  *point;
1688
 
      point = geos_geometry->getGeometryN(i);
1689
 
      getGMLItemFromGeosGeometry(result_item, point, NULL, indent+2);
1690
 
    }
1691
 
    if(nr_geoms)
1692
 
      addNewLineIndentText(result_item, indent);
1693
 
    break;
1694
 
  }
1695
 
        /// a collection of linestrings
1696
 
  case geos::geom::GEOS_MULTILINESTRING:
1697
 
  {
1698
 
    const geos::geom::MultiLineString *multiline = dynamic_cast<const geos::geom::MultiLineString*>(geos_geometry);
1699
 
    if(!dont_check_for_curve_surface && isCurve(multiline))
1700
 
    {
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);
1708
 
 
1709
 
      size_t    nr_geoms = multiline->getNumGeometries();
1710
 
      for(size_t i=0;i<nr_geoms;i++)
1711
 
      {
1712
 
        const geos::geom::Geometry  *linestring;
1713
 
        linestring = multiline->getGeometryN(i);
1714
 
 
1715
 
        zorba::Item   linestring_item;
1716
 
        linestring_item = getGMLItemFromGeosGeometry(segments_item, linestring, NULL, indent+4, "LineStringSegment");
1717
 
 
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);
1724
 
      }
1725
 
      if(nr_geoms)
1726
 
        addNewLineIndentText(segments_item, indent+2);
1727
 
      addNewLineIndentText(result_item, indent);
1728
 
    }
1729
 
    else
1730
 
    {
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);
1733
 
 
1734
 
      size_t    nr_geoms = geos_geometry->getNumGeometries();
1735
 
      for(size_t i=0;i<nr_geoms;i++)
1736
 
      {
1737
 
        const geos::geom::Geometry  *linestring;
1738
 
        linestring = geos_geometry->getGeometryN(i);
1739
 
        getGMLItemFromGeosGeometry(result_item, linestring, NULL, indent+2);
1740
 
      }
1741
 
      if(nr_geoms)
1742
 
        addNewLineIndentText(result_item, indent);
1743
 
    }
1744
 
    break;
1745
 
  }
1746
 
        /// a collection of polygons
1747
 
  case geos::geom::GEOS_MULTIPOLYGON:
1748
 
  {
1749
 
    const geos::geom::MultiPolygon *multipoly = dynamic_cast<const geos::geom::MultiPolygon*>(geos_geometry);
1750
 
    if(!dont_check_for_curve_surface && isSurface(multipoly))
1751
 
    {
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);
1759
 
 
1760
 
      size_t    nr_geoms = multipoly->getNumGeometries();
1761
 
      for(size_t i=0;i<nr_geoms;i++)
1762
 
      {
1763
 
        const geos::geom::Geometry  *polygon;
1764
 
        polygon = multipoly->getGeometryN(i);
1765
 
 
1766
 
        zorba::Item   polygon_item;
1767
 
        polygon_item = getGMLItemFromGeosGeometry(patches_item, polygon, NULL, indent+4, "PolygonPatch");
1768
 
      }
1769
 
      if(nr_geoms)
1770
 
        addNewLineIndentText(patches_item, indent+2);
1771
 
      addNewLineIndentText(result_item, indent);
1772
 
    }
1773
 
    else
1774
 
    {
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);
1777
 
 
1778
 
      size_t    nr_geoms = geos_geometry->getNumGeometries();
1779
 
      for(size_t i=0;i<nr_geoms;i++)
1780
 
      {
1781
 
        const geos::geom::Geometry  *polygon;
1782
 
        polygon = geos_geometry->getGeometryN(i);
1783
 
        getGMLItemFromGeosGeometry(result_item, polygon, NULL, indent+2);
1784
 
      }
1785
 
      if(nr_geoms)
1786
 
        addNewLineIndentText(result_item, indent);
1787
 
    }
1788
 
    break;
1789
 
  }
1790
 
        /// a collection of heterogeneus geometries
1791
 
  case geos::geom::GEOS_GEOMETRYCOLLECTION:
1792
 
  {
1793
 
    size_t    nr_geoms = geos_geometry->getNumGeometries();
1794
 
    if(!nr_geoms)
1795
 
      break;
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);
1798
 
 
1799
 
    for(size_t i=0;i<nr_geoms;i++)
1800
 
    {
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);
1808
 
 
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);
1813
 
    }
1814
 
    if(nr_geoms)
1815
 
      addNewLineIndentText(result_item, indent);
1816
 
    break;
1817
 
  }
1818
 
  default:
1819
 
  {
1820
 
    std::stringstream lErrorMessage;
1821
 
    lErrorMessage << "Geometry type " << geos_geometry->getGeometryType() << " is not supported";
1822
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
1823
 
  }
1824
 
  }
1825
 
 
1826
 
  if(!result_item.isNull() && srs_uri && !srs_uri->isNull())
1827
 
  {
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);
1833
 
  }
1834
 
 
1835
 
//  if(!parent.isNull())
1836
 
//    addNewLineIndentText(parent, indent);
1837
 
  return result_item;
1838
 
}
1839
 
 
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
1842
 
{
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++)
1846
 
  {
1847
 
    const geos::geom::LineString   *linestring = dynamic_cast<const geos::geom::LineString*>(*line_it);
1848
 
    if(end_point.get())
1849
 
    {
1850
 
      std::auto_ptr<geos::geom::Point> start_point;
1851
 
      start_point.reset(linestring->getStartPoint());
1852
 
      if(start_point->compareTo(end_point.get()))
1853
 
        return false;
1854
 
    }
1855
 
    end_point.reset(linestring->getEndPoint());
1856
 
  }
1857
 
  return true;
1858
 
}
1859
 
 
1860
 
bool GeoFunction::isClosedCurve(const geos::geom::Geometry *geos_geometry) const 
1861
 
{
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();
1865
 
  if(!num_segments)
1866
 
    return false;
1867
 
  unsigned int i;
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++)
1874
 
  {
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)))
1878
 
      return false;
1879
 
    coords1 = coords2;
1880
 
    segment1 = segment2;
1881
 
  }
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)))
1886
 
    return false;
1887
 
  
1888
 
  return true;
1889
 
}
1890
 
 
1891
 
geos::geom::LineString *GeoFunction::curveToLineString(const geos::geom::Geometry *geos_geometry) const
1892
 
{
1893
 
  const geos::geom::MultiLineString *curve = dynamic_cast<const geos::geom::MultiLineString *>(geos_geometry);
1894
 
  if(!isCurve(curve))
1895
 
    return NULL;
1896
 
  unsigned int num_segments = (unsigned int)curve->getNumGeometries();
1897
 
  if(!num_segments)
1898
 
    return NULL;
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);
1902
 
  unsigned int i;
1903
 
  for(i=0;i<num_segments;i++)
1904
 
  {
1905
 
    segment = dynamic_cast<const geos::geom::LineString *>(curve->getGeometryN(i));
1906
 
    coords.reset(segment->getCoordinates());
1907
 
    linestring_coords->add(coords.get(), true, true);
1908
 
  }
1909
 
  geos::geom::LineString *linestring = get_geometryFactory()->createLineString(linestring_coords);
1910
 
  linestring->setUserData((void*)GMLSF_LINESTRING);
1911
 
 
1912
 
  return linestring;
1913
 
}
1914
 
 
1915
 
bool GeoFunction::isRingCurve(const geos::geom::Geometry *geos_geometry) const 
1916
 
{
1917
 
  geos::geom::LineString *linestring;
1918
 
  linestring = curveToLineString(geos_geometry);
1919
 
  if(!linestring)
1920
 
    return false;
1921
 
  //use GEOS
1922
 
  bool retval;
1923
 
  retval = linestring->isRing();
1924
 
  delete linestring;
1925
 
 
1926
 
  return retval;
1927
 
}
1928
 
 
1929
 
bool GeoFunction::isSimpleCurve(const geos::geom::Geometry *geos_geometry) const 
1930
 
{
1931
 
  geos::geom::LineString *linestring;
1932
 
  linestring = curveToLineString(geos_geometry);
1933
 
  if(!linestring)
1934
 
    return false;
1935
 
  //use GEOS
1936
 
  bool retval;
1937
 
  retval = linestring->isSimple();
1938
 
  delete linestring;
1939
 
 
1940
 
  return retval;
1941
 
}
1942
 
 
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,
1945
 
                            bool *is_closed,
1946
 
                            geos::geom::LinearRing **exterior_boundary) const
1947
 
{
1948
 
/*
1949
 
  struct _tline
1950
 
  {
1951
 
    double x1, y1, x2, y2;
1952
 
    //bool taken;
1953
 
  };
1954
 
  struct _tpoly
1955
 
  {
1956
 
    std::vector<struct _tline> lines;
1957
 
    bool processed, touched;
1958
 
  };
1959
 
  std::vector<struct _tpoly>  polys;
1960
 
  int p = 0;
1961
 
  //init the data
1962
 
  if(!multipolygon->getNumGeometries())
1963
 
    return false;
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++)
1967
 
  {
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;
1972
 
    int l, nr_points;
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++)
1978
 
    {
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();
1983
 
      if(l)
1984
 
      {
1985
 
        polys[p].lines[l-1].x2 = point->getX();
1986
 
        polys[p].lines[l-1].y2 = point->getY();
1987
 
      }
1988
 
      else
1989
 
      {
1990
 
        polys[p].lines[nr_points-1].x2 = point->getX();
1991
 
        polys[p].lines[nr_points-1].y2 = point->getY();
1992
 
      }
1993
 
    }
1994
 
  }
1995
 
 
1996
 
  //now check
1997
 
  std::vector<struct _tpoly>::iterator  tpoly_it;
1998
 
  bool first_round = true;
1999
 
  while(1)
2000
 
  {
2001
 
    if(first_round)
2002
 
      tpoly_it = polys.begin();
2003
 
    else
2004
 
    {
2005
 
      int total = 0;
2006
 
      int processed = 0;
2007
 
      for(tpoly_it = polys.begin(); tpoly_it != polys.end(); tpoly_it++)
2008
 
      {
2009
 
        total++;
2010
 
        if((*tpoly_it).processed)
2011
 
          processed++;
2012
 
        else if((*tpoly_it).touched)
2013
 
          break;
2014
 
      }
2015
 
      if(tpoly_it == polys.end())
2016
 
      {
2017
 
        if(total == processed)
2018
 
          return true;
2019
 
        else
2020
 
          return false;
2021
 
      }
2022
 
    }
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++)
2029
 
    {
2030
 
      int matches = 0;
2031
 
      std::vector<struct _tpoly>::iterator  tpoly_it2;
2032
 
      for(tpoly_it2 = polys.begin(); tpoly_it2 != polys.end(); tpoly_it2++)
2033
 
      {
2034
 
        if((*tpoly_it2).processed)
2035
 
          continue;
2036
 
        std::vector<struct _tline>::iterator line_it2;
2037
 
        for(line_it2 = (*tpoly_it2).lines.begin(); line_it2 != (*tpoly_it2).lines.end(); line_it2++)
2038
 
        {
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))
2043
 
          {
2044
 
            (*tpoly_it2).touched = true;
2045
 
            matches++;
2046
 
          }
2047
 
        }
2048
 
      }
2049
 
      if(matches > 1)
2050
 
        return false;
2051
 
      all_matches += matches;
2052
 
    }
2053
 
    if(!all_matches)
2054
 
      return false;
2055
 
  }
2056
 
  return true;
2057
 
*/
2058
 
 
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
2062
 
 
2063
 
  std::vector<int>    ids;
2064
 
  unsigned int i;
2065
 
  unsigned int nr_patches = (unsigned int)multipolygon->getNumGeometries();
2066
 
  if(!nr_patches)
2067
 
    return false;
2068
 
  ids.resize(nr_patches);
2069
 
  for(i=0;i<nr_patches;i++)
2070
 
  {
2071
 
    ids[i] = 1;//will be set -i-1 if it is touched by another polygon, and to zero when processed
2072
 
  }
2073
 
 
2074
 
  if(is_closed)
2075
 
    *is_closed = true;
2076
 
  if(exterior_boundary)
2077
 
    *exterior_boundary = NULL;
2078
 
 
2079
 
  std::vector<geos::geom::Geometry*> boundary_segments;//for computing exterior_boundary
2080
 
  bool is_united;
2081
 
 
2082
 
  ids[0] = -1;
2083
 
  while(1)
2084
 
  {
2085
 
    is_united = true;
2086
 
    for(i=0;i<nr_patches;i++)
2087
 
      if(ids[i] > 0)
2088
 
        is_united = false;
2089
 
      else if(ids[i] < 0)
2090
 
        break;
2091
 
    if(i == nr_patches)
2092
 
      break;
2093
 
    ids[i] = 0;
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();
2097
 
 
2098
 
    for(unsigned int j=0;(j<nr_patches);j++)
2099
 
    {
2100
 
      if(j==i)
2101
 
        continue;
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);
2106
 
      if(segment)
2107
 
      {
2108
 
        for(unsigned int s=0;s<segment->getNumGeometries();s++)
2109
 
        {
2110
 
          const geos::geom::Geometry *seg_piece = segment->getGeometryN(s);
2111
 
 
2112
 
          if((seg_piece->getGeometryTypeId() == geos::geom::GEOS_LINESTRING) ||
2113
 
            (seg_piece->getGeometryTypeId() == geos::geom::GEOS_MULTILINESTRING))
2114
 
          {
2115
 
            if(ids[j] > 0)
2116
 
              ids[j] = -1;
2117
 
            for(unsigned int k=0;k<common_segments.size();k++)
2118
 
            {
2119
 
              if(seg_piece->overlaps(common_segments[k]))
2120
 
              {
2121
 
                delete segment;
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];
2126
 
                return false;
2127
 
              }
2128
 
            }
2129
 
            common_segments.push_back(seg_piece->clone());
2130
 
          }
2131
 
        }
2132
 
        delete segment;
2133
 
      }//end if(segment)
2134
 
    }
2135
 
    if((is_closed && *is_closed) || exterior_boundary)
2136
 
    {
2137
 
      if(!common_segments.size())
2138
 
      {
2139
 
        if(is_closed)
2140
 
          *is_closed = false;
2141
 
      }
2142
 
      else
2143
 
      {
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++)
2148
 
        {
2149
 
          temp_union = segment_union->Union(common_segments[c]);
2150
 
          delete segment_union;
2151
 
          segment_union = temp_union;
2152
 
        }
2153
 
        if(!segment_union->equals(ring1))
2154
 
        {
2155
 
          if(is_closed)
2156
 
            *is_closed = false;
2157
 
          if(exterior_boundary)
2158
 
          {
2159
 
            geos::geom::Geometry *diff;
2160
 
            diff = ring1->difference(segment_union);
2161
 
            boundary_segments.push_back(diff);
2162
 
          }
2163
 
        }
2164
 
        delete segment_union;
2165
 
      }
2166
 
    }
2167
 
    for(unsigned int c=0;c<common_segments.size();c++)
2168
 
      delete common_segments[c];
2169
 
    common_segments.clear();
2170
 
  }
2171
 
 
2172
 
  if(is_united && exterior_boundary)
2173
 
  {
2174
 
    //do manual union of boundary_segments
2175
 
    //std::vector<const geos::geom::Point *> points;
2176
 
    geos::geom::CoordinateSequence      *cl = NULL;
2177
 
 
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++)
2181
 
    {
2182
 
      nr_segments += boundary_segments[b]->getNumGeometries();
2183
 
    }
2184
 
    //points.reserve(nr_segments*4);
2185
 
    segments.reserve(nr_segments);
2186
 
    for(unsigned int b=0;b<boundary_segments.size();b++)
2187
 
    {
2188
 
      geos::geom::Geometry* segm = boundary_segments[b];
2189
 
      for(unsigned int s=0;s<segm->getNumGeometries();s++)
2190
 
      {
2191
 
        const geos::geom::Geometry* part = segm->getGeometryN(s);
2192
 
        if(part->getGeometryTypeId() == geos::geom::GEOS_LINESTRING)
2193
 
        {
2194
 
          segments.push_back(dynamic_cast<const geos::geom::LineString *>(part));
2195
 
        }
2196
 
      }
2197
 
    }
2198
 
    const geos::geom::Geometry* part = segments[0];
2199
 
    if(!cl)
2200
 
    {
2201
 
      int srs_dim;
2202
 
#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
2203
 
      srs_dim = part->getCoordinateDimension();
2204
 
#else
2205
 
      srs_dim = getCoordinateDimension(part);
2206
 
#endif
2207
 
      cl = geos::geom::CoordinateArraySequenceFactory::instance()->create((std::size_t)0, srs_dim);
2208
 
    }
2209
 
    std::auto_ptr<const geos::geom::CoordinateSequence> coords(part->getCoordinates());
2210
 
    cl->add(coords.get(), false, true);
2211
 
 
2212
 
    segments[0] = NULL;
2213
 
    while(1)
2214
 
    {
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++)
2218
 
      {
2219
 
        if(!segments[s])
2220
 
          continue;
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))
2225
 
        {
2226
 
          cl->add(coords.get(), false, true);
2227
 
          segments[s] = NULL;
2228
 
          added_points = true;
2229
 
          break;
2230
 
        }
2231
 
        else
2232
 
        {
2233
 
          point = coords->getAt(coords->size()-1);
2234
 
          if(last_point.equals(point))
2235
 
          {
2236
 
            cl->add(coords.get(), false, false);
2237
 
            segments[s] = NULL;
2238
 
            added_points = true;
2239
 
            break;
2240
 
          }
2241
 
        }
2242
 
      }
2243
 
      if(!added_points)
2244
 
        break;
2245
 
    }
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];
2251
 
  }
2252
 
  return is_united;
2253
 
}
2254
 
 
2255
 
///////////////////////////////////////////////////////////////////////
2256
 
ItemSequence_t 
2257
 
SFDimensionFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2258
 
         const StaticContext* aSctxCtx,
2259
 
         const DynamicContext* aDynCtx) const
2260
 
{
2261
 
  Item lItem;
2262
 
  gmlsf_types   geometric_type;
2263
 
  geometric_type = getGeometryNodeType(args, 0, lItem);
2264
 
 
2265
 
  std::auto_ptr<geos::geom::Geometry>  geos_geometry(buildGeosGeometryFromItem(lItem, geometric_type, -1));
2266
 
                                                                                        
2267
 
  geos::geom::Dimension::DimensionType   dim_type = geos::geom::Dimension::DONTCARE;                                                
2268
 
  try{                                                                                  
2269
 
    dim_type = geos_geometry->getDimension();                                  
2270
 
  }catch(std::exception &excep)                                              
2271
 
  {                                                                                     
2272
 
    std::stringstream lErrorMessage;                                                    
2273
 
    lErrorMessage << "Error in GEOS function getDimension : " << excep.what();  
2274
 
    throwError("GEOSError", lErrorMessage.str());                                          
2275
 
  }                                                                                     
2276
 
 
2277
 
  return ItemSequence_t(new SingletonItemSequence(
2278
 
      theModule->getItemFactory()->createInteger((int)dim_type)));
2279
 
}
2280
 
 
2281
 
///////////////////////////////////////////////////////////////////////
2282
 
ItemSequence_t 
2283
 
SFCoordinateDimensionFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2284
 
         const StaticContext* aSctxCtx,
2285
 
         const DynamicContext* aDynCtx) const
2286
 
{
2287
 
  Item lItem;
2288
 
  gmlsf_types   geometric_type;
2289
 
  geometric_type = getGeometryNodeType(args, 0, lItem);
2290
 
 
2291
 
  switch(geometric_type)
2292
 
  {
2293
 
  case GMLSF_INVALID:
2294
 
    {
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());
2301
 
    }
2302
 
    break;
2303
 
  default:
2304
 
    break;
2305
 
  }
2306
 
 
2307
 
  std::auto_ptr<geos::geom::Geometry>  geos_geometry(buildGeosGeometryFromItem(lItem, geometric_type, -1));
2308
 
 
2309
 
#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
2310
 
  int   coord_dim = geos_geometry->getCoordinateDimension();
2311
 
#else
2312
 
  int coord_dim = getCoordinateDimension(geos_geometry.get());
2313
 
#endif
2314
 
  return ItemSequence_t(new SingletonItemSequence(
2315
 
      theModule->getItemFactory()->createInteger(coord_dim)));
2316
 
}
2317
 
 
2318
 
///////////////////////////////////////////////////////////////////////
2319
 
ItemSequence_t 
2320
 
SFGeometryTypeFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2321
 
         const StaticContext* aSctxCtx,
2322
 
         const DynamicContext* aDynCtx) const
2323
 
{
2324
 
  Item lItem;
2325
 
  gmlsf_types   geometric_type;
2326
 
  geometric_type = getGeometryNodeType(args, 0, lItem);
2327
 
 
2328
 
  zorba::String type_string;
2329
 
  switch(geometric_type)
2330
 
  {
2331
 
  case GMLSF_POINT:
2332
 
   type_string = "Point";break;
2333
 
  case GMLSF_LINESTRING:
2334
 
   type_string = "LineString";break;
2335
 
  case GMLSF_CURVE:
2336
 
   type_string = "Curve";break;
2337
 
  case GMLSF_LINEARRING:
2338
 
   type_string = "LineString";break;
2339
 
  case GMLSF_SURFACE:
2340
 
   type_string = "Surface";break;
2341
 
  case GMLSF_POLYGON:
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;
2352
 
 
2353
 
  case GMLSF_INVALID:
2354
 
  default:
2355
 
  /*  {
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());
2362
 
    }
2363
 
  */  break;
2364
 
  }
2365
 
 
2366
 
  if(!type_string.empty())
2367
 
  {
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)));
2372
 
  }
2373
 
  else
2374
 
  {
2375
 
    return ItemSequence_t(NULL);//new EmptySequence());
2376
 
  }
2377
 
}
2378
 
 
2379
 
///////////////////////////////////////////////////////////////////////
2380
 
ItemSequence_t 
2381
 
SFNumGeometriesFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2382
 
         const StaticContext* aSctxCtx,
2383
 
         const DynamicContext* aDynCtx) const
2384
 
{
2385
 
  Item lItem;
2386
 
  gmlsf_types   geometric_type;
2387
 
  geometric_type = getGeometryNodeType(args, 0, lItem);
2388
 
 
2389
 
  switch(geometric_type)
2390
 
  {
2391
 
  case GMLSF_POINT:
2392
 
  case GMLSF_LINESTRING:
2393
 
  //case GMLSF_CURVE:
2394
 
  case GMLSF_LINEARRING:
2395
 
  //case GMLSF_SURFACE:
2396
 
  case GMLSF_POLYGON:
2397
 
    return ItemSequence_t(new SingletonItemSequence(
2398
 
      theModule->getItemFactory()->createUnsignedInt(1)));
2399
 
  case GMLSF_INVALID:
2400
 
    {
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());
2407
 
    }
2408
 
    break;
2409
 
  default:
2410
 
    break;
2411
 
  }
2412
 
 
2413
 
  uint32_t    num_geos = 0;
2414
 
  buildGeosGeometryFromItem(lItem, geometric_type, -1, NULL, COUNT_CHILDREN, &num_geos);
2415
 
 
2416
 
  return ItemSequence_t(new SingletonItemSequence(
2417
 
     theModule->getItemFactory()->createUnsignedInt(num_geos)));
2418
 
}
2419
 
 
2420
 
ItemSequence_t                                                                          
2421
 
SFGeometryNFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
2422
 
         const StaticContext* aSctxCtx,                                                 
2423
 
         const DynamicContext* aDynCtx) const                                           
2424
 
{                                                                                       
2425
 
  Item lItem1;                                                                    
2426
 
  gmlsf_types   geometric_type1;                                                  
2427
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         
2428
 
                                                                                  
2429
 
  switch(geometric_type1)                                                         
2430
 
  {                                                                               
2431
 
  case GMLSF_INVALID:                                                             
2432
 
    {                                                                             
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());                                  
2439
 
    }                                                                             
2440
 
    break;                                                                        
2441
 
  default:                                                                        
2442
 
    break;                                                                        
2443
 
  }                                                                               
2444
 
                                                                                  
2445
 
  Item lItem2;                                                                           
2446
 
  Iterator_t arg1_iter = args[1]->getIterator();
2447
 
  arg1_iter->open();
2448
 
  if (!arg1_iter->next(lItem2)) 
2449
 
  {
2450
 
    std::stringstream lErrorMessage;
2451
 
    lErrorMessage << "An empty-sequence is not allowed as second parameter";
2452
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
2453
 
  }
2454
 
  arg1_iter->close();
2455
 
 
2456
 
  uint32_t n;
2457
 
  n = lItem2.getUnsignedIntValue();
2458
 
                                               
2459
 
  switch(geometric_type1)                                                         
2460
 
  {                                                                               
2461
 
  case GMLSF_POINT:
2462
 
  case GMLSF_LINESTRING:
2463
 
  //case GMLSF_CURVE:
2464
 
  case GMLSF_LINEARRING:
2465
 
  //case GMLSF_SURFACE:
2466
 
  case GMLSF_POLYGON:
2467
 
    if(n == 0)
2468
 
      return ItemSequence_t(new SingletonItemSequence(lItem1));                  
2469
 
    else
2470
 
    {
2471
 
      std::stringstream lErrorMessage;                                              
2472
 
      lErrorMessage << "Index n (" << n << ") is outside the range ";  
2473
 
      throwError("IndexOutsideRange", lErrorMessage.str());                                    
2474
 
    }
2475
 
    break;
2476
 
  default:break;
2477
 
  }
2478
 
 
2479
 
  Item    nth_child;
2480
 
  buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_CHILD, &n, &nth_child);
2481
 
 
2482
 
  if(nth_child.isNull())
2483
 
  {
2484
 
    std::stringstream lErrorMessage;                                              
2485
 
    lErrorMessage << "Index n (" << n << ") is outside the range ";  
2486
 
    throwError("IndexOutsideRange", lErrorMessage.str());                                    
2487
 
  }
2488
 
  return ItemSequence_t(new SingletonItemSequence(nth_child));                  
2489
 
}
2490
 
 
2491
 
 
2492
 
 
2493
 
///////////////////////////////////////////////////////////////////////
2494
 
#define DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_GEOMETRY(sfclass_name, geos_function_name)  \
2495
 
ItemSequence_t                                                                          \
2496
 
sfclass_name::evaluate(const StatelessExternalFunction::Arguments_t& args,              \
2497
 
         const StaticContext* aSctxCtx,                                                 \
2498
 
         const DynamicContext* aDynCtx) const                                           \
2499
 
{                                                                                       \
2500
 
  Item lItem;                                                                           \
2501
 
  gmlsf_types   geometric_type;                                                         \
2502
 
  geometric_type = getGeometryNodeType(args, 0, lItem);                                 \
2503
 
                                                                                        \
2504
 
  switch(geometric_type)                                                                \
2505
 
  {                                                                                     \
2506
 
  case GMLSF_INVALID:                                                                   \
2507
 
    {                                                                                   \
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());                         \
2514
 
    }                                                                                   \
2515
 
    break;                                                                              \
2516
 
  default:                                                                              \
2517
 
    break;                                                                              \
2518
 
  }                                                                                     \
2519
 
                                                                                        \
2520
 
  zorba::Item srs_uri;                                                                  \
2521
 
  std::auto_ptr<geos::geom::Geometry>  geos_geometry(buildGeosGeometryFromItem(lItem, geometric_type, -1, &srs_uri));  \
2522
 
                                                                                        \
2523
 
  std::auto_ptr<geos::geom::Geometry>  geos_result;                                     \
2524
 
  try{                                                                                  \
2525
 
    geos_result.reset(geos_geometry->geos_function_name());                             \
2526
 
  }catch(std::exception &excep)                                                         \
2527
 
  {                                                                                     \
2528
 
    std::stringstream lErrorMessage;                                                    \
2529
 
    lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what();  \
2530
 
    throwError("GEOSError", lErrorMessage.str());                                          \
2531
 
  }                                                                                     \
2532
 
                                                                                        \
2533
 
  zorba::Item   null_parent;                                                            \
2534
 
  zorba::Item   result_item;                                                            \
2535
 
  result_item = getGMLItemFromGeosGeometry(null_parent, geos_result.get(), &srs_uri);         \
2536
 
                                                                                        \
2537
 
  RETURN_RESULT_ITEM;                                                                   \
2538
 
}
2539
 
 
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)
2544
 
 
2545
 
zorba::Item GeoFunction::getBoundary(geos::geom::Geometry *geos_geometry, zorba::Item srs_uri) const 
2546
 
{
2547
 
  std::auto_ptr<geos::geom::Geometry>  geos_result;                                            
2548
 
  if(geos_geometry->getUserData() == (void*)GMLSF_SURFACE)
2549
 
  {
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))
2553
 
    {
2554
 
      std::stringstream lErrorMessage;                                                    
2555
 
      lErrorMessage << "Error in Surface : the patches do not form a polyhedral surface";  
2556
 
      throwError("UnrecognizedGeoObject", lErrorMessage.str());                                          
2557
 
    }
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++)
2561
 
    {
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++)
2564
 
      {
2565
 
        rings->push_back((geos::geom::LineString*)polygon->getInteriorRingN(r));
2566
 
      }
2567
 
    }
2568
 
    geos_result.reset(get_geometryFactory()->createMultiLineString(rings));
2569
 
  }
2570
 
  /*else if(geometric_type == GMLSF_CURVE)
2571
 
  {
2572
 
    geos::geom::LineString *linestring = curveToLineString(geos_geometry);
2573
 
    try{                                                                                  
2574
 
      geos_result = linestring->getBoundary();                                  
2575
 
    }catch(std::exception &excep)                                                         
2576
 
    {                                                                                     
2577
 
      std::stringstream lErrorMessage;                                                    
2578
 
      lErrorMessage << "Error in GEOS function getBoundary : " << excep.what();  
2579
 
      throwError("GEOSError", lErrorMessage.str());                                          
2580
 
    }         
2581
 
    delete linestring;
2582
 
  }
2583
 
  */
2584
 
  else
2585
 
  {
2586
 
    try{                                                                                  
2587
 
      geos_result.reset(geos_geometry->getBoundary());                                  
2588
 
    }catch(std::exception &excep)                                                         
2589
 
    {                                                                                     
2590
 
      std::stringstream lErrorMessage;                                                    
2591
 
      lErrorMessage << "Error in GEOS function getBoundary : " << excep.what();  
2592
 
      throwError("GEOSError", lErrorMessage.str());                                          
2593
 
    }                                                                                     
2594
 
  }
2595
 
 
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);         
2599
 
  return result_item;
2600
 
}
2601
 
 
2602
 
void GeoFunction::getMultiGeometryBoundary(geos::geom::Geometry *geos_geometry, 
2603
 
                                           std::vector<zorba::Item> *boundaries,
2604
 
                                           zorba::Item srs_uri) const 
2605
 
{
2606
 
  for(unsigned int i=0;i<geos_geometry->getNumGeometries();i++)
2607
 
  {
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);
2611
 
    else
2612
 
    {
2613
 
      zorba::Item boundary;
2614
 
      boundary = getBoundary(geom, srs_uri);
2615
 
      if(!boundary.isNull())
2616
 
        boundaries->push_back(boundary);
2617
 
    }
2618
 
  }
2619
 
}
2620
 
 
2621
 
ItemSequence_t                                                                          
2622
 
SFBoundaryFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
2623
 
         const StaticContext* aSctxCtx,                                                 
2624
 
         const DynamicContext* aDynCtx) const                                           
2625
 
{
2626
 
  Item lItem;                                                                           
2627
 
  gmlsf_types   geometric_type;                                                         
2628
 
  geometric_type = getGeometryNodeType(args, 0, lItem);                                 
2629
 
                                                                                        
2630
 
  switch(geometric_type)                                                                
2631
 
  {                                                                                     
2632
 
  case GMLSF_INVALID:                                                                   
2633
 
    {                                                                                   
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());                                        
2640
 
    }                                                                                   
2641
 
    break;                                                                              
2642
 
  default:                                                                              
2643
 
    break;                                                                              
2644
 
  }                                                                                     
2645
 
                                                                                        
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));
2649
 
 
2650
 
  if(geometric_type != GMLSF_MULTIGEOMETRY)
2651
 
  {
2652
 
    zorba::Item result_item;
2653
 
    result_item = getBoundary(geos_geometry.get(), srs_uri);
2654
 
    RETURN_RESULT_ITEM;
2655
 
  }
2656
 
  else
2657
 
  {
2658
 
    std::vector<zorba::Item>  boundaries;
2659
 
    getMultiGeometryBoundary(geos_geometry.get(), &boundaries, srs_uri);
2660
 
    return ItemSequence_t(new VectorItemSequence(boundaries));
2661
 
  }
2662
 
                                                                                        
2663
 
}
2664
 
 
2665
 
///////////////////////////////////////////////////////////////////////
2666
 
ItemSequence_t 
2667
 
SFSridFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2668
 
         const StaticContext* aSctxCtx,
2669
 
         const DynamicContext* aDynCtx) const
2670
 
{
2671
 
  Item lItem;
2672
 
  gmlsf_types   geometric_type;
2673
 
  geometric_type = getGeometryNodeType(args, 0, lItem);
2674
 
 
2675
 
  switch(geometric_type)
2676
 
  {
2677
 
  case GMLSF_INVALID:
2678
 
    {
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());
2685
 
    }
2686
 
    break;
2687
 
  default:
2688
 
    break;
2689
 
  }
2690
 
 
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));
2694
 
 
2695
 
  if(!srs_uri.isNull())
2696
 
    return ItemSequence_t(new SingletonItemSequence(srs_uri));
2697
 
  else
2698
 
    return ItemSequence_t(NULL);
2699
 
}
2700
 
 
2701
 
///////////////////////////////////////////////////////////////////////
2702
 
ItemSequence_t 
2703
 
SFEnvelopeFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2704
 
         const StaticContext* aSctxCtx,
2705
 
         const DynamicContext* aDynCtx) const
2706
 
{
2707
 
  Item lItem;
2708
 
  gmlsf_types   geometric_type;
2709
 
  geometric_type = getGeometryNodeType(args, 0, lItem);
2710
 
 
2711
 
  switch(geometric_type)
2712
 
  {
2713
 
  case GMLSF_INVALID:
2714
 
    {
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());
2721
 
    }
2722
 
    break;
2723
 
  default:
2724
 
    break;
2725
 
  }
2726
 
 
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));
2730
 
 
2731
 
  const geos::geom::Envelope  *envelope = NULL;                                            
2732
 
  try{                                                                                  
2733
 
    envelope = geos_geometry->getEnvelopeInternal();                                  
2734
 
  }catch(std::exception &excep)                                                         
2735
 
  {                                                                                     
2736
 
    std::stringstream lErrorMessage;                                                    
2737
 
    lErrorMessage << "Error in GEOS function getEnvelopeInternal : " << excep.what();  
2738
 
    throwError("GEOSError", lErrorMessage.str());                                          
2739
 
  }                                                                                     
2740
 
 
2741
 
 
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;
2748
 
  char strtemp[100];
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);
2753
 
 
2754
 
  if(!srs_uri.isNull())
2755
 
  {
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);
2761
 
  }
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);
2766
 
 
2767
 
  sprintf(strtemp, "%lf %lf", envelope->getMinX(), envelope->getMinY());
2768
 
  theModule->getItemFactory()->createTextNode(corner_item, strtemp);
2769
 
 
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);
2774
 
 
2775
 
  sprintf(strtemp, "%lf %lf", envelope->getMaxX(), envelope->getMaxY());
2776
 
  theModule->getItemFactory()->createTextNode(corner_item, strtemp);
2777
 
  addNewLineIndentText(envelope_item, 0);
2778
 
 
2779
 
  return ItemSequence_t(new SingletonItemSequence(envelope_item));
2780
 
}
2781
 
 
2782
 
///////////////////////////////////////////////////////////////////////
2783
 
ItemSequence_t 
2784
 
SFAsTextFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2785
 
         const StaticContext* aSctxCtx,
2786
 
         const DynamicContext* aDynCtx) const
2787
 
{
2788
 
  Item lItem;
2789
 
  gmlsf_types   geometric_type;
2790
 
  geometric_type = getGeometryNodeType(args, 0, lItem);
2791
 
 
2792
 
  switch(geometric_type)
2793
 
  {
2794
 
  case GMLSF_INVALID:
2795
 
    {
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());
2802
 
    }
2803
 
    break;
2804
 
  default:
2805
 
    break;
2806
 
  }
2807
 
 
2808
 
  std::auto_ptr<geos::geom::Geometry>  geos_geometry;
2809
 
  geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
2810
 
 
2811
 
  std::string as_text;
2812
 
  as_text = geos_geometry->toString();
2813
 
 
2814
 
  return ItemSequence_t(new SingletonItemSequence(
2815
 
      theModule->getItemFactory()->createString(as_text)));
2816
 
}
2817
 
 
2818
 
unsigned char GeoFunction::hex_to_bin(char hex) const
2819
 
{
2820
 
  if((hex >= '0') && (hex <= '9'))
2821
 
    return hex-'0';
2822
 
  else if((hex >= 'a') && (hex <= 'f'))
2823
 
    return hex-'a'+10;
2824
 
  else if((hex >= 'A') && (hex <= 'F'))
2825
 
    return hex-'A'+10;
2826
 
  else
2827
 
    return 0;
2828
 
}
2829
 
///////////////////////////////////////////////////////////////////////
2830
 
ItemSequence_t 
2831
 
SFAsBinaryFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2832
 
         const StaticContext* aSctxCtx,
2833
 
         const DynamicContext* aDynCtx) const
2834
 
{
2835
 
  Item lItem;
2836
 
  gmlsf_types   geometric_type;
2837
 
  geometric_type = getGeometryNodeType(args, 0, lItem);
2838
 
 
2839
 
  switch(geometric_type)
2840
 
  {
2841
 
  case GMLSF_INVALID:
2842
 
    {
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());
2849
 
    }
2850
 
    break;
2851
 
  default:
2852
 
    break;
2853
 
  }
2854
 
 
2855
 
  std::auto_ptr<geos::geom::Geometry>  geos_geometry;
2856
 
  geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
2857
 
 
2858
 
  std::ostringstream as_binary;
2859
 
  as_binary << *geos_geometry;
2860
 
  
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++)
2866
 
  {
2867
 
    binary_bin[i] = ((hex_to_bin(hex_str[i*2]) << 4) | hex_to_bin(hex_str[i*2+1]));
2868
 
  }
2869
 
 
2870
 
  zorba::Item base64_item = theModule->getItemFactory()->createBase64Binary(binary_bin, binary_len);
2871
 
  delete[] binary_bin;
2872
 
 
2873
 
  return ItemSequence_t(new SingletonItemSequence(base64_item));
2874
 
}
2875
 
 
2876
 
///////////////////////////////////////////////////////////////////////
2877
 
ItemSequence_t 
2878
 
SFIsEmptyFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2879
 
         const StaticContext* aSctxCtx,
2880
 
         const DynamicContext* aDynCtx) const
2881
 
{
2882
 
  Item lItem;
2883
 
  Iterator_t arg0_iter = args[0]->getIterator();
2884
 
  arg0_iter->open();
2885
 
  if (!arg0_iter->next(lItem)) 
2886
 
  {
2887
 
    return ItemSequence_t(new SingletonItemSequence(
2888
 
       theModule->getItemFactory()->createBoolean(true)));
2889
 
  }
2890
 
  arg0_iter->close();
2891
 
 
2892
 
  if(!lItem.isNode() || (lItem.getNodeKind() != store::StoreConsts::elementNode))
2893
 
  {
2894
 
    return ItemSequence_t(new SingletonItemSequence(
2895
 
       theModule->getItemFactory()->createBoolean(true)));
2896
 
  }
2897
 
 
2898
 
  GeoFunction::gmlsf_types geotype = getGmlSFGeometricType(lItem);
2899
 
  if(geotype == GMLSF_INVALID)
2900
 
  {
2901
 
    return ItemSequence_t(new SingletonItemSequence(
2902
 
      theModule->getItemFactory()->createBoolean(true)));
2903
 
  }
2904
 
  
2905
 
  std::auto_ptr<geos::geom::Geometry>  geos_geometry;
2906
 
  geos_geometry.reset(buildGeosGeometryFromItem(lItem, geotype, -1));
2907
 
 
2908
 
  bool is_empty = false;
2909
 
  try{
2910
 
  is_empty = (geos_geometry->getNumPoints() == 0);
2911
 
  }catch(std::exception &excep)                                              
2912
 
  {                                                                                     
2913
 
    std::stringstream lErrorMessage;                                                    
2914
 
    lErrorMessage << "Error in GEOS function getNumGeometries : " << excep.what();  
2915
 
    throwError("GEOSError", lErrorMessage.str());                                          
2916
 
  }                                                                                     
2917
 
 
2918
 
  return ItemSequence_t(new SingletonItemSequence(
2919
 
     theModule->getItemFactory()->createBoolean(is_empty)));
2920
 
}
2921
 
 
2922
 
///////////////////////////////////////////////////////////////////////
2923
 
ItemSequence_t 
2924
 
SFIsSimpleFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2925
 
         const StaticContext* aSctxCtx,
2926
 
         const DynamicContext* aDynCtx) const
2927
 
{
2928
 
  Item lItem;
2929
 
  gmlsf_types   geometric_type;
2930
 
  geometric_type = getGeometryNodeType(args, 0, lItem);
2931
 
 
2932
 
  switch(geometric_type)
2933
 
  {
2934
 
  case GMLSF_INVALID:
2935
 
    {
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());
2942
 
    }
2943
 
    break;
2944
 
  default:
2945
 
    break;
2946
 
  }
2947
 
 
2948
 
  std::auto_ptr<geos::geom::Geometry>  geos_geometry;
2949
 
  geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
2950
 
 
2951
 
  bool is_simple = false;
2952
 
  if(geometric_type == GMLSF_CURVE)
2953
 
  {
2954
 
    is_simple = isSimpleCurve(geos_geometry.get());
2955
 
  }
2956
 
  else
2957
 
  {
2958
 
    try{
2959
 
    is_simple = geos_geometry->isSimple();
2960
 
    }catch(std::exception &excep)                                              
2961
 
    {                                                                                     
2962
 
      std::stringstream lErrorMessage;                                                    
2963
 
      lErrorMessage << "Error in GEOS function isSimple : " << excep.what();  
2964
 
      throwError("GEOSError", lErrorMessage.str());                                          
2965
 
    }                                                                                     
2966
 
  }
2967
 
 
2968
 
  return ItemSequence_t(new SingletonItemSequence(
2969
 
     theModule->getItemFactory()->createBoolean(is_simple)));
2970
 
}
2971
 
 
2972
 
///////////////////////////////////////////////////////////////////////
2973
 
ItemSequence_t 
2974
 
SFIs3DFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
2975
 
         const StaticContext* aSctxCtx,
2976
 
         const DynamicContext* aDynCtx) const
2977
 
{
2978
 
  Item lItem;
2979
 
  gmlsf_types   geometric_type;
2980
 
  geometric_type = getGeometryNodeType(args, 0, lItem);
2981
 
 
2982
 
  switch(geometric_type)
2983
 
  {
2984
 
  case GMLSF_INVALID:
2985
 
    {
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());
2992
 
    }
2993
 
    break;
2994
 
  default:
2995
 
    break;
2996
 
  }
2997
 
 
2998
 
  std::auto_ptr<geos::geom::Geometry>  geos_geometry;
2999
 
  geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));
3000
 
 
3001
 
#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR > 2)
3002
 
  bool is_3D = (geos_geometry->getCoordinateDimension() == 3);
3003
 
#else
3004
 
  bool is_3D = (getCoordinateDimension(geos_geometry.get()) == 3);//for GEOS 3.2.2
3005
 
#endif
3006
 
 
3007
 
  return ItemSequence_t(new SingletonItemSequence(
3008
 
     theModule->getItemFactory()->createBoolean(is_3D)));
3009
 
}
3010
 
 
3011
 
///////////////////////////////////////////////////////////////////////
3012
 
ItemSequence_t 
3013
 
SFIsMeasuredFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,
3014
 
         const StaticContext* aSctxCtx,
3015
 
         const DynamicContext* aDynCtx) const
3016
 
{
3017
 
  Item lItem;
3018
 
  gmlsf_types   geometric_type;
3019
 
  geometric_type = getGeometryNodeType(args, 0, lItem);
3020
 
 
3021
 
  switch(geometric_type)
3022
 
  {
3023
 
  case GMLSF_INVALID:
3024
 
    {
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());
3031
 
    }
3032
 
    break;
3033
 
  default:
3034
 
    break;
3035
 
  }
3036
 
 
3037
 
  return ItemSequence_t(new SingletonItemSequence(
3038
 
     theModule->getItemFactory()->createBoolean(false)));
3039
 
}
3040
 
 
3041
 
///////////////////////////////////////////////////////////////////////
3042
 
 
3043
 
///////////////////////////////////////////////////////////////////////
3044
 
#define DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_BOOLEAN(sfclass_name, geos_function_name)  \
3045
 
ItemSequence_t                                                                    \
3046
 
sfclass_name::evaluate(const StatelessExternalFunction::Arguments_t& args,        \
3047
 
         const StaticContext* aSctxCtx,                                           \
3048
 
         const DynamicContext* aDynCtx) const                                     \
3049
 
{                                                                                 \
3050
 
  Item lItem1;                                                                    \
3051
 
  gmlsf_types   geometric_type1;                                                  \
3052
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         \
3053
 
                                                                                  \
3054
 
  switch(geometric_type1)                                                         \
3055
 
  {                                                                               \
3056
 
  case GMLSF_INVALID:                                                             \
3057
 
    {                                                                             \
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());                                  \
3064
 
    }                                                                             \
3065
 
    break;                                                                        \
3066
 
  default:                                                                        \
3067
 
    break;                                                                        \
3068
 
  }                                                                               \
3069
 
                                                                                  \
3070
 
  Item lItem2;                                                                    \
3071
 
  gmlsf_types   geometric_type2;                                                  \
3072
 
  geometric_type2 = getGeometryNodeType(args, 1, lItem2);                         \
3073
 
                                                                                  \
3074
 
  switch(geometric_type2)                                                         \
3075
 
  {                                                                               \
3076
 
  case GMLSF_INVALID:                                                             \
3077
 
    {                                                                             \
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());                                  \
3084
 
    }                                                                             \
3085
 
    break;                                                                        \
3086
 
  default:                                                                        \
3087
 
    break;                                                                        \
3088
 
  }                                                                               \
3089
 
                                                                                  \
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));            \
3093
 
                                                                                  \
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));            \
3097
 
                                                                                  \
3098
 
  if(!srs_uri1.isNull() && !srs_uri2.isNull() &&                                  \
3099
 
    !srs_uri1.getStringValue().equals(srs_uri2.getStringValue()))                 \
3100
 
  {                                                                               \
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());           \
3105
 
  }                                                                               \
3106
 
                                                                                  \
3107
 
  bool retval = false;                                                            \
3108
 
  try{                                                                            \
3109
 
  retval = geos_geometry1->geos_function_name(geos_geometry2.get());                    \
3110
 
  }catch(std::exception &excep)                                                   \
3111
 
  {                                                                               \
3112
 
    std::stringstream lErrorMessage;                                              \
3113
 
    lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what();  \
3114
 
    throwError("GEOSError", lErrorMessage.str());                                    \
3115
 
  }                                                                               \
3116
 
                                                                                  \
3117
 
                                                                                 \
3118
 
  return ItemSequence_t(new SingletonItemSequence(                                \
3119
 
     theModule->getItemFactory()->createBoolean(retval)));                        \
3120
 
}
3121
 
 
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)
3131
 
 
3132
 
///////////////////////////////////////////////////////////////////////
3133
 
#define DEFINE_EVALUATE_TWO_GEOMETRIES_RETURN_GEOMETRY(sfclass_name, geos_function_name)  \
3134
 
ItemSequence_t                                                                    \
3135
 
sfclass_name::evaluate(const StatelessExternalFunction::Arguments_t& args,        \
3136
 
         const StaticContext* aSctxCtx,                                           \
3137
 
         const DynamicContext* aDynCtx) const                                     \
3138
 
{                                                                                 \
3139
 
  Item lItem1;                                                                    \
3140
 
  gmlsf_types   geometric_type1;                                                  \
3141
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         \
3142
 
                                                                                  \
3143
 
  switch(geometric_type1)                                                         \
3144
 
  {                                                                               \
3145
 
  case GMLSF_INVALID:                                                             \
3146
 
    {                                                                             \
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());                                  \
3153
 
    }                                                                             \
3154
 
    break;                                                                        \
3155
 
  default:                                                                        \
3156
 
    break;                                                                        \
3157
 
  }                                                                               \
3158
 
                                                                                  \
3159
 
  Item lItem2;                                                                    \
3160
 
  gmlsf_types   geometric_type2;                                                  \
3161
 
  geometric_type2 = getGeometryNodeType(args, 1, lItem2);                         \
3162
 
                                                                                  \
3163
 
  switch(geometric_type2)                                                         \
3164
 
  {                                                                               \
3165
 
  case GMLSF_INVALID:                                                             \
3166
 
    {                                                                             \
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());                                  \
3173
 
    }                                                                             \
3174
 
    break;                                                                        \
3175
 
  default:                                                                        \
3176
 
    break;                                                                        \
3177
 
  }                                                                               \
3178
 
                                                                                  \
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));            \
3182
 
                                                                                  \
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));            \
3186
 
                                                                                  \
3187
 
  if(!srs_uri1.isNull() && !srs_uri2.isNull() &&                                  \
3188
 
    !srs_uri1.getStringValue().equals(srs_uri2.getStringValue()))                 \
3189
 
  {                                                                               \
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());           \
3194
 
  }                                                                               \
3195
 
                                                                                  \
3196
 
  std::auto_ptr<geos::geom::Geometry>  geos_result;                               \
3197
 
  try{                                                                            \
3198
 
  geos_result.reset(geos_geometry1->geos_function_name(geos_geometry2.get()));          \
3199
 
  }catch(std::exception &excep)                                                   \
3200
 
  {                                                                               \
3201
 
    std::stringstream lErrorMessage;                                              \
3202
 
    lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what();  \
3203
 
    throwError("GEOSError", lErrorMessage.str());                                    \
3204
 
  }                                                                               \
3205
 
                                                                                  \
3206
 
                                                                                  \
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);   \
3212
 
                                                                                  \
3213
 
  RETURN_RESULT_ITEM;                                                             \
3214
 
}
3215
 
 
3216
 
 
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)
3221
 
 
3222
 
 
3223
 
///////////////////////////////////////////////////////////////////////
3224
 
#define DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_DOUBLE(sfclass_name, geos_function_name)    \
3225
 
ItemSequence_t                                                                          \
3226
 
sfclass_name::evaluate(const StatelessExternalFunction::Arguments_t& args,              \
3227
 
         const StaticContext* aSctxCtx,                                                 \
3228
 
         const DynamicContext* aDynCtx) const                                           \
3229
 
{                                                                                       \
3230
 
  Item lItem;                                                                           \
3231
 
  gmlsf_types   geometric_type;                                                         \
3232
 
  geometric_type = getGeometryNodeType(args, 0, lItem);                                 \
3233
 
                                                                                        \
3234
 
  switch(geometric_type)                                                                \
3235
 
  {                                                                                     \
3236
 
  case GMLSF_INVALID:                                                                   \
3237
 
    {                                                                                   \
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());                                        \
3244
 
    }                                                                                   \
3245
 
    break;                                                                              \
3246
 
  default:                                                                              \
3247
 
    break;                                                                              \
3248
 
  }                                                                                     \
3249
 
                                                                                        \
3250
 
  std::auto_ptr<geos::geom::Geometry>  geos_geometry;                                                 \
3251
 
  geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));                 \
3252
 
                                                                                        \
3253
 
  double  retval = 0;                                                                   \
3254
 
  try{                                                                                  \
3255
 
  retval = geos_geometry->geos_function_name();                                         \
3256
 
  }catch(std::exception &excep)                                                         \
3257
 
  {                                                                                     \
3258
 
    std::stringstream lErrorMessage;                                                    \
3259
 
    lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what();  \
3260
 
    throwError("GEOSError", lErrorMessage.str());                                          \
3261
 
  }                                                                                     \
3262
 
                                                                                        \
3263
 
  return ItemSequence_t(new SingletonItemSequence(                                      \
3264
 
     theModule->getItemFactory()->createDouble(retval)));                               \
3265
 
}
3266
 
 
3267
 
DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_DOUBLE(SFAreaFunction, getArea)
3268
 
DEFINE_EVALUATE_ONE_GEOMETRY_RETURN_DOUBLE(SFLengthFunction, getLength)
3269
 
 
3270
 
ItemSequence_t                                                                          
3271
 
SFRelateFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
3272
 
         const StaticContext* aSctxCtx,                                                 
3273
 
         const DynamicContext* aDynCtx) const                                           
3274
 
{                                                                                       
3275
 
  Item lItem1;                                                                    
3276
 
  gmlsf_types   geometric_type1;                                                  
3277
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         
3278
 
                                                                                  
3279
 
  switch(geometric_type1)                                                         
3280
 
  {                                                                               
3281
 
  case GMLSF_INVALID:                                                             
3282
 
    {                                                                             
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());                                  
3289
 
    }                                                                             
3290
 
    break;                                                                        
3291
 
  default:                                                                        
3292
 
    break;                                                                        
3293
 
  }                                                                               
3294
 
                                                                                  
3295
 
  Item lItem2;                                                                    
3296
 
  gmlsf_types   geometric_type2;                                                  
3297
 
  geometric_type2 = getGeometryNodeType(args, 1, lItem2);                         
3298
 
                                                                                  
3299
 
  switch(geometric_type2)                                                          
3300
 
  {                                                                               
3301
 
  case GMLSF_INVALID:                                                             
3302
 
    {                                                                             
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());                                  
3309
 
    }                                                                             
3310
 
    break;                                                                        
3311
 
  default:                                                                        
3312
 
    break;                                                                        
3313
 
  }                                                                               
3314
 
                                                                                  
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));            
3318
 
                                                                                  
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));            
3322
 
                                                                                  
3323
 
  if(!srs_uri1.isNull() && !srs_uri2.isNull() &&                                  
3324
 
    !srs_uri1.getStringValue().equals(srs_uri2.getStringValue()))                 
3325
 
  {                                                                               
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());                                    
3330
 
  }                                                                               
3331
 
                                                                                  
3332
 
                                                                                        
3333
 
  Item lItem3;                                                                           
3334
 
  Iterator_t arg2_iter = args[2]->getIterator();
3335
 
  arg2_iter->open();
3336
 
  if (!arg2_iter->next(lItem3)) 
3337
 
  {
3338
 
    std::stringstream lErrorMessage;
3339
 
    lErrorMessage << "An empty-sequence is not allowed as parameter";
3340
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
3341
 
  }
3342
 
  arg2_iter->close();
3343
 
 
3344
 
  zorba::String intersection_matrix;
3345
 
  intersection_matrix = lItem3.getStringValue();
3346
 
 
3347
 
  bool is_relate = false;                                                   
3348
 
  try{
3349
 
    is_relate = geos_geometry1->relate(geos_geometry2.get(), intersection_matrix.c_str());                                    
3350
 
  }catch(std::exception &excep)
3351
 
  {
3352
 
    std::stringstream lErrorMessage;
3353
 
    lErrorMessage << "Error in GEOS relate function: " << excep.what();
3354
 
    throwError("GEOSError", lErrorMessage.str());
3355
 
  }
3356
 
                                                                                        
3357
 
  return ItemSequence_t(new SingletonItemSequence(
3358
 
     theModule->getItemFactory()->createBoolean(is_relate)));
3359
 
}
3360
 
 
3361
 
ItemSequence_t                                                                          
3362
 
SFIsWithinDistanceFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
3363
 
         const StaticContext* aSctxCtx,                                                 
3364
 
         const DynamicContext* aDynCtx) const                                           
3365
 
{                                                                                       
3366
 
  Item lItem1;                                                                    
3367
 
  gmlsf_types   geometric_type1;                                                  
3368
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         
3369
 
                                                                                  
3370
 
  switch(geometric_type1)                                                         
3371
 
  {                                                                               
3372
 
  case GMLSF_INVALID:                                                             
3373
 
    {                                                                             
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());                                  
3380
 
    }                                                                             
3381
 
    break;                                                                        
3382
 
  default:                                                                        
3383
 
    break;                                                                        
3384
 
  }                                                                               
3385
 
                                                                                  
3386
 
  Item lItem2;                                                                    
3387
 
  gmlsf_types   geometric_type2;                                                  
3388
 
  geometric_type2 = getGeometryNodeType(args, 1, lItem2);                         
3389
 
                                                                                  
3390
 
  switch(geometric_type2)                                                          
3391
 
  {                                                                               
3392
 
  case GMLSF_INVALID:                                                             
3393
 
    {                                                                             
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());                                  
3400
 
    }                                                                             
3401
 
    break;                                                                        
3402
 
  default:                                                                        
3403
 
    break;                                                                        
3404
 
  }                                                                               
3405
 
                                                                                  
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));            
3409
 
                                                                                  
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));            
3413
 
                                                                                  
3414
 
  if(!srs_uri1.isNull() && !srs_uri2.isNull() &&                                  
3415
 
    !srs_uri1.getStringValue().equals(srs_uri2.getStringValue()))                 
3416
 
  {                                                                               
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());                                    
3421
 
  }                                                                               
3422
 
                                                                                        
3423
 
  Item lItem3;                                                                           
3424
 
  Iterator_t arg2_iter = args[2]->getIterator();
3425
 
  arg2_iter->open();
3426
 
  if (!arg2_iter->next(lItem3)) 
3427
 
  {
3428
 
    std::stringstream lErrorMessage;
3429
 
    lErrorMessage << "An empty-sequence is not allowed as third parameter";
3430
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
3431
 
  }
3432
 
  arg2_iter->close();
3433
 
 
3434
 
  double distance;
3435
 
  distance = lItem3.getDoubleValue();
3436
 
 
3437
 
  bool is_within_distance = false;                                                   
3438
 
  try{
3439
 
  is_within_distance = geos_geometry1->isWithinDistance(geos_geometry2.get(), distance);                                    
3440
 
  }catch(std::exception &excep)                                        
3441
 
  {                                                                               
3442
 
    std::stringstream lErrorMessage;                                              
3443
 
    lErrorMessage << "Error in GEOS function isWithinDistance : " << excep.what();  
3444
 
    throwError("GEOSError", lErrorMessage.str());                                    
3445
 
  }                                                                               
3446
 
                                                                                        
3447
 
  return ItemSequence_t(new SingletonItemSequence(
3448
 
     theModule->getItemFactory()->createBoolean(is_within_distance)));
3449
 
}
3450
 
 
3451
 
ItemSequence_t                                                                          
3452
 
SFDistanceFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
3453
 
         const StaticContext* aSctxCtx,                                                 
3454
 
         const DynamicContext* aDynCtx) const                                           
3455
 
{                                                                                       
3456
 
  Item lItem1;                                                                    
3457
 
  gmlsf_types   geometric_type1;                                                  
3458
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         
3459
 
                                                                                  
3460
 
  switch(geometric_type1)                                                         
3461
 
  {                                                                               
3462
 
  case GMLSF_INVALID:                                                             
3463
 
    {                                                                             
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());                                  
3470
 
    }                                                                             
3471
 
    break;                                                                        
3472
 
  default:                                                                        
3473
 
    break;                                                                        
3474
 
  }                                                                               
3475
 
                                                                                  
3476
 
  Item lItem2;                                                                    
3477
 
  gmlsf_types   geometric_type2;                                                  
3478
 
  geometric_type2 = getGeometryNodeType(args, 1, lItem2);                         
3479
 
                                                                                  
3480
 
  switch(geometric_type2)                                                          
3481
 
  {                                                                               
3482
 
  case GMLSF_INVALID:                                                             
3483
 
    {                                                                             
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());                                  
3490
 
    }                                                                             
3491
 
    break;                                                                        
3492
 
  default:                                                                        
3493
 
    break;                                                                        
3494
 
  }                                                                               
3495
 
                                                                                  
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));            
3499
 
                                                                                  
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));            
3503
 
                                                                                  
3504
 
  if(!srs_uri1.isNull() && !srs_uri2.isNull() &&                                  
3505
 
    !srs_uri1.getStringValue().equals(srs_uri2.getStringValue()))                 
3506
 
  {                                                                               
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());                                    
3511
 
  }
3512
 
                                                                                        
3513
 
  double min_distance = 0;                                                   
3514
 
  try{
3515
 
  min_distance = geos_geometry1->distance(geos_geometry2.get());                                    
3516
 
  }catch(std::exception &excep)                                        
3517
 
  {                                                                               
3518
 
    std::stringstream lErrorMessage;                                              
3519
 
    lErrorMessage << "Error in GEOS function distance : " << excep.what();  
3520
 
    throwError("GEOSError", lErrorMessage.str());                                    
3521
 
  }                                                                               
3522
 
                                                                                        
3523
 
  return ItemSequence_t(new SingletonItemSequence(
3524
 
     theModule->getItemFactory()->createDouble(min_distance)));
3525
 
}
3526
 
 
3527
 
ItemSequence_t                                                                          
3528
 
SFBufferFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
3529
 
         const StaticContext* aSctxCtx,                                                 
3530
 
         const DynamicContext* aDynCtx) const                                           
3531
 
{                                                                                       
3532
 
  Item lItem1;                                                                    
3533
 
  gmlsf_types   geometric_type1;                                                  
3534
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         
3535
 
                                                                                  
3536
 
  switch(geometric_type1)                                                         
3537
 
  {                                                                               
3538
 
  case GMLSF_INVALID:                                                             
3539
 
    {                                                                             
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());                                  
3546
 
    }                                                                             
3547
 
    break;                                                                        
3548
 
  default:                                                                        
3549
 
    break;                                                                        
3550
 
  }                                                                               
3551
 
                                                                                  
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));
3555
 
                                                                                  
3556
 
                                                                                        
3557
 
  Item lItem2;                                                                           
3558
 
  Iterator_t arg1_iter = args[1]->getIterator();
3559
 
  arg1_iter->open();
3560
 
  if (!arg1_iter->next(lItem2)) 
3561
 
  {
3562
 
    std::stringstream lErrorMessage;
3563
 
    lErrorMessage << "An empty-sequence is not allowed as second parameter";
3564
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
3565
 
  }
3566
 
  arg1_iter->close();
3567
 
 
3568
 
  double distance;
3569
 
  distance = lItem2.getDoubleValue();
3570
 
                                                                                        
3571
 
  std::auto_ptr<geos::geom::Geometry>  geos_result;                                          
3572
 
  try{
3573
 
  geos_result.reset(geos_geometry1->buffer(distance));                                    
3574
 
  }catch(std::exception &excep)                                        
3575
 
  {                                                                               
3576
 
    std::stringstream lErrorMessage;                                              
3577
 
    lErrorMessage << "Error in GEOS function buffer : " << excep.what();  
3578
 
    throwError("GEOSError", lErrorMessage.str());                                    
3579
 
  }                                                                               
3580
 
 
3581
 
  zorba::Item   null_parent;                                                      
3582
 
  zorba::Item   result_item;                                                      
3583
 
  result_item = getGMLItemFromGeosGeometry(null_parent, geos_result.get(), &srs_uri);             
3584
 
                                                                                  
3585
 
  RETURN_RESULT_ITEM;                  
3586
 
}
3587
 
 
3588
 
///////////////////////////////////////////////////////////////////////
3589
 
#define DEFINE_EVALUATE_ONE_POINT_RETURN_DOUBLE(sfclass_name, geos_function_name)       \
3590
 
ItemSequence_t                                                                          \
3591
 
sfclass_name::evaluate(const StatelessExternalFunction::Arguments_t& args,              \
3592
 
         const StaticContext* aSctxCtx,                                                 \
3593
 
         const DynamicContext* aDynCtx) const                                           \
3594
 
{                                                                                       \
3595
 
  Item lItem;                                                                           \
3596
 
  gmlsf_types   geometric_type;                                                         \
3597
 
  geometric_type = getGeometryNodeType(args, 0, lItem);                                 \
3598
 
                                                                                        \
3599
 
  switch(geometric_type)                                                                \
3600
 
  {                                                                                     \
3601
 
  case GMLSF_INVALID:                                                                   \
3602
 
    {                                                                                   \
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());                         \
3609
 
    }                                                                                   \
3610
 
    break;                                                                              \
3611
 
  case GMLSF_POINT:                                                                     \
3612
 
    break;                                                                              \
3613
 
  default:                                                                              \
3614
 
    {                                                                                   \
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());                         \
3621
 
    }                                                                                   \
3622
 
    break;                                                                              \
3623
 
  }                                                                                     \
3624
 
                                                                                        \
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());    \
3628
 
                                                                                        \
3629
 
  double  retval = 0;                                                                   \
3630
 
  try{                                                                                  \
3631
 
  retval = geos_point->geos_function_name();                                            \
3632
 
  }catch(std::exception &excep)                                                         \
3633
 
  {                                                                                     \
3634
 
    std::stringstream lErrorMessage;                                                    \
3635
 
    lErrorMessage << "Error in GEOS function " #geos_function_name " : " << excep.what();  \
3636
 
    throwError("GEOSError", lErrorMessage.str());                                          \
3637
 
  }                                                                                     \
3638
 
                                                                                        \
3639
 
  return ItemSequence_t(new SingletonItemSequence(                                      \
3640
 
     theModule->getItemFactory()->createDouble(retval)));                               \
3641
 
}
3642
 
 
3643
 
DEFINE_EVALUATE_ONE_POINT_RETURN_DOUBLE(SFXFunction, getX)
3644
 
DEFINE_EVALUATE_ONE_POINT_RETURN_DOUBLE(SFYFunction, getY)
3645
 
 
3646
 
ItemSequence_t                                                                          
3647
 
SFZFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
3648
 
         const StaticContext* aSctxCtx,                                                 
3649
 
         const DynamicContext* aDynCtx) const                                           
3650
 
{                                                                                       
3651
 
  Item lItem;                                                                           
3652
 
  gmlsf_types   geometric_type;                                                         
3653
 
  geometric_type = getGeometryNodeType(args, 0, lItem);                                 
3654
 
                                                                                        
3655
 
  switch(geometric_type)                                                                
3656
 
  {                                                                                     
3657
 
  case GMLSF_INVALID:                                                                   
3658
 
    {                                                                                   
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());                                        
3665
 
    }                                                                                   
3666
 
    break;                                                                              
3667
 
  case GMLSF_POINT:                                                                     
3668
 
    break;                                                                              
3669
 
  default:                                                                              
3670
 
    {                                                                                   
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());                                        
3677
 
    }                                                                                   
3678
 
    break;                                                                              
3679
 
  }                                                                                     
3680
 
  std::auto_ptr<geos::geom::Geometry>  geos_geometry;                                                 
3681
 
  geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));                     
3682
 
 
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)
3687
 
#else
3688
 
  if(getCoordinateDimension(geos_geometry.get()) == 3)
3689
 
#endif
3690
 
  {
3691
 
    double z = c->z;
3692
 
    return ItemSequence_t(new SingletonItemSequence(                                      
3693
 
       theModule->getItemFactory()->createDouble(z)));                               
3694
 
  }
3695
 
  else
3696
 
  {
3697
 
    return zorba::ItemSequence_t(NULL);
3698
 
  }
3699
 
 
3700
 
}
3701
 
 
3702
 
ItemSequence_t                                                                          
3703
 
SFMFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
3704
 
         const StaticContext* aSctxCtx,                                                 
3705
 
         const DynamicContext* aDynCtx) const                                           
3706
 
{                                                                                       
3707
 
  Item lItem;                                                                           
3708
 
  gmlsf_types   geometric_type;                                                         
3709
 
  geometric_type = getGeometryNodeType(args, 0, lItem);                                 
3710
 
                                                                                        
3711
 
  switch(geometric_type)                                                                
3712
 
  {                                                                                     
3713
 
  case GMLSF_INVALID:                                                                   
3714
 
    {                                                                                   
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());                                        
3721
 
    }                                                                                   
3722
 
    break;                                                                              
3723
 
  case GMLSF_POINT:                                                                     
3724
 
    break;                                                                              
3725
 
  default:                                                                              
3726
 
    {                                                                                   
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());                                        
3733
 
    }                                                                                   
3734
 
    break;                                                                              
3735
 
  }                                                                                     
3736
 
 
3737
 
  //don't know how to get the Measure from Point
3738
 
  return zorba::ItemSequence_t(NULL);
3739
 
 
3740
 
}
3741
 
 
3742
 
 
3743
 
ItemSequence_t                                                                          
3744
 
SFStartPointFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
3745
 
         const StaticContext* aSctxCtx,                                                 
3746
 
         const DynamicContext* aDynCtx) const                                           
3747
 
{                                                                                       
3748
 
  Item lItem1;                                                                    
3749
 
  gmlsf_types   geometric_type1;                                                  
3750
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         
3751
 
                                                                                  
3752
 
  switch(geometric_type1)                                                         
3753
 
  {                                                                               
3754
 
  case GMLSF_INVALID:                                                             
3755
 
    {                                                                             
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());                                  
3762
 
    }                                                                             
3763
 
    break;                                                                        
3764
 
  case GMLSF_LINESTRING:                                                                
3765
 
  case GMLSF_LINEARRING:                                                                
3766
 
  case GMLSF_CURVE:
3767
 
    break;                                                                              
3768
 
  default:                                                                              
3769
 
    {                                                                                   
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());                                        
3776
 
    }                                                                                   
3777
 
    break;                                                                              
3778
 
  }                                                                               
3779
 
                                                                                  
3780
 
  uint32_t n = 0;
3781
 
                                               
3782
 
  Item    nth_child;
3783
 
  buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_POINT, &n, &nth_child);
3784
 
 
3785
 
  if(nth_child.isNull())
3786
 
  {
3787
 
    std::stringstream lErrorMessage;                                              
3788
 
    lErrorMessage << "LineString has no points ";  
3789
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());                                    
3790
 
  }
3791
 
                                                                                  
3792
 
  return ItemSequence_t(new SingletonItemSequence(nth_child));                  
3793
 
}
3794
 
 
3795
 
ItemSequence_t                                                                          
3796
 
SFEndPointFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
3797
 
         const StaticContext* aSctxCtx,                                                 
3798
 
         const DynamicContext* aDynCtx) const                                           
3799
 
{                                                                                       
3800
 
  Item lItem1;                                                                    
3801
 
  gmlsf_types   geometric_type1;                                                  
3802
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         
3803
 
                                                                                  
3804
 
  switch(geometric_type1)                                                         
3805
 
  {                                                                               
3806
 
  case GMLSF_INVALID:                                                             
3807
 
    {                                                                             
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());                                  
3814
 
    }                                                                             
3815
 
    break;                                                                        
3816
 
  case GMLSF_LINESTRING:                                                                
3817
 
  case GMLSF_LINEARRING:                                                                
3818
 
  case GMLSF_CURVE:
3819
 
    break;                                                                              
3820
 
  default:                                                                              
3821
 
    {                                                                                   
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());                                        
3828
 
    }                                                                                   
3829
 
    break;                                                                              
3830
 
  }                                                                               
3831
 
                                                                                  
3832
 
  Item    nth_child;
3833
 
  buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_END_POINT, NULL, &nth_child);
3834
 
 
3835
 
  if(nth_child.isNull())
3836
 
  {
3837
 
    std::stringstream lErrorMessage;                                              
3838
 
    lErrorMessage << "LineString has no points ";  
3839
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());                                    
3840
 
  }
3841
 
                                                                                  
3842
 
  return ItemSequence_t(new SingletonItemSequence(nth_child));                  
3843
 
}
3844
 
 
3845
 
///////////////////////////////////////////////////////////////////////
3846
 
ItemSequence_t                                                                         
3847
 
SFIsClosedFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
3848
 
         const StaticContext* aSctxCtx,                                                 
3849
 
         const DynamicContext* aDynCtx) const                                           
3850
 
{                                                                                       
3851
 
  Item lItem;                                                                           
3852
 
  gmlsf_types   geometric_type;                                                         
3853
 
  geometric_type = getGeometryNodeType(args, 0, lItem);                                 
3854
 
                                                                                        
3855
 
  switch(geometric_type)                                                                
3856
 
  {                                                                                    
3857
 
  case GMLSF_INVALID:                                                                   
3858
 
    {                                                                                   
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());                                        
3865
 
    }                                                                                   
3866
 
    break;                                                                              
3867
 
  case GMLSF_LINESTRING:
3868
 
  case GMLSF_LINEARRING:
3869
 
  case GMLSF_CURVE:
3870
 
  case GMLSF_MULTICURVE:
3871
 
  case GMLSF_SURFACE:
3872
 
    break;                                                                              
3873
 
  default:                                                                              
3874
 
    {                                                                                   
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());                                        
3881
 
    }                                                                                   
3882
 
    break;                                                                              
3883
 
  }                                                                                     
3884
 
                                                                                        
3885
 
  std::auto_ptr<geos::geom::Geometry>  geos_geometry;                                                 
3886
 
  geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));                     
3887
 
                                                                                        
3888
 
  bool  retval = 0;                                                               
3889
 
  if(geometric_type == GMLSF_SURFACE)
3890
 
  {
3891
 
    if(!isSurface(dynamic_cast<geos::geom::MultiPolygon*>(geos_geometry.get()), &retval))
3892
 
      retval = false;
3893
 
  }
3894
 
  else if(geometric_type == GMLSF_CURVE)                                                     
3895
 
  {                                                                                     
3896
 
    retval = isClosedCurve(geos_geometry.get());                                  
3897
 
  }
3898
 
  else
3899
 
  {
3900
 
    try{                                                                                  
3901
 
    if(geometric_type != GMLSF_MULTICURVE)
3902
 
    {
3903
 
      geos::geom::LineString   *geos_line = dynamic_cast<geos::geom::LineString*>(geos_geometry.get());    
3904
 
      retval = geos_line->isClosed();                                             
3905
 
    }
3906
 
    else
3907
 
    {
3908
 
      geos::geom::MultiLineString   *geos_multiline = dynamic_cast<geos::geom::MultiLineString*>(geos_geometry.get());    
3909
 
      retval = geos_multiline->isClosed();                                             
3910
 
    }
3911
 
    }catch(std::exception &excep)                                                         
3912
 
    {                                                                                     
3913
 
      std::stringstream lErrorMessage;                                                    
3914
 
      lErrorMessage << "Error in GEOS function SFIsClosedFunction : " << excep.what();  
3915
 
      throwError("GEOSError", lErrorMessage.str());                                          
3916
 
    }                                                                                     
3917
 
  }                                                                                     
3918
 
  return ItemSequence_t(new SingletonItemSequence(                                      
3919
 
     theModule->getItemFactory()->createBoolean(retval)));                           
3920
 
}
3921
 
 
3922
 
ItemSequence_t                                                                         
3923
 
SFIsRingFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
3924
 
         const StaticContext* aSctxCtx,                                                 
3925
 
         const DynamicContext* aDynCtx) const                                           
3926
 
{                                                                                       
3927
 
  Item lItem;                                                                           
3928
 
  gmlsf_types   geometric_type;                                                         
3929
 
  geometric_type = getGeometryNodeType(args, 0, lItem);                                 
3930
 
                                                                                        
3931
 
  switch(geometric_type)                                                                
3932
 
  {                                                                                    
3933
 
  case GMLSF_INVALID:                                                                   
3934
 
    {                                                                                   
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());                                        
3941
 
    }                                                                                   
3942
 
    break;                                                                              
3943
 
  case GMLSF_LINESTRING:                                                                
3944
 
  case GMLSF_LINEARRING:                                                                
3945
 
  case GMLSF_CURVE:                                                                     
3946
 
    break;                                                                              
3947
 
  default:                                                                              
3948
 
    {                                                                                   
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());                                        
3955
 
    }                                                                                   
3956
 
    break;                                                                              
3957
 
  }                                                                                     
3958
 
                                                                                        
3959
 
  std::auto_ptr<geos::geom::Geometry>  geos_geometry;                                                 
3960
 
  geos_geometry.reset(buildGeosGeometryFromItem(lItem, geometric_type, -1));                     
3961
 
                                                                                        
3962
 
  bool  retval = 0;                                                               
3963
 
  if(geometric_type != GMLSF_CURVE)                                                     
3964
 
  {                                                                                     
3965
 
  try{                                                                                  
3966
 
    geos::geom::LineString   *geos_line = dynamic_cast<geos::geom::LineString*>(geos_geometry.get());    
3967
 
    retval = geos_line->isClosed();                                             
3968
 
  }catch(std::exception &excep)                                                         
3969
 
  {                                                                                     
3970
 
    std::stringstream lErrorMessage;                                                    
3971
 
    lErrorMessage << "Error in GEOS function isClosed : " << excep.what();  
3972
 
    throwError("GEOSError", lErrorMessage.str());                                          
3973
 
  }                                                                                     
3974
 
  }                                                                                     
3975
 
  else                                                                                  
3976
 
  {                                                                                     
3977
 
    retval = isRingCurve(geos_geometry.get());                                  
3978
 
  }                                                                                     
3979
 
  return ItemSequence_t(new SingletonItemSequence(                                      
3980
 
     theModule->getItemFactory()->createBoolean(retval)));                           
3981
 
}
3982
 
 
3983
 
ItemSequence_t                                                                          
3984
 
SFNumPointsFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
3985
 
         const StaticContext* aSctxCtx,                                                 
3986
 
         const DynamicContext* aDynCtx) const                                           
3987
 
{                                                                                       
3988
 
  Item lItem;                                                                           
3989
 
  gmlsf_types   geometric_type;                                                         
3990
 
  geometric_type = getGeometryNodeType(args, 0, lItem);                                 
3991
 
                                                                                        
3992
 
  switch(geometric_type)                                                         
3993
 
  {                                                                               
3994
 
  case GMLSF_INVALID:                                                             
3995
 
    {                                                                             
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());                                  
4002
 
    }                                                                             
4003
 
    break;                                                                        
4004
 
  case GMLSF_LINESTRING:                                                                
4005
 
  case GMLSF_LINEARRING:                                                                
4006
 
  case GMLSF_CURVE:
4007
 
  case GMLSF_MULTICURVE:
4008
 
    break;                                                                              
4009
 
  default:                                                                              
4010
 
    {                                                                                   
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());                                        
4017
 
    }                                                                                   
4018
 
    break;                                                                              
4019
 
  }                                                                               
4020
 
                                                                                        
4021
 
  uint32_t  num_children;
4022
 
  buildGeosGeometryFromItem(lItem, geometric_type, -1, NULL, GET_NUM_POINTS, &num_children);
4023
 
 
4024
 
  return ItemSequence_t(new SingletonItemSequence(                                      
4025
 
     theModule->getItemFactory()->createUnsignedInt(num_children)));                           
4026
 
}
4027
 
 
4028
 
ItemSequence_t                                                                          
4029
 
SFPointNFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
4030
 
         const StaticContext* aSctxCtx,                                                 
4031
 
         const DynamicContext* aDynCtx) const                                           
4032
 
{                                                                                       
4033
 
  Item lItem1;                                                                    
4034
 
  gmlsf_types   geometric_type1;                                                  
4035
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         
4036
 
                                                                                  
4037
 
  switch(geometric_type1)                                                         
4038
 
  {                                                                               
4039
 
  case GMLSF_INVALID:                                                             
4040
 
    {                                                                             
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());                                  
4047
 
    }                                                                             
4048
 
    break;                                                                        
4049
 
  case GMLSF_LINESTRING:                                                                
4050
 
  case GMLSF_LINEARRING:                                                                
4051
 
  case GMLSF_CURVE:
4052
 
  case GMLSF_MULTICURVE:
4053
 
    break;                                                                              
4054
 
  default:                                                                              
4055
 
    {                                                                                   
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());                                        
4062
 
    }                                                                                   
4063
 
    break;                                                                              
4064
 
  }                                                                               
4065
 
                                                                                  
4066
 
                                                                                        
4067
 
  Item lItem2;                                                                           
4068
 
  Iterator_t arg1_iter = args[1]->getIterator();
4069
 
  arg1_iter->open();
4070
 
  if (!arg1_iter->next(lItem2)) 
4071
 
  {
4072
 
    std::stringstream lErrorMessage;
4073
 
    lErrorMessage << "An empty-sequence is not allowed as second parameter";
4074
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
4075
 
  }
4076
 
  arg1_iter->close();
4077
 
 
4078
 
  uint32_t n;
4079
 
  n = lItem2.getUnsignedIntValue();
4080
 
                                               
4081
 
  Item    nth_child;
4082
 
  buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_POINT, &n, &nth_child);
4083
 
 
4084
 
  if(nth_child.isNull())
4085
 
  {
4086
 
    std::stringstream lErrorMessage;                                              
4087
 
    lErrorMessage << "Index n (" << n << ") is outside the range ";  
4088
 
    throwError("IndexOutsideRange", lErrorMessage.str());                                    
4089
 
  }
4090
 
                                                                                  
4091
 
  return ItemSequence_t(new SingletonItemSequence(nth_child));                  
4092
 
}
4093
 
 
4094
 
///////////////////////////////////////////////////////////////////////
4095
 
ItemSequence_t                                                                          
4096
 
SFExteriorRingFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
4097
 
         const StaticContext* aSctxCtx,                                                 
4098
 
         const DynamicContext* aDynCtx) const                                           
4099
 
{                                                                                       
4100
 
  Item lItem;                                                                           
4101
 
  gmlsf_types   geometric_type;                                                         
4102
 
  geometric_type = getGeometryNodeType(args, 0, lItem);                                 
4103
 
                                                                                        
4104
 
  switch(geometric_type)                                                                
4105
 
  {                                                                                     
4106
 
  case GMLSF_INVALID:                                                                   
4107
 
    {                                                                                   
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());                                        
4114
 
    }                                                                                   
4115
 
    break;                                                                              
4116
 
  case GMLSF_POLYGON:                                                                
4117
 
    break;                                                                              
4118
 
  default:                                                                              
4119
 
    {                                                                                   
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());                                        
4126
 
    }                                                                                   
4127
 
    break;                                                                              
4128
 
  }                                                                                     
4129
 
      
4130
 
  Item  result_item;
4131
 
  buildGeosGeometryFromItem(lItem, geometric_type, -1, NULL, GET_EXTERIOR_RING, NULL, &result_item);
4132
 
                                                                                        
4133
 
  RETURN_RESULT_ITEM;                        
4134
 
}
4135
 
 
4136
 
ItemSequence_t                                                                          
4137
 
SFNumInteriorRingFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
4138
 
         const StaticContext* aSctxCtx,                                                 
4139
 
         const DynamicContext* aDynCtx) const                                           
4140
 
{                                                                                       
4141
 
  Item lItem;                                                                           
4142
 
  gmlsf_types   geometric_type;                                                         
4143
 
  geometric_type = getGeometryNodeType(args, 0, lItem);                                 
4144
 
                                                                                        
4145
 
  switch(geometric_type)                                                                
4146
 
  {                                                                                     
4147
 
  case GMLSF_INVALID:                                                                   
4148
 
    {                                                                                   
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());                                        
4155
 
    }                                                                                   
4156
 
    break;                                                                              
4157
 
  case GMLSF_POLYGON:                                                                
4158
 
    break;                                                                              
4159
 
  default:                                                                              
4160
 
    {                                                                                   
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());                                        
4167
 
    }                                                                                   
4168
 
    break;                                                                              
4169
 
  }                                                                                     
4170
 
                                                                                        
4171
 
  uint32_t  num_children;
4172
 
  buildGeosGeometryFromItem(lItem, geometric_type, -1, NULL, COUNT_CHILDREN, &num_children);
4173
 
 
4174
 
  return ItemSequence_t(new SingletonItemSequence(                                      
4175
 
     theModule->getItemFactory()->createUnsignedInt(num_children)));                           
4176
 
}
4177
 
 
4178
 
ItemSequence_t                                                                          
4179
 
SFInteriorRingNFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
4180
 
         const StaticContext* aSctxCtx,                                                 
4181
 
         const DynamicContext* aDynCtx) const                                           
4182
 
{                                                                                       
4183
 
  Item lItem1;                                                                    
4184
 
  gmlsf_types   geometric_type1;                                                  
4185
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         
4186
 
                                                                                  
4187
 
  switch(geometric_type1)                                                         
4188
 
  {                                                                               
4189
 
  case GMLSF_INVALID:                                                             
4190
 
    {                                                                             
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());                                  
4197
 
    }                                                                             
4198
 
    break;                                                                        
4199
 
  case GMLSF_POLYGON:                                                                
4200
 
    break;                                                                              
4201
 
  default:                                                                              
4202
 
    {                                                                                   
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());                                        
4209
 
    }                                                                                   
4210
 
    break;                                                                              
4211
 
  }                                                                               
4212
 
                                                                                  
4213
 
                                                                                  
4214
 
                                                                                        
4215
 
  Item lItem2;                                                                           
4216
 
  Iterator_t arg1_iter = args[1]->getIterator();
4217
 
  arg1_iter->open();
4218
 
  if (!arg1_iter->next(lItem2)) 
4219
 
  {
4220
 
    std::stringstream lErrorMessage;
4221
 
    lErrorMessage << "An empty-sequence is not allowed as second parameter";
4222
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
4223
 
  }
4224
 
  arg1_iter->close();
4225
 
 
4226
 
  uint32_t n;
4227
 
  n = lItem2.getUnsignedIntValue();
4228
 
                                      
4229
 
  Item    nth_child;
4230
 
  buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_CHILD, &n, &nth_child);
4231
 
 
4232
 
  if(nth_child.isNull())
4233
 
  {
4234
 
    std::stringstream lErrorMessage;                                              
4235
 
    lErrorMessage << "Index n (" << n << ") is outside the range ";  
4236
 
    throwError("IndexOutsideRange", lErrorMessage.str());                                    
4237
 
  }
4238
 
                                                                                  
4239
 
  return ItemSequence_t(new SingletonItemSequence(nth_child));                  
4240
 
}
4241
 
 
4242
 
ItemSequence_t                                                                          
4243
 
SFNumPatchesFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
4244
 
         const StaticContext* aSctxCtx,                                                 
4245
 
         const DynamicContext* aDynCtx) const                                           
4246
 
{                                                                                       
4247
 
  Item lItem;                                                                           
4248
 
  gmlsf_types   geometric_type;                                                         
4249
 
  geometric_type = getGeometryNodeType(args, 0, lItem);                                 
4250
 
                                                                                        
4251
 
  switch(geometric_type)                                                                
4252
 
  {                                                                                     
4253
 
  case GMLSF_INVALID:                                                                   
4254
 
    {                                                                                   
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());                                        
4261
 
    }                                                                                   
4262
 
    break;                                                                              
4263
 
  case GMLSF_SURFACE:                                                                
4264
 
    break;                                                                              
4265
 
  default:                                                                              
4266
 
    {                                                                                   
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());                                        
4273
 
    }                                                                                   
4274
 
    break;                                                                              
4275
 
  }                                                                                     
4276
 
                                                                                        
4277
 
  uint32_t  num_children;
4278
 
  buildGeosGeometryFromItem(lItem, geometric_type, -1, NULL, COUNT_CHILDREN, &num_children);
4279
 
 
4280
 
  return ItemSequence_t(new SingletonItemSequence(                                      
4281
 
     theModule->getItemFactory()->createUnsignedInt(num_children)));                           
4282
 
}
4283
 
 
4284
 
ItemSequence_t                                                                          
4285
 
SFPatchNFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
4286
 
         const StaticContext* aSctxCtx,                                                 
4287
 
         const DynamicContext* aDynCtx) const                                           
4288
 
{                                                                                       
4289
 
  Item lItem1;                                                                    
4290
 
  gmlsf_types   geometric_type1;                                                  
4291
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         
4292
 
                                                                                  
4293
 
  switch(geometric_type1)                                                         
4294
 
  {                                                                               
4295
 
  case GMLSF_INVALID:                                                             
4296
 
    {                                                                             
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());                                  
4303
 
    }                                                                             
4304
 
    break;                                                                        
4305
 
  case GMLSF_SURFACE:                                                                
4306
 
    break;                                                                              
4307
 
  default:                                                                              
4308
 
    {                                                                                   
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());                                        
4315
 
    }                                                                                   
4316
 
    break;                                                                              
4317
 
  }                                                                               
4318
 
                                                                                  
4319
 
                                                                                  
4320
 
                                                                                        
4321
 
  Item lItem2;                                                                           
4322
 
  Iterator_t arg1_iter = args[1]->getIterator();
4323
 
  arg1_iter->open();
4324
 
  if (!arg1_iter->next(lItem2)) 
4325
 
  {
4326
 
    std::stringstream lErrorMessage;
4327
 
    lErrorMessage << "An empty-sequence is not allowed as second parameter";
4328
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
4329
 
  }
4330
 
  arg1_iter->close();
4331
 
 
4332
 
  uint32_t n;
4333
 
  n = lItem2.getUnsignedIntValue();
4334
 
                                      
4335
 
  Item    nth_child;
4336
 
  buildGeosGeometryFromItem(lItem1, geometric_type1, -1, NULL, GET_NTH_CHILD, &n, &nth_child);
4337
 
 
4338
 
  if(nth_child.isNull())
4339
 
  {
4340
 
    std::stringstream lErrorMessage;                                              
4341
 
    lErrorMessage << "Index n (" << n << ") is outside the range ";  
4342
 
    throwError("IndexOutsideRange", lErrorMessage.str());                                    
4343
 
  }
4344
 
                                                                                  
4345
 
  return ItemSequence_t(new SingletonItemSequence(nth_child));                  
4346
 
}
4347
 
 
4348
 
 
4349
 
ItemSequence_t                                                                          
4350
 
SFBoundingPolygonsFunction::evaluate(const StatelessExternalFunction::Arguments_t& args,              
4351
 
         const StaticContext* aSctxCtx,                                                 
4352
 
         const DynamicContext* aDynCtx) const                                           
4353
 
{                                                                                       
4354
 
  Item lItem1;                                                                    
4355
 
  gmlsf_types   geometric_type1;                                                  
4356
 
  geometric_type1 = getGeometryNodeType(args, 0, lItem1);                         
4357
 
                                                                                  
4358
 
  switch(geometric_type1)                                                         
4359
 
  {                                                                               
4360
 
  case GMLSF_INVALID:                                                             
4361
 
    {                                                                             
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());                                  
4368
 
    }                                                                             
4369
 
    break;                                                                        
4370
 
  case GMLSF_SURFACE:                                                                
4371
 
    break;                                                                              
4372
 
  default:                                                                              
4373
 
    {                                                                                   
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());                                        
4380
 
    }                                                                                   
4381
 
    break;                                                                              
4382
 
  }                                                                               
4383
 
                                                                                  
4384
 
  Item lItem2;                                                                                
4385
 
  gmlsf_types   geometric_type2;                                                  
4386
 
  geometric_type2 = getGeometryNodeType(args, 1, lItem2);                         
4387
 
                                                                                  
4388
 
  switch(geometric_type2)                                                         
4389
 
  {                                                                               
4390
 
  case GMLSF_INVALID:                                                             
4391
 
    {                                                                             
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());                                  
4398
 
    }                                                                             
4399
 
    break;                                                                        
4400
 
  case GMLSF_POLYGON:
4401
 
  //case GMLSF_POLYGONPATCH:
4402
 
    break;                                                                              
4403
 
  default:                                                                              
4404
 
    {                                                                                   
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());                                        
4411
 
    }                                                                                   
4412
 
    break;                                                                              
4413
 
  }                                                                               
4414
 
                                                                                  
4415
 
  std::vector<Item>   result;
4416
 
  zorba::Item   patches_item;
4417
 
  if(!getChild(lItem1, "patches", "http://www.opengis.net/gml", patches_item))
4418
 
  {//get upset
4419
 
    std::stringstream lErrorMessage;
4420
 
    lErrorMessage << "gml:Surface node must have a gml:patches child";
4421
 
    throwError("UnrecognizedGeoObject", lErrorMessage.str());
4422
 
  }
4423
 
 
4424
 
  Iterator_t    patches_children;
4425
 
  Item          polygon_patch_item;
4426
 
 
4427
 
  patches_children = patches_item.getChildren();
4428
 
  patches_children->open();
4429
 
  unsigned int patch_nr = 0;
4430
 
                                     
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));
4433
 
 
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();
4438
 
 
4439
 
  
4440
 
  unsigned int nr_patches = (unsigned int)surface->getNumGeometries();
4441
 
  unsigned int i;
4442
 
  for(i=0;i<nr_patches;i++)
4443
 
  {
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;
4449
 
    /*
4450
 
    for(unsigned int j=0;j<patch_coords->size();j++)
4451
 
    {
4452
 
      for(unsigned int k=0;k<coords->size();k++)
4453
 
      {
4454
 
        if(coords->getAt(k).equals(patch_coords->getAt(j)))
4455
 
        {
4456
 
          geos::geom::Coordinate next1;
4457
 
          geos::geom::Coordinate next2;
4458
 
          if(k == (coords->size()-1))
4459
 
            next1 = coords->getAt(0);
4460
 
          else
4461
 
            next1 = coords->getAt(k+1);
4462
 
          if(j == (patch_coords->size()-1))
4463
 
            next2 = patch_coords->getAt(0);
4464
 
          else
4465
 
            next2 = patch_coords->getAt(j+1);
4466
 
          if(next1.equals(next2))
4467
 
          {
4468
 
            is_touching = true;
4469
 
            break;
4470
 
          }
4471
 
          if(j == 0)
4472
 
            next2 = patch_coords->getAt(patch_coords->size()-1);
4473
 
          else
4474
 
            next2 = patch_coords->getAt(j-1);
4475
 
          if(next1.equals(next2))
4476
 
          {
4477
 
            is_touching = true;
4478
 
            break;
4479
 
          }
4480
 
        }
4481
 
      }
4482
 
      if(is_touching)
4483
 
        break;
4484
 
    }
4485
 
    */
4486
 
    if(patch_exterior_ring->overlaps(exterior_ring))
4487
 
      is_touching = true;
4488
 
    if(is_touching)
4489
 
    {
4490
 
      //add the coresponding patch item to the list
4491
 
      while(patch_nr <= i)
4492
 
      {
4493
 
        patches_children->next(polygon_patch_item);       
4494
 
        patch_nr++;
4495
 
      }
4496
 
      result.push_back(polygon_patch_item);
4497
 
    }
4498
 
  }
4499
 
  
4500
 
  return ItemSequence_t(new VectorItemSequence(result));                  
4501
 
}
4502
 
 
4503
 
 
4504
 
} /* namespace geomodule */ } /* namespace zorba */