Skip to content
Permalink
Browse files

msProjectionsDiffer(): use proj4 string normalization

If regular comparison detects a difference, then asks proj.4 to
return a proj string after it has resolved stuff like +init=epsg:XXXX.
This helps msDrawRasterLayerLow() figuring out that "init=epsg:3857"
and "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +units=m +k=1.0 +nadgrids=@null"
as defined in maptile.h are indeed the same projection, to avoid
going to the slow resampling path.

I have tried instead to put that normalization logic into msProcessProjection()
itself but altering the p->args cause issues in a number of other
places.
  • Loading branch information
rouault committed Dec 16, 2014
1 parent 6f1b34a commit eeb1e786a36e594ae8133f7a6d5b127175894952
Showing with 89 additions and 1 deletion.
  1. +89 −1 mapproject.c
@@ -986,6 +986,69 @@ int msProjectRect(projectionObj *in, projectionObj *out, rectObj *rect)
#endif
}

#ifdef USE_PROJ
static int msProjectSortString(const void* firstelt, const void* secondelt)
{
char* firststr = *(char**)firstelt;
char* secondstr = *(char**)secondelt;
return strcmp(firststr, secondstr);
}

/************************************************************************/
/* msGetProjectNormalized() */
/************************************************************************/

static projectionObj* msGetProjectNormalized( const projectionObj* p )
{
int i;
char* pszNewProj4Def;
projectionObj* pnew;

pnew = (projectionObj*)msSmallMalloc(sizeof(projectionObj));
msInitProjection(pnew);
msCopyProjection(pnew, (projectionObj*)p);

if(p->proj == NULL )
return pnew;

/* Normalize definition so that msProjectDiffers() works better */
pszNewProj4Def = pj_get_def( p->proj, 0 );
msFreeCharArray(pnew->args, pnew->numargs);
pnew->args = msStringSplit(pszNewProj4Def,'+', &pnew->numargs);
for(i = 0; i < pnew->numargs; i++)
{
/* Remove trailing space */
if( strlen(pnew->args[i]) > 0 && pnew->args[i][strlen(pnew->args[i])-1] == ' ' )
pnew->args[i][strlen(pnew->args[i])-1] = '\0';
/* Remove spurious no_defs or init= */
if( strcmp(pnew->args[i], "no_defs") == 0 ||
strncmp(pnew->args[i], "init=", 5) == 0 )
{
if( i < pnew->numargs - 1 )
{
msFree(pnew->args[i]);
memmove(pnew->args + i, pnew->args + i + 1,
sizeof(char*) * (pnew->numargs - 1 -i ));
}
pnew->numargs --;
i --;
continue;
}
}
/* Sort the strings so they can be compared */
qsort(pnew->args, pnew->numargs, sizeof(char*), msProjectSortString);
/*{
fprintf(stderr, "'%s' =\n", pszNewProj4Def);
for(i = 0; i < p->numargs; i++)
fprintf(stderr, "'%s' ", p->args[i]);
fprintf(stderr, "\n");
}*/
pj_dalloc(pszNewProj4Def);

return pnew;
}
#endif /* USE_PROJ */

/************************************************************************/
/* msProjectionsDiffer() */
/************************************************************************/
@@ -1001,7 +1064,7 @@ int msProjectRect(projectionObj *in, projectionObj *out, rectObj *rect)
** has no arguments, since reprojection won't work anyways.
*/

int msProjectionsDiffer( projectionObj *proj1, projectionObj *proj2 )
static int msProjectionsDifferInternal( projectionObj *proj1, projectionObj *proj2 )

{
int i;
@@ -1025,6 +1088,31 @@ int msProjectionsDiffer( projectionObj *proj1, projectionObj *proj2 )
return MS_FALSE;
}

int msProjectionsDiffer( projectionObj *proj1, projectionObj *proj2 )
{
#ifdef USE_PROJ
int ret;

ret = msProjectionsDifferInternal(proj1, proj2);
if( ret )
{
projectionObj* p1normalized;
projectionObj* p2normalized;

p1normalized = msGetProjectNormalized( proj1 );
p2normalized = msGetProjectNormalized( proj2 );
ret = msProjectionsDifferInternal(p1normalized, p2normalized);
msFreeProjection(p1normalized);
msFree(p1normalized);
msFreeProjection(p2normalized);
msFree(p2normalized);
}
return ret;
#else
return msProjectionsDifferInternal(proj1, proj2);
#endif
}

/************************************************************************/
/* msTestNeedWrap() */
/************************************************************************/

0 comments on commit eeb1e78

Please sign in to comment.
You can’t perform that action at this time.