arcengine classic code
string dbfFilePath = System.IO.Path.GetDirectoryName(strSaveFile);
string strFileName = System.IO.Path.GetFileNameWithoutExtension(strSaveFile);
IWorkspaceFactory pWorkspacefactory = new ShapefileWorkspaceFactoryClass();
IFeatureWorkspace pFWS = pWorkspacefactory.OpenFromFile(dbfFilePath, 0) as IFeatureWorkspace;
IFeatureLayer pfeaturelayer = new FeatureLayerClass();
pfeaturelayer.FeatureClass = pFWS.OpenFeatureClass(strFileName);
pfeaturelayer.Name = strFileName;
pTempLayer = pfeaturelayer as ILayer;
2 IFeature->IDataset->IWorkspace->Path
IFeatureLayer pl = (IFeatureLayer)layer;
IFeatureClass pc = pl.FeatureClass;
IDataset ds = pc as IDataset;
IWorkspace iw = ds.Workspace;
MessageBox.Show(iw.PathName);
3 最短分析
namespace GisEditor
{
/// <summary>
/// 最短路径分析
/// </summary>
public class ClsPathFinder
{
private IGeometricNetwork m_ipGeometricNetwork;
private IMap m_ipMap;
private IPointCollection m_ipPoints;
private IPointToEID m_ipPointToEID;
private double m_dblPathCost =0;
private IEnumNetEID m_ipEnumNetEID_Junctions;
private IEnumNetEID m_ipEnumNetEID_Edges;
private IPolyline m_ipPolyline;
#region Public Function
//返回和设置当前地图
public IMap SetOrGetMap
{
set{ m_ipMap = value;}
get{return m_ipMap;}
}
//打开几何数据集的网络工作空间
public void OpenFeatureDatasetNetwork(IFeatureDataset FeatureDataset)
{
CloseWorkspace();
if (!InitializeNetworkAndMap(FeatureDataset))
Console.WriteLine( "打开network出错");
}
//输入点的集合
public IPointCollection StopPoints
{
set{m_ipPoints= value;}
get{return m_ipPoints;}
}
//路径成本
public double PathCost
{
get {return m_dblPathCost;}
}
//返回路径的几何体
public IPolyline PathPolyLine()
{
IEIDInfo ipEIDInfo;
IGeometry ipGeometry;
if(m_ipPolyline!=null)return m_ipPolyline;
m_ipPolyline = new PolylineClass();
IGeometryCollection ipNewGeometryColl = m_ipPolyline as IGeometryCollection;
ISpatialReference ipSpatialReference = m_ipMap.SpatialReference;
IEIDHelper ipEIDHelper = new EIDHelperClass();
ipEIDHelper.GeometricNetwork = m_ipGeometricNetwork;
ipEIDHelper.OutputSpatialReference = ipSpatialReference;
ipEIDHelper.ReturnGeometries = true;
IEnumEIDInfo ipEnumEIDInfo = ipEIDHelper.CreateEnumEIDInfo(m_ipEnumNetEID_Edges);
int count = ipEnumEIDInfo.Count;
ipEnumEIDInfo.Reset();
for(int i =0;i<count;i++)
{
ipEIDInfo = ipEnumEIDInfo.Next();
ipGeometry = ipEIDInfo.Geometry;
ipNewGeometryColl.AddGeometryCollection( ipGeometry as IGeometryCollection);
}
return m_ipPolyline;
}
//解决路径
public void SolvePath(string WeightName)
{
try
{
int intEdgeUserClassID;
int intEdgeUserID;
int intEdgeUserSubID;
int intEdgeID;
IPoint ipFoundEdgePoint;
double dblEdgePercent;
/*PutEdgeOrigins方法的第二个参数要求是IEdgeFlag类型的数组,
* 在VB等其他语言的代码中,只需传人该类型数组的第一个元素即
* 可,但C#中的机制有所不同,需要作出如下修改:使用
* ITraceFlowSolverGEN替代ITraceFlowSolver
*/
ITraceFlowSolverGEN ipTraceFlowSolver = new TraceFlowSolverClass() as ITraceFlowSolverGEN;
INetSolver ipNetSolver = ipTraceFlowSolver as INetSolver;
INetwork ipNetwork = m_ipGeometricNetwork.Network;
ipNetSolver.SourceNetwork = ipNetwork;
INetElements ipNetElements = ipNetwork as INetElements;
int intCount = m_ipPoints.PointCount;
//定义一个边线旗数组
IEdgeFlag[] pEdgeFlagList = new EdgeFlagClass[intCount];
for(int i = 0;i<intCount ;i++)
{
INetFlag ipNetFlag = new EdgeFlagClass()as INetFlag;
IPoint ipEdgePoint = m_ipPoints.get_Point(i);
//查找输入点的最近的边线
m_ipPointToEID.GetNearestEdge(ipEdgePoint, out intEdgeID,out ipFoundEdgePoint, out dblEdgePercent);
ipNetElements.QueryIDs( intEdgeID, esriElementType.esriETEdge, out intEdgeUserClassID, out intEdgeUserID,out intEdgeUserSubID);
ipNetFlag.UserClassID = intEdgeUserClassID;
ipNetFlag.UserID = intEdgeUserID;
ipNetFlag.UserSubID = intEdgeUserSubID;
IEdgeFlag pTemp = (IEdgeFlag)(ipNetFlag as IEdgeFlag);
pEdgeFlagList=pTemp;
}
ipTraceFlowSolver.PutEdgeOrigins(ref pEdgeFlagList);
INetSchema ipNetSchema = ipNetwork as INetSchema;
INetWeight ipNetWeight = ipNetSchema.get_WeightByName(WeightName);
INetSolverWeights ipNetSolverWeights = ipTraceFlowSolver as INetSolverWeights;
ipNetSolverWeights.FromToEdgeWeight = ipNetWeight;//开始边线的权重
ipNetSolverWeights.ToFromEdgeWeight = ipNetWeight;//终止边线的权重
object [] vaRes =new object[intCount-1];
//通过findpath得到边线和交汇点的集合
ipTraceFlowSolver.FindPath(esriFlowMethod.esriFMConnected,
esriShortestPathObjFn.esriSPObjFnMinSum,
out m_ipEnumNetEID_Junctions,out m_ipEnumNetEID_Edges, intCount-1, ref vaRes);
//计算元素成本
m_dblPathCost = 0;
for (int i =0;i<vaRes.Length;i++)
{
double m_Va =(double) vaRes;
m_dblPathCost = m_dblPathCost + m_Va;
}
m_ipPolyline = null;
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
#endregion
#region Private Function
//初始化几何网络和地图
private bool InitializeNetworkAndMap(IFeatureDataset FeatureDataset)
{
IFeatureClassContainer ipFeatureClassContainer;
IFeatureClass ipFeatureClass ;
IGeoDataset ipGeoDataset;
ILayer ipLayer ;
IFeatureLayer ipFeatureLayer;
IEnvelope ipEnvelope, ipMaxEnvelope ;
double dblSearchTol;
INetworkCollection ipNetworkCollection = FeatureDataset as INetworkCollection;
int count = ipNetworkCollection.GeometricNetworkCount;
//获取第一个几何网络工作空间
m_ipGeometricNetwork = ipNetworkCollection.get_GeometricNetwork(0);
INetwork ipNetwork = m_ipGeometricNetwork.Network;
if(m_ipMap!=null)
{
m_ipMap = new MapClass();
ipFeatureClassContainer = m_ipGeometricNetwork as IFeatureClassContainer;
count = ipFeatureClassContainer.ClassCount;
for(int i =0;i<count;i++)
{
ipFeatureClass = ipFeatureClassContainer.get_Class(i);
ipFeatureLayer = new FeatureLayerClass();
ipFeatureLayer.FeatureClass = ipFeatureClass;
m_ipMap.AddLayer( ipFeatureLayer);
}
}
count = m_ipMap.LayerCount;
ipMaxEnvelope = new EnvelopeClass();
for(int i =0;i<count;i++)
{
ipLayer = m_ipMap.get_Layer(i);
ipFeatureLayer = ipLayer as IFeatureLayer;
ipGeoDataset = ipFeatureLayer as IGeoDataset;
ipEnvelope = ipGeoDataset.Extent;
ipMaxEnvelope.Union( ipEnvelope);
}
m_ipPointToEID = new PointToEIDClass();
m_ipPointToEID.SourceMap = m_ipMap;
m_ipPointToEID.GeometricNetwork = m_ipGeometricNetwork;
double dblWidth = ipMaxEnvelope.Width;
double dblHeight = ipMaxEnvelope.Height;
if( dblWidth > dblHeight)
dblSearchTol = dblWidth / 100;
else
dblSearchTol = dblHeight / 100;
m_ipPointToEID.SnapTolerance = dblSearchTol;
return true ;
}
//关闭工作空间
private void CloseWorkspace()
{
m_ipGeometricNetwork = null;
m_ipPoints = null;
m_ipPointToEID = null;
m_ipEnumNetEID_Junctions = null;
m_ipEnumNetEID_Edges = null;
m_ipPolyline = null;
}
#endregion
}
}
备注:
在调用该类时的次序:
ClsPathFinder m_ipPathFinder;
if(m_ipPathFinder==null)//打开几何网络工作空间
{
m_ipPathFinder = new ClsPathFinder();
ipMap = this.m_ActiveView.FocusMap;
ipLayer = ipMap.get_Layer(0);
ipFeatureLayer = ipLayer as IFeatureLayer;
ipFDB = ipFeatureLayer.FeatureClass.FeatureDataset;
m_ipPathFinder.SetOrGetMap = ipMap;
m_ipPathFinder.OpenFeatureDatasetNetwork(ipFDB);
}
private void ViewMap_OnMouseDown(object sender, ESRI.ArcGIS.MapControl.IMapControlEvents2_OnMouseDownEvent e)//获取地图上鼠标输入的点
{
IPoint ipNew ;
if( m_ipPoints==null)
{
m_ipPoints = new MultipointClass();
m_ipPathFinder.StopPoints = m_ipPoints;
}
ipNew = ViewMap.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x,e.y);
object o = Type.Missing;
m_ipPoints.AddPoint(ipNew,ref o,ref o);
}
m_ipPathFinder.SolvePath("Weight");//先解析路径
IPolyline ipPolyResult = m_ipPathFinder.PathPolyLine();//最后返回最短路径
4 上下左右键移动地图//闪烁线
static void FlashLine(AxMapControl mapControl,IScreenDisplay iScreenDisplay,IGeometry iGeometry)
{
ISimpleLineSymbol iLineSymbol;
ISymbol iSymbol;
IRgbColor iRgbColor;
iLineSymbol = new SimpleLineSymbol();
iLineSymbol.Width = 4;
iRgbColor = new RgbColor();
iRgbColor.Red = 255;
iLineSymbol.Color = iRgbColor;
iSymbol = (ISymbol)iLineSymbol;
iSymbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;
mapControl.FlashShape(iGeometry, 3, 200, iSymbol);
}
//闪烁面
static void FlashPolygon(AxMapControl mapControl, IScreenDisplay iScreenDisplay, IGeometry iGeometry)
{
ISimpleFillSymbol iFillSymbol;
ISymbol iSymbol;
IRgbColor iRgbColor;
iFillSymbol = new SimpleFillSymbol();
iFillSymbol.Style = esriSimpleFillStyle.esriSFSSolid;
iFillSymbol.Outline.Width = 12;
iRgbColor = new RgbColor();
iRgbColor.RGB = System.Drawing.Color.FromArgb(100, 180, 180).ToArgb();
iFillSymbol.Color = iRgbColor;
iSymbol = (ISymbol)iFillSymbol;
iSymbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;
iScreenDisplay.SetSymbol(iSymbol);
mapControl.FlashShape(iGeometry, 3, 200, iSymbol);
}
//闪烁点
static void FlashPoint(AxMapControl mapControl, IScreenDisplay iScreenDisplay, IGeometry iGeometry)
{
ISimpleMarkerSymbol iMarkerSymbol;
ISymbol iSymbol;
IRgbColor iRgbColor;
iMarkerSymbol = new SimpleMarkerSymbol();
iMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
iRgbColor = new RgbColor();
iRgbColor.RGB = System.Drawing.Color.FromArgb(0, 0, 0).ToArgb();
iMarkerSymbol.Color = iRgbColor;
iSymbol = (ISymbol)iMarkerSymbol;
iSymbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;
mapControl.FlashShape(iGeometry, 3, 200, iSymbol);
}
//闪烁目标
public static void FlashFeature(AxMapControl mapControl,IFeature iFeature, IMap iMap)
{
IActiveView iActiveView = iMap as IActiveView;
if (iActiveView != null)
{
iActiveView.ScreenDisplay.StartDrawing(0, (short)esriScreenCache.esriNoScreenCache);
//根据几何类型调用不同的过程
switch (iFeature.Shape.GeometryType)
{
case esriGeometryType.esriGeometryPolyline:
FlashLine(mapControl, iActiveView.ScreenDisplay, iFeature.Shape);
break;
case esriGeometryType.esriGeometryPolygon:
FlashPolygon(mapControl, iActiveView.ScreenDisplay, iFeature.Shape);
break;
case esriGeometryType.esriGeometryPoint:
FlashPoint(mapControl, iActiveView.ScreenDisplay, iFeature.Shape);
break;
default:
break;
}
iActiveView.ScreenDisplay.FinishDrawing();
}
}
从Google Map上弄来的根据经纬度求地球表面两点间距离的实现,稍微改编了一下,对于我国境内空间距离计算,该实现已经够用,以米为单位。.Net2.0,C#实现。
public static double DistanceOfTwoPoints(double lng1,double lat1, double lng2, double lat2, GaussSphere gs)
{
double radLat1 = Rad(lat1);
double radLat2 = Rad(lat2);
double a = radLat1 - radLat2;
double b = Rad(lng1) - Rad(lng2);
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) +
Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
s = s * (gs == GaussSphere.WGS84 ? 6378137.0 : (gs == GaussSphere.Xian80 ? 6378140.0 : 6378245.0));
s = Math.Round(s * 10000) / 10000;
return s;
}
private static double Rad(double d)
{
return d * Math.PI / 180.0;
}
GaussSphere 为自定义枚举类型
/// <summary>
/// 高斯投影中所选用的参考椭球
/// </summary>
public enum GaussSphere
{
Beijing54,
Xian80,
WGS84,
}
iFeature As iFeature
iLayerName As String
End Type
Public M_pFeatureArray() As m_pObjArray
Private Sub ArcSceneControl_OnMouseDown(ByVal Button As Long, ByVal Shift As Long, ByVal X As Long, ByVal Y As Long)
ArcSceneControl.SceneGraph.IsNavigating = False
Call Identify3DMap(X, Y)
end sub
'输入:当前3D地图,x坐标,y坐标,引用公共变量M_pFeatureArray
'输出:对3D地图上的目标选中,调用frmidentify显示选中目标的信息
'功能:单点查询
'程序:tjh 2005.1.29
Private Sub Identify3DMap(X As Long, Y As Long)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'QI for IBasicMap from IScene
Dim pBasicMap As IBasicMap
Set pBasicMap = ArcSceneControl.SceneGraph.Scene
'QI for IScreenDisplay from ISceneGraph
Dim pScreenDisplay As IScreenDisplay
Set pScreenDisplay = ArcSceneControl.SceneGraph
'Translate screen coordinates into mulitple 3D objects
Dim pHit3DSet As IHit3DSet
ArcSceneControl.SceneGraph.LocateMultiple ArcSceneControl.SceneGraph.ActiveViewer, X, Y, esriScenePickGeography, False, pHit3DSet
'Reduce the hit set to the top
'most hits and one hit per layer
pHit3DSet.Topmost 1.5
pHit3DSet.OnePerLayer
pHit3DSet.Topmost 1.1
'Get an array of hits
Dim pArray As IArray
Set pArray = pHit3DSet.Hits
If pArray.Count = 0 Then Exit Sub
'Loop through each hit
Dim i As Integer
ReDim M_pFeatureArray(0)
For i = 0 To pArray.Count - 1
'Get the hit
Dim pHit3D As IHit3D
Set pHit3D = pArray.Element(i)
'Get the hit location
Dim pPoint As IPoint
Set pPoint = pHit3D.Point
If pPoint Is Nothing Then Exit Sub
'Get the layer that was hit
If Not TypeOf pHit3D.Owner Is ILayer Then Exit Sub
Dim pLayer As ILayer
Set pLayer = pHit3D.Owner
'Get the feature that was hit
Dim pObject As IUnknown
Set pObject = pHit3D.object
'Add to identify dialog
ReDim Preserve M_pFeatureArray(UBound(M_pFeatureArray) + 1)
Dim pFeature As iFeature
Set pFeature = pHit3D.object
Set M_pFeatureArray(UBound(M_pFeatureArray) - 1).iFeature = pFeature
M_pFeatureArray(UBound(M_pFeatureArray) - 1).iLayerName = CStr(pLayer.Name)
Next i
'''''''''''''''''''''''''''''''''''''''''''''''''
If frmIdentify.Visible = False Then
frmIdentify.Show 0
End If
frmIdentify.SetFocus
Call frmIdentify.InitTreeView
End Sub
'输入:外部公共变量M_pFeatureArray
'输出:
'功能:将查询到的目标的属性和所属图层添加到treeview中
'程序:tjh 2005.1.29
Public Sub InitTreeView()
Dim i As Long, j As Long
Dim blCheck As Boolean
On Error Resume Next
TreeView.Nodes.Clear
For i = 0 To UBound(M_pFeatureArray) - 1
blCheck = False
For j = 0 To ComboLayer.ListCount
If M_pFeatureArray(i).iLayerName = ComboLayer.List(j) Then
blCheck = True
Exit For
End If
Next j
If blCheck = False Then
ComboLayer.AddItem M_pFeatureArray(i).iLayerName
End If
Next i
''''''''''''''''定制treeview树节点树'''''''''''''''''''''
MSFlexGrid.cols = 2
MSFlexGrid.ColAlignment(1) = flexAlignLeftCenter
MSFlexGrid.TextMatrix(0, 0) = "字段"
MSFlexGrid.ColWidth(0) = 1600
MSFlexGrid.ColWidth(1) = 2500
MSFlexGrid.TextMatrix(0, 1) = "值"
If UBound(M_pFeatureArray) = 0 Then Exit Sub
Dim Node1 As Node
Dim Node2 As Node
ComboLayer.Text = ComboLayer.List(0)
For i = 0 To ComboLayer.ListCount - 1
Set Node1 = TreeView.Nodes.Add(, , , ComboLayer.List(i))
For j = 0 To UBound(M_pFeatureArray) - 1
If M_pFeatureArray(j).iLayerName = ComboLayer.List(i) Then
Set Node2 = TreeView.Nodes.Add(Node1.Index, tvwChild, , CStr(M_pFeatureArray(j).iFeature.Value(0)))
End If
Next
If i = 0 Then
Node1.Expanded = True
End If
Next i
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
MSFlexGrid.Rows = M_pFeatureArray(0).iFeature.Fields.FieldCount + 10
For i = 0 To M_pFeatureArray(0).iFeature.Fields.FieldCount - 1
MSFlexGrid.TextMatrix(i + 1, 0) = M_pFeatureArray(0).iFeature.Fields.Field(i).AliasName
If M_pFeatureArray(0).iFeature.Fields.Field(i).Type = 7 Then
MSFlexGrid.TextMatrix(i + 1, 1) = ReturnGeometryName(M_pFeatureArray(0).iFeature.Shape.GeometryType)
Else
MSFlexGrid.TextMatrix(i + 1, 1) = CStr(M_pFeatureArray(0).iFeature.Value(i)) + ""
End If
Next i
Dim strXY As String
strXY = CStr(M_pFeatureArray(0).iFeature.Extent.xMin) + " " + CStr(M_pFeatureArray(0).iFeature.Extent.yMin)
TextCor.Text = "位置: (" + strXY + ")"
Dim pobjGeometry As IGeometry
Set pobjGeometry = M_pFeatureArray(0).iFeature.Shape
Dim pDisplay3D As IDisplay3D
If m_CheckOperate = isQuery Then
' Call FlashFeature(M_pFeatureArray(i).iFeature, frmMapControl.arcMapControl.ActiveView.FocusMap)
frmMapControl.arcMapControl.FlashShape pobjGeometry
ElseIf m_CheckOperate = iscls3dQuery Then
Set pDisplay3D = FrmMap3D.ArcSceneControl.Scene.SceneGraph
pDisplay3D.AddFlashFeature pobjGeometry
pDisplay3D.FlashFeatures
End If
' Show the nodes that are blChecked.
End Sub
Private Sub Form_Load()
' Me.Move (frmMain.Width - Me.Width), frmMain.Top
End Sub
Private Sub Form_Unload(cancel As Integer)
ReDim M_pFeatureArray(0)
End Sub
'输入:--调用ModFlash中的过程
'输出:目标flash
'功能:将点击的目标在地图上闪烁
'程序:tjh 2005.1.29
Private Sub TreeView_NodeClick(ByVal Node As MSComctlLib.Node)
Dim i As Long
Dim j As Long
Dim iLayerName As String
Dim ObjName As String
Dim pDisplay3D As IDisplay3D
On Error Resume Next
If Not Node.Parent Is Nothing Then
iLayerName = Node.Parent.Text
ObjName = Node.Text
For i = 0 To UBound(M_pFeatureArray) - 1
If iLayerName = M_pFeatureArray(i).iLayerName And ObjName = CStr(M_pFeatureArray(i).iFeature.Value(0)) Then
MSFlexGrid.Clear
MSFlexGrid.cols = 2
MSFlexGrid.ColAlignment(1) = flexAlignLeftCenter
MSFlexGrid.TextMatrix(0, 0) = "字段"
MSFlexGrid.ColWidth(0) = 1600
MSFlexGrid.ColWidth(1) = 2500
MSFlexGrid.TextMatrix(0, 1) = "值"
MSFlexGrid.Rows = M_pFeatureArray(i).iFeature.Fields.FieldCount + 10
For j = 0 To M_pFeatureArray(i).iFeature.Fields.FieldCount - 1
MSFlexGrid.TextMatrix(j + 1, 0) = M_pFeatureArray(i).iFeature.Fields.Field(j).AliasName
If M_pFeatureArray(i).iFeature.Fields.Field(j).Type = 7 Then
MSFlexGrid.TextMatrix(j + 1, 1) = ReturnGeometryName(M_pFeatureArray(i).iFeature.Shape.GeometryType)
Else
MSFlexGrid.TextMatrix(j + 1, 1) = M_pFeatureArray(i).iFeature.Value(j)
End If
Next j
Dim pobjGeometry As IGeometry
Set pobjGeometry = M_pFeatureArray(i).iFeature.Shape
If m_CheckOperate = isQuery Then
Call FlashFeature(M_pFeatureArray(i).iFeature, frmMapControl.arcMapControl.ActiveView.FocusMap)
ElseIf m_CheckOperate = iscls3dQuery Then
Set pDisplay3D = FrmMap3D.ArcSceneControl.Scene.SceneGraph
pDisplay3D.AddFlashFeature M_pFeatureArray(i).iFeature.Shape
pDisplay3D.FlashFeatures
End If
MSFlexGrid.TopRow = 1
Dim strXY As String
strXY = CStr(M_pFeatureArray(i).iFeature.Extent.xMin) + " " + CStr(M_pFeatureArray(i).iFeature.Extent.yMin)
TextCor.Text = "位置: (" + strXY + ")"
Exit For
End If
Next i
End If
End Sub
7. 数据加载
1、 数据加载问题:
任何系统都离不开数据的加载,下边就AE中几种常用的数据加载做一个列举。以便查阅:
1、加载个人数据库
个人数据库是保存在Access中的数据库。其加载方式有两种:通过名字和通过属性加载(也许不只这两种,AE中实现同一功能可以有多种方式)。
A、通过设置属性加载个人数据库。
首先通过IPropertySet接口定义要连接数据库的一些相关属性,在个人数据库中为数据库的路径,例如:
IPropertySet Propset = new PropertySetClass();
Propset.SetProperty("DATABASE",@"D:\test\Ao\data\sh\MapData.mdb" );
当定义完属性并设置属性后就可以进行打开数据库的操作了,在ArcEngine开发中存在IWorkspaceFactory、IFeatureWorkspace、IFeatureClass、IFeatureLayer等几个常用的用于打开和操作数据空间地物的接口。IWorkspaceFactory是一个用于创建和打开工作空间的接口,它是一个抽象的接口,我们在具体应用时要用对应的工作空间实例化它,如下:
IWorkspaceFactory Fact = new AccessWorkspaceFactoryClass ();
如果我们打开的是SDE数据库就要用SdeWorkspaceFactoryClass实例化Fact。当我们完成了工作空间的实例化后就可以根据上边设置的属性打开对应的Access数据库了。打开方式如下:
IFeatureWorkspace Workspace = Fact.Open(Propset,0) as IFeatureWorkspace;
打开Access工作空间后接下来的事情是做什么了,很简单,找到对应的地物类,赋给相应的层,通过MapControl控件添加对应的层,然后刷新地图。以下为添加某一层的代码:
IFeatureClass Fcls = Workspace.OpenFeatureClass("District");
IFeatureLayer Fly = new FeatureLayerClass();
Fly.FeatureClass = Fcls;
MapCtr.Map.AddLayer (Fly);
MapCtr.ActiveView.Refresh();
其中District为地物类的名字,MapCtr为AE中MapControl的对象。上边的通过属性设置加载数据空间的方式还可以用于SDE数据库,在SDE数据库加载时会介绍。
以下为通过设置属性加载Access数据库的完整C#代码:
public void AddAccessDBByPro()
{
IPropertySet Propset = new PropertySetClass();
Propset.SetProperty("DATABASE",@"D:\test\Ao\data\sh\MapData.mdb" );
IWorkspaceFactory Fact = new AccessWorkspaceFactoryClass ();
IFeatureWorkspace Workspace = Fact.Open(Propset,0) as IFeatureWorkspace;
IFeatureClass Fcls = Workspace.OpenFeatureClass ("District");
IFeatureLayer Fly = new FeatureLayerClass();
Fly.FeatureClass = Fcls;
MapCtr.Map.AddLayer(Fly);
MapCtr.ActiveView.Refresh();
}
B、通过数据库名字加载个人数据库
在这我先把完整的代码写出来,让您先跟上边的代码做个对比。以下为完整的代码:
public void AddAccessDBByName()
{
IWorkspaceName pWorkspaceName = new WorkspaceNameClass() ;
pWorkspaceName.WorkspaceFactoryProgID = "esriDataSourcesGDB.AccessWorkspaceFactory";
pWorkspaceName.PathName = @"D:\test\Ao\data\sh\MapData.mdb";
IName n = pWorkspaceName as IName ;
IFeatureWorkspace Workspace = n.Open() as IFeatureWorkspace;
IFeatureClass Fcls = Workspace.OpenFeatureClass ("District");
IFeatureLayer Fly = new FeatureLayerClass();
Fly.FeatureClass = Fcls;
MapCtr.Map.AddLayer (Fly);
MapCtr.ActiveView.Refresh();
}
细心的人已经注意到,打开Access工作空间后接下来的代码是一样的,都是找到对应的地物类,赋给相应的层,通过MapControl控件添加对应的层,然后刷新地图。现在讲解一下上边的代码,首先是创建一个个人数据库工作空间名,在指定工作空间名的ProgID,以确定打开的是什么类型的工作空间,例如在打开Access个人数据库时使用的是下边的代码:
IWorkspaceName pWorkspaceName = new WorkspaceNameClass() ;
pWorkspaceName.WorkspaceFactoryProgID = "esriDataSourcesGDB.AccessWorkspaceFactory";
pWorkspaceName.PathName = @"D:\test\Ao\data\sh\MapData.mdb";
属性WorkspaceFactoryProgID可以确保工作空间是AccessWorkspaceFactory,即个人数据库,同时指定要打开数据库的路径。为了打开数据库,我们通过AE的类图可以发现打开工作空间必须使用IName接口(个人认为,不一定正确,可以思考一下看有其他办法没有),所以接着定义IName对象,并把工作空间名转换成IName类型并赋值给IName对象,然后通过IName对象的Open()方法打开相应的工作空间,代码如下:
IName n = pWorkspaceName as IName ;
IFeatureWorkspace Workspace = n.Open () as IFeatureWorkspace;
接下来的事情就是上边提到。
2、加载SDE数据库
什么是SDE数据库?这个问题要详细地讲解将花费大量的时间,但我可以告诉你SDE数据数据库可以是任何关系数据库。ESRI公司为了使空间数据能保存在关系数据库中,并且能很好的查询相关的空间属性而开发的一个中间件,使用SDE能很好的将空间数据保存在关系数据库中。如Orcale SQL Server 等。SDE具体细节的了解请查找相关的资料,这里只介绍怎么连接SDE数据库。SDE数据库的联机分为直接连接和通过SDE连接。当服务器的性能比较好的时候可以采用SDE连接,否则采用直接连接,这样可以减轻服务器的任务。建议采用直接连接,其实,SDE连接方式和直接连接的方式只是一个属性参数设置的问题。跟个人数据库采用属性连接的方式一样,先定义一个属性对象,然后设置属性参数,接着定义一个工作空间并用SdeWorkspaceFactoryClass()实例化它,接着加在加载图层,至于加载图层的代码,与加载个人数据库中图层的方法一样,其实不只加载这两种数据类型,加载其他类型的数据时也是采用相同的方法加载图层,只是工作空间采用不同的实例而已,下边为完整的对吗”//”后的为注析:
public void AddSDELayer(bool ChkSdeLinkModle)
{
//定义一个属性
IPropertySet Propset = new PropertySetClass();
if (ChkSdeLinkModle==true) // 采用SDE连接
{
//设置数据库服务器名
Propset.SetProperty ("SERVER", "zhpzh");
//设置SDE的端口,这是安装时指定的,默认安装时"port:5151"
Propset.SetProperty ("INSTANCE", "port:5151");
//SDE的用户名
Propset.SetProperty ("USER", "sa");
//密码
Propset.SetProperty ("PASSWORD", "sa");
//设置数据库的名字,只有SQL Server Informix 数据库才需要设置
Propset.SetProperty ("DATABASE", "sde");
//SDE的版本,在这为默认版本
Propset.SetProperty ("VERSION", "SDE.DEFAULT");
}
else // 直接连接
{
//设置数据库服务器名,如果是本机可以用"sde:sqlserver:."
Propset.SetProperty ("INSTANCE", "sde:sqlserver:zhpzh");
//SDE的用户名
Propset.SetProperty ("USER", "sa");
//密码
Propset.SetProperty ("PASSWORD", "sa");
//设置数据库的名字,只有SQL Server Informix 数据库才需要设置 Propset.SetProperty ("DATABASE", "sde");
//SDE的版本,在这为默认版本
Propset.SetProperty ("VERSION", "SDE.DEFAULT");
}
//定义一个工作空间,并实力化为SDE的工作空间
IWorkspaceFactory Fact = new SdeWorkspaceFactoryClass();
//打开SDE工作空间,并转化为地物工作空间
IFeatureWorkspace Workspace = (IFeatureWorkspace )Fact.Open(Propset,0);
/*定义一个地物类,并打开SDE中的管点地物类,写的时候一定要写全.如SDE中有一个管点层,你不能写成IFeatureClass Fcls = Workspace.OpenFeatureClass ("管点");这样,一定要写成下边的样子.*/
IFeatureClass Fcls = Workspace.OpenFeatureClass ("sde.dbo.管点");
IFeatureLayer Fly = new FeatureLayerClass ();
Fly.FeatureClass = Fcls;
MapCtr.Map.AddLayer (Fly);
MapCtr.ActiveView.Refresh ();
}
不知道注意到了没有,直接连接跟SDE连接的最大的不同是直接连接不要设置端口,同时他们的参数设置也不一样,好好注意参数的设置。
3、加载CAD图层
CAD图层的加载可以分为:分图层加载和整幅图加载
A、 分图层加载
我们可以把CAD图分为点线面标注加载到MapControl中,跟加载其他数据一样,首先要定义一个工作空间,并用CadWorkspaceFactoryClass()实例化它,当得到了工作空间后就可以打开相应的工作空间,然后再打开指定的层类型。下边为完整的代码:
public void AddCADByLayer()
{
//定义工作空间,并用CadWorkspaceFactoryClass()实例化它
IWorkspaceFactory Fact = new CadWorkspaceFactoryClass();
//打开相应的工作空间,并赋值给要素空间,OpenFromFile()
//中的参数为CAD文件夹的路径
IFeatureWorkspace Workspace = Fact.OpenFromFile(@"I:\test\",0) as IFeatureWorkspace;
/*打开线要素类,如果要打开点类型的要素,需要把下边的代码该成:
IFeatureClass Fcls = Workspace.OpenFeatureClass ("modle.dwg:point");
由此可见modle.dwg为CAD图的名字,后边加上要打开的要素类的类型,中间用冒号 隔开,大家可以想想多边形和标注是怎么打开的。 */
IFeatureClass Fcls = Workspace.OpenFeatureClass ("modle.dwg:polyline");
IFeatureLayer Fly = new FeatureLayerClass ();
Fly.FeatureClass = Fcls;
MapCtr.Map.AddLayer (Fly);
MapCtr.ActiveView.Refresh ();
}
B、 整幅CAD图的加载
当我们要加载整幅CAD图时,需要使用下边的代码,这跟加载地物类有一定的区别,详细地介绍请看代码中的注析:
public void AddWholeCAD()
{
/*下边的两行代码是定义一个CAD工作空间,然后打开它,但这次不是赋值给
IFeatureWorkspace对象,而是赋值给IWorkspace定义的对象*/
IWorkspaceFactory Fact = new CadWorkspaceFactoryClass();
IWorkspace Workspace = Fact.OpenFromFile(@"I:\test\",0);
//定义一个CAD画图空间,并把上边打开的工作空间赋给它
ICadDrawingWorkspace dw = Workspace as ICadDrawingWorkspace;
//定义一个CAD的画图数据集,并且打开上边指定的工作空间中一幅CAD图
//然后赋值给CAD数据集
ICadDrawingDataset ds = dw.OpenCadDrawingDataset ("modle.DWG");
//通过ICadLayer类,把上边得到的CAD数据局赋值给ICadLayer类对象的
//CadDrawingDataset属性
ICadLayer CadLayer = new CadLayerClass();
CadLayer.CadDrawingDataset = ds;
//利用MapControl加载CAD层
MapCtr.Map.AddLayer (CadLayer);
MapCtr.ActiveView.Refresh ();
}
通过上边的代码和相关的解析,大家可能对整幅CAD图的加载有一个了解,但要具体搞清楚它的含义,也不那么容易。这留给大家去慢慢体会,在这我谈谈我自己的体会,但不一定正确。要打开数据集,首先要打开它的工作空间,至于什么是工作空间,我也说不太明白,但我的理解是,如果数据是保存在文件中的,工作空间大概就是它对应的文件夹,如果是数据库中的数据,我想大概就是对应的数据库。打开数据空间后,在这因为是整幅CAD图加载,所以跟以前的有点不同,这也就是相当整个CAD图就是一个数据集,所以要转到CAD画图的工作空间,然后把CAD图作为CAD数据集打开。为了在MapControl中加载CAD层,必须使用ICadLayer控件的对象,因为MapCtr.Map.AddLayer ()方法中只能是ICadLayer的对象。
8. 连接 关系数据库
Private Sub txtCollectID_AfterUpdate_thru_SQL_Server()
'This method uses a more direct connection to the SQL Server Collection table through OLE DB
'It checks to see whether a record exists in the Collections db already based on the Collection field
On Error GoTo MyError
dblCollID = Val(txtCollectID.Value)
'++ Create and populate a new property set
Dim pPropset As IPropertySet
Set pPropset = New PropertySet
pPropset.SetProperty "CONNECTSTRING", "Provider=SQLOLEDB;Data source=CARL;Initial Catalog=VAFWIS;User ID=sa;Password=gis"
'++ Create a new workspacefactory/workspace
Dim pFeatureWorkspace As IFeatureWorkspace
Dim pWorkspaceFact As IWorkspaceFactory
Set pWorkspaceFact = New OLEDBWorkspaceFactory
Set pFeatureWorkspace = pWorkspaceFact.Open(pPropset, 0)
'Open the table
Dim pTable As Itable
Set pTable = pFeatureWorkspace.OpenTable("Collections")
'Set up the query