我试图为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)¢roid;
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(¢roid,&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