ArcGIS Desktop – Finding Nearest Raster Cell Value Based on Vector Point

arcgis-desktoprasterspatial-analystvector

I have two layers in ArcGIS: One is a vector point and the other is a raster layer. I want to append the value of the raster data grid to the vector point. The problem is the vector point is away from any existing raster grids with value, so the command "Sample" return no value for those vector point.

So my question is: How can I find the nearest raster cell given a vector point and extract the value from the cell?

Actually there are two things I need to do:

  1. Identify the outliner within a ranger (Usually 1-2 cells away from my existing raster)
  2. Assign a value from the nearest raster to them, if they are in a range

Edited:
I have about 3000 vector points and my problem is this:
enter image description here

I need to append the raster value based on locations to the vector points. I used the tool "Sample" and it works well for most of the points.

However, there is a situation like this
enter image description here

The right point can get the value from the raster ("Sample" works) but the left point cannot due to the alignment issues.

Raster to polygon is not working because I get error message that I cannot turn them into vector because they are out of the domain. Also I have points like thisenter image description here

Those upper points should not get any values because they are too far away from the raster.

I thought of someways to work around:

Step 1. Do the "sample" first

Step 2. Select the null value after the "sample" operations

Step 3. construct buffer zones (within 1 decimal degree) based on the null points

Step 4. use zonal statistics??? or other tools to loop through all the raster cells in the buffer, find the nearest one, extract its value and put it in the vector point.

I am stucked at step 4. I don't know which tool in ArcSDK I can use to achieve this function.

Or else…Do you have better idea to deal with that?

I have 20 raster layers like this and I would like to make it automatically (using model builder and arcobject).

Best Answer

A raster outline occupies a rectangle bounded on the lower left by the origin, having coordinates (say) (x0, y0), and on the upper right by (x1, y1): these are properties easily discovered of any raster. You can use this information to move any points outside the raster's extent onto the nearest point on the raster's boundary and extract the raster values at the new locations.

Tasks like this are often readily worked out by considering lower dimensions. A one-dimensional raster's extent is just an interval of numbers, say from x0 to x1 > x0, conventionally written [x0,x1]. Suppose you want to find the nearest point in this interval to a given number x. There are three cases: x < x0 (x is to the left), x0 <= x <= x1 (x is in the interval), and x1 < x (x is to the right). Clearly the nearest points are x0, x, and x1, respectively. A formula for this result is

x --> min(max(x,x0),x1),

as you can see by contemplating each of the three cases separately.

Because the extent of a raster is the Cartesian product of two intervals, [x0,x1] * [y0,y1], the same formula works in two dimensions. Just apply it to each interval. Thus the projected point's coordinates can be computed (in a Field Calculator, say) as

(x,y) --> ( min(max(x,x0),x1), min(max(y,y0),y1 ).

Here is this formula in action with 100 points randomly placed around and within a grid's extent:

Figure

The dashed lines visually associate points outside the extent to the locations where they will be moved.

Create a point layer from these computed coordinates and apply the Sample tool to extract the raster values. Join the results back to the original point layer.

As a practical matter, to avoid problems with floating point roundoff that might keep the new points from lying within the grid's extent, it would be wise to make x0 and y0 slightly bigger than the true origin (you might add half the cellsize to them) and, similarly, make x1 and y1 slightly smaller.

In summary, the workflow consists of calculating two fields (the new coordinates) in the original point layer's table, creating a point event layer from those new coordinates, running the Sample tool, and performing a database join (not a spatial join).


When you have many more vector points than there are cells in the raster, you should prefer the solution given by @celenius (who proposes converting the raster to points and using a spatial join). Normally, though, rasters have lots of cells--millions to billions--and the conversion to points is so time-consuming and disk-consuming that it should be approached with caution.

Alternatively, you could expedite Celenius' solution by using a raster calculation to make an integer grid with values only along its boundary. Converting that to a point layer is quick and easy because it will have few points. Let's call this the "boundary layer." Sample the grid at the boundary layer points, thereby copying the grid values into the boundary layer's attribute table. After running Sample with the original point layer, remove all points where a sample was successfully obtained. Spatially join the boundary layer to the remaining points to complete the sampling process.

(One way to make a grid with values only along its boundary is to apply a focal neighborhood operation that fails along the boundary: examples include finding slopes, hillshading, 3 x 3 neighborhood focal stats. This creates a grid with a one-cell-thick ring of NoData around its edge. Using IsNull and SetNull to detect NoData cells and convert between NoData and data cells produces a grid full of NoData values except around the boundary.)

Related Question