예제 #1
0
int msProjectShape(projectionObj *in, projectionObj *out, shapeObj *shape)
{
#ifdef USE_PROJ
  int i;

  for( i = shape->numlines-1; i >= 0; i-- )
  {
      if( shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON )
      {
          if( msProjectShapeLine( in, out, shape, i ) == MS_FAILURE )
              msShapeDeleteLine( shape, i );
      }
      else if( msProjectLine(in, out, shape->line+i ) == MS_FAILURE )
      {
          msShapeDeleteLine( shape, i );
      }
  }

  if( shape->numlines == 0 ) {
      msFreeShape( shape );
      return MS_FAILURE;
  } else {
      msComputeBounds( shape ); /* fixes bug 1586 */
      return(MS_SUCCESS);
  }
#else
  msSetError(MS_PROJERR, "Projection support is not available.", "msProjectShape()");
  return(MS_FAILURE);
#endif
}
예제 #2
0
int msProjectShape(projectionObj *in, projectionObj *out, shapeObj *shape)
{
#ifdef USE_PROJ
  int i;
#ifdef USE_PROJ_FASTPATHS
  int j;

  if(in->wellknownprojection == wkp_lonlat && out->wellknownprojection == wkp_gmerc) {
    for( i = shape->numlines-1; i >= 0; i-- ) {
      for( j = shape->line[i].numpoints-1; j >= 0; j-- ) {
#define p_x shape->line[i].point[j].x
#define p_y shape->line[i].point[j].y
        p_x *= MAXEXTENTby180;
        p_y = log(tan((90 + p_y) * M_PIby360)) * MS_RAD_TO_DEG;
        p_y *= MAXEXTENTby180;
        if (p_x > MAXEXTENT) p_x = MAXEXTENT;
        if (p_x < -MAXEXTENT) p_x = -MAXEXTENT;
        if (p_y > MAXEXTENT) p_y = MAXEXTENT;
        if (p_y < -MAXEXTENT) p_y = -MAXEXTENT;
#undef p_x
#undef p_y
      }
    }
    msComputeBounds( shape ); /* fixes bug 1586 */
    return MS_SUCCESS;
  }
#endif



  for( i = shape->numlines-1; i >= 0; i-- ) {
    if( shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON ) {
      if( msProjectShapeLine( in, out, shape, i ) == MS_FAILURE )
        msShapeDeleteLine( shape, i );
    } else if( msProjectLine(in, out, shape->line+i ) == MS_FAILURE ) {
      msShapeDeleteLine( shape, i );
    }
  }

  if( shape->numlines == 0 ) {
    msFreeShape( shape );
    return MS_FAILURE;
  } else {
    msComputeBounds( shape ); /* fixes bug 1586 */
    return(MS_SUCCESS);
  }
#else
  msSetError(MS_PROJERR, "Projection support is not available.", "msProjectShape()");
  return(MS_FAILURE);
#endif
}
예제 #3
0
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
}
예제 #4
0
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
}