1 #include "csf.h"
2 #include "csfimpl.h"
3 
4 #include <math.h> /* floor */
5 
6 /* compute (fractional) row, column index from true world co-ordinate.
7  * RasterCoords2RowCol computes row, column index from true world co-ordinate.
8  * The row and column co-ordinate are returned as fractions (See parameters
9  * section).
10  * The x,y co-ordinate
11  * don't have to be on the map. They are just relative to upper left position.
12  *
13  * returns
14  * 0 if the co-ordinate is outside the map,
15  * 1 if inside,
16  * -1 in case of an error
17  *
18  * Merrno
19  * ILL_CELLSIZE
20  */
RasterCoords2RowCol(const CSF_RASTER_LOCATION_ATTRIBUTES * m,double x,double y,double * row,double * col)21 void RasterCoords2RowCol(
22  const CSF_RASTER_LOCATION_ATTRIBUTES *m,
23  double x,      /* x of true co-ordinate */
24  double y,      /* y of true co-ordinate */
25  double *row,   /* write-only. Row index (y-pos). floor(row) is row number,
26                  * if (row >= 0) then fmod(row, 1) is in-pixel displacement from pixel-top,
27                  * if (row <0) then fmod(row, 1) is in-pixel displacement from pixel-bottom.
28                  */
29  double *col)   /* write-only. Column index (x-pos). floor(col) is column number,
30                  * if (col >= 0) then fmod(col, 1) is in-pixel displacement from pixel-left,
31                  * if (col <0) then fmod(col, 1) is in-pixel displacement from pixel-right.
32                  */
33 {
34 	double cs = m->cellSize;
35 	double xCol = (x - m->xUL) / cs;
36 	double yRow = (((m->projection == PT_YINCT2B)
37 	                ? (y - m->yUL)
38 	                : (m->yUL - y)) / cs);
39 	/* rotate clockwise: */
40 	double c = m->angleCos;    /* cos(t) == cos(-t) */
41 	double s = -(m->angleSin); /* -sin(t) == sin(-t) */
42 	*col  = xCol * c - yRow * s;
43 	*row  = xCol * s + yRow * c;
44 }
45 
RasterCoords2RowColChecked(const CSF_RASTER_LOCATION_ATTRIBUTES * m,double x,double y,double * row,double * col)46 int RasterCoords2RowColChecked(
47  const CSF_RASTER_LOCATION_ATTRIBUTES *m,
48  double x,      /* x of true co-ordinate */
49  double y,      /* y of true co-ordinate */
50  double *row,
51  double *col)
52 {
53 	double row_,col_; /* use copies, func( , , ,&dummy, &dummy) will fail */
54 	RasterCoords2RowCol(m,x,y,&row_,&col_);
55   *row = row_;
56   *col = col_;
57 	return( row_ >= 0 && col_ >= 0 &&
58 	        (m->nrRows > row_) && (m->nrCols > col_) );
59 }
60 
61 /* compute (fractional) row, column index from true world co-ordinate.
62  * Rcoord2RowCol computes row, column index from true world co-ordinate.
63  * The row and column co-ordinate are returned as fractions (See parameters
64  * section).
65  * The x,y co-ordinate
66  * don't have to be on the map. They are just relative to upper left position.
67  *
68  * returns
69  * 0 if the co-ordinate is outside the map,
70  * 1 if inside,
71  * -1 in case of an error
72  *
73  * Merrno
74  * ILL_CELLSIZE
75  */
Rcoords2RowCol(const MAP * m,double x,double y,double * row,double * col)76 int Rcoords2RowCol(
77  const MAP *m,  /* map handle */
78  double x,      /* x of true co-ordinate */
79  double y,      /* y of true co-ordinate */
80  double *row,   /* write-only. Row index (y-pos). floor(row) is row number,
81                  * if (row >= 0) then fmod(row, 1) is in-pixel displacement from pixel-top,
82                  * if (row <0) then fmod(row, 1) is in-pixel displacement from pixel-bottom.
83                  */
84  double *col)   /* write-only. Column index (x-pos). floor(col) is column number,
85                  * if (col >= 0) then fmod(col, 1) is in-pixel displacement from pixel-left,
86                  * if (col <0) then fmod(col, 1) is in-pixel displacement from pixel-right.
87                  */
88 {
89 	double row_,col_; /* use copies, func( , , ,&dummy, &dummy) will fail
90 	                   * otherwise
91 	                   */
92 	if (m->raster.cellSize <= 0
93 	    || (m->raster.cellSize != m->raster.cellSizeDupl ) )
94 	{ /* CW we should put this in Mopen */
95 		M_ERROR(ILL_CELLSIZE);
96 		goto error;
97 	}
98 
99 	RasterCoords2RowCol(&(m->raster),x,y,&row_,&col_);
100         *row = row_;
101         *col = col_;
102 	return( row_ >= 0 && col_ >= 0 &&
103 	        (m->raster.nrRows > row_) && (m->raster.nrCols > col_) );
104 error:  return(-1);
105 }
106 
107 
108 /* compute row, column number of true world co-ordinate
109  * RgetRowCol computes row, column number of true world co-ordinate.
110  *
111  * returns
112  * 0  if the co-ordinate is outside the map,
113  * 1 if inside,
114  * -1 in case of an error
115  *
116  * Merrno
117  * ILL_CELLSIZE
118  */
RgetRowCol(const MAP * m,double x,double y,size_t * row,size_t * col)119 int RgetRowCol(
120 	const MAP *m, /* map handle */
121 	double x,     /* x of true co-ordinate */
122 	double y,     /* y of true co-ordinate */
123 	size_t *row,   /* write-only. Row number (y-pos).
124 	               * Undefined if (x,y) is outside of map
125 	               */
126 	size_t *col)   /* write-only. Column number (x-pos).
127 	               * Undefined if (x,y) is outside of map
128 	               */
129 {
130 	double row_d,col_d;
131 	int    result;
132 	result = Rcoords2RowCol(m,x,y,&row_d,&col_d);
133 	if (result > 0)
134 	{
135 		*row = (size_t)floor(row_d);
136 		*col = (size_t)floor(col_d);
137 	}
138 	return(result);
139 }
140