From 2586506225a4cfc65f3869d969bbafe98865c7a7 Mon Sep 17 00:00:00 2001 From: Thomas Bonfort Date: Wed, 11 Apr 2012 16:57:02 +0200 Subject: [PATCH] implement shortcutting proj.4 for 4326->3857 transforms --- configure | 21 +++++++++++++++++++++ configure.in | 11 +++++++++++ mapcopy.c | 1 + mapfile.c | 10 ++++++++++ mapproject.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ mapproject.h | 5 +++++ 6 files changed, 96 insertions(+) diff --git a/configure b/configure index 853ba2b7ce..ffce16671b 100755 --- a/configure +++ b/configure @@ -639,6 +639,7 @@ PHP_REGEX_INC PHP_VERSION_FLAG PHPCONFIG DEBUG_FLAGS +PROJ_FASTPATH_ENABLED USE_NINT USE_POINT_Z_M IGNORE_MISSING_DATA @@ -898,6 +899,7 @@ enable_ignore_missing_data enable_point_z_m with_warnings enable_debug +enable_proj_fastpath enable_cgi_cl_debug_args enable_gcov with_php @@ -1550,6 +1552,8 @@ Optional Features: --disable-fast-nint Use safe MS_NINT with reliable rounding --enable-debug Include "-g" in CFLAGS for debugging. --disable-debug Do not include "-g" in CFLAGS (the default). + --enable-proj-fastpath bypass proj.4 for epsg:4326 to epsg:3857 + reprojections --enable-cgi-cl-debug-args Enable mapserv CGI command-line debug arguments (disabled by default). These command-line args may @@ -21972,6 +21976,21 @@ else CFLAGS=`echo "$CFLAGS -DNDEBUG " | sed "s/-g //"` fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable proj shortcuts..." >&5 +$as_echo "$as_me: checking whether to enable proj shortcuts..." >&6;} +# Check whether --enable-proj-fastpath was given. +if test "${enable_proj_fastpath+set}" = set; then : + enableval=$enable_proj_fastpath; +fi + + +if test "$enable_proj_fastpath" = "yes" ; then + PROJ_FASTPATH_ENABLED="-DUSE_PROJ_FASTPATHS" + ALL_ENABLED="$PROJ_FASTPATH_ENABLED $ALL_ENABLED" +fi +PROJ_FASTPATH_ENABLED=$PROJ_FASTPATH_ENABLED + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we should enable mapserv CGI command-line debug arguments..." >&5 $as_echo "$as_me: checking whether we should enable mapserv CGI command-line debug arguments..." >&6;} @@ -25153,6 +25172,8 @@ $as_echo "" >&6; } $as_echo " -------------- Support Libraries --------- " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Proj.4 support: ${PROJ_ENABLED}" >&5 $as_echo " Proj.4 support: ${PROJ_ENABLED}" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Proj Fastpaths: ${PROJ_FASTPATH_ENABLED}" >&5 +$as_echo " Proj Fastpaths: ${PROJ_FASTPATH_ENABLED}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Libxml2 support: ${XML2_ENABLED}" >&5 $as_echo " Libxml2 support: ${XML2_ENABLED}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: FriBidi support: ${FRIBIDI_ENABLED}" >&5 diff --git a/configure.in b/configure.in index 83e72c2080..ac71ed17da 100755 --- a/configure.in +++ b/configure.in @@ -2529,6 +2529,16 @@ else CFLAGS=`echo "$CFLAGS -DNDEBUG " | sed "s/-g //"` fi +AC_CHECKING(whether to enable proj shortcuts) +AC_ARG_ENABLE(proj-fastpath, + AC_HELP_STRING([--enable-proj-fastpath], [bypass proj.4 for epsg:4326 to epsg:3857 reprojections]),,) + +if test "$enable_proj_fastpath" = "yes" ; then + PROJ_FASTPATH_ENABLED="-DUSE_PROJ_FASTPATHS" + ALL_ENABLED="$PROJ_FASTPATH_ENABLED $ALL_ENABLED" +fi +AC_SUBST(PROJ_FASTPATH_ENABLED,$PROJ_FASTPATH_ENABLED) + dnl --------------------------------------------------------------------- dnl Check --enable-cgi-cl-debug-args option (OFF by default) dnl --------------------------------------------------------------------- @@ -2836,6 +2846,7 @@ AC_MSG_RESULT() AC_MSG_RESULT([ -------------- Support Libraries --------- ]) AC_MSG_RESULT([ Proj.4 support: ${PROJ_ENABLED}]) +AC_MSG_RESULT([ Proj Fastpaths: ${PROJ_FASTPATH_ENABLED}]) AC_MSG_RESULT([ Libxml2 support: ${XML2_ENABLED}]) AC_MSG_RESULT([ FriBidi support: ${FRIBIDI_ENABLED}]) AC_MSG_RESULT([ Curl support: ${CURL_ENABLED}]) diff --git a/mapcopy.c b/mapcopy.c index 3eefd53a1b..ee92aba241 100644 --- a/mapcopy.c +++ b/mapcopy.c @@ -72,6 +72,7 @@ int msCopyProjection(projectionObj *dst, projectionObj *src) { } #endif + MS_COPYSTELEM(wellknownprojection); return MS_SUCCESS; } diff --git a/mapfile.c b/mapfile.c index a56731ddbc..91fb3105de 100644 --- a/mapfile.c +++ b/mapfile.c @@ -1308,7 +1308,17 @@ int msLoadProjectionStringEPSG(projectionObj *p, const char *value) #ifdef USE_PROJ if(p) msFreeProjection(p); +#ifdef USE_FASTPATH_PROJS p->gt.need_geotransform = MS_FALSE; + if(strcasestr(value,"epsg:4326")) { + p->wellknownprojection = wkp_lonlat; + } else if(strcasestr(value,"epsg:3857")) { + p->wellknownprojection = wkp_gmerc; + } else { + p->wellknownprojection = wkp_none; + } +#endif + if (strncasecmp(value, "EPSG:", 5) == 0) { diff --git a/mapproject.c b/mapproject.c index c7d3100989..9db0f717c2 100644 --- a/mapproject.c +++ b/mapproject.c @@ -292,6 +292,30 @@ msProjectShapeLine(projectionObj *in, projectionObj *out, int line_alloc = numpoints_in; int wrap_test; +#ifdef USE_PROJ_FASTPATHS +#define MAXEXTENT 20037508.34 +#define M_PIby360 .0087266462599716479 +#define MAXEXTENTby180 111319.4907777777777777777 + if(in->wellknownprojection == wkp_lonlat && out->wellknownprojection == wkp_gmerc) { + for( i = line->numpoints-1; i >= 0; i-- ) { +#define p_x line->point[i].x +#define p_y line->point[i].y + p_x *= MAXEXTENTby180; + p_y = log(tan((90 + p_y) * M_PIby360)) * MS_RAD_TO_DEG; + p_y *= MAXEXTENTby180; + if (p_x > MAXEXTENT) p_x = MAXEXTENT; + if (p_x < -MAXEXTENT) p_x = -MAXEXTENT; + if (p_y > MAXEXTENT) p_y = MAXEXTENT; + if (p_y < -MAXEXTENT) p_y = -MAXEXTENT; +#undef p_x +#undef p_y + } + return MS_SUCCESS; + } +#endif + + + wrap_test = out != NULL && out->proj != NULL && pj_is_latlong(out->proj) && !pj_is_latlong(in->proj); @@ -473,6 +497,30 @@ int msProjectShape(projectionObj *in, projectionObj *out, shapeObj *shape) { #ifdef USE_PROJ int i; +#ifdef USE_PROJ_FASTPATHS + int j; + + if(in->wellknownprojection == wkp_lonlat && out->wellknownprojection == wkp_gmerc) { + for( i = shape->numlines-1; i >= 0; i-- ) { + for( j = shape->line[i].numpoints-1; j >= 0; j-- ) { +#define p_x shape->line[i].point[j].x +#define p_y shape->line[i].point[j].y + p_x *= MAXEXTENTby180; + p_y = log(tan((90 + p_y) * M_PIby360)) * MS_RAD_TO_DEG; + p_y *= MAXEXTENTby180; + if (p_x > MAXEXTENT) p_x = MAXEXTENT; + if (p_x < -MAXEXTENT) p_x = -MAXEXTENT; + if (p_y > MAXEXTENT) p_y = MAXEXTENT; + if (p_y < -MAXEXTENT) p_y = -MAXEXTENT; +#undef p_x +#undef p_y + } + } + return MS_SUCCESS; + } +#endif + + for( i = shape->numlines-1; i >= 0; i-- ) { diff --git a/mapproject.h b/mapproject.h index 9056301fd9..d2e384f524 100644 --- a/mapproject.h +++ b/mapproject.h @@ -41,6 +41,10 @@ extern "C" { # include #endif +#define wkp_none 0 +#define wkp_lonlat 1 +#define wkp_gmerc 2 + typedef struct { #ifdef SWIG @@ -63,6 +67,7 @@ typedef struct { #endif geotransformObj gt; /* extra transformation to apply */ #endif + int wellknownprojection; } projectionObj; #ifndef SWIG