195
197
#endif /* def USE_PROJ */
197
199
/************************************************************************/
198
/* msProjectRect() */
199
/************************************************************************/
201
#define NUMBER_OF_SAMPLE_POINTS 100
203
int msProjectRect(projectionObj *in, projectionObj *out, rectObj *rect)
208
int rect_initialized = MS_FALSE, failure=0;
214
dx = (rect->maxx - rect->minx)/NUMBER_OF_SAMPLE_POINTS;
215
dy = (rect->maxy - rect->miny)/NUMBER_OF_SAMPLE_POINTS;
217
/* first ensure the top left corner is processed, even if the rect
218
turns out to be degenerate. */
220
prj_point.x = rect->minx;
221
prj_point.y = rect->miny;
225
#endif /* USE_POINT_Z_M */
227
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
230
/* sample along top and bottom */
232
for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ )
234
x = rect->minx + ix * dx;
237
prj_point.y = rect->miny;
238
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
242
prj_point.y = rect->maxy;
243
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
248
/* sample along left and right */
250
for(iy = 0; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ )
252
y = rect->miny + iy * dy;
255
prj_point.x = rect->minx;
256
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
259
prj_point.x = rect->maxx;
261
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
267
** If there have been any failures around the edges, then we had better
268
** try and fill in the interior to get a close bounds.
273
for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ )
275
x = rect->minx + ix * dx;
277
for(iy = 0; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ )
279
y = rect->miny + iy * dy;
283
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
288
if( !rect_initialized )
290
if( out == NULL || out->proj == NULL
291
|| pj_is_latlong(in->proj) )
293
prj_rect.minx = -180;
300
prj_rect.minx = -22000000;
301
prj_rect.maxx = 22000000;
302
prj_rect.miny = -11000000;
303
prj_rect.maxy = 11000000;
306
msDebug( "msProjectRect(): all points failed to reproject, trying to fall back to using world bounds ... hope this helps.\n" );
310
msDebug( "msProjectRect(): some points failed to reproject, doing internal sampling.\n" );
314
rect->minx = prj_rect.minx;
315
rect->miny = prj_rect.miny;
316
rect->maxx = prj_rect.maxx;
317
rect->maxy = prj_rect.maxy;
319
if( !rect_initialized )
324
msSetError(MS_PROJERR, "Projection support is not available.", "msProjectRect()");
329
/************************************************************************/
330
200
/* msProjectSegment() */
332
202
/* Interpolate along a line segment for which one end */
699
571
/************************************************************************/
572
/* msProjectRectGrid() */
573
/************************************************************************/
575
#define NUMBER_OF_SAMPLE_POINTS 100
577
int msProjectRectGrid(projectionObj *in, projectionObj *out, rectObj *rect)
582
int rect_initialized = MS_FALSE, failure=0;
588
dx = (rect->maxx - rect->minx)/NUMBER_OF_SAMPLE_POINTS;
589
dy = (rect->maxy - rect->miny)/NUMBER_OF_SAMPLE_POINTS;
591
/* first ensure the top left corner is processed, even if the rect
592
turns out to be degenerate. */
594
prj_point.x = rect->minx;
595
prj_point.y = rect->miny;
599
#endif /* USE_POINT_Z_M */
601
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
605
for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ )
607
x = rect->minx + ix * dx;
609
for(iy = 0; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ )
611
y = rect->miny + iy * dy;
615
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
620
if( !rect_initialized )
622
if( out == NULL || out->proj == NULL
623
|| pj_is_latlong(in->proj) )
625
prj_rect.minx = -180;
632
prj_rect.minx = -22000000;
633
prj_rect.maxx = 22000000;
634
prj_rect.miny = -11000000;
635
prj_rect.maxy = 11000000;
638
msDebug( "msProjectRect(): all points failed to reproject, trying to fall back to using world bounds ... hope this helps.\n" );
642
msDebug( "msProjectRect(): some points failed to reproject, doing internal sampling.\n" );
645
rect->minx = prj_rect.minx;
646
rect->miny = prj_rect.miny;
647
rect->maxx = prj_rect.maxx;
648
rect->maxy = prj_rect.maxy;
650
if( !rect_initialized )
655
msSetError(MS_PROJERR, "Projection support is not available.", "msProjectRect()");
660
/************************************************************************/
661
/* msProjectRectTraditionalEdge() */
662
/************************************************************************/
665
msProjectRectTraditionalEdge(projectionObj *in, projectionObj *out,
671
int rect_initialized = MS_FALSE, failure=0;
677
dx = (rect->maxx - rect->minx)/NUMBER_OF_SAMPLE_POINTS;
678
dy = (rect->maxy - rect->miny)/NUMBER_OF_SAMPLE_POINTS;
680
/* first ensure the top left corner is processed, even if the rect
681
turns out to be degenerate. */
683
prj_point.x = rect->minx;
684
prj_point.y = rect->miny;
688
#endif /* USE_POINT_Z_M */
690
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
693
/* sample along top and bottom */
695
for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ )
697
x = rect->minx + ix * dx;
700
prj_point.y = rect->miny;
701
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
705
prj_point.y = rect->maxy;
706
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
711
/* sample along left and right */
713
for(iy = 0; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ )
715
y = rect->miny + iy * dy;
718
prj_point.x = rect->minx;
719
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
722
prj_point.x = rect->maxx;
724
msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
730
** If there have been any failures around the edges, then we had better
731
** try and fill in the interior to get a close bounds.
734
return msProjectRectGrid( in, out, rect );
736
rect->minx = prj_rect.minx;
737
rect->miny = prj_rect.miny;
738
rect->maxx = prj_rect.maxx;
739
rect->maxy = prj_rect.maxy;
741
if( !rect_initialized )
746
msSetError(MS_PROJERR, "Projection support is not available.", "msProjectRect()");
750
#endif /* def notdef */
752
/************************************************************************/
753
/* msProjectRectAsPolygon() */
754
/************************************************************************/
757
msProjectRectAsPolygon(projectionObj *in, projectionObj *out,
763
// pointObj ringPoints[NUMBER_OF_SAMPLE_POINTS*4+4];
764
pointObj *ringPoints;
769
ringPoints = (pointObj*) calloc(sizeof(pointObj),NUMBER_OF_SAMPLE_POINTS*4+4);
770
ring.point = ringPoints;
773
msInitShape( &polygonObj );
774
polygonObj.type = MS_SHAPE_POLYGON;
776
/* -------------------------------------------------------------------- */
777
/* Build polygon as steps around the source rectangle. */
778
/* -------------------------------------------------------------------- */
779
dx = (rect->maxx - rect->minx)/NUMBER_OF_SAMPLE_POINTS;
780
dy = (rect->maxy - rect->miny)/NUMBER_OF_SAMPLE_POINTS;
782
/* sample along top */
784
for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ )
786
ringPoints[ring.numpoints].x = rect->minx + ix * dx;
787
ringPoints[ring.numpoints++].y = rect->miny;
791
/* sample on along right side */
793
for(iy = 1; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ )
795
ringPoints[ring.numpoints].x = rect->maxx;
796
ringPoints[ring.numpoints++].y = rect->miny + iy * dy;
800
/* sample along bottom */
802
for(ix = NUMBER_OF_SAMPLE_POINTS-1; ix >= 0; ix-- )
804
ringPoints[ring.numpoints].x = rect->minx + ix * dx;
805
ringPoints[ring.numpoints++].y = rect->maxy;
809
/* sample on along left side */
811
for(iy = NUMBER_OF_SAMPLE_POINTS-1; iy >= 0; iy-- )
813
ringPoints[ring.numpoints].x = rect->minx;
814
ringPoints[ring.numpoints++].y = rect->miny + iy * dy;
818
msAddLineDirectly( &polygonObj, &ring );
820
/* -------------------------------------------------------------------- */
821
/* Attempt to reproject. */
822
/* -------------------------------------------------------------------- */
823
msProjectShapeLine( in, out, &polygonObj, 0 );
825
/* If no points reprojected, try a grid sampling */
826
if( polygonObj.numlines == 0 || polygonObj.line[0].numpoints == 0 )
828
msFreeShape( &polygonObj );
829
return msProjectRectGrid( in, out, rect );
832
/* -------------------------------------------------------------------- */
833
/* Collect bounds. */
834
/* -------------------------------------------------------------------- */
835
rect->minx = rect->maxx = polygonObj.line[0].point[0].x;
836
rect->miny = rect->maxy = polygonObj.line[0].point[0].y;
838
for( ix = 1; ix < polygonObj.line[0].numpoints; ix++ )
840
pointObj *pnt = polygonObj.line[0].point + ix;
842
rect->minx = MS_MIN(rect->minx,pnt->x);
843
rect->maxx = MS_MAX(rect->maxx,pnt->x);
844
rect->miny = MS_MIN(rect->miny,pnt->y);
845
rect->maxy = MS_MAX(rect->maxy,pnt->y);
848
msFreeShape( &polygonObj );
850
/* -------------------------------------------------------------------- */
851
/* Special case to handle reprojection from "more than the */
852
/* whole world" projected coordinates that sometimes produce a */
853
/* region greater than 360 degrees wide due to various wrapping */
855
/* -------------------------------------------------------------------- */
856
if( out && pj_is_latlong(out->proj) && in && !pj_is_latlong(in->proj)
857
&& rect->maxx - rect->minx > 360.0 )
865
msSetError(MS_PROJERR, "Projection support is not available.", "msProjectRect()");
870
/************************************************************************/
871
/* msProjectRect() */
872
/************************************************************************/
874
int msProjectRect(projectionObj *in, projectionObj *out, rectObj *rect)
877
return msProjectRectTraditionalEdge( in, out, rect );
879
return msProjectRectAsPolygon( in, out, rect );
883
/************************************************************************/
700
884
/* msProjectionsDiffer() */
701
885
/************************************************************************/