Coverage Report

Created: 2026-06-09 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgis/liblwgeom/lwcurvepoly.c
Line
Count
Source
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) 2001-2006 Refractions Research Inc.
22
 *
23
 **********************************************************************/
24
25
26
/* basic LWCURVEPOLY manipulation */
27
28
#include <stdio.h>
29
#include <stdlib.h>
30
#include <string.h>
31
#include "liblwgeom_internal.h"
32
#include "lwgeom_log.h"
33
34
LWCURVEPOLY *
35
lwcurvepoly_construct_empty(int32_t srid, char hasz, char hasm)
36
6.20k
{
37
6.20k
  LWCURVEPOLY *ret;
38
39
6.20k
  ret = lwalloc(sizeof(LWCURVEPOLY));
40
6.20k
  ret->type = CURVEPOLYTYPE;
41
6.20k
  ret->flags = lwflags(hasz, hasm, 0);
42
6.20k
  ret->srid = srid;
43
6.20k
  ret->nrings = 0;
44
6.20k
  ret->maxrings = 1; /* Allocate room for sub-members, just in case. */
45
6.20k
  ret->rings = lwalloc(ret->maxrings * sizeof(LWGEOM*));
46
6.20k
  ret->bbox = NULL;
47
48
6.20k
  return ret;
49
6.20k
}
50
51
LWCURVEPOLY *
52
lwcurvepoly_construct_from_lwpoly(LWPOLY *lwpoly)
53
0
{
54
0
  LWCURVEPOLY *ret;
55
0
  uint32_t i;
56
0
  ret = lwalloc(sizeof(LWCURVEPOLY));
57
0
  ret->type = CURVEPOLYTYPE;
58
0
  ret->flags = lwpoly->flags;
59
0
  ret->srid = lwpoly->srid;
60
0
  ret->nrings = lwpoly->nrings;
61
0
  ret->maxrings = lwpoly->nrings; /* Allocate room for sub-members, just in case. */
62
0
  ret->rings = lwalloc(ret->maxrings * sizeof(LWGEOM*));
63
0
  ret->bbox = lwpoly->bbox ? gbox_clone(lwpoly->bbox) : NULL;
64
0
  for ( i = 0; i < ret->nrings; i++ )
65
0
  {
66
0
    ret->rings[i] = lwline_as_lwgeom(lwline_construct(ret->srid, NULL, ptarray_clone_deep(lwpoly->rings[i])));
67
0
  }
68
0
  return ret;
69
0
}
70
71
int lwcurvepoly_add_ring(LWCURVEPOLY *poly, LWGEOM *ring)
72
103k
{
73
103k
  uint32_t i;
74
75
  /* Can't do anything with NULLs */
76
103k
  if( ! poly || ! ring )
77
3.34k
  {
78
3.34k
    LWDEBUG(4,"NULL inputs!!! quitting");
79
3.34k
    return LW_FAILURE;
80
3.34k
  }
81
82
  /* Check that we're not working with garbage */
83
99.9k
  if ( poly->rings == NULL && (poly->nrings || poly->maxrings) )
84
0
  {
85
0
    LWDEBUG(4,"mismatched nrings/maxrings");
86
0
    lwerror("Curvepolygon is in inconsistent state. Null memory but non-zero collection counts.");
87
0
    return LW_FAILURE;
88
0
  }
89
90
  /* Check that we're adding an allowed ring type */
91
99.9k
  if ( ! ( ring->type == LINETYPE || ring->type == CIRCSTRINGTYPE || ring->type == COMPOUNDTYPE ) )
92
7
  {
93
7
    LWDEBUGF(4,"got incorrect ring type: %s",lwtype_name(ring->type));
94
7
    return LW_FAILURE;
95
7
  }
96
97
98
  /* In case this is a truly empty, make some initial space  */
99
99.9k
  if ( poly->rings == NULL )
100
0
  {
101
0
    poly->maxrings = 2;
102
0
    poly->nrings = 0;
103
0
    poly->rings = lwalloc(poly->maxrings * sizeof(LWGEOM*));
104
0
  }
105
106
  /* Allocate more space if we need it */
107
99.9k
  if ( poly->nrings == poly->maxrings )
108
1.34k
  {
109
1.34k
    poly->maxrings *= 2;
110
1.34k
    poly->rings = lwrealloc(poly->rings, sizeof(LWGEOM*) * poly->maxrings);
111
1.34k
  }
112
113
  /* Make sure we don't already have a reference to this geom */
114
439M
  for ( i = 0; i < poly->nrings; i++ )
115
439M
  {
116
439M
    if ( poly->rings[i] == ring )
117
0
    {
118
0
      LWDEBUGF(4, "Found duplicate geometry in collection %p == %p", poly->rings[i], ring);
119
0
      return LW_SUCCESS;
120
0
    }
121
439M
  }
122
123
  /* Add the ring and increment the ring count */
124
99.9k
  poly->rings[poly->nrings] = (LWGEOM*)ring;
125
99.9k
  poly->nrings++;
126
99.9k
  return LW_SUCCESS;
127
99.9k
}
128
129
/**
130
 * This should be rewritten to make use of the curve itself.
131
 */
132
double
133
lwcurvepoly_area(const LWCURVEPOLY *curvepoly)
134
0
{
135
0
  double area = 0.0;
136
0
  LWPOLY *poly;
137
0
  if( lwgeom_is_empty((LWGEOM*)curvepoly) )
138
0
    return 0.0;
139
0
  poly = lwcurvepoly_stroke(curvepoly, 32);
140
0
  area = lwpoly_area(poly);
141
0
  lwpoly_free(poly);
142
0
  return area;
143
0
}
144
145
146
double
147
lwcurvepoly_perimeter(const LWCURVEPOLY *poly)
148
0
{
149
0
  double result=0.0;
150
0
  uint32_t i;
151
152
0
  for (i=0; i<poly->nrings; i++)
153
0
    result += lwgeom_length(poly->rings[i]);
154
155
0
  return result;
156
0
}
157
158
double
159
lwcurvepoly_perimeter_2d(const LWCURVEPOLY *poly)
160
0
{
161
0
  double result=0.0;
162
0
  uint32_t i;
163
164
0
  for (i=0; i<poly->nrings; i++)
165
0
    result += lwgeom_length_2d(poly->rings[i]);
166
167
0
  return result;
168
0
}