/src/postgis/liblwgeom/lwmline.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 2001-2006 Refractions Research Inc. |
22 | | * |
23 | | **********************************************************************/ |
24 | | |
25 | | |
26 | | #include <stdio.h> |
27 | | #include <stdlib.h> |
28 | | #include <string.h> |
29 | | #include "liblwgeom_internal.h" |
30 | | |
31 | | void |
32 | | lwmline_release(LWMLINE *lwmline) |
33 | 0 | { |
34 | 0 | lwgeom_release(lwmline_as_lwgeom(lwmline)); |
35 | 0 | } |
36 | | |
37 | | LWMLINE * |
38 | | lwmline_construct_empty(int32_t srid, char hasz, char hasm) |
39 | 0 | { |
40 | 0 | LWMLINE *ret = (LWMLINE*)lwcollection_construct_empty(MULTILINETYPE, srid, hasz, hasm); |
41 | 0 | return ret; |
42 | 0 | } |
43 | | |
44 | | |
45 | | |
46 | | LWMLINE* lwmline_add_lwline(LWMLINE *mobj, const LWLINE *obj) |
47 | 67.7k | { |
48 | 67.7k | return (LWMLINE*)lwcollection_add_lwgeom((LWCOLLECTION*)mobj, (LWGEOM*)obj); |
49 | 67.7k | } |
50 | | |
51 | | /** |
52 | | * Re-write the measure ordinate (or add one, if it isn't already there) interpolating |
53 | | * the measure between the supplied start and end values. |
54 | | */ |
55 | | LWMLINE* |
56 | | lwmline_measured_from_lwmline(const LWMLINE *lwmline, double m_start, double m_end) |
57 | 0 | { |
58 | 0 | uint32_t i = 0; |
59 | 0 | int hasm = 0, hasz = 0; |
60 | 0 | double length = 0.0, length_so_far = 0.0; |
61 | 0 | double m_range = m_end - m_start; |
62 | 0 | LWGEOM **geoms = NULL; |
63 | |
|
64 | 0 | if ( lwmline->type != MULTILINETYPE ) |
65 | 0 | { |
66 | 0 | lwerror("lwmline_measured_from_lmwline: only multiline types supported"); |
67 | 0 | return NULL; |
68 | 0 | } |
69 | | |
70 | 0 | hasz = FLAGS_GET_Z(lwmline->flags); |
71 | 0 | hasm = 1; |
72 | | |
73 | | /* Calculate the total length of the mline */ |
74 | 0 | for ( i = 0; i < lwmline->ngeoms; i++ ) |
75 | 0 | { |
76 | 0 | LWLINE *lwline = (LWLINE*)lwmline->geoms[i]; |
77 | 0 | if ( lwline->points && lwline->points->npoints > 1 ) |
78 | 0 | { |
79 | 0 | length += ptarray_length_2d(lwline->points); |
80 | 0 | } |
81 | 0 | } |
82 | |
|
83 | 0 | if ( lwgeom_is_empty((LWGEOM*)lwmline) ) |
84 | 0 | { |
85 | 0 | return (LWMLINE*)lwcollection_construct_empty(MULTILINETYPE, lwmline->srid, hasz, hasm); |
86 | 0 | } |
87 | | |
88 | 0 | geoms = lwalloc(sizeof(LWGEOM*) * lwmline->ngeoms); |
89 | |
|
90 | 0 | for ( i = 0; i < lwmline->ngeoms; i++ ) |
91 | 0 | { |
92 | 0 | double sub_m_start, sub_m_end; |
93 | 0 | double sub_length = 0.0; |
94 | 0 | LWLINE *lwline = (LWLINE*)lwmline->geoms[i]; |
95 | |
|
96 | 0 | if ( lwline->points && lwline->points->npoints > 1 ) |
97 | 0 | { |
98 | 0 | sub_length = ptarray_length_2d(lwline->points); |
99 | 0 | } |
100 | |
|
101 | 0 | sub_m_start = (m_start + m_range * length_so_far / length); |
102 | 0 | sub_m_end = (m_start + m_range * (length_so_far + sub_length) / length); |
103 | |
|
104 | 0 | geoms[i] = (LWGEOM*)lwline_measured_from_lwline(lwline, sub_m_start, sub_m_end); |
105 | |
|
106 | 0 | length_so_far += sub_length; |
107 | 0 | } |
108 | |
|
109 | 0 | return (LWMLINE*)lwcollection_construct(lwmline->type, lwmline->srid, NULL, lwmline->ngeoms, geoms); |
110 | 0 | } |
111 | | |
112 | | void lwmline_free(LWMLINE *mline) |
113 | 4.01k | { |
114 | 4.01k | if (!mline) |
115 | 0 | return; |
116 | | |
117 | 4.01k | if (mline->bbox) |
118 | 263 | lwfree(mline->bbox); |
119 | | |
120 | 4.01k | if (mline->geoms) |
121 | 4.00k | { |
122 | 255k | for (uint32_t i = 0; i < mline->ngeoms; i++) |
123 | 251k | if (mline->geoms[i]) |
124 | 251k | lwline_free(mline->geoms[i]); |
125 | 4.00k | lwfree(mline->geoms); |
126 | 4.00k | } |
127 | | |
128 | 4.01k | lwfree(mline); |
129 | 4.01k | } |