Beispiel #1
0
/*
** Routine for clipping a polyline, stored in a shapeObj struct, to a
** rectangle. Uses clipLine() function to create a new shapeObj.
*/
void msClipPolylineRect(shapeObj *shape, rectObj rect)
{
  int i,j;
  lineObj line={0,NULL};
  double x1, x2, y1, y2;
  shapeObj tmp={0,NULL};

  if(shape->numlines == 0) /* nothing to clip */
    return;

  for(i=0; i<shape->numlines; i++) {

    line.point = (pointObj *)malloc(sizeof(pointObj)*shape->line[i].numpoints);
    line.numpoints = 0;

    x1 = shape->line[i].point[0].x;
    y1 = shape->line[i].point[0].y;
    for(j=1; j<shape->line[i].numpoints; j++) {
      x2 = shape->line[i].point[j].x;
      y2 = shape->line[i].point[j].y;

      if(clipLine(&x1,&y1,&x2,&y2,rect) == MS_TRUE) {
	if(line.numpoints == 0) { /* first segment, add both points */
	  line.point[0].x = x1;
	  line.point[0].y = y1;
	  line.point[1].x = x2;
	  line.point[1].y = y2;
	  line.numpoints = 2;
	} else { /* add just the last point */
	  line.point[line.numpoints].x = x2;
	  line.point[line.numpoints].y = y2;
	  line.numpoints++;
	}

	if((x2 != shape->line[i].point[j].x) || (y2 != shape->line[i].point[j].y)) {
	  msAddLine(&tmp, &line);
	  line.numpoints = 0; /* new line */
	}
      }

      x1 = shape->line[i].point[j].x;
      y1 = shape->line[i].point[j].y;
    }

    if(line.numpoints > 0)
      msAddLine(&tmp, &line);
    free(line.point);
    line.numpoints = 0; /* new line */
  }

  for (i=0; i<shape->numlines; i++) free(shape->line[i].point);
  free(shape->line);

  shape->line = tmp.line;
  shape->numlines = tmp.numlines;
}
Beispiel #2
0
int msCopyShape(shapeObj *from, shapeObj *to) {
  int i;

  if(!from || !to) return(-1);

  for(i=0; i<from->numlines; i++)
    msAddLine(to, &(from->line[i])); // copy each line

  to->type = from->type;

  to->bounds.minx = from->bounds.minx;
  to->bounds.miny = from->bounds.miny;
  to->bounds.maxx = from->bounds.maxx;
  to->bounds.maxy = from->bounds.maxy;

  if(from->text) to->text = _strdup(from->text);

  to->classindex = from->classindex;
  to->index = from->index;
  to->tileindex = from->tileindex;

  if(from->values) {
    to->values = (char **)malloc(sizeof(char *)*from->numvalues);
    for(i=0; i<from->numvalues; i++)
      to->values[i] = _strdup(from->values[i]);
    to->numvalues = from->numvalues;
  }

  return(0);
}
Beispiel #3
0
int msUVRASTERLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record)
{
  uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *) layer->layerinfo;
  lineObj line ;
  pointObj point;
  int i, j, k, x=0, y=0;
  long shapeindex = record->shapeindex;

  msFreeShape(shape);
  shape->type = MS_SHAPE_NULL;

  if( shapeindex < 0 || shapeindex >= uvlinfo->query_results ) {
    msSetError(MS_MISCERR,
               "Out of range shape index requested.  Requested %ld\n"
               "but only %d shapes available.",
               "msUVRASTERLayerGetShape()",
               shapeindex, uvlinfo->query_results );
    return MS_FAILURE;
  }

  /* loop to the next non null vector */
  k = 0;
  for (i=0, x=-1; i<uvlinfo->width && k<=shapeindex; ++i, ++x) {
    for (j=0, y=-1; j<uvlinfo->height && k<=shapeindex; ++j, ++k, ++y) {
      if (uvlinfo->u[i][j] == 0 && uvlinfo->v[i][j] == 0)
        --k;
    }
  }

  point.x = Pix2Georef(x, 0, uvlinfo->width-1,
                       uvlinfo->extent.minx, uvlinfo->extent.maxx, MS_FALSE);
  point.y = Pix2Georef(y, 0, uvlinfo->height-1,
                       uvlinfo->extent.miny, uvlinfo->extent.maxy, MS_TRUE);
  if (layer->debug == 5)
    msDebug("msUVRASTERLayerWhichShapes(): shapeindex: %ld, x: %g, y: %g\n",
            shapeindex, point.x, point.y);

#ifdef USE_POINT_Z_M
  point.m = 0.0;
#endif

  shape->type = MS_SHAPE_POINT;
  line.numpoints = 1;
  line.point = &point;
  msAddLine( shape, &line );
  msComputeBounds( shape );

  shape->numvalues = layer->numitems;
  shape->values = msUVRASTERGetValues(layer, &uvlinfo->u[x][y], &uvlinfo->v[x][y]);

  return MS_SUCCESS;

}
/* static pointObj get_metrics(pointObj *p, int position, rectObj rect, int ox, int oy, double angle, int buffer, shapeObj *poly) */
pointObj get_metrics(pointObj *p, int position, rectObj rect, int ox, int oy, double angle, int buffer, shapeObj *poly)
{
  lineObj newline;
  pointObj newpoints[5];
  pointObj rp;
  newline.numpoints=5;
  newline.point=newpoints;
  rp = get_metrics_line(p, position, rect, ox,oy, angle, buffer, &newline);
  if(poly) {
    msAddLine(poly,&newline);
    msComputeBounds(poly);
  }
  return rp;
}
Beispiel #5
0
/*
** Converts a rect array to a shapeObj structure. Note order is CW assuming y origin
** is in the lower left corner (normal cartesian coordinate system). Also polygon is
** is closed (i.e. first=last). This conforms to the shapefile specification. For image
** coordinate systems (i.e. GD) this is back-ass-ward, which is fine cause the function
** that calculates direction assumes min y = lower left, this way it'll still work. Drawing
** functions are independent of direction. Orientation problems can cause some nasty bugs.
*/
void msRectToPolygon(rectObj rect, shapeObj *poly)
{
  lineObj line={0,NULL};

  line.point = (pointObj *)malloc(sizeof(pointObj)*5);

  line.point[0].x = rect.minx;
  line.point[0].y = rect.miny;
  line.point[1].x = rect.minx;
  line.point[1].y = rect.maxy;
  line.point[2].x = rect.maxx;
  line.point[2].y = rect.maxy;
  line.point[3].x = rect.maxx;
  line.point[3].y = rect.miny;
  line.point[4].x = line.point[0].x;
  line.point[4].y = line.point[0].y;

  line.numpoints = 5;

  msAddLine(poly, &line);
  poly->type = MS_SHAPE_POLYGON;
  poly->bounds = rect;
  free(line.point);
}
Beispiel #6
0
static int 
msProjectShapeLine(projectionObj *in, projectionObj *out, 
                   shapeObj *shape, int line_index)

{
    int i;
    pointObj	lastPoint, thisPoint, wrkPoint, firstPoint;
    lineObj *line = shape->line + line_index;
    lineObj *line_out = line;
    int valid_flag = 0; /* 1=true, -1=false, 0=unknown */
    int numpoints_in = line->numpoints;
    int line_alloc = numpoints_in;
    int wrap_test;

    wrap_test = out != NULL && out->proj != NULL && pj_is_latlong(out->proj)
        && !pj_is_latlong(in->proj);

    line->numpoints = 0;

    if( numpoints_in > 0 )
        firstPoint = line->point[0];

    memset( &lastPoint, 0, sizeof(lastPoint) );

/* -------------------------------------------------------------------- */
/*      Loop over all input points in linestring.                       */
/* -------------------------------------------------------------------- */
    for( i=0; i < numpoints_in; i++ )
    {
        int ms_err;
        wrkPoint = thisPoint = line->point[i];

        ms_err = msProjectPoint(in, out, &wrkPoint );

/* -------------------------------------------------------------------- */
/*      Apply wrap logic.                                               */
/* -------------------------------------------------------------------- */
        if( wrap_test && i > 0 && ms_err != MS_FAILURE )
        {
            double dist;
            pointObj pt1Geo;

            if( line_out->numpoints > 0 )
                pt1Geo = line_out->point[0];
            else
                pt1Geo = wrkPoint; /* this is a cop out */

            dist = wrkPoint.x - pt1Geo.x;
            if( fabs(dist) > 180.0 
                && msTestNeedWrap( thisPoint, firstPoint, 
                                   pt1Geo, in, out ) )
            {
                if( dist > 0.0 )
                    wrkPoint.x -= 360.0;
                else if( dist < 0.0 )
                    wrkPoint.x += 360.0;
            }
        }

/* -------------------------------------------------------------------- */
/*      Put result into output line with appropriate logic for          */
/*      failure breaking lines, etc.                                    */
/* -------------------------------------------------------------------- */
        if( ms_err == MS_FAILURE ) 
        {
            /* We have started out invalid */
            if( i == 0 )
            {
                valid_flag = -1;
            }
            
            /* valid data has ended, we need to work out the horizon */
            else if( valid_flag == 1 )
            {
                pointObj startPoint, endPoint;
                
                startPoint = lastPoint;
                endPoint = thisPoint;
                if( msProjectSegment( in, out, &startPoint, &endPoint ) 
                    == MS_SUCCESS )
                {
                    line_out->point[line_out->numpoints++] = endPoint;
                }
                valid_flag = -1;
            }

            /* Still invalid ... */
            else if( valid_flag == -1 )
            {
                /* do nothing */
            }
        }

        else
        {
            /* starting out valid. */
            if( i == 0 )
            {
                line_out->point[line_out->numpoints++] = wrkPoint;
                valid_flag = 1;
            }
            
            /* Still valid, nothing special */
            else if( valid_flag == 1 )
            {
                line_out->point[line_out->numpoints++] = wrkPoint;
            }
            
            /* we have come over the horizon, figure out where, start newline*/
            else
            {
                pointObj startPoint, endPoint;
                
                startPoint = lastPoint;
                endPoint = thisPoint;
                if( msProjectSegment( in, out, &endPoint, &startPoint ) 
                    == MS_SUCCESS )
                {
                    lineObj newLine;

                    /* force pre-allocation of lots of points room */
                    if( line_out->numpoints > 0 
                        && shape->type == MS_SHAPE_LINE )
                    {
                        newLine.numpoints = numpoints_in - i + 1;
                        newLine.point = line->point;
                        msAddLine( shape, &newLine );

                        /* new line is now lineout, but start without any points */
                        line_out = shape->line + shape->numlines-1;

                        line_out->numpoints = 0;

                        /* the shape->line array is realloc, refetch "line" */
                        line = shape->line + line_index;
                    }
                    else if( line_out == line
                             && line->numpoints >= i-2 )
                    {
                        newLine.numpoints = numpoints_in;
                        newLine.point = line->point;
                        msAddLine( shape, &newLine );

                        line = shape->line + line_index;

                        line_out = shape->line + shape->numlines-1;
                        line_out->numpoints = line->numpoints;
                        line->numpoints = 0;
                        
                        /*
                         * Now realloc this array large enough to hold all
                         * the points we could possibly need to add. 
                         */
                        line_alloc = line_alloc * 2;

                        line_out->point = (pointObj *) 
                            realloc(line_out->point, 
                                    sizeof(pointObj) * line_alloc);
                    }
                     
                    line_out->point[line_out->numpoints++] = startPoint;
                }
                line_out->point[line_out->numpoints++] = wrkPoint;
                valid_flag = 1;
            }
        }

        lastPoint = thisPoint;
    }

/* -------------------------------------------------------------------- */
/*      Make sure that polygons are closed, even if the trip over       */
/*      the horizon left them unclosed.                                 */
/* -------------------------------------------------------------------- */
    if( shape->type == MS_SHAPE_POLYGON 
        && line_out->numpoints > 2 
        && (line_out->point[0].x != line_out->point[line_out->numpoints-1].x
            || line_out->point[0].y != line_out->point[line_out->numpoints-1].y) )
    {
        /* make a copy because msAddPointToLine can realloc the array */
        pointObj sFirstPoint = line_out->point[0];
        msAddPointToLine( line_out, &sFirstPoint );
    }

    return(MS_SUCCESS);
}
Beispiel #7
0
/*
 * RFC89 implementation:
 *  - transform directly the shapeobj
 */
int msGeomTransformShape(mapObj *map, layerObj *layer, shapeObj *shape)
{
  int i;
  expressionObj *e =  &layer->_geomtransform;  

#ifdef USE_V8_MAPSCRIPT
  if (!map->v8context) {
    msV8CreateContext(map);
    if (!map->v8context)
    {
      msSetError(MS_V8ERR, "Unable to create v8 context.", "msGeomTransformShape()");
      return MS_FAILURE;
    }
  }

  msV8ContextSetLayer(map, layer);
#endif
 
  switch(e->type) {
    case MS_GEOMTRANSFORM_EXPRESSION: {
      int status;
      shapeObj *tmpshp;
      parseObj p;

      p.shape = shape; /* set a few parser globals (hence the lock) */
      p.expr = e;
      p.expr->curtoken = p.expr->tokens; /* reset */
      p.type = MS_PARSE_TYPE_SHAPE;
      p.dblval = map->cellsize * (msInchesPerUnit(map->units,0)/msInchesPerUnit(layer->units,0));
      p.dblval2 = 0;
      /* data_cellsize is only set with contour layer */
      if (layer->connectiontype == MS_CONTOUR)
      {
        char *value = msLookupHashTable(&layer->metadata, "__data_cellsize__");
        if (value)
          p.dblval2 = atof(value);
      }
          
      status = yyparse(&p);
      if (status != 0) {
        msSetError(MS_PARSEERR, "Failed to process shape expression: %s", "msGeomTransformShape()", e->string);
        return MS_FAILURE;
      }
      
      tmpshp = p.result.shpval;

      for (i= 0; i < shape->numlines; i++)
        free(shape->line[i].point);
      shape->numlines = 0;
      if (shape->line) free(shape->line);
      
      for(i=0; i<tmpshp->numlines; i++)
        msAddLine(shape, &(tmpshp->line[i])); /* copy each line */

      msFreeShape(tmpshp);
      msFree(tmpshp);
    }
    break;
    default:
      msSetError(MS_MISCERR, "unknown geomtransform", "msGeomTransformShape()");
      return MS_FAILURE;
  }
  
  return MS_SUCCESS;
}
Beispiel #8
0
static int
msProjectShapeLine(projectionObj *in, projectionObj *out,
                   shapeObj *shape, int line_index)

{
  int i;
  pointObj  lastPoint, thisPoint, wrkPoint;
  lineObj *line = shape->line + line_index;
  lineObj *line_out = line;
  int valid_flag = 0; /* 1=true, -1=false, 0=unknown */
  int numpoints_in = line->numpoints;
  int line_alloc = numpoints_in;
  int wrap_test;

#ifdef USE_PROJ_FASTPATHS
#define MAXEXTENT 20037508.34
#define M_PIby360 .0087266462599716479
#define MAXEXTENTby180 111319.4907777777777777777
#define p_x line->point[i].x
#define p_y line->point[i].y
  if(in->wellknownprojection == wkp_lonlat && out->wellknownprojection == wkp_gmerc) {
    for( i = line->numpoints-1; i >= 0; i-- ) {
      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;
    }
    return MS_SUCCESS;
  }
  if(in->wellknownprojection == wkp_gmerc && out->wellknownprojection == wkp_lonlat) {
    for( i = line->numpoints-1; i >= 0; i-- ) {
      if (p_x > MAXEXTENT) p_x = MAXEXTENT;
      else if (p_x < -MAXEXTENT) p_x = -MAXEXTENT;
      if (p_y > MAXEXTENT) p_y = MAXEXTENT;
      else if (p_y < -MAXEXTENT) p_y = -MAXEXTENT;
      p_x = (p_x / MAXEXTENT) * 180;
      p_y = (p_y / MAXEXTENT) * 180;
      p_y = MS_RAD_TO_DEG * (2 * atan(exp(p_y * MS_DEG_TO_RAD)) - MS_PI2);
    }
    msComputeBounds( shape ); /* fixes bug 1586 */
    return MS_SUCCESS;
  }
#undef p_x
#undef p_y
#endif



  wrap_test = out != NULL && out->proj != NULL && pj_is_latlong(out->proj)
              && !pj_is_latlong(in->proj);

  line->numpoints = 0;

  memset( &lastPoint, 0, sizeof(lastPoint) );

  /* -------------------------------------------------------------------- */
  /*      Loop over all input points in linestring.                       */
  /* -------------------------------------------------------------------- */
  for( i=0; i < numpoints_in; i++ ) {
    int ms_err;
    wrkPoint = thisPoint = line->point[i];

    ms_err = msProjectPoint(in, out, &wrkPoint );

    /* -------------------------------------------------------------------- */
    /*      Apply wrap logic.                                               */
    /* -------------------------------------------------------------------- */
    if( wrap_test && i > 0 && ms_err != MS_FAILURE ) {
      double dist;
      pointObj pt1Geo;

      if( line_out->numpoints > 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, lastPoint,
                             pt1Geo, in, out ) ) {
        if( dist > 0.0 )
          wrkPoint.x -= 360.0;
        else if( dist < 0.0 )
          wrkPoint.x += 360.0;
      }
    }

    /* -------------------------------------------------------------------- */
    /*      Put result into output line with appropriate logic for          */
    /*      failure breaking lines, etc.                                    */
    /* -------------------------------------------------------------------- */
    if( ms_err == MS_FAILURE ) {
      /* We have started out invalid */
      if( i == 0 ) {
        valid_flag = -1;
      }

      /* valid data has ended, we need to work out the horizon */
      else if( valid_flag == 1 ) {
        pointObj startPoint, endPoint;

        startPoint = lastPoint;
        endPoint = thisPoint;
        if( msProjectSegment( in, out, &startPoint, &endPoint )
            == MS_SUCCESS ) {
          line_out->point[line_out->numpoints++] = endPoint;
        }
        valid_flag = -1;
      }

      /* Still invalid ... */
      else if( valid_flag == -1 ) {
        /* do nothing */
      }
    }

    else {
      /* starting out valid. */
      if( i == 0 ) {
        line_out->point[line_out->numpoints++] = wrkPoint;
        valid_flag = 1;
      }

      /* Still valid, nothing special */
      else if( valid_flag == 1 ) {
        line_out->point[line_out->numpoints++] = wrkPoint;
      }

      /* we have come over the horizon, figure out where, start newline*/
      else {
        pointObj startPoint, endPoint;

        startPoint = lastPoint;
        endPoint = thisPoint;
        if( msProjectSegment( in, out, &endPoint, &startPoint )
            == MS_SUCCESS ) {
          lineObj newLine;

          /* force pre-allocation of lots of points room */
          if( line_out->numpoints > 0
              && shape->type == MS_SHAPE_LINE ) {
            newLine.numpoints = numpoints_in - i + 1;
            newLine.point = line->point;
            msAddLine( shape, &newLine );

            /* new line is now lineout, but start without any points */
            line_out = shape->line + shape->numlines-1;

            line_out->numpoints = 0;

            /* the shape->line array is realloc, refetch "line" */
            line = shape->line + line_index;
          } else if( line_out == line
                     && line->numpoints >= i-2 ) {
            newLine.numpoints = numpoints_in;
            newLine.point = line->point;
            msAddLine( shape, &newLine );

            line = shape->line + line_index;

            line_out = shape->line + shape->numlines-1;
            line_out->numpoints = line->numpoints;
            line->numpoints = 0;

            /*
             * Now realloc this array large enough to hold all
             * the points we could possibly need to add.
             */
            line_alloc = line_alloc * 2;

            line_out->point = (pointObj *)
                              realloc(line_out->point,
                                      sizeof(pointObj) * line_alloc);
          }

          line_out->point[line_out->numpoints++] = startPoint;
        }
        line_out->point[line_out->numpoints++] = wrkPoint;
        valid_flag = 1;
      }
    }

    lastPoint = thisPoint;
  }

  /* -------------------------------------------------------------------- */
  /*      Make sure that polygons are closed, even if the trip over       */
  /*      the horizon left them unclosed.                                 */
  /* -------------------------------------------------------------------- */
  if( shape->type == MS_SHAPE_POLYGON
      && line_out->numpoints > 2
      && (line_out->point[0].x != line_out->point[line_out->numpoints-1].x
          || line_out->point[0].y != line_out->point[line_out->numpoints-1].y) ) {
    /* make a copy because msAddPointToLine can realloc the array */
    pointObj sFirstPoint = line_out->point[0];
    msAddPointToLine( line_out, &sFirstPoint );
  }

  return(MS_SUCCESS);
}
Beispiel #9
0
/*
** Slightly modified version of the Liang-Barsky polygon clipping algorithm
*/
void msClipPolygonRect(shapeObj *shape, rectObj rect)
{
  int i, j;
  double deltax, deltay, xin,xout,  yin,yout;
  double tinx,tiny,  toutx,touty,  tin1, tin2,  tout;
  double x1,y1, x2,y2;

  shapeObj tmp;
  lineObj line={0,NULL};

  msInitShape(&tmp);

  if(shape->numlines == 0) /* nothing to clip */
    return;

  for(j=0; j<shape->numlines; j++) {

    line.point = (pointObj *)malloc(sizeof(pointObj)*2*shape->line[j].numpoints+1); /* worst case scenario, +1 allows us to duplicate the 1st and last point */
    line.numpoints = 0;

    for (i = 0; i < shape->line[j].numpoints-1; i++) {

      x1 = shape->line[j].point[i].x;
      y1 = shape->line[j].point[i].y;
      x2 = shape->line[j].point[i+1].x;
      y2 = shape->line[j].point[i+1].y;

      deltax = x2-x1;
      if (deltax == 0) { /* bump off of the vertical */
	deltax = (x1 > rect.minx) ? -NEARZERO : NEARZERO ;
      }
      deltay = y2-y1;
      if (deltay == 0) { /* bump off of the horizontal */
	deltay = (y1 > rect.miny) ? -NEARZERO : NEARZERO ;
      }

      if (deltax > 0) {		/*  points to right */
	xin = rect.minx;
	xout = rect.maxx;
      }
      else {
	xin = rect.maxx;
	xout = rect.minx;
      }
      if (deltay > 0) {		/*  points up */
	yin = rect.miny;
	yout = rect.maxy;
      }
      else {
	yin = rect.maxy;
	yout = rect.miny;
      }

      tinx = (xin - x1)/deltax;
      tiny = (yin - y1)/deltay;

      if (tinx < tiny) {	/* hits x first */
	tin1 = tinx;
	tin2 = tiny;
      } else {			/* hits y first */
	tin1 = tiny;
	tin2 = tinx;
      }

      if (1 >= tin1) {
	if (0 < tin1) {
	  line.point[line.numpoints].x = xin;
	  line.point[line.numpoints].y = yin;
	  line.numpoints++;
	}
	if (1 >= tin2) {
	  toutx = (xout - x1)/deltax;
	  touty = (yout - y1)/deltay;

	  tout = (toutx < touty) ? toutx : touty ;

	  if (0 < tin2 || 0 < tout) {
	    if (tin2 <= tout) {
	      if (0 < tin2) {
		if (tinx > tiny) {
		  line.point[line.numpoints].x = xin;
		  line.point[line.numpoints].y = y1 + tinx*deltay;
		  line.numpoints++;
		} else {
		  line.point[line.numpoints].x = x1 + tiny*deltax;
		  line.point[line.numpoints].y = yin;
		  line.numpoints++;
		}
	      }
	      if (1 > tout) {
		if (toutx < touty) {
		  line.point[line.numpoints].x = xout;
		  line.point[line.numpoints].y = y1 + toutx*deltay;
		  line.numpoints++;
		} else {
		  line.point[line.numpoints].x = x1 + touty*deltax;
		  line.point[line.numpoints].y = yout;
		  line.numpoints++;
		}
	      }	else {
		line.point[line.numpoints].x = x2;
		line.point[line.numpoints].y = y2;
		line.numpoints++;
	      }
	    } else {
	      if (tinx > tiny) {
		line.point[line.numpoints].x = xin;
		line.point[line.numpoints].y = yout;
		line.numpoints++;
	      } else {
		line.point[line.numpoints].x = xout;
		line.point[line.numpoints].y = yin;
		line.numpoints++;
	      }
	    }
	  }
	}
      }
    }

    if(line.numpoints > 0) {
      line.point[line.numpoints].x = line.point[0].x; // force closure
      line.point[line.numpoints].y = line.point[0].y;
      line.numpoints++;
      msAddLine(&tmp, &line);
    }

    free(line.point);
  } /* next line */

  for (i=0; i<shape->numlines; i++) free(shape->line[i].point);
  free(shape->line);

  shape->line = tmp.line;
  shape->numlines = tmp.numlines;

  return;
}
Beispiel #10
0
shapeObj* msSmoothShapeSIA(shapeObj *shape, int ss, int si, char *preprocessing)
{
  int i, j;
  pointObj *p;
  double *coeff;
  shapeObj *newShape;

  newShape = (shapeObj *) msSmallMalloc(sizeof (shapeObj));
  msInitShape(newShape);

  if (ss < 3)
    ss = 3;
  
  if (si < 1)
    si = 1;

  /* Apply preprocessing */
  if (preprocessing)
  {
    if (strcasecmp(preprocessing, "all") == 0)
      processShapePathDistance(shape, MS_TRUE);
    else if (strcasecmp(preprocessing, "angle") == 0)
      processShapePathDistance(shape, MS_FALSE);
  }
  
  p = (pointObj *) msSmallMalloc(ss*sizeof(pointObj));
  coeff = (double *) msSmallMalloc(ss*sizeof (double));        
  
  for (i=0;i<si;++i) {
    shapeObj initialShape;
    
    if (si > 1 && i>0) {
      msInitShape(&initialShape);    
      msCopyShape(shape, &initialShape);
      
      /* Clean our shape object */
      for (j=0; j < newShape->numlines; ++j)
        free(newShape->line[j].point);
      newShape->numlines = 0;
      if (newShape->line) {
        free(newShape->line);
        newShape->line = NULL;
      }

      shape = &initialShape;
    }
    
    for (j=0;j<shape->numlines;++j) {
      int k, ws, res;      
      lineObj newLine = {0,NULL};
      lineWindow lw;

      /* determine if we can use the ss for this line */
      ws = ss;      
      if (ws >= shape->line[j].numpoints) {
        ws = shape->line[j].numpoints-1;
      }

      if (ws%2==0)
        ws-=1;  

      initLineWindow(&lw, &shape->line[j], ws);
      msAddLine(newShape, &newLine);

      coeff[lw.index] = 1;
      for (k=0;k<lw.index;++k) {
        coeff[lw.index+(k+1)] = coeff[lw.index-k]/2;
        coeff[lw.index-(k+1)] = coeff[lw.index+k]/2;    
      }
      
      
      while ((res = nextLineWindow(&lw)) != MS_DONE) {
        double sum_x=0, sum_y=0, sum = 0;
        pointObj point;
        int k = 0;        

        if (res == MS_FALSE) { /* invalid window */
          msAddPointToLine(&newShape->line[j],
                           lw.points[lw.index]);
          continue;
        }

        /* Apply Coefficient */
        p[lw.index] = *lw.points[lw.index];
        for (k=0; k<lw.index; ++k) {
          p[lw.index-(k+1)] = *lw.points[lw.index-(k+1)];
          p[lw.index-(k+1)].x *= coeff[lw.index-(k+1)];
          p[lw.index-(k+1)].y *= coeff[lw.index-(k+1)];
          p[lw.index+(k+1)] = *lw.points[lw.index+(k+1)];
          p[lw.index+(k+1)].x *= coeff[lw.index+(k+1)];
          p[lw.index+(k+1)].y *= coeff[lw.index+(k+1)];
        }
        
        for (k=0; k<lw.size; ++k) {
          sum += coeff[k];
          sum_x += p[k].x;
          sum_y += p[k].y;          
        }
      
        point.x = sum_x/sum;
        point.y = sum_y/sum;
        msAddPointToLine(&newShape->line[j],
                         &point);
      }

      freeLineWindow(&lw);      
    }
    
    if (i>0) {
      msFreeShape(shape);
      shape = newShape;
    }
    
  }
  
  free(p);
  free(coeff);
  
  return newShape;
}
Beispiel #11
0
/* Pre-Processing of a shape. It modifies the shape by adding intermediate
   points where a loop is detected to improve the smoothing result. */
static int processShapePathDistance(shapeObj *shape, int force)
{
  shapeObj initialShape, *newShape;
  int i;
  
  /* initial shape to process */
  msInitShape(&initialShape);    
  msCopyShape(shape, &initialShape);

  newShape = shape; /* we modify the shape object directly */
  shape = &initialShape;
  
  /* Clean our shape object */
  for (i= 0; i < newShape->numlines; i++)
    free(newShape->line[i].point);
  newShape->numlines = 0;
  if (newShape->line) free(newShape->line);
  
  for (i=0;i<shape->numlines;++i) {
    const int windowSize = 5;
    int res;
    lineWindow lw;
    lineObj line = {0, NULL};

    initLineWindow(&lw, &shape->line[i], windowSize);
    msAddLine(newShape, &line);

    while ((res = nextLineWindow(&lw)) != MS_DONE) {
      double ratio = 0;
      pointObj point;

      if (lw.lineIsRing && lw.pos==lw.line->numpoints-1) {
        point = newShape->line[i].point[0];
        msAddPointToLine(&newShape->line[i],
                         &point);
        continue;
      }

      if (res == MS_FALSE) { /* invalid window */
        msAddPointToLine(&newShape->line[i],
                         lw.points[lw.index]);
        continue;
      }

      if (!force)
        ratio = computePathDistanceRatio(lw.points, windowSize);
                      
      if (force || (ratio > 1.3)) {
        point.x = (lw.line->point[lw.pos].x + lw.points[lw.index-1]->x)/2;
        point.y = (lw.line->point[lw.pos].y + lw.points[lw.index-1]->y)/2;
        msAddPointToLine(&newShape->line[i],
                         &point);
      }
      
      point = lw.line->point[lw.pos];
      msAddPointToLine(&newShape->line[i],
                       &point);
      
      if (force || (ratio > 1.3)) {
        point.x = (lw.line->point[lw.pos].x + lw.points[lw.index+1]->x)/2;
        point.y = (lw.line->point[lw.pos].y + lw.points[lw.index+1]->y)/2;
        msAddPointToLine(&newShape->line[i],
                         &point);
      }
      
    }
       
    freeLineWindow(&lw);
  }
    
  msFreeShape(shape);
  
  return MS_SUCCESS;
}