/** * Create a new circularstring. Null point array implies empty. Null dimensionality * implies no specified dimensionality in the WKT. * Circular strings are just like linestrings, except with slighty different * validity rules (minpoint == 3, numpoints % 2 == 1). */ LWGEOM* wkt_parser_circularstring_new(POINTARRAY *pa, char *dimensionality) { uint8_t flags = wkt_dimensionality(dimensionality); LWDEBUG(4,"entered"); /* No pointarray means it is empty */ if( ! pa ) return lwcircstring_as_lwgeom(lwcircstring_construct_empty(SRID_UNKNOWN, FLAGS_GET_Z(flags), FLAGS_GET_M(flags))); /* If the number of dimensions is not consistent, we have a problem. */ if( wkt_pointarray_dimensionality(pa, flags) == LW_FALSE ) { ptarray_free(pa); SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS); return NULL; } /* Apply check for not enough points, if requested. */ if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_MINPOINTS) && (pa->npoints < 3) ) { ptarray_free(pa); SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS); return NULL; } /* Apply check for odd number of points, if requested. */ if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_ODD) && ((pa->npoints % 2) == 0) ) { ptarray_free(pa); SET_PARSER_ERROR(PARSER_ERROR_ODDPOINTS); return NULL; } return lwcircstring_as_lwgeom(lwcircstring_construct(SRID_UNKNOWN, NULL, pa)); }
/* * Construct a LWCIRCSTRING from a LWMPOINT */ LWCIRCSTRING * lwcircstring_from_lwmpoint(int SRID, LWMPOINT *mpoint) { unsigned int i; POINTARRAY *pa; char zmflag = TYPE_GETZM(mpoint->type); size_t ptsize, size; uchar *newpoints, *ptr; if (zmflag == 0) ptsize = 2 * sizeof(double); else if (zmflag == 3) ptsize = 4 * sizeof(double); else ptsize = 3 * sizeof(double); /* Allocate space for output points */ size = ptsize * mpoint->ngeoms; newpoints = lwalloc(size); memset(newpoints, 0, size); ptr = newpoints; for (i = 0; i < mpoint->ngeoms; i++) { memcpy(ptr, getPoint_internal(mpoint->geoms[i]->point, 0), ptsize); ptr += ptsize; } pa = pointArray_construct(newpoints, zmflag&2, zmflag&1, mpoint->ngeoms); LWDEBUGF(3, "lwcurve_from_lwmpoint: constructed pointarray for %d points, %d zmflag", mpoint->ngeoms, zmflag); return lwcircstring_construct(SRID, NULL, pa); }
/* * Construct a LWCIRCSTRING from a LWMPOINT */ LWCIRCSTRING * lwcircstring_from_lwmpoint(int srid, LWMPOINT *mpoint) { uint32_t i; POINTARRAY *pa; char zmflag = FLAGS_GET_ZM(mpoint->flags); size_t ptsize, size; uint8_t *newpoints, *ptr; if (zmflag == 0) ptsize = 2 * sizeof(double); else if (zmflag == 3) ptsize = 4 * sizeof(double); else ptsize = 3 * sizeof(double); /* Allocate space for output points */ size = ptsize * mpoint->ngeoms; newpoints = lwalloc(size); memset(newpoints, 0, size); ptr = newpoints; for (i = 0; i < mpoint->ngeoms; i++) { memcpy(ptr, getPoint_internal(mpoint->geoms[i]->point, 0), ptsize); ptr += ptsize; } pa = ptarray_construct_reference_data(zmflag&2, zmflag&1, mpoint->ngeoms, newpoints); LWDEBUGF(3, "lwcurve_from_lwmpoint: constructed pointarray for %d points, %d zmflag", mpoint->ngeoms, zmflag); return lwcircstring_construct(srid, NULL, pa); }
LWCIRCSTRING * lwcircstring_removepoint(LWCIRCSTRING *curve, uint32_t index) { POINTARRAY *newpa; LWCIRCSTRING *ret; newpa = ptarray_removePoint(curve->points, index); ret = lwcircstring_construct(curve->srid, NULL, newpa); return ret; }
LWCIRCSTRING * lwcircstring_addpoint(LWCIRCSTRING *curve, LWPOINT *point, uint32_t where) { POINTARRAY *newpa; LWCIRCSTRING *ret; newpa = ptarray_addPoint(curve->points, getPoint_internal(point->point, 0), FLAGS_NDIMS(point->flags), where); ret = lwcircstring_construct(curve->srid, NULL, newpa); return ret; }
LWCIRCSTRING * lwcircstring_addpoint(LWCIRCSTRING *curve, LWPOINT *point, unsigned int where) { POINTARRAY *newpa; LWCIRCSTRING *ret; newpa = ptarray_addPoint(curve->points, getPoint_internal(point->point, 0), TYPE_NDIMS(point->type), where); ret = lwcircstring_construct(curve->SRID, NULL, newpa); return ret; }
static LWGEOM* circstring_from_pa(const POINTARRAY *pa, int srid, int start, int end) { POINT4D p0, p1, p2; POINTARRAY *pao = ptarray_construct(ptarray_has_z(pa), ptarray_has_m(pa), 3); LWDEBUGF(4, "srid=%d, start=%d, end=%d", srid, start, end); getPoint4d_p(pa, start, &p0); ptarray_set_point4d(pao, 0, &p0); getPoint4d_p(pa, (start+end)/2, &p1); ptarray_set_point4d(pao, 1, &p1); getPoint4d_p(pa, end+1, &p2); ptarray_set_point4d(pao, 2, &p2); return lwcircstring_as_lwgeom(lwcircstring_construct(srid, NULL, pao)); }
LWCIRCSTRING * lwcirc_grid(LWCIRCSTRING *line, gridspec *grid) { LWCIRCSTRING *oline; POINTARRAY *opa; opa = ptarray_grid(line->points, grid); /* Skip line3d with less then 2 points */ if ( opa->npoints < 2 ) return NULL; /* TODO: grid bounding box... */ oline = lwcircstring_construct(line->srid, NULL, opa); return oline; }
/* * Construct a LWCIRCSTRING from an array of LWPOINTs * LWCIRCSTRING dimensions are large enough to host all input dimensions. */ LWCIRCSTRING * lwcircstring_from_lwpointarray(int srid, uint32_t npoints, LWPOINT **points) { int zmflag=0; uint32_t i; POINTARRAY *pa; uint8_t *newpoints, *ptr; size_t ptsize, size; /* * Find output dimensions, check integrity */ for (i = 0; i < npoints; i++) { if (points[i]->type != POINTTYPE) { lwerror("lwcurve_from_lwpointarray: invalid input type: %s", lwtype_name(points[i]->type)); return NULL; } if (FLAGS_GET_Z(points[i]->flags)) zmflag |= 2; if (FLAGS_GET_M(points[i]->flags)) zmflag |= 1; if (zmflag == 3) break; } if (zmflag == 0) ptsize = 2 * sizeof(double); else if (zmflag == 3) ptsize = 4 * sizeof(double); else ptsize = 3 * sizeof(double); /* * Allocate output points array */ size = ptsize * npoints; newpoints = lwalloc(size); memset(newpoints, 0, size); ptr = newpoints; for (i = 0; i < npoints; i++) { size = ptarray_point_size(points[i]->point); memcpy(ptr, getPoint_internal(points[i]->point, 0), size); ptr += ptsize; } pa = ptarray_construct_reference_data(zmflag&2, zmflag&1, npoints, newpoints); return lwcircstring_construct(srid, NULL, pa); }
/* * Construct a LWCIRCSTRING from an array of LWPOINTs * LWCIRCSTRING dimensions are large enough to host all input dimensions. */ LWCIRCSTRING * lwcircstring_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points) { int zmflag=0; unsigned int i; POINTARRAY *pa; uchar *newpoints, *ptr; size_t ptsize, size; /* * Find output dimensions, check integrity */ for (i = 0; i < npoints; i++) { if (TYPE_GETTYPE(points[i]->type) != POINTTYPE) { lwerror("lwcurve_from_lwpointarray: invalid input type: %s", lwgeom_typename(TYPE_GETTYPE(points[i]->type))); return NULL; } if (TYPE_HASZ(points[i]->type)) zmflag |= 2; if (TYPE_HASM(points[i]->type)) zmflag |=1; if (zmflag == 3) break; } if (zmflag == 0) ptsize = 2 * sizeof(double); else if (zmflag == 3) ptsize = 4 * sizeof(double); else ptsize = 3 * sizeof(double); /* * Allocate output points array */ size = ptsize * npoints; newpoints = lwalloc(size); memset(newpoints, 0, size); ptr = newpoints; for (i = 0; i < npoints; i++) { size = pointArray_ptsize(points[i]->point); memcpy(ptr, getPoint_internal(points[i]->point, 0), size); ptr += ptsize; } pa = pointArray_construct(newpoints, zmflag&2, zmflag&1, npoints); return lwcircstring_construct(SRID, NULL, pa); }
/** * CIRCULARSTRING * Read a WKB circularstring, starting just after the endian byte, * type number and optional srid number. Advance the parse state * forward appropriately. * There is only one pointarray in a linestring. Optionally * check for minimal following of rules (three point minimum, * odd number of points). */ static LWCIRCSTRING* lwcircstring_from_wkb_state(wkb_parse_state *s) { POINTARRAY *pa = ptarray_from_wkb_state(s); if( pa == NULL || pa->npoints == 0 ) return lwcircstring_construct_empty(s->srid, s->has_z, s->has_m); if( s->check & LW_PARSER_CHECK_MINPOINTS && pa->npoints < 3 ) { lwerror("%s must have at least three points", lwtype_name(s->lwtype)); return NULL; } if( s->check & LW_PARSER_CHECK_ODD && ! (pa->npoints % 2) ) { lwerror("%s must have an odd number of points", lwtype_name(s->lwtype)); return NULL; } return lwcircstring_construct(s->srid, NULL, pa); }
/* * TODO: Invalid segmentization. This should accomodate the curvature. */ LWCIRCSTRING * lwcircstring_segmentize2d(LWCIRCSTRING *curve, double dist) { return lwcircstring_construct(curve->SRID, NULL, ptarray_segmentize2d(curve->points, dist)); }