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
View
@@ -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.