define DM_CUSTOM_CIRCLE 30
define DM_CUSTOM_ELLIPSE 31
define DM_CUSTOM_RECT 32
define DM_CUSTOM_LINE 33
define DM_CUSTOM_POINT 34
define DM_CUSTOM_POLYGON 35
define DM_CUSTOM_POLYLINE 36
In the handler assigned to your toolbutton, you can extract the coordinates or the object drawn by the user. Most of the draw modes gives you back the coordinates where the user clicked and potentially where the user released the mouse button again. The draw modes for polylines and polygons are different, they return the actual object drawn by the user.
You can use the CommandInfo function to extract the values after the tool was used. Typically, you will use the CMD_INFO_X and CMD_INFO_Y attributes to extract the coordinates. For draw modes that return two coordinates, use CMD_INFO_X2 and CMD_INFO_Y2 to get the coordinate of the feature drawn. For polylines and polygons, use CMD_INFO_CUSTOM_OBJ to extract the feature that was drawn. These attributes are all defined in MapBasic.def:
Define CMD_INFO_X 1
Define CMD_INFO_Y 2
Define CMD_INFO_X2 5
Define CMD_INFO_Y2 6
Define CMD_INFO_CUSTOM_OBJ 1
We add a toolbutton to an existing SplitButton control and set the drawmode to DM_CUSTOM_CIRCLE in this case. In the source code below, I'm using the RIBBONLib to create the TolButton:
sTabName = "TabMap"sGroupName = "MapSelection"sSplitButtonName = "MapFindSplitButton"sSplitButtonGroupName = "MapFindSplitButtonGroup"
nCtrlIdx = RBNSplitButtonGroupAddControl("cmdFindUsingPoint", "Find Using Point", "", ControlType_ToolButton, sTabName, sGroupName, sSplitButtonName, sSplitButtonGroupName)If nCtrlIdx > 0 Then Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(), "Find records around a point using a custom Spectrum Web Service", "") Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, MI_IMG_SPA_SETTARGET_16, MI_IMG_SPA_SETTARGET_32) Call RBNControlSetCustomMBXHandlerIdx(nCtrlIdx, "MENUSearchUsingPoint") '**Specify the drawmode of the tool Call RBNControlSetDrawModeIdx(nCtrlIdx, DM_CUSTOM_CIRCLE) Call RBNControlSetMICursorIdx(nCtrlIdx, MI_CURSOR_FINGER_LEFT, "")End If
Now when the user uses the tool, the handler MENUSearchUsingPoint will get called after the tool was used. In the handler/subprocedure, we extract the coordinates of the drawn feature. In the map window, the user sees a dotted circle being drawn as he moves the cursor to make the circle larger.
To extract the coordinates in the subprocedure, you will use CommandInfo using the coordinate attributes, X, Y, X2, and Y2:
Set CoordSys Earth Projection 1, 104fXMin = CommandInfo(CMD_INFO_X)fYMin = CommandInfo(CMD_INFO_Y)fXMax = CommandInfo(CMD_INFO_X2)fYMax = CommandInfo(CMD_INFO_Y2)It's important to notice, that the coordinates you extract are the center and a point on the circle. It's the minimum and maximum coordinates of the minimum bounding rectangle of the circle:
Set CoordSys Earth Projection 1, 104fXMin = CommandInfo(CMD_INFO_X)fYMin = CommandInfo(CMD_INFO_Y)fXMax = CommandInfo(CMD_INFO_X2)fYMax = CommandInfo(CMD_INFO_Y2)
Also notice that the red circle and the white rectangle in the map, are drawn for illustration purpose. If you want them drawn, you will have to drawn them yourself, That is not part of the drawmode.
To calculate the center of the circle, you need to find the middle between the two coordinates given:
fXCenter = (fXMin + fXMax) / 2 fYCenter = (fYMin + fYMax) / 2
fXCenter = (fXMin + fXMax) / 2
And finally, to calculate the redius of the circle, you need to calculate the distance from the center to a point on the circle. We will use this point (MaxX, centerY) which is the point at the middle of the right side.
I will use the Distance function to calculate the length of the radius. If you are using projected coordinate systems, I would recommend that you use the CartesianDistance function.
fDistance = Distance(fXCenter, fYCenter, fXMax, fYCenter, "m")
Now I have the values I need to be able to calculate the circle drawn by the user. I can do this using the Buffer()/CartesianBuffer() function or using the CreateCircle() function. In this case I'm passing the details to a service and let this deal with the calculations.
Have you used any of the draw modes in your custom MapBasic tool?