1
/**********************************************************************
2
* $Id: lwgeom_gml.c 4168 2009-06-11 16:44:03Z pramsey $
4
* PostGIS - Spatial Types for PostgreSQL
5
* http://postgis.refractions.net
6
* Copyright 2001-2003 Refractions Research Inc.
8
* This is free software; you can redistribute and/or modify it under
9
* the terms of hte GNU General Public Licence. See the COPYING file.
11
**********************************************************************/
14
* @file GML output routines.
16
**********************************************************************/
20
#include "executor/spi.h"
22
#include "lwgeom_pg.h"
23
#include "liblwgeom.h"
25
Datum LWGEOM_asGML(PG_FUNCTION_ARGS);
27
char *geometry_to_gml2(uchar *srl, char *srs, int precision);
29
static size_t asgml2_point_size(LWPOINT *point, char *srs, int precision);
30
static char *asgml2_point(LWPOINT *point, char *srs, int precision);
31
static size_t asgml2_line_size(LWLINE *line, char *srs, int precision);
32
static char *asgml2_line(LWLINE *line, char *srs, int precision);
33
static size_t asgml2_poly_size(LWPOLY *poly, char *srs, int precision);
34
static char *asgml2_poly(LWPOLY *poly, char *srs, int precision);
35
static size_t asgml2_inspected_size(LWGEOM_INSPECTED *geom, char *srs, int precision);
36
static char *asgml2_inspected(LWGEOM_INSPECTED *geom, char *srs, int precision);
37
static size_t pointArray_toGML2(POINTARRAY *pa, char *buf, int precision);
39
char *geometry_to_gml3(uchar *srl, char *srs, int precision, bool is_deegree);
41
static size_t asgml3_point_size(LWPOINT *point, char *srs, int precision);
42
static char *asgml3_point(LWPOINT *point, char *srs, int precision, bool is_deegree);
43
static size_t asgml3_line_size(LWLINE *line, char *srs, int precision);
44
static char *asgml3_line(LWLINE *line, char *srs, int precision, bool is_deegree);
45
static size_t asgml3_poly_size(LWPOLY *poly, char *srs, int precision);
46
static char *asgml3_poly(LWPOLY *poly, char *srs, int precision, bool is_deegree);
47
static size_t asgml3_inspected_size(LWGEOM_INSPECTED *geom, char *srs, int precision);
48
static char *asgml3_inspected(LWGEOM_INSPECTED *geom, char *srs, int precision, bool is_deegree);
49
static size_t pointArray_toGML3(POINTARRAY *pa, char *buf, int precision, bool is_deegree);
51
static size_t pointArray_GMLsize(POINTARRAY *pa, int precision);
52
static char *getSRSbySRID(int SRID, bool short_crs);
55
#define SHOW_DIGS_DOUBLE 15
56
#define MAX_DOUBLE_PRECISION 15
57
#define MAX_DIGS_DOUBLE (SHOW_DIGS_DOUBLE + 2) /* +2 mean add dot and sign */
61
* Encode feature in GML
63
PG_FUNCTION_INFO_V1(LWGEOM_asGML);
64
Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
73
int precision = MAX_DOUBLE_PRECISION;
75
bool is_deegree = false;
78
version = PG_GETARG_INT32(0);
79
if ( version != 2 && version != 3 )
81
elog(ERROR, "Only GML 2 and GML 3 are supported");
85
/* Get the geometry */
86
if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
87
geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
89
/* Retrieve precision if any (default is max) */
90
if (PG_NARGS() >2 && !PG_ARGISNULL(2))
92
precision = PG_GETARG_INT32(2);
93
if ( precision > MAX_DOUBLE_PRECISION )
94
precision = MAX_DOUBLE_PRECISION;
95
else if ( precision < 0 ) precision = 0;
99
if (PG_NARGS() >3 && !PG_ARGISNULL(3))
100
option = PG_GETARG_INT32(3);
102
SRID = lwgeom_getsrid(SERIALIZED_FORM(geom));
103
if (SRID == -1) srs = NULL;
104
else if (option & 1) srs = getSRSbySRID(SRID, false);
105
else srs = getSRSbySRID(SRID, true);
107
if (option & 16) is_deegree = true;
110
gml = geometry_to_gml2(SERIALIZED_FORM(geom), srs, precision);
112
gml = geometry_to_gml3(SERIALIZED_FORM(geom), srs, precision, is_deegree);
114
PG_FREE_IF_COPY(geom, 1);
116
len = strlen(gml) + VARHDRSZ;
118
result = palloc(len);
119
SET_VARSIZE(result, len);
121
memcpy(VARDATA(result), gml, len-VARHDRSZ);
125
PG_RETURN_POINTER(result);
131
* @brief VERSION GML 2
132
* takes a GEOMETRY and returns a GML@ representation
135
geometry_to_gml2(uchar *geom, char *srs, int precision)
141
LWGEOM_INSPECTED *inspected;
143
type = lwgeom_getType(geom[0]);
148
point = lwpoint_deserialize(geom);
149
return asgml2_point(point, srs, precision);
152
line = lwline_deserialize(geom);
153
return asgml2_line(line, srs, precision);
156
poly = lwpoly_deserialize(geom);
157
return asgml2_poly(poly, srs, precision);
161
case MULTIPOLYGONTYPE:
163
inspected = lwgeom_inspect(geom);
164
return asgml2_inspected(inspected, srs, precision);
167
lwerror("geometry_to_gml2: '%s' geometry type not supported", lwgeom_typename(type));
173
asgml2_point_size(LWPOINT *point, char *srs, int precision)
176
size = pointArray_GMLsize(point->point, precision);
177
size += sizeof("<gml:point><gml:coordinates>/") * 2;
178
if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
183
asgml2_point_buf(LWPOINT *point, char *srs, char *output, int precision)
189
ptr += sprintf(ptr, "<gml:Point srsName=\"%s\">", srs);
193
ptr += sprintf(ptr, "<gml:Point>");
195
ptr += sprintf(ptr, "<gml:coordinates>");
196
ptr += pointArray_toGML2(point->point, ptr, precision);
197
ptr += sprintf(ptr, "</gml:coordinates></gml:Point>");
203
asgml2_point(LWPOINT *point, char *srs, int precision)
208
size = asgml2_point_size(point, srs, precision);
209
output = palloc(size);
210
asgml2_point_buf(point, srs, output, precision);
215
asgml2_line_size(LWLINE *line, char *srs, int precision)
218
size = pointArray_GMLsize(line->points, precision);
219
size += sizeof("<gml:linestring><gml:coordinates>/") * 2;
220
if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
225
asgml2_line_buf(LWLINE *line, char *srs, char *output, int precision)
231
ptr += sprintf(ptr, "<gml:LineString srsName=\"%s\">", srs);
235
ptr += sprintf(ptr, "<gml:LineString>");
237
ptr += sprintf(ptr, "<gml:coordinates>");
238
ptr += pointArray_toGML2(line->points, ptr, precision);
239
ptr += sprintf(ptr, "</gml:coordinates></gml:LineString>");
245
asgml2_line(LWLINE *line, char *srs, int precision)
250
size = asgml2_line_size(line, srs, precision);
251
output = palloc(size);
252
asgml2_line_buf(line, srs, output, precision);
257
asgml2_poly_size(LWPOLY *poly, char *srs, int precision)
262
size = sizeof("<gml:polygon></gml:polygon>");
263
size += sizeof("<gml:outerboundaryis><gml:linearring><gml:coordinates>/") * 2;
264
size += sizeof("<gml:innerboundaryis><gml:linearring><gml:coordinates>/") * 2 *
266
if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
268
for (i=0; i<poly->nrings; i++)
269
size += pointArray_GMLsize(poly->rings[i], precision);
275
asgml2_poly_buf(LWPOLY *poly, char *srs, char *output, int precision)
282
ptr += sprintf(ptr, "<gml:Polygon srsName=\"%s\">", srs);
286
ptr += sprintf(ptr, "<gml:Polygon>");
288
ptr += sprintf(ptr, "<gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>");
289
ptr += pointArray_toGML2(poly->rings[0], ptr, precision);
290
ptr += sprintf(ptr, "</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs>");
291
for (i=1; i<poly->nrings; i++)
293
ptr += sprintf(ptr, "<gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>");
294
ptr += pointArray_toGML2(poly->rings[i], ptr, precision);
295
ptr += sprintf(ptr, "</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs>");
297
ptr += sprintf(ptr, "</gml:Polygon>");
303
asgml2_poly(LWPOLY *poly, char *srs, int precision)
308
size = asgml2_poly_size(poly, srs, precision);
309
output = palloc(size);
310
asgml2_poly_buf(poly, srs, output, precision);
315
* Compute max size required for GML version of this
316
* inspected geometry. Will recurse when needed.
317
* Don't call this with single-geoms inspected.
320
asgml2_inspected_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
325
/* the longest possible multi version */
326
size = sizeof("<gml:MultiLineString></gml:MultiLineString>");
328
if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
330
for (i=0; i<insp->ngeometries; i++)
335
LWGEOM_INSPECTED *subinsp;
338
if ((point=lwgeom_getpoint_inspected(insp, i)))
340
size += sizeof("<gml:pointMember>/") * 2;
341
size += asgml2_point_size(point, 0, precision);
342
lwpoint_release(point);
344
else if ((line=lwgeom_getline_inspected(insp, i)))
346
size += sizeof("<gml:lineStringMember>/") * 2;
347
size += asgml2_line_size(line, 0, precision);
348
lwline_release(line);
350
else if ((poly=lwgeom_getpoly_inspected(insp, i)))
352
size += sizeof("<gml:polygonMember>/") * 2;
353
size += asgml2_poly_size(poly, 0, precision);
354
lwpoly_release(poly);
358
subgeom = lwgeom_getsubgeometry_inspected(insp, i);
359
subinsp = lwgeom_inspect(subgeom);
360
size += asgml2_inspected_size(subinsp, 0, precision);
361
lwinspected_release(subinsp);
369
* Don't call this with single-geoms inspected!
372
asgml2_inspected_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision)
374
int type = lwgeom_getType(insp->serialized_form[0]);
380
if (type == MULTIPOINTTYPE) gmltype = "MultiPoint";
381
else if (type == MULTILINETYPE) gmltype = "MultiLineString";
382
else if (type == MULTIPOLYGONTYPE) gmltype = "MultiPolygon";
383
else gmltype = "MultiGeometry";
385
/* Open outmost tag */
388
ptr += sprintf(ptr, "<gml:%s srsName=\"%s\">", gmltype, srs);
392
ptr += sprintf(ptr, "<gml:%s>", gmltype);
395
for (i=0; i<insp->ngeometries; i++)
400
LWGEOM_INSPECTED *subinsp;
403
if ((point=lwgeom_getpoint_inspected(insp, i)))
405
ptr += sprintf(ptr, "<gml:pointMember>");
406
ptr += asgml2_point_buf(point, 0, ptr, precision);
407
lwpoint_release(point);
408
ptr += sprintf(ptr, "</gml:pointMember>");
410
else if ((line=lwgeom_getline_inspected(insp, i)))
412
ptr += sprintf(ptr, "<gml:lineStringMember>");
413
ptr += asgml2_line_buf(line, 0, ptr, precision);
414
lwline_release(line);
415
ptr += sprintf(ptr, "</gml:lineStringMember>");
417
else if ((poly=lwgeom_getpoly_inspected(insp, i)))
419
ptr += sprintf(ptr, "<gml:polygonMember>");
420
ptr += asgml2_poly_buf(poly, 0, ptr, precision);
421
lwpoly_release(poly);
422
ptr += sprintf(ptr, "</gml:polygonMember>");
426
subgeom = lwgeom_getsubgeometry_inspected(insp, i);
427
subinsp = lwgeom_inspect(subgeom);
428
ptr += asgml2_inspected_buf(subinsp, 0, ptr, precision);
429
lwinspected_release(subinsp);
433
/* Close outmost tag */
434
ptr += sprintf(ptr, "</gml:%s>", gmltype);
440
* Don't call this with single-geoms inspected!
443
asgml2_inspected(LWGEOM_INSPECTED *insp, char *srs, int precision)
448
size = asgml2_inspected_size(insp, srs, precision);
450
asgml2_inspected_buf(insp, srs, gml, precision);
455
pointArray_toGML2(POINTARRAY *pa, char *output, int precision)
459
char x[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
460
char y[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
461
char z[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
465
if ( ! TYPE_HASZ(pa->dims) )
467
for (i=0; i<pa->npoints; i++)
470
getPoint2d_p(pa, i, &pt);
471
sprintf(x, "%.*f", precision, pt.x);
472
trim_trailing_zeros(x);
473
sprintf(y, "%.*f", precision, pt.y);
474
trim_trailing_zeros(y);
475
if ( i ) ptr += sprintf(ptr, " ");
476
ptr += sprintf(ptr, "%s,%s", x, y);
481
for (i=0; i<pa->npoints; i++)
484
getPoint4d_p(pa, i, &pt);
485
sprintf(x, "%.*f", precision, pt.x);
486
trim_trailing_zeros(x);
487
sprintf(y, "%.*f", precision, pt.y);
488
trim_trailing_zeros(y);
489
sprintf(z, "%.*f", precision, pt.z);
490
trim_trailing_zeros(z);
491
if ( i ) ptr += sprintf(ptr, " ");
492
ptr += sprintf(ptr, "%s,%s,%s", x, y, z);
505
/* takes a GEOMETRY and returns a GML representation */
507
geometry_to_gml3(uchar *geom, char *srs, int precision, bool is_deegree)
513
LWGEOM_INSPECTED *inspected;
515
type = lwgeom_getType(geom[0]);
520
point = lwpoint_deserialize(geom);
521
return asgml3_point(point, srs, precision, is_deegree);
524
line = lwline_deserialize(geom);
525
return asgml3_line(line, srs, precision, is_deegree);
528
poly = lwpoly_deserialize(geom);
529
return asgml3_poly(poly, srs, precision, is_deegree);
532
inspected = lwgeom_inspect(geom);
533
return asgml3_inspected(inspected, srs, precision, is_deegree);
538
asgml3_point_size(LWPOINT *point, char *srs, int precision)
541
size = pointArray_GMLsize(point->point, precision);
542
size += sizeof("<gml:point><gml:pos>/") * 2;
543
if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
548
asgml3_point_buf(LWPOINT *point, char *srs, char *output, int precision, bool is_deegree)
554
ptr += sprintf(ptr, "<gml:Point srsName=\"%s\">", srs);
558
ptr += sprintf(ptr, "<gml:Point>");
560
ptr += sprintf(ptr, "<gml:pos>");
561
ptr += pointArray_toGML3(point->point, ptr, precision, is_deegree);
562
ptr += sprintf(ptr, "</gml:pos></gml:Point>");
568
asgml3_point(LWPOINT *point, char *srs, int precision, bool is_deegree)
573
size = asgml3_point_size(point, srs, precision);
574
output = palloc(size);
575
asgml3_point_buf(point, srs, output, precision, is_deegree);
581
asgml3_line_size(LWLINE *line, char *srs, int precision)
584
size = pointArray_GMLsize(line->points, precision);
585
size += sizeof("<gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>/") * 2;
586
if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
591
asgml3_line_buf(LWLINE *line, char *srs, char *output, int precision, bool is_deegree)
597
ptr += sprintf(ptr, "<gml:Curve srsName=\"%s\">", srs);
601
ptr += sprintf(ptr, "<gml:Curve>");
603
ptr += sprintf(ptr, "<gml:segments>");
604
ptr += sprintf(ptr, "<gml:LineStringSegment>");
605
ptr += sprintf(ptr, "<gml:posList>");
606
ptr += pointArray_toGML3(line->points, ptr, precision, is_deegree);
607
ptr += sprintf(ptr, "</gml:posList></gml:LineStringSegment>");
608
ptr += sprintf(ptr, "</gml:segments>");
609
ptr += sprintf(ptr, "</gml:Curve>");
615
asgml3_line(LWLINE *line, char *srs, int precision, bool is_deegree)
620
size = asgml3_line_size(line, srs, precision);
621
output = palloc(size);
622
asgml3_line_buf(line, srs, output, precision, is_deegree);
628
asgml3_poly_size(LWPOLY *poly, char *srs, int precision)
633
size = sizeof("<gml:Polygon>");
635
size += sizeof("<gml:exterior><gml:LinearRing><gml:posList>");
636
size += sizeof("</gml:posList></gml:LinearRing></gml:exterior>");
638
size += sizeof("<gml:interior><gml:LinearRing><gml:posList>") * (poly->nrings - 1);
639
size += sizeof("</gml:posList></gml:LinearRing></gml:interior>") * (poly->nrings - 1);
641
size += sizeof("</gml:Polygon>");
643
if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
645
for (i=0; i<poly->nrings; i++)
646
size += pointArray_GMLsize(poly->rings[i], precision);
652
asgml3_poly_buf(LWPOLY *poly, char *srs, char *output, int precision, bool is_deegree)
659
ptr += sprintf(ptr, "<gml:Polygon srsName=\"%s\">", srs);
663
ptr += sprintf(ptr, "<gml:Polygon>");
665
ptr += sprintf(ptr, "<gml:exterior><gml:LinearRing><gml:posList>");
666
ptr += pointArray_toGML3(poly->rings[0], ptr, precision, is_deegree);
667
ptr += sprintf(ptr, "</gml:posList></gml:LinearRing></gml:exterior>");
668
for (i=1; i<poly->nrings; i++)
670
ptr += sprintf(ptr, "<gml:interior><gml:LinearRing><gml:posList>");
671
ptr += pointArray_toGML3(poly->rings[i], ptr, precision, is_deegree);
672
ptr += sprintf(ptr, "</gml:posList></gml:LinearRing></gml:interior>");
674
ptr += sprintf(ptr, "</gml:Polygon>");
680
asgml3_poly(LWPOLY *poly, char *srs, int precision, bool is_deegree)
685
size = asgml3_poly_size(poly, srs, precision);
686
output = palloc(size);
687
asgml3_poly_buf(poly, srs, output, precision, is_deegree);
692
* Compute max size required for GML version of this
693
* inspected geometry. Will recurse when needed.
694
* Don't call this with single-geoms inspected.
697
asgml3_inspected_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
702
/* the longest possible multi version */
703
size = sizeof("<gml:MultiLineString></gml:MultiLineString>");
705
if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
707
for (i=0; i<insp->ngeometries; i++)
712
LWGEOM_INSPECTED *subinsp;
715
if ((point=lwgeom_getpoint_inspected(insp, i)))
717
size += sizeof("<gml:pointMember>/") * 2;
718
size += asgml3_point_size(point, 0, precision);
719
lwpoint_release(point);
721
else if ((line=lwgeom_getline_inspected(insp, i)))
723
size += sizeof("<gml:curveMember>/") * 2;
724
size += asgml3_line_size(line, 0, precision);
725
lwline_release(line);
727
else if ((poly=lwgeom_getpoly_inspected(insp, i)))
729
size += sizeof("<gml:surfaceMember>/") * 2;
730
size += asgml3_poly_size(poly, 0, precision);
731
lwpoly_release(poly);
735
subgeom = lwgeom_getsubgeometry_inspected(insp, i);
736
subinsp = lwgeom_inspect(subgeom);
737
size += asgml3_inspected_size(subinsp, 0, precision);
738
lwinspected_release(subinsp);
746
* Don't call this with single-geoms inspected!
749
asgml3_inspected_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, bool is_deegree)
751
int type = lwgeom_getType(insp->serialized_form[0]);
757
if (type == MULTIPOINTTYPE) gmltype = "MultiPoint";
758
else if (type == MULTILINETYPE) gmltype = "MultiCurve";
759
else if (type == MULTIPOLYGONTYPE) gmltype = "MultiSurface";
760
else gmltype = "MultiGeometry";
762
/* Open outmost tag */
765
ptr += sprintf(ptr, "<gml:%s srsName=\"%s\">", gmltype, srs);
769
ptr += sprintf(ptr, "<gml:%s>", gmltype);
772
for (i=0; i<insp->ngeometries; i++)
777
LWGEOM_INSPECTED *subinsp;
780
if ((point=lwgeom_getpoint_inspected(insp, i)))
782
ptr += sprintf(ptr, "<gml:pointMember>");
783
ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree);
784
lwpoint_release(point);
785
ptr += sprintf(ptr, "</gml:pointMember>");
787
else if ((line=lwgeom_getline_inspected(insp, i)))
789
ptr += sprintf(ptr, "<gml:curveMember>");
790
ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree);
791
lwline_release(line);
792
ptr += sprintf(ptr, "</gml:curveMember>");
794
else if ((poly=lwgeom_getpoly_inspected(insp, i)))
796
ptr += sprintf(ptr, "<gml:surfaceMember>");
797
ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree);
798
lwpoly_release(poly);
799
ptr += sprintf(ptr, "</gml:surfaceMember>");
803
subgeom = lwgeom_getsubgeometry_inspected(insp, i);
804
subinsp = lwgeom_inspect(subgeom);
805
ptr += asgml3_inspected_buf(subinsp, 0, ptr, precision, is_deegree);
806
lwinspected_release(subinsp);
810
/* Close outmost tag */
811
ptr += sprintf(ptr, "</gml:%s>", gmltype);
817
* Don't call this with single-geoms inspected!
820
asgml3_inspected(LWGEOM_INSPECTED *insp, char *srs, int precision, bool is_deegree)
825
size = asgml3_inspected_size(insp, srs, precision);
827
asgml3_inspected_buf(insp, srs, gml, precision, is_deegree);
831
/* In GML3, inside <posList> or <pos>, coordinates are separated by a space separator
832
* In GML3 also, lat/lon are reversed for geocentric data
835
pointArray_toGML3(POINTARRAY *pa, char *output, int precision, bool is_deegree)
839
char x[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
840
char y[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
841
char z[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
845
if ( ! TYPE_HASZ(pa->dims) )
847
for (i=0; i<pa->npoints; i++)
850
getPoint2d_p(pa, i, &pt);
851
sprintf(x, "%.*f", precision, pt.x);
852
trim_trailing_zeros(x);
853
sprintf(y, "%.*f", precision, pt.y);
854
trim_trailing_zeros(y);
855
if ( i ) ptr += sprintf(ptr, " ");
857
ptr += sprintf(ptr, "%s %s", y, x);
859
ptr += sprintf(ptr, "%s %s", x, y);
864
for (i=0; i<pa->npoints; i++)
867
getPoint4d_p(pa, i, &pt);
868
sprintf(x, "%.*f", precision, pt.x);
869
trim_trailing_zeros(x);
870
sprintf(y, "%.*f", precision, pt.y);
871
trim_trailing_zeros(y);
872
sprintf(z, "%.*f", precision, pt.z);
873
trim_trailing_zeros(z);
874
if ( i ) ptr += sprintf(ptr, " ");
876
ptr += sprintf(ptr, "%s %s %s", y, x, z);
878
ptr += sprintf(ptr, "%s %s %s", x, y, z);
888
* Common GML routines
892
getSRSbySRID(int SRID, bool short_crs)
899
if (SPI_OK_CONNECT != SPI_connect ())
901
elog(NOTICE, "getSRSbySRID: could not connect to SPI manager");
907
sprintf(query, "SELECT auth_name||':'||auth_srid \
908
FROM spatial_ref_sys WHERE srid='%d'", SRID);
910
sprintf(query, "SELECT 'urn:ogc:def:crs:'||auth_name||':'||auth_srid \
911
FROM spatial_ref_sys WHERE srid='%d'", SRID);
914
err = SPI_exec(query, 1);
917
elog(NOTICE, "getSRSbySRID: error executing query %d", err);
922
/* no entry in spatial_ref_sys */
923
if (SPI_processed <= 0)
925
/*elog(NOTICE, "getSRSbySRID: no record for SRID %d", SRID); */
931
srs = SPI_getvalue(SPI_tuptable->vals[0],
932
SPI_tuptable->tupdesc, 1);
937
/*elog(NOTICE, "getSRSbySRID: null result"); */
942
/* copy result to upper executor context */
943
size = strlen(srs)+1;
944
srscopy = SPI_palloc(size);
945
memcpy(srscopy, srs, size);
947
/* disconnect from SPI */
954
* Returns maximum size of rendered pointarray in bytes.
957
pointArray_GMLsize(POINTARRAY *pa, int precision)
959
if (TYPE_NDIMS(pa->dims) == 2)
960
return (MAX_DIGS_DOUBLE + precision + sizeof(", "))
963
return (MAX_DIGS_DOUBLE + precision + sizeof(", ")) * 3 * pa->npoints;