Finding nearest raster cell value based on vector point?

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: 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 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 this 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).

• @whuber: Your method sounds very clever. My question is I am handling data on a global scale and how can I determine the x0 and x1 for the outlining raster? – Seen May 7 '11 at 16:50
• Inspect its properties after adding it to the project. – whuber May 7 '11 at 17:37
• Zonal stats is a dead end. Based on your edit, there is a simple direct solution: expand the raster slightly around its boundary and sample the expanded raster. There are many ways to do this, but they all require a little facility with raster calculations. One of the simplest is to enlarge the analysis extent, compute a focal mean and (using 'con') paste its values into the NoData boundary zone. This assigns a mean of nearby raster values to each off-raster sample location. – whuber May 7 '11 at 17:41
• @whuber There is another problem is that I don't know where the outliners are. So there are actually 2 procedures in my process: identify the outliners and assign values to them. – Seen May 7 '11 at 21:08
• What is an "outliner"? If it's a point not covered by a raster value, you can't help but find them: these will be the points that don't receive any values when you apply the Sample tool. – whuber May 8 '11 at 13:55

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: 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.)

• 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). Could you elaborate how to do this? (You can see my pics for my problem). Thanks! – Seen May 7 '11 at 16:37
• I have about 15% points have this problem. how can you determine the x0 and x1 for each point? – Seen May 7 '11 at 16:46
• @Seen the x0, y0, x1, y1 are for the grids. The point coordinates (x,y) can be computed in the Field Calculator as described in the ArcGIS help or in several threads on this site. There are menu items for making an XY point layer and database joins: these are standard, basic operations. – whuber May 7 '11 at 17:36

You can convert the raster to points (ref), and then do a spatial join on the points (from the rasters) to the point.

(I just learned that points can be spatially joined here yesterday)

• +1 for a clever approach. For large grids, where this becomes impracticable, convert only the raster's boundary cells to points. (I describe how at the end of my reply.) – whuber May 7 '11 at 15:24
• I have thousands of cells of each raster layer and I have 20 layers like that...so turning those in to vector points are time consuming... – Seen May 7 '11 at 16:00
• Also, when I try to do raster to polygon, I get an error message as ERROR 000864 Input raster: The input is not within the defined domain. ERROR 000863: Invalid GP data type – Seen May 7 '11 at 16:04
• Do you get an error when converting raster to points? – djq May 7 '11 at 20:39
• @celenius It works but it took a long time. – Seen May 7 '11 at 21:05

You could convert the raster layer to a polygon using the Raster to Polygon tool and either run spatial join (right click on the point layer and select Joins and Relates - Join, on the first drop down select the spatial join option and select the is closest to option on the readio button), or use the Near tool.

• How do you use the result of the spatial join to extract the appropriate raster value? – whuber May 7 '11 at 14:47
• @whuber, within the Join Data dialog when you select the "is closest to it" option the spatial join selects the nearest polygon feature (result from the Raster to Polygon tool) and adds this attribute info to the point feature. Is this what you question was asking? My initial reply was posted before his edit. I'm guessing Seen's raster may have been too large to convert to polygon? – artwork21 May 8 '11 at 4:33
• The idea isn't to find the nearest raster. Really, what is wanted is a way to extrapolate a raster's values beyond its original extent. The question proposes a nearest neighbor approach: at any nearby point not on the raster, find the nearest cell in the raster and use that cell's value. – whuber May 8 '11 at 13:54
• Upon re-reading your last comment, it seems you might be proposing to turn the raster not into "a polygon" but into a polygon layer with one polygon for each cell (or contiguous set of cells). If that's so, it might succeed with very small rasters, but why do you propose this--which is a complex, expensive operation (and works only for integer grids)--instead of the similar but more efficient solution @celenius offered earlier? What advantages does your solution offer? – whuber May 8 '11 at 15:01
• @whuber, polygon layer is correct. Yes, celenius method would cost less memory. – artwork21 May 9 '11 at 1:24