Coverage Report

Created: 2026-08-14 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}