Skip to content

Commit eeb1e78

Browse files
committed
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.
1 parent 6f1b34a commit eeb1e78

File tree

1 file changed

+89
-1
lines changed

1 file changed

+89
-1
lines changed

mapproject.c

+89-1
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,69 @@ int msProjectRect(projectionObj *in, projectionObj *out, rectObj *rect)
986986
#endif
987987
}
988988

989+
#ifdef USE_PROJ
990+
static int msProjectSortString(const void* firstelt, const void* secondelt)
991+
{
992+
char* firststr = *(char**)firstelt;
993+
char* secondstr = *(char**)secondelt;
994+
return strcmp(firststr, secondstr);
995+
}
996+
997+
/************************************************************************/
998+
/* msGetProjectNormalized() */
999+
/************************************************************************/
1000+
1001+
static projectionObj* msGetProjectNormalized( const projectionObj* p )
1002+
{
1003+
int i;
1004+
char* pszNewProj4Def;
1005+
projectionObj* pnew;
1006+
1007+
pnew = (projectionObj*)msSmallMalloc(sizeof(projectionObj));
1008+
msInitProjection(pnew);
1009+
msCopyProjection(pnew, (projectionObj*)p);
1010+
1011+
if(p->proj == NULL )
1012+
return pnew;
1013+
1014+
/* Normalize definition so that msProjectDiffers() works better */
1015+
pszNewProj4Def = pj_get_def( p->proj, 0 );
1016+
msFreeCharArray(pnew->args, pnew->numargs);
1017+
pnew->args = msStringSplit(pszNewProj4Def,'+', &pnew->numargs);
1018+
for(i = 0; i < pnew->numargs; i++)
1019+
{
1020+
/* Remove trailing space */
1021+
if( strlen(pnew->args[i]) > 0 && pnew->args[i][strlen(pnew->args[i])-1] == ' ' )
1022+
pnew->args[i][strlen(pnew->args[i])-1] = '\0';
1023+
/* Remove spurious no_defs or init= */
1024+
if( strcmp(pnew->args[i], "no_defs") == 0 ||
1025+
strncmp(pnew->args[i], "init=", 5) == 0 )
1026+
{
1027+
if( i < pnew->numargs - 1 )
1028+
{
1029+
msFree(pnew->args[i]);
1030+
memmove(pnew->args + i, pnew->args + i + 1,
1031+
sizeof(char*) * (pnew->numargs - 1 -i ));
1032+
}
1033+
pnew->numargs --;
1034+
i --;
1035+
continue;
1036+
}
1037+
}
1038+
/* Sort the strings so they can be compared */
1039+
qsort(pnew->args, pnew->numargs, sizeof(char*), msProjectSortString);
1040+
/*{
1041+
fprintf(stderr, "'%s' =\n", pszNewProj4Def);
1042+
for(i = 0; i < p->numargs; i++)
1043+
fprintf(stderr, "'%s' ", p->args[i]);
1044+
fprintf(stderr, "\n");
1045+
}*/
1046+
pj_dalloc(pszNewProj4Def);
1047+
1048+
return pnew;
1049+
}
1050+
#endif /* USE_PROJ */
1051+
9891052
/************************************************************************/
9901053
/* msProjectionsDiffer() */
9911054
/************************************************************************/
@@ -1001,7 +1064,7 @@ int msProjectRect(projectionObj *in, projectionObj *out, rectObj *rect)
10011064
** has no arguments, since reprojection won't work anyways.
10021065
*/
10031066

1004-
int msProjectionsDiffer( projectionObj *proj1, projectionObj *proj2 )
1067+
static int msProjectionsDifferInternal( projectionObj *proj1, projectionObj *proj2 )
10051068

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

1091+
int msProjectionsDiffer( projectionObj *proj1, projectionObj *proj2 )
1092+
{
1093+
#ifdef USE_PROJ
1094+
int ret;
1095+
1096+
ret = msProjectionsDifferInternal(proj1, proj2);
1097+
if( ret )
1098+
{
1099+
projectionObj* p1normalized;
1100+
projectionObj* p2normalized;
1101+
1102+
p1normalized = msGetProjectNormalized( proj1 );
1103+
p2normalized = msGetProjectNormalized( proj2 );
1104+
ret = msProjectionsDifferInternal(p1normalized, p2normalized);
1105+
msFreeProjection(p1normalized);
1106+
msFree(p1normalized);
1107+
msFreeProjection(p2normalized);
1108+
msFree(p2normalized);
1109+
}
1110+
return ret;
1111+
#else
1112+
return msProjectionsDifferInternal(proj1, proj2);
1113+
#endif
1114+
}
1115+
10281116
/************************************************************************/
10291117
/* msTestNeedWrap() */
10301118
/************************************************************************/

0 commit comments

Comments
 (0)