PostGIS  2.1.10dev-r@@SVN_REVISION@@
lwcompound.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * Copyright (C) 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 #include "lwgeom_log.h"
18 
19 
20 
21 int
23 {
24  size_t size;
25  int npoints=0;
26 
27  if ( lwgeom_has_z((LWGEOM*)compound) )
28  {
29  size = sizeof(POINT3D);
30  }
31  else
32  {
33  size = sizeof(POINT2D);
34  }
35 
36  if ( compound->geoms[compound->ngeoms - 1]->type == CIRCSTRINGTYPE )
37  {
38  npoints = ((LWCIRCSTRING *)compound->geoms[compound->ngeoms - 1])->points->npoints;
39  }
40  else if (compound->geoms[compound->ngeoms - 1]->type == LINETYPE)
41  {
42  npoints = ((LWLINE *)compound->geoms[compound->ngeoms - 1])->points->npoints;
43  }
44 
45  if ( memcmp(getPoint_internal( (POINTARRAY *)compound->geoms[0]->data, 0),
46  getPoint_internal( (POINTARRAY *)compound->geoms[compound->ngeoms - 1]->data,
47  npoints - 1),
48  size) )
49  {
50  return LW_FALSE;
51  }
52 
53  return LW_TRUE;
54 }
55 
56 double lwcompound_length(const LWCOMPOUND *comp)
57 {
58  return lwcompound_length_2d(comp);
59 }
60 
61 double lwcompound_length_2d(const LWCOMPOUND *comp)
62 {
63  int i;
64  double length = 0.0;
65  if ( lwgeom_is_empty((LWGEOM*)comp) )
66  return 0.0;
67 
68  for (i = 0; i < comp->ngeoms; i++)
69  {
70  length += lwgeom_length_2d(comp->geoms[i]);
71  }
72  return length;
73 }
74 
76 {
77  LWCOLLECTION *col = (LWCOLLECTION*)comp;
78 
79  /* Empty things can't continuously join up with other things */
80  if ( lwgeom_is_empty(geom) )
81  {
82  LWDEBUG(4, "Got an empty component for a compound curve!");
83  return LW_FAILURE;
84  }
85 
86  if( col->ngeoms > 0 )
87  {
88  POINT4D last, first;
89  /* First point of the component we are adding */
90  LWLINE *newline = (LWLINE*)geom;
91  /* Last point of the previous component */
92  LWLINE *prevline = (LWLINE*)(col->geoms[col->ngeoms-1]);
93 
94  getPoint4d_p(newline->points, 0, &first);
95  getPoint4d_p(prevline->points, prevline->points->npoints-1, &last);
96 
97  if ( !(FP_EQUALS(first.x,last.x) && FP_EQUALS(first.y,last.y)) )
98  {
99  LWDEBUG(4, "Components don't join up end-to-end!");
100  LWDEBUGF(4, "first pt (%g %g %g %g) last pt (%g %g %g %g)", first.x, first.y, first.z, first.m, last.x, last.y, last.z, last.m);
101  return LW_FAILURE;
102  }
103  }
104 
105  col = lwcollection_add_lwgeom(col, geom);
106  return LW_SUCCESS;
107 }
108 
109 LWCOMPOUND *
110 lwcompound_construct_empty(int srid, char hasz, char hasm)
111 {
113  return ret;
114 }
115 
116 int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt)
117 {
118  switch( geom->type )
119  {
120  case LINETYPE:
121  return ptarray_contains_point(((LWLINE*)geom)->points, pt);
122  case CIRCSTRINGTYPE:
123  return ptarrayarc_contains_point(((LWCIRCSTRING*)geom)->points, pt);
124  case COMPOUNDTYPE:
125  return lwcompound_contains_point((LWCOMPOUND*)geom, pt);
126  }
127  lwerror("lwgeom_contains_point failed");
128  return LW_FAILURE;
129 }
130 
131 int
133 {
134  int i;
135  LWLINE *lwline;
136  LWCIRCSTRING *lwcirc;
137  int wn = 0;
138  int winding_number = 0;
139  int result;
140 
141  for ( i = 0; i < comp->ngeoms; i++ )
142  {
143  LWGEOM *lwgeom = comp->geoms[i];
144  if ( lwgeom->type == LINETYPE )
145  {
146  lwline = lwgeom_as_lwline(lwgeom);
147  if ( comp->ngeoms == 1 )
148  {
149  return ptarray_contains_point(lwline->points, pt);
150  }
151  else
152  {
153  /* Don't check closure while doing p-i-p test */
154  result = ptarray_contains_point_partial(lwline->points, pt, LW_FALSE, &winding_number);
155  }
156  }
157  else
158  {
159  lwcirc = lwgeom_as_lwcircstring(lwgeom);
160  if ( ! lwcirc ) {
161  lwerror("Unexpected component of type %s in compound curve", lwtype_name(lwgeom->type));
162  return 0;
163  }
164  if ( comp->ngeoms == 1 )
165  {
166  return ptarrayarc_contains_point(lwcirc->points, pt);
167  }
168  else
169  {
170  /* Don't check closure while doing p-i-p test */
171  result = ptarrayarc_contains_point_partial(lwcirc->points, pt, LW_FALSE, &winding_number);
172  }
173  }
174 
175  /* Propogate boundary condition */
176  if ( result == LW_BOUNDARY )
177  return LW_BOUNDARY;
178 
179  wn += winding_number;
180  }
181 
182  /* Outside */
183  if (wn == 0)
184  return LW_OUTSIDE;
185 
186  /* Inside */
187  return LW_INSIDE;
188 }
double x
Definition: liblwgeom.h:308
#define LINETYPE
Definition: liblwgeom.h:61
int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt)
Definition: lwcompound.c:116
double m
Definition: liblwgeom.h:308
int npoints
Definition: liblwgeom.h:327
#define COMPOUNDTYPE
Definition: liblwgeom.h:68
int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt)
For POINTARRAYs representing CIRCULARSTRINGS.
Definition: ptarray.c:796
#define LW_SUCCESS
Definition: liblwgeom.h:55
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:50
LWGEOM ** geoms
Definition: liblwgeom.h:478
double lwgeom_length_2d(const LWGEOM *geom)
Definition: lwgeom.c:1588
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:792
char ** result
Definition: liblwgeom.h:218
double lwcompound_length(const LWCOMPOUND *comp)
Definition: lwcompound.c:56
#define LW_FAILURE
Definition: liblwgeom.h:54
void * data
Definition: liblwgeom.h:356
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:67
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:164
#define LW_FALSE
Definition: liblwgeom.h:52
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:51
LWGEOM ** geoms
Definition: liblwgeom.h:465
int ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number)
Definition: ptarray.c:703
uint8_t * getPoint_internal(const POINTARRAY *pa, int n)
Definition: ptarray.c:1645
#define LW_INSIDE
Constants for point-in-polygon return values.
int lwcompound_is_closed(const LWCOMPOUND *compound)
Definition: lwcompound.c:22
double z
Definition: liblwgeom.h:308
int lwcompound_add_lwgeom(LWCOMPOUND *comp, LWGEOM *geom)
Add a component, allocating extra space if necessary.
Definition: lwcompound.c:75
LWCOMPOUND * lwcompound_construct_empty(int srid, char hasz, char hasm)
Definition: lwcompound.c:110
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:89
LWCIRCSTRING * lwgeom_as_lwcircstring(const LWGEOM *lwgeom)
Definition: lwgeom.c:98
int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt)
Definition: lwcompound.c:132
#define LW_BOUNDARY
int ngeoms
Definition: liblwgeom.h:476
uint8_t type
Definition: liblwgeom.h:352
#define FP_EQUALS(A, B)
int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt)
Return 1 if the point is inside the POINTARRAY, -1 if it is outside, and 0 if it is on the boundary...
Definition: ptarray.c:697
POINTARRAY * points
Definition: liblwgeom.h:400
#define CIRCSTRINGTYPE
Definition: liblwgeom.h:67
#define LW_OUTSIDE
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
double y
Definition: liblwgeom.h:308
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
Definition: lwcollection.c:81
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:55
int ptarrayarc_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number)
Definition: ptarray.c:802
double lwcompound_length_2d(const LWCOMPOUND *comp)
Definition: lwcompound.c:61
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
Definition: lwcollection.c:174
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
Definition: lwgeom_api.c:217
POINTARRAY * points
Definition: liblwgeom.h:378