/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 | } |