示例#1
0
/* compute true world co-ordinate of a pixel
 * RrowCol2Coords computes the true world co-ordinate from a 
 * row, column index. 
 * The row, column co-ordinate 
 * don't have to be on the map. They are just relative to upper left position.
 * For example (row,col) = (-1,0) computes the (x,y) co-ordinate of
 * the pixel that is right above upper left pixel. 
 *
 * returns
 *  0  if the co-ordinate is outside the map.
 *  1 if inside.
 * -1 in case of an error.
 *
 * Merrno
 * ILL_CELLSIZE
 */
int RgetCoords(
	const MAP *m,	/* map handle */
	int inCellPos,  /* nonzero if you want the co-ordinate
			 * at the centre of the cell, 0 if you
			 * want the upper left co-ordinate of the cell
			 */
	size_t row,      /* Row number (relates to y position). */
	size_t col,      /* Column number (relates to x position). */
	double *x,      /* write-only. Returns x of true co-ordinate */
	double *y)      /* write-only. Returns y of true co-ordinate */
{
	return RrowCol2Coords(m,
		(double)row+(inCellPos ? 0.5 : 0.0),
		(double)col+(inCellPos ? 0.5 : 0.0),
		x,y);
}
示例#2
0
/* Calculates one pixel from output map, given the input maps.
 * Puts all values of input pixels in a list and determines the value of
 * the output pixel according to these values and the overlapping areas.
 * Returns 0 if no error occurs, 1 otherwise.
 */
static int CalcPixel(
	MAP *out,		/* write-only output map */
 	MAP **in,		/* read-only list input maps */
 	size_t nrCoverCells,	/* min. nr. non-MV cells for non-MV */
 	size_t nrMaps,		/* nr. of input maps */
 	double rOut,		/* row number pixel */
 	double cOut,		/* column number pixel */
 	BOOL aligned,		/* maps are aligned */
 	REAL8 angle)		/* angle of output map */
{		
	PTYPE 	tlX, tlY, trX, trY, brX, brY, blX, blY;
	double 	r, c;
	DATA 	*list = NULL;  	/* areas and values of input cells */
   	size_t 	i, nrList = 0;	/* number of items in list */
	POINT2D 	*outputCell;	/* polygon of output cell */
   	size_t 	nr = 4;		/* nr of points of cell */
   	CSF_VS	vs;		/* value scale of first input map */

	if(nrCoverCells > 0 && nrMaps > 1)
		raster = InitRaster(raster); /* initialize the raster */

   	/* Determine the four corners of output pixel */
   	RrowCol2Coords(out, rOut, cOut, &tlX, &tlY); /* top left */
   	RrowCol2Coords(out, rOut, cOut + 1, &trX, &trY); /* top right */
   	RrowCol2Coords(out, rOut + 1, cOut, &blX, &blY); /* bottom left */
   	RrowCol2Coords(out, rOut + 1, cOut + 1, &brX, &brY); /* bottom right */
	outputCell = PutInPol(tlX, tlY, trX, trY, brX, brY, blX, blY);
	if(outputCell == NULL)
		return 1;

	POSTCOND(outputCell[0].x == outputCell[nr].x);
	POSTCOND(outputCell[0].y == outputCell[nr].y);

	/* Get pixel on every input map */
	for(i = 0; i < nrMaps; i++)
	{
		MAP 	*X = in[i];	/* input map number i */
		PTYPE 	tlC, tlR, trC, trR, brC, brR, blC, blR;
		PTYPE 	tlX2, tlY2, trX2, trY2, brX2, brY2, blX2, blY2;
   		double 	leftB, belowB, rightB, upperB;	/* boundaries */

		/* Corners: (tlX, tlY), (trX, trY), (blX, blY) and
		 * (brX, brY). Translate for input map.
		 */
   		Rcoords2RowCol(X, tlX, tlY, &tlC, &tlR); /* top left */
   		Rcoords2RowCol(X, trX, trY, &trC, &trR); /* top right */
   		Rcoords2RowCol(X, blX, blY, &blC, &blR); /* bottom left */
   		Rcoords2RowCol(X, brX, brY, &brC, &brR); /* bottom right */

   		/* Boundaries in the input map */
   		rightB = ceil(MaxPoint(tlR, trR, blR, brR));	
   		belowB = ceil(MaxPoint(tlC, trC, blC, brC));	
   		leftB = floor(MinPoint(tlR, trR, blR, brR));	
   		upperB = floor(MinPoint(tlC, trC, blC, brC));	
   		
		PRECOND(upperB <= belowB);
		PRECOND(leftB <= rightB);

		/* Check all cells between the boundaries */
		for(r = upperB; r < belowB; r++)
		{
			REAL8 *currRow;
			if(0 <= r && r <= RgetNrRows(X))
		 	 currRow = (REAL8 *)CacheGetRow(in, i,  r);

			for(c = leftB; c < rightB; c++)
		 	{  /* Cells that might be in pixel */
   			    POINT2D *inputCell;  /* polygon input cell */

			    if(r < 0 || RgetNrRows(X) <= r || c < 0 ||
			       RgetNrCols(X) <= c)
			    	continue;

   			    /* Top left & right, bottom left & right */
   			    RrowCol2Coords(X, r, c, &tlX2, &tlY2);
   			    RrowCol2Coords(X, r, c+1, &trX2, &trY2);
   			    RrowCol2Coords(X, r+1, c, &blX2, &blY2);
   			    RrowCol2Coords(X, r+1, c+1, &brX2, &brY2);
			    inputCell = PutInPol(tlX2, tlY2, trX2, trY2,
					brX2, brY2, blX2, blY2);
			    if(inputCell == NULL)
				return 1;

			    POSTCOND(inputCell[0].x == inputCell[nr].x);
			    POSTCOND(inputCell[0].y == inputCell[nr].y);

			    /* Add item to list for cell */
			    if(AddCell(&list, raster, &nrList, inputCell,
				  outputCell, currRow, X, nrMaps,
				   (size_t)c, nrCoverCells, aligned, angle))
				      return 1;
			    Free(inputCell);	/* deallocate */
		 	}
		}
	}	 

	/* calculate output value of pixel according value scale */
	vs = RgetValueScale(in[0]);
	if(vs != VS_DIRECTION)
		CalcScalarOut(out, (size_t)rOut, (size_t)cOut, nrList, list, nrCoverCells, nrMaps);
	else
		CalcDirectionOut(out, (size_t) rOut, (size_t) cOut, nrList, list, nrCoverCells, nrMaps);

	Free(outputCell);		/* deallocate */
	Free(list);			/* deallocate */
	return 0;			/* successfully terminated */
}
示例#3
0
文件: main.c 项目: pcraster/pcraster
/* Determines smallest rectangle around nonMv values.
 * The border value can be added around this rectangle.
 * Returns x0, y0 , nrRows and nrCols for out.
 */
static int SmallestNonMVRect(
	REAL8 *X0out,		/* write-only X0 */
	REAL8 *Y0out,		/* write-only Y0 */
	size_t *nrRows,		/* write-only nr of rows */
	size_t *nrCols,		/* write-only nr of columns */
	MAP **in,  		/* read-only pointer in maps */
	int borderValue,	/* border value */
	size_t nrMaps,		/* number of input maps */
	CSF_VS valueScale,	/* value scale of output map */
	REAL8 cellSize,		/* cellSize of map */
	REAL8 angle,		/* angle of output map */
	CSF_PT projection,	/* projection of output map */
	BOOL contract)		/* map should be contracted */
{
	size_t 	i;
	POINT2D 	leftUpperC, leftLowerC, rightUpperC, rightLowerC;
	REAL8 	upperB=0, leftB=0, rightB=0, belowB=0;
 	   /* ^- shut up about use before def */

	for(i = 0; i < nrMaps; i++)
	{
		MAP	*X = in[i];
		BOOL	first = TRUE;
		POINT2D	polygon[4];
		size_t 	r, c;
		size_t 	nrR = RgetNrRows(X);
		size_t 	nrC = RgetNrCols(X);

		for(r = 0; r < nrR; r++)
		 for(c = 0; c < nrC; c++)
		 {
	 		INT4 int4Val;
	 		REAL8 real8Val;

	 		if((AppIsClassified(valueScale) &&
	 		  RgetCell(in[i], r, c, &int4Val) &&
	 		  int4Val != MV_INT4) ||
	 		  (!AppIsClassified(valueScale) && 
	 		  RgetCell(in[i], r, c, &real8Val) &&
	 		  (IsMV(in[i], &real8Val) == FALSE)))
	 		{
				if(first || c < leftB)
					leftB = c;
				if(first || c > rightB)
					rightB = c;
				if(first || r > belowB)
					belowB = r;
				if(first || r < upperB)
					upperB = r;
				first = FALSE;
			}
		}

		/* Get coordinates of corners */
		RrowCol2Coords(X, upperB, leftB, &polygon[0].x,
			&polygon[0].y);
		RrowCol2Coords(X, upperB, rightB + 1 - EPSILON,
			&polygon[1].x, &polygon[1].y);
		RrowCol2Coords(X, belowB + 1 - EPSILON, leftB,
			&polygon[2].x, &polygon[2].y);
		RrowCol2Coords(X, belowB + 1 - EPSILON,
		    rightB + 1 - EPSILON, &polygon[3].x, &polygon[3].y);

		/* Rotate all corners of map */	
		if(angle != 0)
		{
			for(c = 0; c < 4; c++)
		   	    polygon[c] = *RotPoint(polygon + c, angle);
		}

		/* Determine boundaries of rotated output map */
		for(c = 0; c < 4; c++)
		{
			if(polygon[c].y > belowB || (i == 0 && c == 0))
				belowB = polygon[c].y;
			if(polygon[c].y < upperB || (i == 0 && c == 0))
				upperB = polygon[c].y;
			if(polygon[c].x > rightB || (i == 0 && c == 0))
				rightB = polygon[c].x;
			if(polygon[c].x < leftB || (i == 0 && c == 0))
				leftB = polygon[c].x;
		}
	}

	leftUpperC.x = leftB;
	rightUpperC.x = rightB;
	leftLowerC.x = leftB;
	rightLowerC.x = rightB;

	if(projection == PT_YINCT2B)
	{
		leftUpperC.y = upperB;
		rightUpperC.y = upperB;
		leftLowerC.y = belowB;
		rightLowerC.y = belowB;
	}
	else
	{
		leftUpperC.y = belowB;
		rightUpperC.y = belowB;
		leftLowerC.y = upperB;
		rightLowerC.y = upperB;
	}

	CalcBound(X0out, Y0out, nrRows, nrCols, &leftUpperC, &rightUpperC,
	 	&leftLowerC, &rightLowerC, borderValue, cellSize, angle,
	 	projection, contract);
	return 0;
}
示例#4
0
文件: main.c 项目: pcraster/pcraster
/* Determines the smallest fitting rectangle around input maps. 
 * The bordervalue is added.
 * Returns x0, y0, nrRows and nrCols for out.
 */
static int SmallestFittingRectangle(
	REAL8 *X0out,		/* write-only X0 */
	REAL8 *Y0out,		/* write-only Y0 */
	size_t *nrRows,		/* write-only nr of rows */
	size_t *nrCols,		/* write-only nr of columns */
	MAP **in,  		/* read-only pointer to input maps */
	int borderValue,	/* bordervalue */
	size_t nrMaps,		/* number of input maps */
	REAL8 cellSize,		/* cell size of output map */
	REAL8 angle,		/* angle of output map */
	CSF_PT projection,	/* projection of output map */
	BOOL contract)		/* map should be contracted */
{
	size_t	i;
	REAL8	upperB=0, leftB=0, rightB=0, belowB=0;
	   /* ^- shut up about use before def */
	POINT2D	leftUpperC, rightUpperC, leftLowerC, rightLowerC;

	/* determine the boundaries for every map */
	for(i = 0; i < nrMaps; i++)
	{
		MAP	*X = in[i];
		int	c;
		POINT2D	polygon[4];		/* rectangle */
		REAL8	X0 = RgetX0(X);
		REAL8	Y0 = RgetY0(X);
		REAL8	nrR = (REAL8) RgetNrRows(X);
		REAL8	nrC = (REAL8) RgetNrCols(X);

		/* transform corners of map into x- and y-coordinates */
		polygon[0].x = X0;
		polygon[0].y = Y0;
		RrowCol2Coords(X, 0.0, nrC - EPSILON, &polygon[1].x,
				&polygon[1].y);
		RrowCol2Coords(X, nrR - EPSILON, nrC - EPSILON,
				&polygon[2].x, &polygon[2].y);
		RrowCol2Coords(X, nrR - EPSILON, 0.0, &polygon[3].x,
			&polygon[3].y);

		/* Rotate all corners of map */	
		if(angle != 0)
			for(c = 0; c < 4; c++)
			    RotPoint(polygon + c, angle);

		/* Determine boundaries of rotated output map */
		for(c = 0; c < 4; c++)
		{
			if((i==0&&c==0)||polygon[c].y > belowB)
				belowB = polygon[c].y;
			if((i==0&&c==0)||polygon[c].y < upperB)
				upperB = polygon[c].y;
			if((i==0&&c==0)||polygon[c].x > rightB)
				rightB = polygon[c].x;
			if((i==0&&c==0)||polygon[c].x < leftB)
				leftB = polygon[c].x;
		}
	}

	/* Put boundaries in corners of the rotated map */
	leftUpperC.x = leftB;
	rightUpperC.x = rightB;
	leftLowerC.x = leftB;
	rightLowerC.x = rightB;

	if(projection == PT_YINCT2B)
	{
		leftUpperC.y = upperB;
		rightUpperC.y = upperB;
		leftLowerC.y = belowB;
		rightLowerC.y = belowB;
	}
	else
	{
		leftUpperC.y = belowB;
		rightUpperC.y = belowB;
		leftLowerC.y = upperB;
		rightLowerC.y = upperB;
	}

	/* calculate the boundary of the output map */
	CalcBound(X0out, Y0out, nrRows, nrCols, &leftUpperC, &rightUpperC,
	 	&leftLowerC, &rightLowerC, borderValue, cellSize, angle,
	 	projection, contract);
	return 0;
}