Permalink
Browse files

Fix dateline wrapping logic for bounding boxes (#4896)

- Fixes a typo in the shapefile wrapping code to compare a vertex
  against its predecessor rather than the initial vertex to detect
  potential dateline hops.
- Forces +over proj parameter when reprojecting bboxes in order to
  conserve the initial property of wether the bbox intersects the
  dateline.
  • Loading branch information...
tbonfort committed Mar 26, 2014
1 parent 079f816 commit 46a4feaa752bae2cab14f38d8411ac87da387087
Showing with 72 additions and 12 deletions.
  1. +19 −4 mapcopy.c
  2. +51 −7 mapproject.c
  3. +1 −0 mapserver.h
  4. +1 −1 msautotest
View
@@ -50,33 +50,48 @@
#include "mapcopy.h"
/***********************************************************************
* msCopyProjection() *
* msCopyProjectioExtended() *
* *
* Copy a projectionObj *
* Copy a projectionObj while adding additional arguments *
**********************************************************************/
int msCopyProjection(projectionObj *dst, projectionObj *src)
int msCopyProjectionExtended(projectionObj *dst, projectionObj *src, char ** args, int num_args)
{
#ifdef USE_PROJ
int i;
MS_COPYSTELEM(numargs);
MS_COPYSTELEM(gt);
MS_COPYSTELEM(automatic);
for (i = 0; i < dst->numargs; i++) {
/* Our destination consists of unallocated pointers */
dst->args[i] = msStrdup(src->args[i]);
}
for(i=0 ; i< num_args; i++) {
dst->args[dst->numargs++] = msStrdup(args[i]);
}
if (dst->numargs != 0) {
if (msProcessProjection(dst) != MS_SUCCESS)
return MS_FAILURE;
}
#endif
MS_COPYSTELEM(wellknownprojection);
return MS_SUCCESS;
}
/***********************************************************************
* msCopyProjection() *
* *
* Copy a projectionObj *
**********************************************************************/
int msCopyProjection(projectionObj *dst, projectionObj *src)
{
return msCopyProjectionExtended(dst,src,NULL,0);
}
/***********************************************************************
* msCopyLine() *
* *
View
@@ -292,7 +292,7 @@ msProjectShapeLine(projectionObj *in, projectionObj *out,
{
int i;
pointObj lastPoint, thisPoint, wrkPoint, firstPoint;
pointObj lastPoint, thisPoint, wrkPoint;
lineObj *line = shape->line + line_index;
lineObj *line_out = line;
int valid_flag = 0; /* 1=true, -1=false, 0=unknown */
@@ -342,9 +342,6 @@ msProjectShapeLine(projectionObj *in, projectionObj *out,
line->numpoints = 0;
if( numpoints_in > 0 )
firstPoint = line->point[0];
memset( &lastPoint, 0, sizeof(lastPoint) );
/* -------------------------------------------------------------------- */
@@ -364,13 +361,13 @@ msProjectShapeLine(projectionObj *in, projectionObj *out,
pointObj pt1Geo;
if( line_out->numpoints > 0 )
pt1Geo = line_out->point[0];
pt1Geo = line_out->point[line_out->numpoints-1];
else
pt1Geo = wrkPoint; /* this is a cop out */
dist = wrkPoint.x - pt1Geo.x;
if( fabs(dist) > 180.0
&& msTestNeedWrap( thisPoint, firstPoint,
&& msTestNeedWrap( thisPoint, lastPoint,
pt1Geo, in, out ) ) {
if( dist > 0.0 )
wrkPoint.x -= 360.0;
@@ -874,6 +871,14 @@ msProjectRectAsPolygon(projectionObj *in, projectionObj *out,
msAddLineDirectly( &polygonObj, &ring );
#ifdef notdef
FILE *wkt = fopen("/tmp/www-before.wkt","w");
char *tmp = msShapeToWKT(&polygonObj);
fprintf(wkt,"%s\n", tmp);
free(tmp);
fclose(wkt);
#endif
/* -------------------------------------------------------------------- */
/* Attempt to reproject. */
/* -------------------------------------------------------------------- */
@@ -885,6 +890,14 @@ msProjectRectAsPolygon(projectionObj *in, projectionObj *out,
return msProjectRectGrid( in, out, rect );
}
#ifdef notdef
wkt = fopen("/tmp/www-after.wkt","w");
tmp = msShapeToWKT(&polygonObj);
fprintf(wkt,"%s\n", tmp);
free(tmp);
fclose(wkt);
#endif
/* -------------------------------------------------------------------- */
/* Collect bounds. */
/* -------------------------------------------------------------------- */
@@ -930,7 +943,38 @@ int msProjectRect(projectionObj *in, projectionObj *out, rectObj *rect)
#ifdef notdef
return msProjectRectTraditionalEdge( in, out, rect );
#else
return msProjectRectAsPolygon( in, out, rect );
char *over = "+over";
int ret;
projectionObj in_over,out_over,*inp,*outp;
/*
* Issue #4892: When projecting a rectangle we do not want proj to wrap resulting
* coordinates around the dateline, as in practice a requested bounding box of
* -22.000.000, -YYY, 22.000.000, YYY should be projected as
* -190,-YYY,190,YYY rather than 170,-YYY,-170,YYY as would happen when wrapping (and
* vice-versa when projecting from lonlat to metric).
* To enforce this, we clone the input projections and add the "+over" proj
* parameter in order to disable dateline wrapping.
*/
if(out) {
msInitProjection(&out_over);
msCopyProjectionExtended(&out_over,out,&over,1);
outp = &out_over;
} else {
outp = out;
}
if(in) {
msInitProjection(&in_over);
msCopyProjectionExtended(&in_over,in,&over,1);
inp = &in_over;
} else {
inp = in;
}
ret = msProjectRectAsPolygon(inp,outp, rect );
if(in)
msFreeProjection(&in_over);
if(out)
msFreeProjection(&out_over);
return ret;
#endif
}
View
@@ -2729,6 +2729,7 @@ void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, char
MS_DLL_EXPORT int msCopyLabelLeader(labelLeaderObj *dst, labelLeaderObj *src);
MS_DLL_EXPORT int msCopyLine(lineObj *dst, lineObj *src);
MS_DLL_EXPORT int msCopyProjection(projectionObj *dst, projectionObj *src);
MS_DLL_EXPORT int msCopyProjectionExtended(projectionObj *dst, projectionObj *src, char ** args, int num_args);
int msCopyExpression(expressionObj *dst, expressionObj *src);
int msCopyProjection(projectionObj *dst, projectionObj *src);
Submodule msautotest updated from bb0a72 to 313691

0 comments on commit 46a4fea

Please sign in to comment.