1 ArcGIS中定義查詢和屬性查詢
1.1 SQL語句
以SQL模糊查詢LIKE運算符對應的通配符爲例
通配符查詢
通配符 | 描述 | 示例 |
---|---|---|
% | 包含零個或更多字符的任意字符串。 | WHERE title LIKE '%computer%' 將查找處於書名任意位置的包含單詞 computer 的所有書名。 |
_(下劃線) | 任何單個字符。 | WHERE au_fname LIKE '_ean' 將查找以 ean 結尾的所有 4 個字母的名字(Dean、Sean 等)。 |
[ ] | 指定範圍 ([a-f]) 或集合 ([abcdef]) 中的任何單個字符。 | WHERE au_lname LIKE '[C-P]arsen' 將查找以arsen 結尾且以介於 C 與 P 之間的任何單個字符開始的作者姓氏,例如,Carsen、Larsen、Karsen 等。 |
[^] | 不屬於指定範圍 ([a-f]) 或集合 ([abcdef]) 的任何單個字符。 | WHERE au_lname LIKE 'de[^l]%' 將查找以 de 開始且其後的字母不爲 l 的所有作者的姓氏。 |
從圖層中選擇要素的代碼:
///<summary>Select features in the IActiveView by an attribute query using a SQL syntax in a where clause.</summary>
///
///<param name="activeView">An IActiveView interface</param>
///<param name="featureLayer">An IFeatureLayer interface to select upon</param>
///<param name="whereClause">A System.String that is the SQL where clause syntax to select features. Example: "CityName = 'Redlands'"</param>
///
///<remarks>Providing and empty string "" will return all records.</remarks>
public void SelectMapFeaturesByAttributeQuery(ESRI.ArcGIS.Carto.IActiveView activeView, ESRI.ArcGIS.Carto.IFeatureLayer featureLayer, System.String whereClause)
{
if(activeView == null || featureLayer == null || whereClause == null)
{
return;
}
ESRI.ArcGIS.Carto.IFeatureSelection featureSelection = featureLayer as ESRI.ArcGIS.Carto.IFeatureSelection; // Dynamic Cast
// Set up the query
ESRI.ArcGIS.Geodatabase.IQueryFilter queryFilter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
queryFilter.WhereClause = whereClause;
// Invalidate only the selection cache. Flag the original selection
activeView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeoSelection, null, null);
// Perform the selection
featureSelection.SelectFeatures(queryFilter, ESRI.ArcGIS.Carto.esriSelectionResultEnum.esriSelectionResultNew, false);
// Flag the new selection
activeView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeoSelection, null, null);
}
whereas語句的寫法:
//查詢與某一指定字符串一致的記錄
//直接寫
WhereClause = "RN = Y003";
//使用參數變量傳遞
string fieldStr = "Y003";
WhereClause = "RN = '" + fieldStr + "'";//注意單引號不要忘
//查詢以固定字符串開頭的記錄
//LXBM = "Y003456789"
//RN = "Y003"
WhereClause = "LXBM like 'Y003%'"
WhereClause = "LXBM like '" + RN+ "'%'";//注意單引號
//不等於
WhereClause = "LXBM != 10011";
WhereClause = "LXBM <> 10011";
//查詢多個要素
WhereClause = "NAME IS NOT NULL AND NAME <> '高架'"
語句 | 含義 |
FEAID IS NOT NULL | 查詢FEAID不爲空的要素記錄 |
NAME <> '高架' | 查詢NAME不爲高架的記錄,結果中不包含爲null的項 |
1.2 查詢不重複的要素
1.2.1 從GDB獲取不重複要素
//使用FeatureClass對象的IDataset接口來獲取dataset和workspace的信息
IDataset dataset = (IDataset)currentFeatureLayer.FeatureClass;
//使用IQueryDef接口的對象來定義和查詢屬性信息。通過IWorkspace接口的CreateQueryDef()方法創建該對象。
IQueryDef queryDef = ((IFeatureWorkspace)dataset.Workspace).CreateQueryDef();
//設置所需查詢的表格名稱爲dataset的名稱
queryDef.Tables = dataset.Name;
//設置查詢的字段名稱。可以聯合使用SQL語言的關鍵字,如查詢唯一值可以使用DISTINCT關鍵字。
queryDef.SubFields = currentFieldName ;
//執行查詢並返回ICursor接口的對象來訪問整個結果的集合
ICursor cursor = queryDef.Evaluate();
//使用IField接口獲取當前所需要使用的字段的信息
IFields fields = currentFeatureLayer.FeatureClass.Fields;
IField field = fields.get_Field(fields.FindField(currentFieldName));
//對整個結果集合進行遍歷,從而添加所有的唯一值
//使用IRow接口來操作結果集合。首先定位到第一個查詢結果。
IRow row = cursor.NextRow();
//如果查詢結果非空,則一直進行添加操作
while (row != null)
{
//對String類型的字段,唯一值的前後添加'和',以符合SQL語句的要求
if (field.Type == esriFieldType.esriFieldTypeString)
{
listBoxValues.Items.Add("\'" + row.get_Value(0).ToString() + "\'");
}
else
{
listBoxValues.Items.Add(row.get_Value(0).ToString());
}
//繼續執行下一個結果的添加
row = cursor.NextRow();
}
1.2.2 從GDB/SHP獲取不重複要素
//獲取要素圖層的源
IFeatureClass feclass = currentFeatureLayer.FeatureClass;
//根據源數據創建遊標
IFeatureCursor cusro = feclass.Search(null, true);
IFeature fea = cusro.NextFeature();
//獲取源數據的所有字段
IFields fields = currentFeatureLayer.FeatureClass.Fields;
//獲取所選字段的Index
int index = fields.FindField(currentFieldName);
while (fea != null)
{
string str;
str = fea.get_Value(index).ToString();
//如果值列表中還沒有str這個值
if (!listBoxValues.Items.Contains("\'" + str + "\'"))
{
//將str加入到值列表,並且str前後加上單引號
listBoxValues.Items.Add("\'" + str + "\'");
}
fea = cusro.NextFeature();
}
-
2 IMap、ILayer、IFeatureLayer和IFeatureClass關係
剛開時學習 Engine 開發時,對於這幾個接口之間的關係總是理不清,因此寫下這篇文章做個總結。
2.1 是什麼
在 engine 開發中,我覺得使用過程中應該將每個接口對應到 ArcMap 中的具體事物中,這才能對它們有深刻的認識,那麼,這幾個接口代表的事物是什麼呢?
- IMap
這相對來說比較好理解,Map就是許多圖層的集合,就像 ArcMap 中的 MXD文檔一樣,可以包括許多圖層 Layer. - ILayer
Layer 是圖層對象,是數據的外殼,必須建立在數據的基礎上纔有意義。在 ArcMap 中,它可以表示任何圖層,例如要素圖層( IFeatureLayer ),柵格圖層( IRasterLayer ),圖形圖層集合( ICompositeGraphicsLayer ) - IFeatureLayer
繼承自ILayer,提供了訪問基於矢量數據圖層的屬性和方法,圖層的數據可以是Geodatabase、Shapefile或Coverage數據。如果使用FeatureLayer組件類,還可以通過IGeoFeatureLayer接口獲得更多的屬性和方法。提供了控制要素圖層的屬性和方法,例如標記屬性( AnnotationProperties )、註記顯示設置( DisplayAnnotation ) - IFeatureClass
獲取和設置要素類屬性的主要接口。如獲取要素類的類型,得到滿足某個查詢條件的要素個數,或在要素類中創建一個新的功能。
2.2 關係
其中IMap是由多個ILayer構成的,而IFeatureLayer是ILayer的一個子類,IFeatureClass是IFeatureLayer的一個屬性。
2.2.1 從IMap中獲取IFeatureLayer
/// <summary>
/// 根據圖層名找到圖層
/// </summary>
/// <param name="pMap">地圖名稱</param>
/// <param name="layerName">圖層名稱</param>
/// <returns>未找到圖層返回null,找到圖層返回目標圖層</returns>
public static IFeatureLayer GetLayerByName(IMap pMap, string layerName)
{
for(int i = 0; i < pMap.LayerCount; i++)
{
if(pMap.getLayer(i).Name == layerName)
{
return pMap.getLayer(i) as IFeatureLayer;
}
}
return null;
}
2.2.2 從IMap中獲取IFeatureClass
注意:使用此函數時,不能再通過接口跳轉到IFeatureLayer
/// <summary>
/// 根據圖層名找到圖層
/// </summary>
/// <param name="pMap">地圖名稱</param>
/// <param name="layerName">圖層名稱</param>
/// <returns>未找到圖層返回null,找到圖層返回目標圖層</returns>
public static IFeatureClass GetLayer(IMap pMap, string layerName)
{
for(int i = 0; i < pMap.LayerCount; i++)
{
if(pMap.getLayer(i).Name == layerName)
{
return (pMap.getLayer(i) as IFeatureLayer).FeatureClass;
}
}
return null;
}
2.3 向圖層中添加字段
public void addFieldIntoFeatureClass(IFeatureClass feaClass, string fieldName)
{
int fieldIndex = feaClass.FinfField(fieldName);
if(fieldIndex != -1)
{
IField pField = new FieldClass();
IFieldEdit pFieldEdit = (IFieldEdit)pField;
pFieldEdit.Name_2 = fieldName;
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
pFieldEdit.Length_2 = 100;
pFieldsEdit.AddField(pField);
}
}
2.4 獲取IMap下某圖層所屬的數據庫名稱
IFeatureLayer pFeaLayer = getLayerByName(pMap, "LRDL");
string gdbName = pFeaLayer.FeatureClass.FeatureDataset.Workspace.PathName;