今天来说一说超图场景框选的实现。其实这里的场景框选并不是真正意义的框选,而是通过空间查询来达到和场景框选一样的效果。
框选需要用到的接口主要有以下几个:
1.bool IsCounterClockwise(int index); SuperMap.Data程序集 GeoRegion类
判断二维面的第index部分是否为顺时针。若为顺时针返回true;否则 返回false
2.GeoModel3D LinearExtrude(Geometry geometry, bool bLonLat, double height, double twist, double scaleX, double scaleY); SuperMap.Realspace.ThreeDDesigner程序集 ModelBuilder3D类
线性拉伸。参数以此表示欲拉伸的面(支持二三维面,最好是简单对象,无自相交、无岛、无环、无洞等特殊面);是否为经纬度(稍后会解释);拉伸高度;旋转角度,X和Y缩放倍数
3.bool Convert(Geometry geometry, PrjCoordSys srcPrjCoordSys, PrjCoordSys desPrjCoordSys, CoordSysTransParameter coordSysTransParameter, CoordSysTransMethod coordSysTransMethod); SuperMap.Data程序集 CoordSysTranslator类
坐标转换。 参数依次为欲转换的对象;原坐标系;目标坐标系;转换参数;转换方法
4. List<int> SpatialQuery(Geometry3D geometry, Recordset modelRecordset, PositionMode posMode);
空间查询。意思为在modelRecordset中查询与geometry具有posMode这种关系的id列表,目前支持点与点、点与模型、模型与点、模型与模型
PositionMode 共有六种关系
主要的流程如下:
一、.绘制面并对面做处理
private void m_sceneControl_Tracked(object sender, Tracked3DEventArgs e)
{
int index = m_sceneControl.Scene.TrackingLayer.IndexOf(this.m_tag);
if (index > -1)
{
m_sceneControl.Scene.TrackingLayer.Remove(index);
}
//如果是三维面
if (e.Geometry is GeoRegion3D)
{
Point2Ds pnts = (e.Geometry as GeoRegion3D)[0].ToPoint2Ds();
GeoRegion region = new GeoRegion(pnts);
GeoLine geoline = new GeoLine(region[0]);
//如果是顺时针
if (!region.IsCounterClockwise(0))
{
//反转一下点
geoline.Reverse();
}
//重新由点构面
m_queryRegion = geoline.ConvertToRegion();
//查询相关
QueryForm queryForm = new QueryForm(m_sceneControl, m_queryRegion);
if (queryForm.ShowDialog() == DialogResult.OK)
{
MessageBox.Show(queryForm.SelectionMessage);
}
m_queryRegion.Dispose();
m_queryRegion = null;
}
//绘制结束注销相关事件处理函数
m_sceneControl.Action = Action3D.Pan;
m_sceneControl.Tracking -= m_sceneControl_Tracking;
m_sceneControl.Tracked -= m_sceneControl_Tracked;
}
二、面拉伸及查询
QueryForm窗体类界面
需要选择图层,底部高程,拉伸高度

主要代码
private void m_btnOK_Click(object sender, EventArgs e)
{
if (this.m_SceneControl != null && this.m_queryRegion != null)
{
this.Cursor = Cursors.WaitCursor;
//拉伸高度
double height = (double)m_numericUpDownHeight.Value;
//底部高程
double bottomAltitude = (double)m_numericUpDownBottomAltitude.Value;
GeoModel3D model3d = null;
Recordset recordset = null;
try
{
bool bLonLat = true;
bool bNeedConvert = false;
Layer3DDataset selectedLayer = m_comboBoxLayer3D.SelectedItem as Layer3DDataset;
if (m_SceneControl.Scene.Type != SceneType.Globe)
{
bLonLat = false;
}
if (selectedLayer.Dataset.PrjCoordSys.Type != PrjCoordSysType.EarthLongitudeLatitude)
{
bNeedConvert = true;
}
model3d = ModelBuilder3D.LinearExtrude(this.m_queryRegion, bLonLat, height, 0, 1, 1);
if (model3d == null)
{
return;
}
model3d.Position = new Point3D(model3d.Position.X, model3d.Position.Y, bottomAltitude);
recordset = (selectedLayer.Dataset as DatasetVector).GetRecordset(false, CursorType.Static);
if (bNeedConvert)
{
if (bLonLat)
{
PrjCoordSys sourceprj = new PrjCoordSys(PrjCoordSysType.EarthLongitudeLatitude);
//转换参数和方法new一个就行
CoordSysTranslator.Convert(model3d, sourceprj, selectedLayer.Dataset.PrjCoordSys, new CoordSysTransParameter(), new CoordSysTransMethod());
}
}
recordset = (selectedLayer.Dataset as DatasetVector).GetRecordset(false, CursorType.Dynamic);
List<int> IDs = null;
PositionMode mode = PositionMode.Contains;
if (m_checkBoxSelectBorder.Checked)
{
//包含与FGometry模型相交的对象
mode = PositionMode.IntersectsOrContains;
}
IDs = SpatialQuery3D.SpatialQuery(model3d, recordset, mode);
if (IDs != null)
{
if (IDs.Count > 0)
{
//清除已经选中的对象
foreach (Layer3D layer in m_SceneControl.Scene.Layers)
{
if (layer.Selection != null)
{
layer.Selection.Clear();
}
}
//将查询到的对象选中
selectedLayer.Selection.AddRange(IDs.ToArray());
selectedLayer.Selection.UpdateData();
}
SelectionMessage = "共选中" + IDs.Count.ToString() + "个对象。";
}
}
catch (System.Exception ex)
{
}
finally
{
if (model3d != null)
{
model3d.Dispose();
model3d = null;
}
if (recordset != null)
{
recordset.Dispose();
recordset = null;
}
this.DialogResult = DialogResult.OK;
this.Cursor = Cursors.Default;
this.Close();
}
}
}
工程代码:
http://download.csdn.net/download/wy1334526911/10142512
不包含bin包