PostGIS  2.1.10dev-r@@SVN_REVISION@@
lwmline.c
Go to the documentation of this file.
1 /**********************************************************************
2  * $Id: lwmline.c 13134 2014-12-01 08:47:21Z strk $
3  *
4  * PostGIS - Spatial Types for PostgreSQL
5  * http://postgis.net
6  * Copyright 2001-2006 Refractions Research Inc.
7  *
8  * This is free software; you can redistribute and/or modify it under
9  * the terms of the GNU General Public Licence. See the COPYING file.
10  *
11  **********************************************************************/
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include "liblwgeom_internal.h"
17 
18 void
20 {
22 }
23 
24 LWMLINE *
25 lwmline_construct_empty(int srid, char hasz, char hasm)
26 {
27  LWMLINE *ret = (LWMLINE*)lwcollection_construct_empty(MULTILINETYPE, srid, hasz, hasm);
28  return ret;
29 }
30 
31 
32 
34 {
35  return (LWMLINE*)lwcollection_add_lwgeom((LWCOLLECTION*)mobj, (LWGEOM*)obj);
36 }
37 
42 LWMLINE*
43 lwmline_measured_from_lwmline(const LWMLINE *lwmline, double m_start, double m_end)
44 {
45  int i = 0;
46  int hasm = 0, hasz = 0;
47  double length = 0.0, length_so_far = 0.0;
48  double m_range = m_end - m_start;
49  LWGEOM **geoms = NULL;
50 
51  if ( lwmline->type != MULTILINETYPE )
52  {
53  lwerror("lwmline_measured_from_lmwline: only multiline types supported");
54  return NULL;
55  }
56 
57  hasz = FLAGS_GET_Z(lwmline->flags);
58  hasm = 1;
59 
60  /* Calculate the total length of the mline */
61  for ( i = 0; i < lwmline->ngeoms; i++ )
62  {
63  LWLINE *lwline = (LWLINE*)lwmline->geoms[i];
64  if ( lwline->points && lwline->points->npoints > 1 )
65  {
66  length += ptarray_length_2d(lwline->points);
67  }
68  }
69 
70  if ( lwgeom_is_empty((LWGEOM*)lwmline) )
71  {
72  return (LWMLINE*)lwcollection_construct_empty(MULTILINETYPE, lwmline->srid, hasz, hasm);
73  }
74 
75  geoms = lwalloc(sizeof(LWGEOM*) * lwmline->ngeoms);
76 
77  for ( i = 0; i < lwmline->ngeoms; i++ )
78  {
79  double sub_m_start, sub_m_end;
80  double sub_length = 0.0;
81  LWLINE *lwline = (LWLINE*)lwmline->geoms[i];
82 
83  if ( lwline->points && lwline->points->npoints > 1 )
84  {
85  sub_length = ptarray_length_2d(lwline->points);
86  }
87 
88  sub_m_start = (m_start + m_range * length_so_far / length);
89  sub_m_end = (m_start + m_range * (length_so_far + sub_length) / length);
90 
91  geoms[i] = (LWGEOM*)lwline_measured_from_lwline(lwline, sub_m_start, sub_m_end);
92 
93  length_so_far += sub_length;
94  }
95 
96  return (LWMLINE*)lwcollection_construct(lwmline->type, lwmline->srid, NULL, lwmline->ngeoms, geoms);
97 }
98 
99 void lwmline_free(LWMLINE *mline)
100 {
101  int i;
102  if ( ! mline ) return;
103 
104  if ( mline->bbox )
105  lwfree(mline->bbox);
106 
107  for ( i = 0; i < mline->ngeoms; i++ )
108  if ( mline->geoms && mline->geoms[i] )
109  lwline_free(mline->geoms[i]);
110 
111  if ( mline->geoms )
112  lwfree(mline->geoms);
113 
114  lwfree(mline);
115 }
LWLINE * lwline_measured_from_lwline(const LWLINE *lwline, double m_start, double m_end)
Add a measure dimension to a line, interpolating linearly from the start to the end value...
Definition: lwline.c:366
uint8_t type
Definition: liblwgeom.h:433
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:30
void lwfree(void *mem)
Definition: lwutil.c:190
int npoints
Definition: liblwgeom.h:327
double ptarray_length_2d(const POINTARRAY *pts)
Find the 2d length of the given POINTARRAY (even if it's 3d)
Definition: ptarray.c:1586
void lwline_free(LWLINE *line)
Definition: lwline.c:63
LWGEOM * lwmline_as_lwgeom(const LWMLINE *obj)
Definition: lwgeom.c:209
int ngeoms
Definition: liblwgeom.h:437
LWMLINE * lwmline_measured_from_lwmline(const LWMLINE *lwmline, double m_start, double m_end)
Re-write the measure ordinate (or add one, if it isn't already there) interpolating the measure betwe...
Definition: lwmline.c:43
void lwmline_free(LWMLINE *mline)
Definition: lwmline.c:99
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:67
uint8_t flags
Definition: liblwgeom.h:434
void lwmline_release(LWMLINE *lwmline)
Definition: lwmline.c:19
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
Definition: liblwgeom.h:106
LWMLINE * lwmline_construct_empty(int srid, char hasz, char hasm)
Definition: lwmline.c:25
LWLINE ** geoms
Definition: liblwgeom.h:439
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
Definition: lwgeom.c:328
void * lwalloc(size_t size)
Definition: lwutil.c:175
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
Definition: lwgeom.c:1229
#define MULTILINETYPE
Definition: liblwgeom.h:64
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
Definition: lwcollection.c:81
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
Definition: lwcollection.c:174
if(!(yy_init))
Definition: lwin_wkt_lex.c:860
GBOX * bbox
Definition: liblwgeom.h:435
LWMLINE * lwmline_add_lwline(LWMLINE *mobj, const LWLINE *obj)
Definition: lwmline.c:33
int32_t srid
Definition: liblwgeom.h:436
POINTARRAY * points
Definition: liblwgeom.h:378