在postgresql中为POINT3DZ

时间:2017-07-29 13:22:13

标签: c postgresql postgis postgresql-9.4

我试图为3d点编写自己的索引 - POINT3DZ(使用pgis和postgres 9.4)。 我编写了类似于spgquadtreeproc.c [1]

的代码

这是我的spg_quad_point3dz_picksplit功能:

PG_FUNCTION_INFO_V1(spg_quad_point3dz_picksplit);
/* Decides how to create a new inner tuple over a set of leaf tuples. */
Datum
spg_quad_point3dz_picksplit(PG_FUNCTION_ARGS){
    spgPickSplitIn *in = (spgPickSplitIn *) PG_GETARG_POINTER(0);
    spgPickSplitOut *out = (spgPickSplitOut *) PG_GETARG_POINTER(1);
    int i;
    POINT3DZ centroid, ctemp;

#ifdef USE_MEDIAN
    /* Use the median values of x and y as the centroid point */
    POINT3DZ      **sorted;

    sorted = palloc(sizeof(*sorted) * in->nTuples);
    for (i = 0; i < in->nTuples-1; i++){
        datumGetPoint3dzP(in->datums[i], sorted[i]);
    }

    centroid = palloc(sizeof(*centroid));

    qsort(sorted, in->nTuples, sizeof(*sorted), x_cmp);
    centroid->x = sorted[in->nTuples >> 1]->x;
    qsort(sorted, in->nTuples, sizeof(*sorted), y_cmp);
    centroid->y = sorted[in->nTuples >> 1]->y;
#else
    /* Use the average values of x and y as the centroid point */

    for (i = 0; i < in->nTuples; i++)
    {
        datumGetPoint3dzP(in->datums[i],&ctemp);
        centroid.x += ctemp.x;
        centroid.y += ctemp.y;
    }
    centroid.x /= in->nTuples;
    centroid.y /= in->nTuples;
#endif

    out->hasPrefix = true;
    out->prefixDatum = (Datum)&centroid;
    out->nNodes = 4;
    out->nodeLabels = NULL;     /* we don't need node labels */
    out->mapTuplesToNodes = palloc(sizeof(int) * in->nTuples);
    out->leafTupleDatums = palloc(sizeof(Datum) * in->nTuples);

    for (i = 0; i < in->nTuples; i++)   {
        POINT3DZ p;
        datumGetPoint3dzP(in->datums[i], &p);

        int quadrant = getQuadrant(&centroid,&p);

        out->leafTupleDatums[i] = (Datum)&p;
        out->mapTuplesToNodes[i] = quadrant- 1;
    }

    PG_RETURN_VOID();
} 

没有定义Constans USE_MEDIAN所以在函数中从函数顶部执行行,next - 从else到endif的行,最后是其余的代码。 不幸的是,第一个for循环工作正常,但第二个在执行datumGetPoint3dzP时出错。

这就是datumGetPoint3dzP函数的内部结构:

void datumGetPoint3dzP(Datum dt, POINT3DZ *p){
    GSERIALIZED *geom;
    LWGEOM *lwgeom;
    LWPOINT *point = NULL;
    geom = (GSERIALIZED *)PG_DETOAST_DATUM(dt);
    if ( gserialized_get_type(geom) != POINTTYPE )
        lwerror("Argument to X() must be a point");
    lwgeom = lwgeom_from_gserialized(geom);
    point = lwgeom_as_lwpoint(lwgeom);
    getPoint3dz_p(point->point, 0, p);
}

我在调试中发现在调用getPoint3dz_p时发生错误。

getPoint3dz_p是PostGIS(lwgeom)[2]

中的一个函数

ERROR:

CREATE INDEX example_sensors_index1 ON sensors_data USING spgist( geom geometry_point3dz_ops );
DEBUG:  StartTransactionCommand
DEBUG:  StartTransaction
DEBUG:  name: unnamed; blockState:       DEFAULT; state: INPROGR, xid/subid/cid: 0/1/0, nestlvl: 1, children: 
DEBUG:  ProcessUtility
DEBUG:  Creating index "example_sensors_index1" on table "sensors_data"
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.

日志: 一些消息是波兰语。对于每个人,我在每条消息下都发布了翻译。 以下是我的日志的一部分:https://pastebin.com/dYyb0tFb

你遇到过这样的错误吗?如何正确修复此代码?提前感谢您的帮助。

链接:
[1] 37.187.79.115/postgresql-9.4beta3/src/backend/access/spgist/spgquadtreeproc.c
[2] http://postgis.net/docs/doxygen/2.1/da/de7/liblwgeom_8h_acfc410375b25ddd41feec1b7337173c6.html

0 个答案:

没有答案