關於ArcShapeFileNet

關於ArcShapeFileNet

.net下操作shp文件的類庫不是很多,git上找一找也能找到不少。
但是呢,這麼多年一致用的是Arcgis全家桶,所以呢就找了找,還真找到了一個古老的Arcgis對shp文件操作的類庫。
老歸老,但能滿足需求,所以足夠了。
主要用途是用於dwg轉換shp格式,又不想花錢,又要東西,很爲難。
ArcShapeFileNet到底多少年了,沒深究,但裏面的有些設計,明顯能感覺到很古老,比如數組是從1開始計數。
又比如對編碼格式的支持,中文的只有gb2312,且這個國標android不認識,uft-8是沒有的。

原版類庫獲取方式

1、可以去Arcgis portal資源中心去找,有下載地址
2、百度雲下載
鏈接:https://pan.baidu.com/s/1MjiWsV3eNub33hk9DYTKHg 
提取碼:qwsj 
這個是官網原版的類庫,不過並不好用,缺點就是中文支持不好,數組都是從1開始計數,不習慣了。

修改過後的類庫和代碼

後來呢,又認真找了找,發現了源碼,不過被修改過,數組從0開始了
有些不合適的屬性和函數也修改過,但還是不支持utf8
所以呢,只好自己加上utf8編碼,重新編譯了一下
源碼和編譯後的dll百度雲
鏈接:https://pan.baidu.com/s/1zKaIERISJli_dXY0amD1aQ 
提取碼:nqwi

支持utf8編碼修改代碼很少

eLanguage枚舉增加了 Codepage_UTF_8 = 0x76
		GetCodePageName()函數增加了三行代碼
                case eLanguage.Codepage_UTF_8:
                    functionReturnValue = "UTF-8";
                    break;
SetDelimiter()函數修改了
                case eLanguage.Codepage_932_Japanese_Windows:
                case eLanguage.Codepage_936_Chinese_Windows:
                case eLanguage.Codepage_950_Chinese_Windows:
                case eLanguage.Codepage_UTF_8:
                    DelimterValue = ".";
                    break;
然後就可以愉快的使用utf8編碼了。以後的代碼都是基於修改後的類庫。

操作shp文件

打開shp文件

//filePath爲shp文件全路徑
        public static ShapeFile OpenShapeFile(string filePath)
        {
            ShapeFile shapeFiles = new ShapeFile();
            shapeFiles.Language = eLanguage.Codepage_UTF_8;
            shapeFiles.Open(filePath);
            return shapeFiles;
        }

創建shp文件

//filePath爲shp文件全路徑,type是文件類型
        public static ShapeFile CreateShpFile(string filePath, eShapeType type)
        {
            ShapeFile shapeFiles = new ShapeFile();
            shapeFiles.Language = eLanguage.Codepage_UTF_8;
            shapeFiles.Open(filePath, type);
            return shapeFiles;
        }

添加屬性字段

//字段名稱、字段類型、字段長度、精度
//如果是文本字段長度不能超多255、精度可不給
    public static void AddField(ShapeFile shapeFiles, string name, eFieldType type, short size = 0, short fieldDecimal = 0)
        {
            if (shapeFiles == null)
            {
                return;
            }
            shapeFiles.Fields.Add(name, type, size, fieldDecimal);
            shapeFiles.WriteFieldDefs();
        }

添加數據記錄

                shapeFiles.Vertices.Add(dBPoint.Position.X, dBPoint.Position.Y);
                shapeFiles.Fields[ShpFieldNames.DataType].Value = dBPoint.GetType().Name;
                shapeFiles.Fields[ShpFieldNames.Layer].Value = dBPoint.Layer;
                shapeFiles.WriteShape();

添加線數據記錄

     shapeFiles.Vertices.Add(line.StartPoint.X, line.StartPoint.Y);
     shapeFiles.Vertices.Add(line.EndPoint.X, line.EndPoint.Y);
     shapeFiles.Fields[ShpFieldNames.DataType].Value = line.GetType().Name;
     shapeFiles.Fields[ShpFieldNames.Layer].Value = line.Layer;
     shapeFiles.Fields[ShpFieldNames.Code].Value = line.Linetype;
     shapeFiles.WriteShape();
這個類庫操作shp很簡單,並不想AO那樣有很複雜的集合圖形結構
這裏都是直接堆點,只要順序堆得堆,其他都不是問題
這個類庫也支持多環,只需要將點放入到shapeFiles.Parts集合裏面就可以。
下面是一個從Patrs屬性獲取多換的例子
   for (int i = 0; i < shapeFiles.Parts.Count; i++)
            {
                Part part = shapeFiles.Parts[i];
                using (Polyline polyline = new Polyline())
                {
                    for (int j = part.Begins; j < part.Ends; j++)
                    {
                        polyline.AddVertexAt(j - part.Begins, new Point2d(shapeFiles.Vertices[j].X_Cord, shapeFiles.Vertices[j].Y_Cord), 0, 0, 0);
                    }
                    blockTableRecord.AppendEntity(polyline);
                }
            }

遍歷shp文件的數據

//屬性、用法都是比較遠古
ShapeFile shapeFiles = InputShapeFiles[i];
while (!shapeFiles.EOF)
    {
          OnConvertFeature(shapeFiles, OutputDatabase, blockTableRecord);
          shapeFiles.MoveNext();
     }

其他

這個庫操作shp效率很高,也不存在鎖死shp文件的問題,用完不關閉文件也不會鎖定shp文件。

其他源碼修改

後來在使用過程中發現對於點類型的數據,shp文件中心點座標信息計算有問題。
看源碼發現如果是點,就沒有去計算中心點值,後來追加了計算代碼。
在ShaprFile文件10130行開始位置
                case eShapeType.shpPoint:
                    if (mvarReadmode != eReadMode.FastRead)
                    {
                        if (mvarCentroidX == 0)
                        {
                            mvarCentroidX = mvarVertices.xMin;
                        }
                        else
                        {
                            mvarCentroidX = (mvarVertices.xMin + mvarCentroidX) / 2.0;
                        }
                        if (mvarCentroidY == 0)
                        {
                            mvarCentroidY = mvarVertices.yMin;
                        }
                        else
                        {
                            mvarCentroidY = (mvarVertices.yMin + mvarCentroidY) / 2.0;
                        }
                        mvarVertices.Add(mvarVertices.xMin, mvarVertices.yMin);
                    }
                    break;
                case eShapeType.shpPointM:
                    if (mvarReadmode != eReadMode.FastRead)
                    {
                        if (mvarCentroidX == 0)
                        {
                            mvarCentroidX = mvarVertices.xMin;
                        }
                        else
                        {
                            mvarCentroidX = (mvarVertices.xMin + mvarCentroidX) / 2.0;
                        }
                        if (mvarCentroidY == 0)
                        {
                            mvarCentroidY = mvarVertices.yMin;
                        }
                        else
                        {
                            mvarCentroidY = (mvarVertices.yMin + mvarCentroidY) / 2.0;
                        }
                        MVal = mvarVertices.mMin;
                        mvarVertices.Add(mvarVertices.xMin, mvarVertices.yMin, MVal);
                    }

                    break;
                case eShapeType.shpPointZ:
                    if (mvarReadmode != eReadMode.FastRead)
                    {
                        if (mvarCentroidX == 0)
                        {
                            mvarCentroidX = mvarVertices.xMin;
                        }
                        else
                        {
                            mvarCentroidX = (mvarVertices.xMin + mvarCentroidX) / 2.0;
                        }
                        if (mvarCentroidY == 0)
                        {
                            mvarCentroidY = mvarVertices.yMin;
                        }
                        else
                        {
                            mvarCentroidY = (mvarVertices.yMin + mvarCentroidY) / 2.0;
                        }
                        MVal = mvarVertices.mMin;
                        mvarVertices.Add(mvarVertices.xMin, mvarVertices.yMin, MVal, Convert.ToDouble(mvarVertices.zMin));
                    }
                    break;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章