Greetings,
Thanks to everyone who wrote with suggestions on how to find the distance
from a given point to the nearest object of a given type. The two basic
solution approaches are:
1) Create a number of lines that radiate out from the known point and
detect intersection. I implemented this using 36 lines (every 10 degrees).
I used the GetEndpoint subroutine from the MapBasic library to find each
lines' endpoint. After finding the closest intersection, I ran a more
refined search from -10 degrees to +10 degrees from the original line
(that produced the closest intersect). Results: this works nicely in
situations in which the objects of interest are arranged "around" the known
point. An example is a state boundary -- this would work well to find the
distance from any point within a state to the closest state boundary. It
does not work well when the objects are small and likely to fall in between
the radiating lines. An example of this would be finding the closest city,
assuming city objects are small relative to the distances between them.
2) Create buffers around the known point and detect intersection. Set
upper and lower limits on the distance based on teh detection of
intersection. Alter the size of the buffer using a binary search until you
are within a given tolerance (difference between upper and lower limits).
Although this method *seemed* to take longer to process than the radiating
lines, it is sure to capture small objects or lines that would be parallel
to the radiating lines.
After experimentation, I used the second method. The following simple
routine is the one I use to find the closest object to a given point. I've
only tried it on linear objects and point objects, but it should work on
regions as well. I'd appreciate any suggestions or comments. I've only
used MB for a few weeks and welcome even seemingly trivial suggestions.
Thanks and good luck,
Steve Riese
[EMAIL PROTECTED]
'**************************************************************************
****
Function Distance_to_Object(x1, y1 As Float) As Float
'Created By: Stephen R. Riese
'E-Mail: [EMAIL PROTECTED]
'Date: 1/6/00
'This function determines the distance from a known point
'(x1, y1) to the nearest obect in a table. As it is written, it
'assumes that (x1, y1) is the center of a grid cell. If you don't
'use grid cells, you will need an object to replace "cell."
'These cells are objects in a table called "Grid." At this point
'in the program, the appropriate row in Grid is selected.
'The buffers created to detect intersection have 32 points.
'I use meters and a measurement within 2 meters is close enough.
'The variables "lower" and "upper" are the bounds on the binary
search.
Dim x2, x_intercept, y2, y_intercept, dist As Float,
feature_object, intersection, cell, cell_buffer As Object,
row_number, short_row As SmallInt,
lower, radius, upper, difference As Integer,
close_enough, intersect As Logical
close_enough = FALSE
lower = 0
'starting lower limit
radius = 10000 'starting
"guess" value
upper = 50000 'arbitrary
upper limit
cell = Grid.obj
Do While close_enough = FALSE
cell_buffer = Buffer(cell, 32, radius, "m")
'creates buffer object
'
' leave these lines in to show what's going on graphically
' Insert Into Grid (Obj)
' Values (cell_buffer)
'
Fetch First From Object_Table
intersect = FALSE
Do While Not EOT(Object_Table) 'check each
object in the table
row_number = Object_Table.RowID
feature_object = Object_Table.obj
If cell_buffer Intersects feature_object Then
'if intersects then subtract
upper = radius 'set new
upper limit
radius = radius - (radius - lower)/2
'new "guess"
Fetch Last From Object_Table
intersect = TRUE
End If
Fetch Next From Object_Table
Loop
If intersect = FALSE Then
lower = radius 'set new
lower limit
radius = radius + (upper - radius)/2
'new "guess"
End If
difference = upper - lower
If difference < 3 Then
'checks for stopping condition
close_enough = TRUE
End If
Loop
cell_buffer = Buffer(cell, 32, upper, "m")
x_intercept = CentroidX(IntersectNodes(cell_buffer, feature_object,
INCL_ALL))
y_intercept = CentroidY(IntersectNodes(cell_buffer, feature_object,
INCL_ALL))
dist = Distance(x1, y1, x_intercept, y_intercept, "m")
Distance_to_Object = dist
End Function 'Distance_to_Object
'**************************************************************************
****
----------------------------------------------------------------------
To unsubscribe from this list, send e-mail to [EMAIL PROTECTED] and put
"unsubscribe MAPINFO-L" in the message body, or contact [EMAIL PROTECTED]