I am looking for the fastest way to assign new values to a whole row of a large raster.
I have a large raster called ras
> ras
class : RasterLayer
dimensions : 71476, 49933, 3569011108 (nrow, ncol, ncell)
resolution : 30, 30 (x, y)
extent : 593235, 2091225, -3314375, -1170095 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=aea +lat_1=-18 +lat_2=-36 +lat_0=0 +lon_0=132 +x_0=0 +y_0=0 +ellps=GRS80 +units=m +no_defs
data source : C:/Users/smithj/AppData/Local/Temp/RtmpiynZ5N/raster/r_tmp_2019-05-04_232648_206436_44436.grd
names : layer
values : 0, 255 (min, max)
And I have a vector of length n=ncol values called newvals. I generate newvals through a function that is not amenable to use with the calc function, but in the example below it is just a randomly generated vector for the purposes of this question.
#create example values
newvals<-sample(0:100,49933, replace=TRUE)
My question is, if I wanted to replace the 7023rd row of ras with newvals is there a faster method than the one below?
#insert newvals into row 7023 of ras
ras[7023,]<-newvals
I have also looked at setValues, but it seems to only set values for a whole raster, not part of it(?). Any help would be appreciated
You do not provide much context. The problem is that you have a large dataset that is file-based, so any change will create a new file (unless you use update).
If you need to do this many times, for example row by row, you can open a new file for writing and write row by row (see writeStart). If it is only one row that needs to be changed, perhaps try your luck with raster::update.
I am using QwtPlotBarChart to draw a histogram. I have set the chart up so that there is zero spacing between bars, and my xBottom axis has the real range of the data.
Samples are set on the chart using a QVector of QPointF, with the x values corresponding to the midpoints of the bins.
A QwtPlotPicker hovering over the bars shows that they start and end at the actual start and ends of the bins.
However, I am having trouble getting the ticks where the labels are drawn to show up in the correct place along the x axis. I am using a custom scaledraw, similar to the distrowatch example. I have an additional couple of parameters, namely the minimum value of the data range, and the bin size. My label index code looks like this:
virtual QwtText label( double value ) const
{
QwtText lbl;
//const int index = qRound( value );
const int index = (int)(value-_min_val)/_bin_size;
if ( index >= 0 && index < d_labels.size() )
{
lbl = d_labels[ index ];
}
return lbl;
}
This seems to be ok; my labels show the min and max values of each bin and a nearly in the right place.
I have tried to set the tick positions as follows:
QwtScaleDiv div = _plot->axisScaleDiv(QwtPlot::xBottom);
div.setTicks(QwtScaleDiv::MajorTick, x_data.toList());
_plot->setAxisScaleDiv(QwtPlot::xBottom, div);
here x_data is the vector of bin midpoints used to plot the data. The axis range is set using:
double half_bin = bin_size / 2.0;
_plot->setAxisScale(QwtPlot::xBottom, x_data.first() - half_bin, x_data.last() + half_bin, bin_size);
Any ideas what I'm missing? Depending on the number of bins, the ticks (and subsequently the labels) will occasionally line up with the mid point of the bins (or at least most of them), but as I change the bin count, the ticks will become more or less offset from the center of the bin.
So, I have a list of x,y coordiates. I want to find out whether that list of coordinates span all rows of a matrix of values and same for columns.
i.e.
T F F F
T T F F
F T F F
F T T F
Here the group of T's are provided as coordinates so it would be something like [(0,0),(0,1),(1,1),(1,2),(1,3),(2,3)]. How can i find out using these coordinates that the set they describe spans all rows of the matrix? This also applies to columns, as well as both ( so, whether the set spans both rows and columns ).
The values are currently stored as vector<vector<coord>> where coord is a struct like :
struct coord {
int x, int y;
}
Assuming that all you have is the size of the matrix (m x n = row x column) and the position of T's in term of coordinates (std::vector<std::vector<coord>>), you can do:
std::vector<std::vector<coord>> Ts_pos;
std::set<int> rows;
std::set<int> cols;
bool spansRow = false;
bool spansCol = false;
for (int i = 0; i < Ts_pos.size(); i++)
{
for (int j = 0; j < Ts_pos[i].size(); j++)
{
item = Ts_pos[i][j];
cols.insert(item.x);
rows.insert(item.y);
}
}
if (rows.size() == numRows) spansRow = true;
if (cols.size() == numCols) spansCol = true;
After executing the loop, the two set will contain the index number of the rows and of the columns touched by the T's, i.e: consider, in you exemple, the first T. It has coordinates (0,0) so it touches the column with index 0 and the row with the index 0, so you insert 0 in the row set and 0 in the col set. Then, you consider the second T in your list and so on.
Outside the loop, you can discover if all rows have been touched simply querying for the size of the row set. If it is equal to the number of rows of the matrix, then, all the rows have been touched and the set of T's spans the matrix by row, at least.
The same you do for the column set.
Then you can std::cout what you want according to the value of spansRow and spansCol.
We can store all the x-coordinates and all the y-coordinates in separate vectors, sort these vectors and check if values from 0-n are present in each vector (where n is the no. of rows for x-vector and no. of columns for y-vector).
Missing values, values ranging to less than n, values starting from greater than 0, etc will provide us with the answer whether the set spans both rows and columns.
You just need to de-duplicate the xs and the ys, and compare them to the required indexes. E.g.
std::set<int> required = { 0, 1, 2, 3 }; // values that must be present
bool spans_direction(const std::vector<coord> & coords, std::function<int(coord)> projection)
{
std::set<int> projected;
std::transform(coords.begin(), coords.end(), std::inserter(projected, projected.end()), projection);
return projected == required;
}
bool spans_cols(const std::vector<coord> & coords)
{
return spans_direction(coords, [](coord c) { return c.x; });
}
bool spans_rows(const std::vector<coord> & coords)
{
return spans_direction(coords, [](coord c) { return c.y; });
}
The grid is a list of 7 lists, each list is a column that can contains 6 elements maximum. For victory check, I implemented vertical victory and horizontal victory as below. But I have problems with diagonal check. Any suggestions?
% Vertical end check
isEndVert(Grid, J, N) :-
getColumn(N, Grid, Column),
sublist([J,J,J,J], Column),
!.
isEndVert(Grid, J, N) :-
N > 0,
N1 is N-1,
isEndVert(Grid, J, N1).
% Horizontal end check
isEndHor(Grid, J, N) :-
getLine(N, Grid, Line),
sublist([J,J,J,J], Line),
!.
isEndHor(Grid, J, N) :-
N > 0,
N1 is N-1,
isEndHor(Grid, J, N1).
Well, you have getLine/3 and getColumn/3, let's make getDiagonal/3:
getDiagonal(Grid, Diagonal) :-
length(Grid, Columns),
bagof(Cell,
I^Row^(between(1, Columns, I),
(nth1(I, Grid, Row),
nth1(I, Row, Cell))),
Diagonal).
This gets us the "Ith" elements of the list for each list numbered from I. This gets us basically the descending diagonal. We need another clause to get the other:
getDiagonal(Grid, Diagonal) :-
length(Grid, Columns),
bagof(Cell,
OppositeI^I^Row^(between(1, Columns, I),
(OppositeI is Columns + 1 - I,
nth1(I, Grid, Row),
nth1(OppositeI, Row, Cell))),
Diagonal).
The ^ syntax in here is a quantifier; it basically says to bagof/3 that we don't consider different instantiations of those variables as necessitating new bags. findall/3 is more concise but I have a strange preference for bagof/3.
Having built that you can probably solve the problem the way you do for the vertical and horizontal cases.
using only list scan, an example of 2 wins, matching forward and backward diagonals:
test(J) :- Grid=[
[-,-,-,-,-,-,-],
[-,-,-,-,-,-,-],
[-,-,-,J,-,-,-],
[-,-,J,-,J,-,-],
[-,J,-,-,-,J,-],
[J,-,-,-,-,-,J]
], append(_,[A,B,C,D|_],Grid), % test 4 consecutive rows
( start([A,B,C,D],J) ; start([D,C,B,A],J) ).
% on first row of 4, find first matching column
start([[J|_]|R],J) :- skip1(R,S), diag(S,J). % first found, match diag
start(R,J) :- skip1(R,S), start(S,J).
% each first cell of rows' sequence must match
diag([[J|_]],J). % last row: success
diag([[J|_]|T],J) :- skip1(T,S), diag(S,J).
% discard first column of each row
skip1([],[]).
skip1([[_|R]|T],[R|S]) :- skip1(T,S).
I think it should work independently of the matrix representation being rows or columns oriented. Comments assume a row oriented representation.
Some sample code about image processing using OpenCV give somethings like this:
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
if(pointPolygonTest(Point(i,j),myPolygon))
{
// do some processing
}
}
}
In the iteration, why we need to start from height and width? and also why the Point is store (height, width) so that is -> (y,x) ?
Ranges between [0..Height] and [0..Width] are maximum boundaries of your working area.
This code is testing which pixels of whole image are inside the polygon myPolygon.
The word "whole" means you should check all pixels of your image so you should iterate from 0 to height for Y, and iterate from 0 to width for X.
Actually here, the row/column convention is used to iterate over the whole image.
height = Number of Rows
width = Number of Columns
The image is being accessed row wise.The outer loop is iterating over rows of the image and the inner loop is iterating on columns. So basically i is the current row and j is the current column of the image.
The inner loop processes a complete row of the image.