static int msProjectRectTraditionalEdge(projectionObj *in, projectionObj *out, rectObj *rect) { #ifdef USE_PROJ pointObj prj_point; rectObj prj_rect; int rect_initialized = MS_FALSE, failure=0; int ix, iy; double dx, dy; double x, y; dx = (rect->maxx - rect->minx)/NUMBER_OF_SAMPLE_POINTS; dy = (rect->maxy - rect->miny)/NUMBER_OF_SAMPLE_POINTS; /* first ensure the top left corner is processed, even if the rect turns out to be degenerate. */ prj_point.x = rect->minx; prj_point.y = rect->miny; #ifdef USE_POINT_Z_M prj_point.z = 0.0; prj_point.m = 0.0; #endif /* USE_POINT_Z_M */ msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point, &failure); /* sample along top and bottom */ if(dx > 0) { for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ ) { x = rect->minx + ix * dx; prj_point.x = x; prj_point.y = rect->miny; msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point, &failure); prj_point.x = x; prj_point.y = rect->maxy; msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point, &failure); } } /* sample along left and right */ if(dy > 0) { for(iy = 0; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ ) { y = rect->miny + iy * dy; prj_point.y = y; prj_point.x = rect->minx; msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point, &failure); prj_point.x = rect->maxx; prj_point.y = y; msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point, &failure); } } /* ** If there have been any failures around the edges, then we had better ** try and fill in the interior to get a close bounds. */ if( failure > 0 ) return msProjectRectGrid( in, out, rect ); rect->minx = prj_rect.minx; rect->miny = prj_rect.miny; rect->maxx = prj_rect.maxx; rect->maxy = prj_rect.maxy; if( !rect_initialized ) return MS_FAILURE; else return(MS_SUCCESS); #else msSetError(MS_PROJERR, "Projection support is not available.", "msProjectRect()"); return(MS_FAILURE); #endif }
static int msProjectRectAsPolygon(projectionObj *in, projectionObj *out, rectObj *rect) { #ifdef USE_PROJ shapeObj polygonObj; lineObj ring; // pointObj ringPoints[NUMBER_OF_SAMPLE_POINTS*4+4]; pointObj *ringPoints; int ix, iy; double dx, dy; ringPoints = (pointObj*) calloc(sizeof(pointObj),NUMBER_OF_SAMPLE_POINTS*4+4); ring.point = ringPoints; ring.numpoints = 0; msInitShape( &polygonObj ); polygonObj.type = MS_SHAPE_POLYGON; /* -------------------------------------------------------------------- */ /* Build polygon as steps around the source rectangle. */ /* -------------------------------------------------------------------- */ dx = (rect->maxx - rect->minx)/NUMBER_OF_SAMPLE_POINTS; dy = (rect->maxy - rect->miny)/NUMBER_OF_SAMPLE_POINTS; /* sample along top */ if(dx != 0) { for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ ) { ringPoints[ring.numpoints].x = rect->minx + ix * dx; ringPoints[ring.numpoints++].y = rect->miny; } } /* sample on along right side */ if(dy != 0) { for(iy = 1; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ ) { ringPoints[ring.numpoints].x = rect->maxx; ringPoints[ring.numpoints++].y = rect->miny + iy * dy; } } /* sample along bottom */ if(dx != 0) { for(ix = NUMBER_OF_SAMPLE_POINTS-1; ix >= 0; ix-- ) { ringPoints[ring.numpoints].x = rect->minx + ix * dx; ringPoints[ring.numpoints++].y = rect->maxy; } } /* sample on along left side */ if(dy != 0) { for(iy = NUMBER_OF_SAMPLE_POINTS-1; iy >= 0; iy-- ) { ringPoints[ring.numpoints].x = rect->minx; ringPoints[ring.numpoints++].y = rect->miny + iy * dy; } } msAddLineDirectly( &polygonObj, &ring ); /* -------------------------------------------------------------------- */ /* Attempt to reproject. */ /* -------------------------------------------------------------------- */ msProjectShapeLine( in, out, &polygonObj, 0 ); /* If no points reprojected, try a grid sampling */ if( polygonObj.numlines == 0 || polygonObj.line[0].numpoints == 0 ) { msFreeShape( &polygonObj ); return msProjectRectGrid( in, out, rect ); } /* -------------------------------------------------------------------- */ /* Collect bounds. */ /* -------------------------------------------------------------------- */ rect->minx = rect->maxx = polygonObj.line[0].point[0].x; rect->miny = rect->maxy = polygonObj.line[0].point[0].y; for( ix = 1; ix < polygonObj.line[0].numpoints; ix++ ) { pointObj *pnt = polygonObj.line[0].point + ix; rect->minx = MS_MIN(rect->minx,pnt->x); rect->maxx = MS_MAX(rect->maxx,pnt->x); rect->miny = MS_MIN(rect->miny,pnt->y); rect->maxy = MS_MAX(rect->maxy,pnt->y); } msFreeShape( &polygonObj ); /* -------------------------------------------------------------------- */ /* Special case to handle reprojection from "more than the */ /* whole world" projected coordinates that sometimes produce a */ /* region greater than 360 degrees wide due to various wrapping */ /* logic. */ /* -------------------------------------------------------------------- */ if( out && pj_is_latlong(out->proj) && in && !pj_is_latlong(in->proj) && rect->maxx - rect->minx > 360.0 ) { rect->maxx = 180; rect->minx = -180; } return MS_SUCCESS; #else msSetError(MS_PROJERR, "Projection support is not available.", "msProjectRect()"); return(MS_FAILURE); #endif }
static int msProjectRectAsPolygon(projectionObj *in, projectionObj *out, rectObj *rect) { #ifdef USE_PROJ shapeObj polygonObj; lineObj ring; /* pointObj ringPoints[NUMBER_OF_SAMPLE_POINTS*4+4]; */ pointObj *ringPoints; int ix, iy; double dx, dy; /* If projecting from longlat to projected */ if( out && !pj_is_latlong(out->proj) && in && pj_is_latlong(in->proj) && fabs(rect->minx - -180.0) < 1e-5 && fabs(rect->miny - -90.0) < 1e-5 && fabs(rect->maxx - 180.0) < 1e-5 && fabs(rect->maxy - 90.0) < 1e-5) { rect->minx = -1e15; rect->miny = -1e15; rect->maxx = 1e15; rect->maxy = 1e15; return MS_SUCCESS; } /* -------------------------------------------------------------------- */ /* Build polygon as steps around the source rectangle. */ /* -------------------------------------------------------------------- */ dx = (rect->maxx - rect->minx)/NUMBER_OF_SAMPLE_POINTS; dy = (rect->maxy - rect->miny)/NUMBER_OF_SAMPLE_POINTS; if(dx==0 && dy==0) { pointObj foo; msDebug( "msProjectRect(): Warning: degenerate rect {%f,%f,%f,%f}\n",rect->minx,rect->miny,rect->minx,rect->miny ); foo.x = rect->minx; foo.y = rect->miny; msProjectPoint(in,out,&foo); rect->minx=rect->maxx=foo.x; rect->miny=rect->maxy=foo.y; return MS_SUCCESS; } ringPoints = (pointObj*) calloc(sizeof(pointObj),NUMBER_OF_SAMPLE_POINTS*4+4); ring.point = ringPoints; ring.numpoints = 0; msInitShape( &polygonObj ); polygonObj.type = MS_SHAPE_POLYGON; /* sample along top */ if(dx != 0) { for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ ) { ringPoints[ring.numpoints].x = rect->minx + ix * dx; ringPoints[ring.numpoints++].y = rect->miny; } } /* sample on along right side */ if(dy != 0) { for(iy = 1; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ ) { ringPoints[ring.numpoints].x = rect->maxx; ringPoints[ring.numpoints++].y = rect->miny + iy * dy; } } /* sample along bottom */ if(dx != 0) { for(ix = NUMBER_OF_SAMPLE_POINTS-1; ix >= 0; ix-- ) { ringPoints[ring.numpoints].x = rect->minx + ix * dx; ringPoints[ring.numpoints++].y = rect->maxy; } } /* sample on along left side */ if(dy != 0) { for(iy = NUMBER_OF_SAMPLE_POINTS-1; iy >= 0; iy-- ) { ringPoints[ring.numpoints].x = rect->minx; ringPoints[ring.numpoints++].y = rect->miny + iy * dy; } } 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. */ /* -------------------------------------------------------------------- */ msProjectShapeLine( in, out, &polygonObj, 0 ); /* If no points reprojected, try a grid sampling */ if( polygonObj.numlines == 0 || polygonObj.line[0].numpoints == 0 ) { msFreeShape( &polygonObj ); 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. */ /* -------------------------------------------------------------------- */ rect->minx = rect->maxx = polygonObj.line[0].point[0].x; rect->miny = rect->maxy = polygonObj.line[0].point[0].y; for( ix = 1; ix < polygonObj.line[0].numpoints; ix++ ) { pointObj *pnt = polygonObj.line[0].point + ix; rect->minx = MS_MIN(rect->minx,pnt->x); rect->maxx = MS_MAX(rect->maxx,pnt->x); rect->miny = MS_MIN(rect->miny,pnt->y); rect->maxy = MS_MAX(rect->maxy,pnt->y); } msFreeShape( &polygonObj ); /* -------------------------------------------------------------------- */ /* Special case to handle reprojection from "more than the */ /* whole world" projected coordinates that sometimes produce a */ /* region greater than 360 degrees wide due to various wrapping */ /* logic. */ /* -------------------------------------------------------------------- */ if( out && pj_is_latlong(out->proj) && in && !pj_is_latlong(in->proj) && rect->maxx - rect->minx > 360.0 ) { rect->maxx = 180; rect->minx = -180; } return MS_SUCCESS; #else msSetError(MS_PROJERR, "Projection support is not available.", "msProjectRect()"); return(MS_FAILURE); #endif }