之前写的几种格式不是专门gis格式,这次来说说加载dwg。首先dwg格式不同于dxf格式,虽然autocad都能加载进去,真正用的比较多的是dwg格式,反正测绘,国土规划部门都是,吐槽下,然而autocad软件也是很贵的。首先为什么dwg格式加载为什么这么麻烦?
dwg格式随着autocad版本升级,它的文件编码是不一样的,dxf是开源的,dwg是不开源的,只有跟autocad公司合作的企业才可以解析它的,现在我这里写的大部分都是对地图相关的,所以arcgis自然就可以加载。arcgis api就可以解析dwg。
首先必须先上传dwg文件到服务器目录,服务器打开dwg文件, IFeatureClassContainer接口可以打开dwg,dwg文件有点,线,面,标注,dwg标注这个东西过于复杂,往往转arcgis格式时候会丢失太多,这个必须得用FME软件去搞,这里先处理点,线,面。我的思想是把这些dwg文件存到sde数据库里,当然事先也要建立点,线,面,标注图层,在flex显示的时候可以把这些图层发布,用arcgisdymaiclayer去显示,减少自己对坐标操作,还有地图元素很多小数点要精确到6位小数,后台大量传输这种高精度的坐标不好。
下面是我写的dwgtool工具类。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;
using CheckServices.Class;
using CheckServices.Ext;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using System.Xml; namespace CheckServices.query
{
public class DwgTool
{ public DwgTool()
{
ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop);
ESRI.ArcGIS.esriSystem.IAoInitialize aoInitialize = new ESRI.ArcGIS.esriSystem.AoInitializeClass();
aoInitialize.Initialize(ESRI.ArcGIS.esriSystem.esriLicenseProductCode.esriLicenseProductCodeArcInfo);
} public string _guid;
public string _userID;
public string _withCoordFlag = "false";
public IEnvelope env = new EnvelopeClass();
public string coord = string.Empty;
public string polygonNum = "";
public string CadLoad(string dwgfile,string guid,string userID,string withCoordFlag)
{
_guid = guid;
_userID = userID;
_withCoordFlag = withCoordFlag;
string dwgloadStr = string.Empty;
IFeatureClassContainer pFeaClsContainer = OpenCadFile(dwgfile);
IFeatureClass cadFeatClass = null;
string SDE = "SPA";
for (int i = ; i < pFeaClsContainer.ClassCount; i++)
{
cadFeatClass = pFeaClsContainer.get_Class(i);
if (cadFeatClass.FeatureType == esriFeatureType.esriFTCoverageAnnotation || cadFeatClass.FeatureType == esriFeatureType.esriFTAnnotation)
{
CadAnnotationCopy("SDE.DWG_ANNOTAION", SDE, cadFeatClass); }
else if (cadFeatClass.ShapeType == esriGeometryType.esriGeometryPoint)
{ CadLayerCopy("SDE.DWG_POINT", SDE, cadFeatClass);
}
else if (cadFeatClass.ShapeType == esriGeometryType.esriGeometryPolyline)
{ CadLayerCopy("SDE.DWG_POLYLINE", SDE, cadFeatClass); }
else if (cadFeatClass.ShapeType == esriGeometryType.esriGeometryPolygon)
{ CadLayerCopy("SDE.DWG_POLYGON", SDE, cadFeatClass); }
else if (cadFeatClass.ShapeType == esriGeometryType.esriGeometryMultiPatch)
{
//esriGeometryMultiPatch 不用新增到sde,和polygon是一样的
continue;
}
} return createResultXML();
} private string createResultXML()
{
XmlDocument doc = new XmlDocument();
XmlElement rootElement = doc.CreateElement("DWGRESULT"); XmlElement extentElement = doc.CreateElement("EXTENT");
if (env.IsEmpty == false)
{
extentElement.AppendChild(createXmlNode(doc, "XMin", env.XMin.ToString()));
extentElement.AppendChild(createXmlNode(doc, "YMin", env.YMin.ToString()));
extentElement.AppendChild(createXmlNode(doc, "XMax", env.XMax.ToString()));
extentElement.AppendChild(createXmlNode(doc, "YMax", env.YMax.ToString()));
}
rootElement.AppendChild(extentElement);
rootElement.AppendChild(createXmlNode(doc, "COORD", coord ));
rootElement.AppendChild(createXmlNode(doc, "POLYONNUM", polygonNum));
rootElement.AppendChild(createXmlNode(doc, "GUID", _guid));
rootElement.AppendChild(createXmlNode(doc, "USERID",_userID));
doc.AppendChild(rootElement);
return doc.InnerXml;
} private XmlElement createXmlNode(XmlDocument doc, String elementName, String innerText)
{
XmlElement element = doc.CreateElement(elementName);
element.InnerText = innerText;
return element;
} private void clearEnv()
{
env = new EnvelopeClass();
} //图层拷贝函数
private void CadLayerCopy(String layerName, String sde, IFeatureClass cadFeatClass)
{ IFeatureClass fc = openFeatureClass(layerName, sde); IFeatureCursor cadFeatureCursor = cadFeatClass.Search(null, false);
IFeature pFeature1 = cadFeatureCursor.NextFeature(); if (pFeature1 == null)
return; IDataset dSet = fc as IDataset;
IWorkspaceEdit pWE = dSet.Workspace as IWorkspaceEdit;
IMultiuserWorkspaceEdit pMWE = pWE as IMultiuserWorkspaceEdit;
if (pMWE.SupportsMultiuserEditSessionMode(esriMultiuserEditSessionMode.esriMESMNonVersioned))
pMWE.StartMultiuserEditing(esriMultiuserEditSessionMode.esriMESMNonVersioned);
else
pWE.StartEditing(false);
pWE.StartEditOperation(); IFeatureCursor pFtcursor = fc.Insert(true); Dictionary<string, bool> drawingDic = getCadDrawingLayer(cadFeatClass); if(pFeature1.Shape is IPolygon)
{
coord = ArcGISUtil.PolygonToString(pFeature1.Shape as IPolygon);
env = pFeature1.Extent;
}
while(pFeature1 != null)
{
//处理cad非显示图层
string cadLayerName = getCadLayerName(pFeature1);
if (drawingDic.ContainsKey(cadLayerName))
{
if (drawingDic[cadLayerName] == false)
{
pFeature1 = cadFeatureCursor.NextFeature();
continue;
} } //若是polygon 计算env
setEnv(env,pFeature1);
//设置polygon个数
setPolygonNum(pFeature1); //针对返回多坐标的操作必须在setPolygonNum之前
setCoord(pFeature1);
//因为是大批量增加数据 用createfeaturebuffer会好些
IFeatureBuffer pFeatureBuff = fc.CreateFeatureBuffer();
updateFeature(pFeatureBuff, pFeature1);
try
{
object pfid = pFtcursor.InsertFeature(pFeatureBuff);
}
catch (Exception e)
{ }
pFeature1 = cadFeatureCursor.NextFeature();
}
pFtcursor.Flush();
pWE.StopEditOperation();
pWE.StopEditing(true); ArcGISUtil.FinalReleaseComObject(pFeature1);
ArcGISUtil.FinalReleaseComObject(pWE);
ArcGISUtil.FinalReleaseComObject(fc); } private void setPolygonNum(IFeature pFeature1)
{
if (pFeature1.Shape is IPolygon && polygonNum == "")
{
polygonNum = "";
}
else if (pFeature1.Shape is IPolygon && polygonNum == "")
{
polygonNum = "N";
}
} private void setCoord(IFeature pFeature1)
{
if (pFeature1.Shape is IPolygon && _withCoordFlag == "true" && polygonNum == "N")
{
coord += "*" + ArcGISUtil.PolygonToString(pFeature1.Shape as IPolygon);
}
} private void setEnv(IEnvelope env, IFeature pFeature1)
{
if (pFeature1.Shape is IPolygon)
{
if (pFeature1.Extent.XMin < env.XMin)
env.XMin = pFeature1.Extent.XMin; if (pFeature1.Extent.XMax > env.XMax)
env.XMax = pFeature1.Extent.XMax; if (pFeature1.Extent.YMin < env.YMin)
env.YMin = pFeature1.Extent.YMin; if (pFeature1.Extent.YMax > env.YMax)
env.YMax = pFeature1.Extent.YMax;
}
} private string getCadLayerName(IFeature pFeature1)
{
string cadLayer = string.Empty;
int fieldIndex = pFeature1.Fields.FindField("LAYER"); if (fieldIndex != -)
{
cadLayer = pFeature1.get_Value(fieldIndex).ToString();
}
return cadLayer;
} //得到cad可见图层 private Dictionary<string, bool> getCadDrawingLayer(IFeatureClass cadFeatClass)
{
Dictionary<string, bool> drawingDic = new Dictionary<string, bool>();
IFeatureLayer pFeatLayer = new CadFeatureLayer() as IFeatureLayer; pFeatLayer.FeatureClass = cadFeatClass; ICadDrawingLayers pCadDwgLayers =(ICadDrawingLayers)pFeatLayer; for (int i = ; i <= pCadDwgLayers.DrawingLayerCount - ; i++)
{
drawingDic.Add(pCadDwgLayers.get_DrawingLayerName(i),pCadDwgLayers.get_DrawingLayerVisible(i));
}
return drawingDic;
} //标注图层不能和几何图层那样加 需用IAnnotationFeature 添加elements实现 ,另外一种ifdographiclayer 我不知道怎么添加自定义属性 作罢
private void CadAnnotationCopy(String layerName, String sde, IFeatureClass pCadFC)
{ IFeatureClass pSdeFC = openFeatureClass(layerName, sde); IFeatureCursor pCADFeatureCur = pCadFC.Search(null, false);
ITextSymbol pTextSymbol = getTextSymbol(pSdeFC); ITextElement pTextElement = null;
string pAnnoText;
double pAngle;
int pAnnoTextID;
int pAngleID;
pAnnoTextID = pCadFC.Fields.FindField("Text");
pAngleID = pCadFC.Fields.FindField("txtAngle"); //启动编辑
IDataset dSet = pSdeFC as IDataset;
IWorkspaceEdit pWE = dSet.Workspace as IWorkspaceEdit;
IMultiuserWorkspaceEdit pMWE = pWE as IMultiuserWorkspaceEdit;
if (pMWE.SupportsMultiuserEditSessionMode(esriMultiuserEditSessionMode.esriMESMNonVersioned))
pMWE.StartMultiuserEditing(esriMultiuserEditSessionMode.esriMESMNonVersioned);
else
pWE.StartEditing(false);
pWE.StartEditOperation(); IFeature pCADFeature = pCADFeatureCur.NextFeature();
IFeatureCursor pFtcursor = pSdeFC.Insert(true); Dictionary<string, bool> drawingDic = getCadDrawingLayer(pCadFC);
while (null != pCADFeature)
{
string cadLayerName = getCadLayerName(pCADFeature);
if (drawingDic.ContainsKey(cadLayerName))
{
if (drawingDic[cadLayerName] == false)
{
pCADFeature = pCADFeatureCur.NextFeature();
continue;
}
} pAnnoText = pCADFeature.get_Value(pAnnoTextID).ToString();
pAngle = Convert.ToDouble(pCADFeature.get_Value(pAngleID));
pTextElement = MakeTextElement(pCADFeature, pAnnoText, pAngle, pTextSymbol); IAnnotationFeature a = pSdeFC.CreateFeatureBuffer() as IAnnotationFeature;
a.Annotation = pTextElement as IElement;
upadteFeatureGUIDandUserID(a as IFeature);
object pfid = pFtcursor.InsertFeature(a as IFeatureBuffer); pCADFeature = pCADFeatureCur.NextFeature();
}
pFtcursor.Flush();
pWE.StopEditOperation();
pWE.StopEditing(true);
ArcGISUtil.FinalReleaseComObject(pSdeFC);
ArcGISUtil.FinalReleaseComObject(pWE);
ArcGISUtil.FinalReleaseComObject(pCadFC); } //更新图层的GUID和USERID
private void upadteFeatureGUIDandUserID(IFeature pFeature)
{
int fieldIndex = pFeature.Fields.FindField("GUID");
if (fieldIndex != -)
{
pFeature.set_Value(fieldIndex, _guid);
}
int fieldIndex1 = pFeature.Fields.FindField("USERID");
if (fieldIndex1 != -)
{
pFeature.set_Value(fieldIndex1, _userID);
}
int fieldIndex2 = pFeature.Fields.FindField("DWGDATE");
if (fieldIndex2 != -)
{
DateTime dt = DateTime.Now;
string date = dt.ToShortDateString().ToString();
pFeature.set_Value(fieldIndex2, date);
}
} //创建textelecmnt函数
private ITextElement MakeTextElement(IFeature pFeature, string pAnnoText, double pAngle, ITextSymbol pTextSymbol)
{
IPoint pPoint = new PointClass();
pPoint = pFeature.ShapeCopy as IPoint;
ITextElement pTextElement = new TextElementClass();
pTextElement.Symbol = pTextSymbol;
pTextElement.ScaleText = true;
pTextElement.Text = pAnnoText;
IElement pElement = pTextElement as IElement;
pElement.Geometry = pPoint;
if (pAngle != )
{
ITransform2D pTransform2D = pTextElement as ITransform2D;
pTransform2D.Rotate(pPoint, pAngle * (System.Math.PI / ));
}
return pTextElement;
} private ITextSymbol getTextSymbol(IFeatureClass pFeatureClass)
{
ITextSymbol pTextSymbol = null;
IAnnoClass pAnnoClass = pFeatureClass.Extension as IAnnoClass;
if (pAnnoClass.SymbolCollection != null)
{
ISymbolCollection pSColl = pAnnoClass.SymbolCollection;
pSColl.Reset(); ISymbolIdentifier pSymID = pSColl.Next();
while (pSymID != null)
{
if (pSymID.Symbol is ITextSymbol)
{
pTextSymbol = pSymID.Symbol as ITextSymbol; break;
}
pSymID = pSColl.Next();
}
}
else
{
IFeatureCursor pFCur = pFeatureClass.Search(null, false);
IAnnotationFeature pAnnofeat = pFCur.NextFeature() as IAnnotationFeature;
while (pAnnofeat != null)
{
if (pAnnofeat.Annotation is ITextElement)
{
pTextSymbol = pAnnofeat.Annotation as ITextSymbol;
}
pAnnofeat = pFCur.NextFeature() as IAnnotationFeature;
}
}
return pTextSymbol;
} //图形复制函数
private Boolean updateFeature(IFeatureBuffer pFeature, IFeature pFeature1)
{
try
{
for (int i = ; i < pFeature1.Fields.FieldCount; i++)
{
string str = pFeature1.Fields.get_Field(i).Name;
int fieldIndex = -; if (str.ToUpper() == "SHAPE")
{
IGeometryDef pGeometryDef;
pGeometryDef = pFeature1.Fields.get_Field(i).GeometryDef as IGeometryDef; IGeometry geometry = pFeature1.ShapeCopy; if (pFeature1.ShapeCopy is IPolygon)
{
(geometry as ITopologicalOperator).Simplify();
} //dwg z轴有点的情况要解决
if (pGeometryDef.HasZ)
{
IZAware pzaware = (IZAware)geometry;
pzaware.ZAware = false; } pFeature.Shape = geometry;
}
else
{ fieldIndex = pFeature.Fields.FindField(str.ToUpper());
if (fieldIndex != -)
{
if (pFeature.Fields.get_Field(fieldIndex).Editable)
{
pFeature.set_Value(fieldIndex, pFeature1.get_Value(i));
} }
}
}
upadteFeatureGUIDandUserID(pFeature as IFeature); return true;
}
catch (Exception e)
{
return false;
}
} //加载cad文件
private IFeatureClassContainer OpenCadFile(string fileName)
{
IFeatureClassContainer pFeatClassContainer = null;
IWorkspaceFactory pWorkspaceFactory;
IFeatureWorkspace pFeatureWorkspace;
IFeatureDataset pFeatureDataset; try
{ //string dicPath = filePath.Substring(0, filePath.LastIndexOf("\\"));
//string fileName = filePath.Split('\\')[filePath.Split('\\').Length - 1];//"08558.dwg"; string dicPath = HttpContext.Current.Server.MapPath(@"\Checkservices\updwg\");
pWorkspaceFactory = new CadWorkspaceFactoryClass();
pFeatureWorkspace = (IFeatureWorkspace)pWorkspaceFactory.OpenFromFile(dicPath, );
pFeatureDataset = pFeatureWorkspace.OpenFeatureDataset(fileName);
pFeatClassContainer = (IFeatureClassContainer)pFeatureDataset; }
catch (Exception e)
{ } return pFeatClassContainer;
} private IFeatureClass openFeatureClass(String layerName, String sde)
{
IFeatureClass fc = null;
try
{
fc = SdeConnectManager.getFeatureClass(layerName, sde);
}
catch
{
return null;
}
return fc;
} } }
gtool处理的工具类