1 /**********************************************************************
2 *
3 * PostGIS - Spatial Types for PostgreSQL
4 * http://postgis.net
5 *
6 * PostGIS is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * PostGIS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18 *
19 **********************************************************************
20 *
21 * Copyright (C) 2004 Refractions Research Inc.
22 *
23 **********************************************************************/
24
25
26 #include "lwgeom_log.h"
27 #include "liblwgeom.h"
28
29 #include <stdio.h>
30 #include <string.h>
31
32 /* Place to hold the ZM string used in other summaries */
33 static char tflags[6];
34
35 static char *
lwgeom_flagchars(LWGEOM * lwg)36 lwgeom_flagchars(LWGEOM *lwg)
37 {
38 int flagno = 0;
39 if ( FLAGS_GET_Z(lwg->flags) ) tflags[flagno++] = 'Z';
40 if ( FLAGS_GET_M(lwg->flags) ) tflags[flagno++] = 'M';
41 if ( FLAGS_GET_BBOX(lwg->flags) ) tflags[flagno++] = 'B';
42 if ( FLAGS_GET_GEODETIC(lwg->flags) ) tflags[flagno++] = 'G';
43 if ( lwg->srid != SRID_UNKNOWN ) tflags[flagno++] = 'S';
44 tflags[flagno] = '\0';
45
46 LWDEBUGF(4, "Flags: %s - returning %p", lwg->flags, tflags);
47
48 return tflags;
49 }
50
51 /*
52 * Returns an alloced string containing summary for the LWGEOM object
53 */
54 static char *
lwpoint_summary(LWPOINT * point,int offset)55 lwpoint_summary(LWPOINT *point, int offset)
56 {
57 char *result;
58 char *pad="";
59 char *zmflags = lwgeom_flagchars((LWGEOM*)point);
60
61 result = (char *)lwalloc(128+offset);
62
63 sprintf(result, "%*.s%s[%s]",
64 offset, pad, lwtype_name(point->type),
65 zmflags);
66 return result;
67 }
68
69 static char *
lwline_summary(LWLINE * line,int offset)70 lwline_summary(LWLINE *line, int offset)
71 {
72 char *result;
73 char *pad="";
74 char *zmflags = lwgeom_flagchars((LWGEOM*)line);
75
76 result = (char *)lwalloc(128+offset);
77
78 sprintf(result, "%*.s%s[%s] with %d points",
79 offset, pad, lwtype_name(line->type),
80 zmflags,
81 line->points->npoints);
82 return result;
83 }
84
85
86 static char *
lwcollection_summary(LWCOLLECTION * col,int offset)87 lwcollection_summary(LWCOLLECTION *col, int offset)
88 {
89 size_t size = 128;
90 char *result;
91 char *tmp;
92 uint32_t i;
93 static char *nl = "\n";
94 char *pad="";
95 char *zmflags = lwgeom_flagchars((LWGEOM*)col);
96
97 LWDEBUG(2, "lwcollection_summary called");
98
99 result = (char *)lwalloc(size);
100
101 sprintf(result, "%*.s%s[%s] with %d element%s",
102 offset, pad, lwtype_name(col->type),
103 zmflags,
104 col->ngeoms,
105 col->ngeoms ?
106 ( col->ngeoms > 1 ? "s:\n" : ":\n")
107 : "s");
108
109 for (i=0; i<col->ngeoms; i++)
110 {
111 tmp = lwgeom_summary(col->geoms[i], offset+2);
112 size += strlen(tmp)+1;
113 result = lwrealloc(result, size);
114
115 LWDEBUGF(4, "Reallocated %d bytes for result", size);
116 if ( i > 0 ) strcat(result,nl);
117
118 strcat(result, tmp);
119 lwfree(tmp);
120 }
121
122 LWDEBUG(3, "lwcollection_summary returning");
123
124 return result;
125 }
126
127 static char *
lwpoly_summary(LWPOLY * poly,int offset)128 lwpoly_summary(LWPOLY *poly, int offset)
129 {
130 char tmp[256];
131 size_t size = 64*(poly->nrings+1)+128;
132 char *result;
133 uint32_t i;
134 char *pad="";
135 static char *nl = "\n";
136 char *zmflags = lwgeom_flagchars((LWGEOM*)poly);
137
138 LWDEBUG(2, "lwpoly_summary called");
139
140 result = (char *)lwalloc(size);
141
142 sprintf(result, "%*.s%s[%s] with %i ring%s",
143 offset, pad, lwtype_name(poly->type),
144 zmflags,
145 poly->nrings,
146 poly->nrings ?
147 ( poly->nrings > 1 ? "s:\n" : ":\n")
148 : "s");
149
150 for (i=0; i<poly->nrings; i++)
151 {
152 sprintf(tmp,"%s ring %i has %i points",
153 pad, i, poly->rings[i]->npoints);
154 if ( i > 0 ) strcat(result,nl);
155 strcat(result,tmp);
156 }
157
158 LWDEBUG(3, "lwpoly_summary returning");
159
160 return result;
161 }
162
163 char *
lwgeom_summary(const LWGEOM * lwgeom,int offset)164 lwgeom_summary(const LWGEOM *lwgeom, int offset)
165 {
166 char *result;
167
168 switch (lwgeom->type)
169 {
170 case POINTTYPE:
171 return lwpoint_summary((LWPOINT *)lwgeom, offset);
172
173 case CIRCSTRINGTYPE:
174 case TRIANGLETYPE:
175 case LINETYPE:
176 return lwline_summary((LWLINE *)lwgeom, offset);
177
178 case POLYGONTYPE:
179 return lwpoly_summary((LWPOLY *)lwgeom, offset);
180
181 case TINTYPE:
182 case MULTISURFACETYPE:
183 case MULTICURVETYPE:
184 case CURVEPOLYTYPE:
185 case COMPOUNDTYPE:
186 case MULTIPOINTTYPE:
187 case MULTILINETYPE:
188 case MULTIPOLYGONTYPE:
189 case COLLECTIONTYPE:
190 return lwcollection_summary((LWCOLLECTION *)lwgeom, offset);
191 default:
192 result = (char *)lwalloc(256);
193 sprintf(result, "Object is of unknown type: %d",
194 lwgeom->type);
195 return result;
196 }
197
198 return NULL;
199 }
200