]> granicus.if.org Git - postgis/commitdiff
PROJ6: Use proj_trans for single points
authorRaúl Marín Rodríguez <rmrodriguez@carto.com>
Wed, 19 Jun 2019 15:19:31 +0000 (15:19 +0000)
committerRaúl Marín Rodríguez <rmrodriguez@carto.com>
Wed, 19 Jun 2019 15:19:31 +0000 (15:19 +0000)
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

liblwgeom/lwgeom_transform.c
libpgcommon/lwgeom_cache.h

index 59154ff888fbc8c22c7b6f6886470feb845eb952..b7e9636128ec99d191a0ac18ac62f2bf7cddc93c 100644 (file)
@@ -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)
index 034e494c5d33f005a717e940a41410a5334cb106..4a5c88531aca28c4ae51b26f97d8133ee66c6e49 100644 (file)
@@ -84,7 +84,7 @@ typedef struct struct_PROJPortalCache
 {
        int type;
        PROJSRSCacheItem PROJSRSCache[PROJ_CACHE_ITEMS];
-       int PROJSRSCacheCount;
+       uint32_t PROJSRSCacheCount;
        MemoryContext PROJSRSCacheContext;
 }
 PROJPortalCache;