今天來說一說超圖場景框選的實作。其實這裡的場景框選并不是真正意義的框選,而是通過空間查詢來達到和場景框選一樣的效果。
框選需要用到的接口主要有以下幾個:
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包