/**********************************************************************
*
* rttopo - topology library
* http://git.osgeo.org/gitea/rttopo/librttopo
*
* rttopo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* rttopo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rttopo. If not, see .
*
**********************************************************************
*
* Copyright (C) 2001-2006 Refractions Research Inc.
*
**********************************************************************/
#include
#include
#include
#include "rttopo_config.h"
/*#define RTGEOM_DEBUG_LEVEL 4*/
#include "librttopo_geom_internal.h"
#include "rtgeom_log.h"
/*
* Convenience functions to hide the RTPOINTARRAY
* TODO: obsolete this
*/
int
rtpoint_getPoint2d_p(const RTCTX *ctx, const RTPOINT *point, RTPOINT2D *out)
{
return rt_getPoint2d_p(ctx, point->point, 0, out);
}
/* convenience functions to hide the RTPOINTARRAY */
int
rtpoint_getPoint3dz_p(const RTCTX *ctx, const RTPOINT *point, RTPOINT3DZ *out)
{
return rt_getPoint3dz_p(ctx, point->point,0,out);
}
int
rtpoint_getPoint3dm_p(const RTCTX *ctx, const RTPOINT *point, RTPOINT3DM *out)
{
return rt_getPoint3dm_p(ctx, point->point,0,out);
}
int
rtpoint_getPoint4d_p(const RTCTX *ctx, const RTPOINT *point, RTPOINT4D *out)
{
return rt_getPoint4d_p(ctx, point->point,0,out);
}
double
rtpoint_get_x(const RTCTX *ctx, const RTPOINT *point)
{
RTPOINT4D pt;
if ( rtpoint_is_empty(ctx, point) )
rterror(ctx, "rtpoint_get_x called with empty geometry");
rt_getPoint4d_p(ctx, point->point, 0, &pt);
return pt.x;
}
double
rtpoint_get_y(const RTCTX *ctx, const RTPOINT *point)
{
RTPOINT4D pt;
if ( rtpoint_is_empty(ctx, point) )
rterror(ctx, "rtpoint_get_y called with empty geometry");
rt_getPoint4d_p(ctx, point->point, 0, &pt);
return pt.y;
}
double
rtpoint_get_z(const RTCTX *ctx, const RTPOINT *point)
{
RTPOINT4D pt;
if ( rtpoint_is_empty(ctx, point) )
rterror(ctx, "rtpoint_get_z called with empty geometry");
if ( ! RTFLAGS_GET_Z(point->flags) )
rterror(ctx, "rtpoint_get_z called without z dimension");
rt_getPoint4d_p(ctx, point->point, 0, &pt);
return pt.z;
}
double
rtpoint_get_m(const RTCTX *ctx, const RTPOINT *point)
{
RTPOINT4D pt;
if ( rtpoint_is_empty(ctx, point) )
rterror(ctx, "rtpoint_get_m called with empty geometry");
if ( ! RTFLAGS_GET_M(point->flags) )
rterror(ctx, "rtpoint_get_m called without m dimension");
rt_getPoint4d_p(ctx, point->point, 0, &pt);
return pt.m;
}
/*
* Construct a new point. point will not be copied
* use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
*/
RTPOINT *
rtpoint_construct(const RTCTX *ctx, int srid, RTGBOX *bbox, RTPOINTARRAY *point)
{
RTPOINT *result;
uint8_t flags = 0;
if (point == NULL)
return NULL; /* error */
result = rtalloc(ctx, sizeof(RTPOINT));
result->type = RTPOINTTYPE;
RTFLAGS_SET_Z(flags, RTFLAGS_GET_Z(point->flags));
RTFLAGS_SET_M(flags, RTFLAGS_GET_M(point->flags));
RTFLAGS_SET_BBOX(flags, bbox?1:0);
result->flags = flags;
result->srid = srid;
result->point = point;
result->bbox = bbox;
return result;
}
RTPOINT *
rtpoint_construct_empty(const RTCTX *ctx, int srid, char hasz, char hasm)
{
RTPOINT *result = rtalloc(ctx, sizeof(RTPOINT));
result->type = RTPOINTTYPE;
result->flags = gflags(ctx, hasz, hasm, 0);
result->srid = srid;
result->point = ptarray_construct(ctx, hasz, hasm, 0);
result->bbox = NULL;
return result;
}
RTPOINT *
rtpoint_make2d(const RTCTX *ctx, int srid, double x, double y)
{
RTPOINT4D p = {x, y, 0.0, 0.0};
RTPOINTARRAY *pa = ptarray_construct_empty(ctx, 0, 0, 1);
ptarray_append_point(ctx, pa, &p, RT_TRUE);
return rtpoint_construct(ctx, srid, NULL, pa);
}
RTPOINT *
rtpoint_make3dz(const RTCTX *ctx, int srid, double x, double y, double z)
{
RTPOINT4D p = {x, y, z, 0.0};
RTPOINTARRAY *pa = ptarray_construct_empty(ctx, 1, 0, 1);
ptarray_append_point(ctx, pa, &p, RT_TRUE);
return rtpoint_construct(ctx, srid, NULL, pa);
}
RTPOINT *
rtpoint_make3dm(const RTCTX *ctx, int srid, double x, double y, double m)
{
RTPOINT4D p = {x, y, 0.0, m};
RTPOINTARRAY *pa = ptarray_construct_empty(ctx, 0, 1, 1);
ptarray_append_point(ctx, pa, &p, RT_TRUE);
return rtpoint_construct(ctx, srid, NULL, pa);
}
RTPOINT *
rtpoint_make4d(const RTCTX *ctx, int srid, double x, double y, double z, double m)
{
RTPOINT4D p = {x, y, z, m};
RTPOINTARRAY *pa = ptarray_construct_empty(ctx, 1, 1, 1);
ptarray_append_point(ctx, pa, &p, RT_TRUE);
return rtpoint_construct(ctx, srid, NULL, pa);
}
RTPOINT *
rtpoint_make(const RTCTX *ctx, int srid, int hasz, int hasm, const RTPOINT4D *p)
{
RTPOINTARRAY *pa = ptarray_construct_empty(ctx, hasz, hasm, 1);
ptarray_append_point(ctx, pa, p, RT_TRUE);
return rtpoint_construct(ctx, srid, NULL, pa);
}
void rtpoint_free(const RTCTX *ctx, RTPOINT *pt)
{
if ( ! pt ) return;
if ( pt->bbox )
rtfree(ctx, pt->bbox);
if ( pt->point )
ptarray_free(ctx, pt->point);
rtfree(ctx, pt);
}
void printRTPOINT(const RTCTX *ctx, RTPOINT *point)
{
rtnotice(ctx, "RTPOINT {");
rtnotice(ctx, " ndims = %i", (int)RTFLAGS_NDIMS(point->flags));
rtnotice(ctx, " BBOX = %i", RTFLAGS_GET_BBOX(point->flags) ? 1 : 0 );
rtnotice(ctx, " SRID = %i", (int)point->srid);
printPA(ctx, point->point);
rtnotice(ctx, "}");
}
/* @brief Clone RTPOINT object. Serialized point lists are not copied.
*
* @see ptarray_clone
*/
RTPOINT *
rtpoint_clone(const RTCTX *ctx, const RTPOINT *g)
{
RTPOINT *ret = rtalloc(ctx, sizeof(RTPOINT));
RTDEBUG(ctx, 2, "rtpoint_clone called");
memcpy(ret, g, sizeof(RTPOINT));
ret->point = ptarray_clone(ctx, g->point);
if ( g->bbox ) ret->bbox = gbox_copy(ctx, g->bbox);
return ret;
}
void
rtpoint_release(const RTCTX *ctx, RTPOINT *rtpoint)
{
rtgeom_release(ctx, rtpoint_as_rtgeom(ctx, rtpoint));
}
/* check coordinate equality */
char
rtpoint_same(const RTCTX *ctx, const RTPOINT *p1, const RTPOINT *p2)
{
return ptarray_same(ctx, p1->point, p2->point);
}
RTPOINT*
rtpoint_force_dims(const RTCTX *ctx, const RTPOINT *point, int hasz, int hasm)
{
RTPOINTARRAY *pdims = NULL;
RTPOINT *pointout;
/* Return 2D empty */
if( rtpoint_is_empty(ctx, point) )
{
pointout = rtpoint_construct_empty(ctx, point->srid, hasz, hasm);
}
else
{
/* Artays we duplicate the ptarray and return */
pdims = ptarray_force_dims(ctx, point->point, hasz, hasm);
pointout = rtpoint_construct(ctx, point->srid, NULL, pdims);
}
pointout->type = point->type;
return pointout;
}
int rtpoint_is_empty(const RTCTX *ctx, const RTPOINT *point)
{
if ( ! point->point || point->point->npoints < 1 )
return RT_TRUE;
return RT_FALSE;
}
RTPOINT *
rtpoint_grid(const RTCTX *ctx, const RTPOINT *point, const gridspec *grid)
{
RTPOINTARRAY *opa = ptarray_grid(ctx, point->point, grid);
return rtpoint_construct(ctx, point->srid, NULL, opa);
}