From: Raúl Marín Rodríguez Date: Wed, 19 Jun 2019 15:19:31 +0000 (+0000) Subject: PROJ6: Use proj_trans for single points X-Git-Tag: 3.0.0alpha3~23 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3a238bc9409070b10ed4c69d9acf41a3179a0049;p=postgis PROJ6: Use proj_trans for single points It's slighly faster to use it for single points, and improves it to match PROJ5 performance References #4372 git-svn-id: http://svn.osgeo.org/postgis/trunk@17545 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/lwgeom_transform.c b/liblwgeom/lwgeom_transform.c index 59154ff88..b7e963612 100644 --- a/liblwgeom/lwgeom_transform.c +++ b/liblwgeom/lwgeom_transform.c @@ -442,7 +442,7 @@ ptarray_transform(POINTARRAY *pa, LWPROJ *pj) double *pa_double = (double*)(pa->serialized_pointlist); /* Convert to radians if necessary */ - if (proj_angular_input(pj->pj, PJ_FWD)) /* CACHE THIS TOO */ + if (proj_angular_input(pj->pj, PJ_FWD)) { for (i = 0; i < pa->npoints; i++) { @@ -454,43 +454,61 @@ ptarray_transform(POINTARRAY *pa, LWPROJ *pj) if (pj->source_swapped) ptarray_swap_ordinates(pa, LWORD_X, LWORD_Y); - /* - * size_t proj_trans_generic(PJ *P, PJ_DIRECTION direction, - * double *x, size_t sx, size_t nx, - * double *y, size_t sy, size_t ny, - * double *z, size_t sz, size_t nz, - * double *t, size_t st, size_t nt) - */ - - n_converted = proj_trans_generic(pj->pj, - PJ_FWD, - pa_double, - point_size, - n_points, /* X */ - pa_double + 1, - point_size, - n_points, /* Y */ - has_z ? pa_double + 2 : NULL, - has_z ? point_size : 0, - has_z ? n_points : 0, /* Z */ - NULL, - 0, - 0 /* M */ - ); - - if (n_converted != n_points) + if (n_points == 1) { - lwerror("ptarray_transform: converted (%d) != input (%d)", - n_converted, n_points); - return LW_FAILURE; - } + /* For single points it's faster to call proj_trans */ + PJ_XYZT v = {pa_double[0], pa_double[1], has_z ? pa_double[2] : 0.0, 0.0}; + PJ_COORD t = proj_trans(pj->pj, PJ_FWD, (PJ_COORD)v); - int pj_errno_val = proj_errno(pj->pj); - if (pj_errno_val) + int pj_errno_val = proj_errno(pj->pj); + if (pj_errno_val) + { + lwerror("transform: %s (%d)", proj_errno_string(pj_errno_val), pj_errno_val); + return LW_FAILURE; + } + pa_double[0] = ((PJ_XYZT)t.xyzt).x; + pa_double[1] = ((PJ_XYZT)t.xyzt).y; + if (has_z) + pa_double[2] = ((PJ_XYZT)t.xyzt).z; + } + else { - lwerror("transform: %s (%d)", - proj_errno_string(pj_errno_val), pj_errno_val); - return LW_FAILURE; + /* + * size_t proj_trans_generic(PJ *P, PJ_DIRECTION direction, + * double *x, size_t sx, size_t nx, + * double *y, size_t sy, size_t ny, + * double *z, size_t sz, size_t nz, + * double *t, size_t st, size_t nt) + */ + + n_converted = proj_trans_generic(pj->pj, + PJ_FWD, + pa_double, + point_size, + n_points, /* X */ + pa_double + 1, + point_size, + n_points, /* Y */ + has_z ? pa_double + 2 : NULL, + has_z ? point_size : 0, + has_z ? n_points : 0, /* Z */ + NULL, + 0, + 0 /* M */ + ); + + if (n_converted != n_points) + { + lwerror("ptarray_transform: converted (%d) != input (%d)", n_converted, n_points); + return LW_FAILURE; + } + + int pj_errno_val = proj_errno(pj->pj); + if (pj_errno_val) + { + lwerror("transform: %s (%d)", proj_errno_string(pj_errno_val), pj_errno_val); + return LW_FAILURE; + } } if (pj->target_swapped) diff --git a/libpgcommon/lwgeom_cache.h b/libpgcommon/lwgeom_cache.h index 034e494c5..4a5c88531 100644 --- a/libpgcommon/lwgeom_cache.h +++ b/libpgcommon/lwgeom_cache.h @@ -84,7 +84,7 @@ typedef struct struct_PROJPortalCache { int type; PROJSRSCacheItem PROJSRSCache[PROJ_CACHE_ITEMS]; - int PROJSRSCacheCount; + uint32_t PROJSRSCacheCount; MemoryContext PROJSRSCacheContext; } PROJPortalCache;