这两天修改一个选择热点的功能。需求很简单,捕获用户在页面上鼠标点击的位置并获取到缓冲范围内的热点,弹出页面显示相关属性。
这个功能主要在于如何把屏幕的距离转换为实际的地理距离,如果是在C/S中,可以用如下代码搞定:
//获取IActiveView过程省略
pActiveView.ScreenDisplay.DisplayTransformation.FromPoints(1);
但在AGS中发现根据此接口计算出来的距离根本不正确,无论放大到什么比例尺,DisplayTransformation的属性VisibleBounds始终没变化,手工赋值也不行。估计这可能是AGS的服务端对象无法获取到客户端的控件范围造成的。后来在Arcmap的VBA环境中用如下宏测出了比例尺和屏幕像素之间的比例关系:
Public Sub GetScalePixelConst()
Dim pMxApp As IMxApplication
Dim pDoc As IMxDocument
Dim pMap As IMap
Dim pActiveView As IActiveView
Dim ScalePixelCons As Double
Set pMxApp = Application
Set pDoc = Application.Document
Set pMap = pDoc.FocusMap
Set pActiveView = pMap
ScalePixelCons = pActiveView.ScreenDisplay.DisplayTransformation.FromPoints(1)
MsgBox pMap.MapScale / ScalePixelCons
End Sub
输出的值为2834.64.OK,这样的话就可以自己编函数来实现类似于DisplayTransformation.FromPoints()的功能了:
private const double ScalePerScreenPoint = 2834.64;
/// <summary>
/// 把屏幕像素点数所代表的距离转换为实际地理距离
/// </summary>
/// <param name="mapScale">地图比例尺</param>
/// <param name="pixelUnits">屏幕像素个数</param>
/// <returns>实际地理距离</returns>
public static double ConvertPixelsToMapUnits(double mapScale, double pixelUnits)
{
return pixelUnits * mapScale / ScalePerScreenPoint;
}
经测试顺利通过,这样只要传入当前地图比例尺和所要缓冲的像素点就可以轻松获取到实际的缓冲距离了。这是个很小的问题,解决方法也很简单,但却告诉我,以后遇到难题,不要在一条路上把自己堵死了,要发散思维,从不同角度去思考问题。任何问题总有解决的办法,关键在于你是否能在该绕弯的时候勇敢地走出来!