• Arcengine开发的pas函数


    unit utGISPub;
    
    interface
    uses esriControls_TLB, esriCarto_TLB, esriDisplay_TLB, esriGeometry_TLB,
        esriGeoDatabase_TLB, esriSystem_TLB, esriDataSourcesFile_TLB, Windows,
        Messages,
        Graphics, Dialogs, SysUtils, Classes, ActiveX,
        OleCtrls, ComObj, Variants, ComCtrls, Forms;
    const
        MaxDimGeoMetryNum                   = 100; //最大定义数组个数
        PixelNum                            = 5; //像素
    function GetRGBColor(Color: Tcolor): IRgbColor; overload;
    function SetRGBColor(Color: Icolor): Tcolor;
    function GetRGBColor(Red, Green, Blue: integer): IRgbColor; overload;
    //屏幕的像素转化为地图
    function ConvertPixelsToMapUnits(pAView: IActiveView; pixelUnits: double):
        double;
    //加宽一个
    function WidenEnvelope(pEnv: IEnvelope; wd: double): IGeoMetry;
    //加宽一个
    function WidenEnvelopeToPolygon(pEnv: IEnvelope; wd: double): IGeoMetry;
    //矩形转化为区域
    function EnvToPoly(pEnv: IEnvelope): IPolygon;
    //矩形转化为折线
    function EnvToLine(pEnv: IEnvelope): IPolyLine;
    //两点线
    function PointToLine(x1, y1, x2, y2: double): IPolyLine; overload;
    //两点线
    function PointToLine(P1, p2: IPoint): IPolyLine; overload;
    //根据shp文件路径获得workspace
    function GetShpWorkSpace(FilePath: widestring): IWorkspace;
    
    //buffer
    
    function buffer(pgeometry: IGeoMetry; BufferDistance: double): IGeoMetry;
    //Boundary获得,边缘,线边缘是端点,面的为线
    function Boundary(pgeometry: IGeoMetry): IGeoMetry;
    //ConvexHull,外界凸多边性
    function ConvexHull(pgeometry: IGeoMetry): IGeoMetry;
    
    //合并对象
    function Combine(PGeoMetry1, PGeoMetry2: IGeoMetry): IGeoMetry; overload
    //合并对象
    function Erase(PGeoMetry1, PGeoMetry2: IGeoMetry): IGeoMetry; overload
    function Combine(PFCursor: IFeatureCursor): IGeoMetry; overload;
    
    //按长度分割线
    function SplitLineByLength(PPolyLine: IPolyLine; Distance: double;
        var outLine1, outLine2: IPolyLine): boolean;
    //按点分割线
    function SplitLineByPoint(PPolyLine: IPolyLine; P: IPoint;
        var outLine1, outLine2: IPolyLine): boolean;
    //线的首尾节点交换
    function ReversePolyLine(PPolyLine: IPolyLine): IPolyLine;
    //求两个对象的相交部分
    function Intersect(PGeoMetry1, PGeoMetry2: IGeoMetry): IGeoMetry;
    //求两个对象的相交点
    function IntersectPoint(PGeoMetry1, PGeoMetry2: IGeoMetry): IPointCollection;
    
    //擦除对象的,PGeoMetry1是要察除对象,PGeoMetry2是擦除工具对象
    function Difference(PGeoMetry1, PGeoMetry2: IGeoMetry): IGeoMetry;
    
    //返回两个对象的最近距离
    function ReturnDistance(PGeoMetry1, PGeoMetry2: IGeoMetry): double;
    //获得图层和PGeoMetry相交的对象,节点最近距离小于MinDist,yl add 2004.12.07
    function GetIntersetedMinDistpoint(const pEnvelope: IGeoMetry;
        pFeatLayer: IFeatureLayer; YPt: IPoint; MinDist: double): IPoint;
    
    //返回对象距离Pt最近的点
    function ReturnNearPoint(pgeometry: IGeoMetry; Pt: IPoint): IPoint;
    //Convert Features to Graphic Elements
    //将tFeatureToElement
    function ConvertFeatureToElement(pFeature: IFeature): IElement;
    //三点弧线
    function CreateCArcThreePoint(FromPoint: IPoint; ThruPoint: IPoint; ToPoint:
        IPoint; var angle: double): IPolyLine;
    //区域转换为线
    function PolygontoPloyLine(Polygon: IPolygon): IPolyLine; overload;
    //WD是扩张的宽度
    function PolygontoPloyLine(Polygon: IPolygon; wd: double): IPolyLine; overload;
    //idx:integer;//是索引
    procedure PolytoPoints(PPolygon: IPolygon; Tst: TstringList;
        idx: integer = 0); overload;
    procedure PolytoPoints(PPolygon: IPolyLine; Tst: TstringList;
        idx: integer = 0);
    overload;
    //去掉前面的大数
    function PointstoPoly(Tst: TstringList;
        XShift: integer = 0;
        YShift: integer = 0): IPolygon;
    
    //点集转化为PloyLine
    function PointsColltoPolyLine(PointsColl: IPointCollection): IPolyLine;
    function GeoMetryColltoPolyLine(PointsColl: IPointCollection): IPolyLine;
    
    //根据GIS文件获得ObjectClass
    function GetObjectClass(FileName: widestring): IFeatureClass;
    //增加一个对象PGeoMetry到图层
    procedure AddGeoMetry(pOClass: IObjectClass; pgeometry: IGeoMetry);
    //将一个字体转化为IFormattedTextSymbol
    function GetTextSymbolBtyFont(Font: TFont): IFormattedTextSymbol;
    //线切割面,根据小曾的修改
    function PolygonSpiltbyPolyLine(PPolygon: IPolygon; PPolyLine: IPolyLine; var
        FeaArray: array of IGeoMetry): integer;
    
    //删除所有字段
    procedure DeleteField(pFeatureClass: IObjectClass);
    //SymbolType为1点,2线,3为面
    
    function GetSymbol(SymbolType: integer; Color: Tcolor;
        Size: integer; Style: Toleenum): ISymbol;
    //面符号
    
    function GetSimpleFillSymbol(Color: Tcolor; Style: Toleenum;
        LineSize: integer; LineColor: Tcolor; LineStyle: Toleenum): ISymbol;
    
    //获得选择集的对象,Intersected为true表示相交对象,false表示合并后对象
    function GetSelectFeatures(FFeatureLayer: IFeatureLayer;
        var FID: integer; Intersected: boolean = False): IGeoMetry;
    
    //获得对象坐标
    function getGeoMetryCoord(pgeometry: IGeoMetry; List: TstringList;
        Clear: boolean = true; idx: integer = 0): integer;
    //获得图层类型
    function GetLayerType(FFeatureLayer: IFeatureLayer): Toleenum;
    //获得一个对象有几组成
    function GetPartNum(pgeometry: IGeoMetry): integer;
    //获得一个对象对应部分的坐标
    function GetPartPoints(pgeometry: IGeoMetry; Partindex: integer;
        List: TstringList): integer;
    //修改一个对象对应部分的坐标,其他部分不变
    //返回值为新的图形对象
    //Partindex是对应的修改部分,List为坐标点
    function SetPartPoints(pgeometry: IGeoMetry; Partindex: integer;
        List: TstringList): IGeoMetry;
    //替换一个GeoMetry的第几部分
    function ReplaceGeoMetryPartIndex(SourceGeoMetry, ReplaceGeoMetry: IGeoMetry;
        Partindex: integer): IGeoMetry;
    //插入一个节点,在GeoMetry的第几部分的那个位置插入节点
    function InsertPointToGeometry(SourceGeoMetry: IGeoMetry; Partindex: integer;
        vertexIndex: integer; Pt: IPoint): IGeoMetry;
    
    //删除
    function RemovePart(pgeometry: IGeoMetry; Partindex: integer): IGeoMetry;
    //获得对应部分
    function GetPart(pgeometry: IGeoMetry; Partindex: integer): IGeoMetry;
    
    //根据坐标点生成点集
    function CreatePointscollByList(pgeometry: IGeoMetry; List: TstringList):
        IPointCollection;
    //根据对象类型建立点集
    function CreatePointscollByGeoMetryType(pgeometry: IGeoMetry): IPointCollection;
    //根据对象类型建立GeoMetry对象
    function CreateGeoMetryByGeoMetryType(pgeometry: IGeoMetry):
        IGeoMetryCollection;
    
    //获得点集的坐标
    function getPointsCollCoord(pPointsColl: IPointCollection; List: TstringList):
        integer;
    //将合并到一起并分离的对象分解成一个对象
    function decomposeobj(pgeometry: IGeoMetry; var FeaArray: array of IGeoMetry):
        integer; overload;
    //获得一个Feature的图层名称
    function GetLayerName(pFeature: IFeature): widestring;
    //一个线对象被线分割
    function SplitGeoMetryByPolyLine(pgeometry: IGeoMetry;
        PPolyLine: IPolyLine; var FeaArray: array of IGeoMetry): integer;
    //获得一个图层FID字段名,shp和sde文件不一样,shp是fid,sde是objectid
    function GetFIDFieldName(FeatureLayer: IFeatureLayer): string; overload;
    //获得一个图层FID字段名,shp和sde文件不一样,shp是fid,sde是objectid
    function GetFIDFieldName(FeatureClass: IFeatureClass): string; overload;
    
    //获得shape字段的索引 by yl 2004.12.1
    function GetShapeFieldIdx(FeatureLayer: IFeatureLayer): integer;
    //删除一个GeoMetry的第几部分第几个点
    function DelGeoMetry(pgeometry: IGeoMetry; Partindex: integer; index: integer):
        IGeoMetry;
    function PolyLineToPolygon(pPoly: IPolyLine): IPolygon;
    function GeoMetryToPolygon(pgeometry: IGeoMetry): IPolygon;
    
    //获得选择集合并后矩形                                                        function PolyLineToPolygon(pPoly: IPolyLine): IPolygon;
    function GetSelectEnvelope(PSelectionSet: ISelectionSet): IEnvelope;
    //将GeoMetry转化为点对象,以便捕捉
    function GetPointCollByGeoMetry(pgeometry: IGeoMetry): IPointCollection;
    //转化一个图层到IFeatureLayer
    function LayerToFeatureLayer(FLayer: ILayer): IFeatureLayer;
    //获得一个图层extent
    function GetLayerExtent(PLayer: ILayer; IsAll: boolean = False): IEnvelope;
    //获得一个FeatureLayer的extent
    function GetFeatureLayerExtent(PFLayer: IFeatureLayer): IEnvelope;
    //
    function LayerToFeatureSelection(PLayer: ILayer): IFeatureSelection;
    //根据图层类型加载到地图窗口
    procedure AddLayerByType(pFeatureLayers: array of IFeatureLayer; pMap: Imap);
    overload;
    //根据图层类型加载到地图窗口 by yl 2005.8.8
    
    function AddLayerByType(pMap: Imap; PLayer: ILayer): ILayer; overload;
    
    //根据图层类型加载到地图窗口 by yl 2005.8.8
    function AddLayerByType(pFeatureLayer: IFeatureLayer; pMap: Imap):
        IFeatureLayer; overload;
    
    //根据 Featureclass创建图层
    
    function CreateLayerFeatureclass(pFeatCls: IFeatureClass):
        IFeatureLayer; overload;
    //根据当前表的结构创立,一个shp文件
    function CreateLayerFeatureclass(pFeatCls: IFeatureClass;
        FileName: string): IFeatureClass; overload;
    
    //******************************************************************************
    //以下函数为曾洪云新添加的函数和过程
    
    //初始化图层信息,使cmbLayers下拉框中的图层和地图中的图层保持同步
    function DistanceofTwoPoints(FirstPt, SecondPt: IPoint): double;
    function PolygonToPolyLine(pPoly: IPolygon): IPolyLine;
    //******************************************************************************
    //获得图层和Splitter相交的对象,注释yl add
    function GetIntersetedFeatures(const Splitter: IPolyLine; pFeatLayer:
        IFeatureLayer): IFeatureCursor;
    //两个对象是否接触
    function CheckTouch(const SGeometry, TGeometry: IGeoMetry): boolean;
    //合并两个对象
    function UnionGeometry(SGeometry, TGeometry: IGeoMetry): IGeoMetry;
    //按照SourceFeature的字段属性,插入图形AGeometry
    function InsertNewFeature(const AfeatureClass: IFeatureClass;
        const AGeometry: IGeoMetry; const SourceFeature: IFeature): integer;
    function CanSplit(const Splitter: IPolyLine; Poly: IGeoMetry): boolean;
    function CanSplitEx(const Splitter: IPolyLine; PLayer: IFeatureLayer): integer;
    function CreatePolygonfromRing(ExRing: IRing): IGeoMetry;
    function CreatePolyLinefromPath(ExPath: IPath): IGeoMetry;
    //add by yl
    //根据条件加载图层
    function FeatureLayerBywhere(pFeatureLayer: IFeatureLayer; Where: string):
        IFeatureLayer;
    //获得一个对象的面积
    function GetArea(PPolygon: IPolygon): double;
    //给一个图层增加一个字段 by yl 2005.8.11
    function LayerAddField(pFeatureLayer: IFeatureLayer; Field: IField): boolean;
    //获得图层的纪录的个数   by yl 2005.8.11
    function GetRecordcount(FFeatureLayer: IFeatureLayer): integer; overload;
    //获得图层的纪录的个数   by yl 2007.7.25,真正的获得个数
    
    function GetRecordcount2(FFeatureLayer: IFeatureLayer): integer;
    //获得图层的纪录的个数   by yl 2007.7.25,真正的获得个数
    
    function GetshpRecordcount2(FFeatureLayer: IFeatureLayer): integer;
    
    //获得图层的纪录的个数   by yl 2005.8.11
    function GetRecordcount(FFeatureClass: IFeatureClass): integer; overload;
    
    //获得图层的纪录的选择记录个数    by yl 2005.8.11
    function GetSelectRecordcount(FFeatureLayer: IFeatureLayer): integer;
    function SearchbySql(pFeatureClass: IFeatureClass; sql: string;
        var count: integer; Update: boolean = False): IFeatureCursor;
    //获得图层的空间查询   by yl 2005.8.11
    function Searchbyshape(FFeatureLayer: IFeatureLayer; pgeometry: IGeoMetry;
        SearchMode: Toleenum = esriSpatialRelIntersects): IFeatureCursor; overload;
    //获得图层的空间查询   Count是相交的个数
    
    function Searchbyshape(FFeatureClass: IFeatureClass; pgeometry: IGeoMetry;
        WhereStr: string; var count: integer): IFeatureCursor; overload;
    
    //获得图层的空间查询   by yl 2006.8.4
    function Searchbyshape(FFeatureLayer: IFeatureLayer; pgeometry: IGeoMetry;
        WhereStr: string; SearchMode: Toleenum = esriSpatialRelIntersects):
        IFeatureCursor; overload;
    
    //获得图层的空间查询   by yl 2005.8.11
    function Searchbyshape(pFeatureClass: IFeatureClass; pgeometry: IGeoMetry;
        var count: integer; Update: boolean = False; SearchMode: Toleenum =
        esriSpatialRelIntersects): IFeatureCursor; overload;
    //获得图层的空间查询   by yl 2006.9.20
    function Searchbyshape(pFeatureClass: IFeatureClass; WhereStr: string;
        var count: integer): IFeatureCursor; overload;
    
    //获得shape字段的索引 by yl 2005.8.11
    function GetShapeFieldName(FeatureLayer: IFeatureLayer): string; overload;
    //获得shape字段的索引 by yl 2005.8.11
    function GetShapeFieldName(FeatureClass: IFeatureClass): string; overload;
    
    //有Feature获得图层名称 by yl 2005.8.21
    function GetLayerNameByFeature(pFeature: IFeature): string;
    //根据FID获得对象
    function GetFeature(FeatureLayer: IFeatureLayer; FID: integer): IFeature;
    overload;
    //根据FID获得对象
    function GetFeature(FeatureLayer: IFeatureLayer; FID: integer;
        FIDFieldName: widestring): IFeature; overload;
    
    //根据FID获得对象
    
    function GetFeature(pFeatureClass: IFeatureClass; FID: integer; FIDFieldName:
        widestring): IFeature; overload;
    //根据FID获得对象
    function GetFeature(pFeatureClass: IFeatureClass; FID: integer): IFeature;
    overload;
    
    //获得字段的位置
    function GetFieldPos(FeatureLayer: IFeatureLayer; FieldName:
        widestring; ISAlias: boolean = False): integer; overload;
    //获得字段的位置
    function GetFieldPos(pFeatClass: IFeatureClass; FieldName:
        widestring; ISAlias: boolean = False): integer; overload;
    
    //获得字段的位置
    function GetFieldPos(pFeature: IFeature; FieldName:
        widestring): integer; overload;
    //获得字段的位置
    function GetField(pFeatClass: IFeatureClass; FieldName:
        widestring): IField;
    
    //获得字段的类型
    function GetFieldType(FeatureLayer: IFeatureLayer; FieldName:
        widestring): Toleenum; overload;
    //获得字段的类型
    
    function GetFieldType(pFcc: IFeatureClass; FieldName:
        widestring): Toleenum; overload;
    
    //返回对应索引字段的值,ptype主要解决空值(null)转换,没有空值就不需要
    function getfieldvalue(pFeature: IFeature; idx: integer;
        ptype: TVarType = varString): variant; overload;
    function SetFieldValue(pFeature: IFeature; FieldName: string; value: string):
        boolean;
    
    function getfieldvalue(pFeature: IFeature; FieldName: string): variant;
    
    overload;
    //判断对象自相交
    function IsSelfCross(pgeometry: IGeoMetry): boolean;
    //增加影像图,Filename含路径
    
    function AddRasterFile(FileName: string): IRasterLayer;
    //获得字段的唯一值
    
    procedure listUniqueValue(PLayer: IFeatureLayer;
        pFieldName: string; List: TstringList;
        Isthread: boolean = False; ISmark: string = ''); overload;
    //获得字段的唯一值
    
    procedure listUniqueValue(pFeatureClass: IFeatureClass;
        pFieldName: string; List: TstringList; Isthread: boolean = False); overload;
    
    //获得选择集合并后对象
    
    function GetSelectUnion(PSelectionSet: ISelectionSet): IGeoMetry; overload;
    //选择图层查询
    function Get_SelectLayer(pMap: Imap; var FtLayerArr: array of IFeatureLayer):
        integer; overload;
    //选择图层查询
    function Get_SelectLayer(pMap: Imap; List: TstringList): integer; overload;
    
    //获得失量图层查询
    function Get_FeatureLayer(pMap: Imap; var FtLayerArr: array of IFeatureLayer):
        integer;
    
    //获得选择集合并后对象
    function GetSelectUnion(pMap: Imap): IGeoMetry; overload;
    //获得点在矩形八个点的位置,dis是最小距离大于,最小距离返回-1
    function GetPosINEnvelope(pEnvelope: IEnvelope; x, Y: double; Dis: double):
        integer;
    //----------------------------------拖拽--------------------------
     //OleDrop中增加图层
    function CreateLayer(pName: IName; pMap: Imap): boolean;
    //将地图拷贝(SMap)到地图上(TMap),
    
    procedure CopyMap(SMap: Imap; TMap: Imap);
    procedure CopyElement(SGraphicsContainer, TGraphicsContainer:
        IGraphicsContainer);
    //获得一个图层的坐标
    function GetSpatialReference(FeatureLayer: IFeatureLayer): ISpatialReference;
    overload;
    function GetSpatialReference(FeatureClass: IFeatureClass): ISpatialReference;
    overload;
    
    //把一个图层的选择对象装入TTreeView
    function LoadTreeByselectobj(FeatureLayer: IFeatureLayer; TV: TTreeView):
        boolean;
    //获得图斑层选择对象的集合
    function getSelectGeoMetry(PFLayer: ILayer): IEnvelope;
    //获得选择对象,字段的唯一值
    
    procedure listSelectUniqueValue(PLayer: IFeatureLayer;
        pFieldName: string; List: TstringList; Isthread: boolean = False);
    //获得唯一值
    procedure listUniqueValue(PCursor: IFeatureCursor;
        pFieldName: string; List: TstringList; Isthread: boolean = False; ISmark:
        string = ''); overload;
    procedure SetFilter(var pTSF: ISpatialFilter; pgeometry: IGeoMetry;
        WhereStr: string = '');
    //获得图层的空间查询   Count是相交的个数
    function Searchbyshape(FFeatureLayer: IFeatureLayer; pgeometry: IGeoMetry; var
        count: integer): IFeatureCursor; overload;
    
    //说明:删除对象分割后旧的要素
    procedure DeleteSplitObjFeat(FID: integer; pFClass: IFeatureClass);
    //分解对象
    function decomposeobj(pFeature: IFeature; pFeatureClass: IFeatureClass):
        integer; overload;
    function UpdateFeature(FID: integer; pGeom: IGeoMetry; pFeatLayer:
        IFeatureLayer): boolean; overload;
    function UpdateFeature(FID: integer; pGeom: IGeoMetry;
        pFeatClass: IFeatureClass): boolean; overload;
    
    function UpdateFeature(pFeature: IFeature; pGeom: IGeoMetry): boolean; overload
    
    procedure CreateFeature(SourceFeature: IFeature; pGeom: IGeoMetry;
        pFeatureClass: IFeatureClass);
    function PointIsGeom(pGeom: IGeoMetry; x, Y: double): boolean; overload;
    function PointIsGeom(PPoint: IPoint; pGeom: IGeoMetry): boolean; overload;
    
    //传入一个对象,创建线 ,返回相交部分
    
    procedure Createline(XMin, YMin, XMax, YMax: double; pGeom:
        IGeoMetry; var pGeomLine: IGeoMetry);
    //取得对象中心坐标
    
    procedure GetGeomCenterXY(pGeom: IGeoMetry; var cx, cy:
        double);
    //取得对象中心坐标
    
    procedure GetGeoMetryCenterXY(pGeom: IGeoMetry; var cx, cy:
        double);
    
    //开始编辑
    function StartEdit(FeatureLayer: IFeatureLayer): boolean; overload;
    //结束编辑
    function StopEdit(FeatureLayer: IFeatureLayer): boolean; overload;
    
    function StartEdit(FWorkspace: IWorkspace): boolean; overload;
    
    //结束编辑
    
    function StopEdit(FWorkspace: IWorkspace): boolean; overload;
    //简单拓扑一个对象
    procedure IsSimple(var pgeometry: IGeoMetry);
    //获得一个对象的长度
    
    function GetLineLength(pgeometry: IGeoMetry): double;
    //对于线了,获得长度,对于面了,获得面积,其他为0
    function GetValue(pgeometry: IGeoMetry): double;
    function Move(pgeometry: IGeoMetry; x, Y: double): IGeoMetry;
    function RingtoPolygon(PRing: IRing): IPolygon;
    function RingtoPolyLine(PRing: IRing): IPolyLine;
    function PathtoPolyLine(PPath: IPath): IPolyLine;
    function GeoMetrytoPolyLine(pgeometry: IGeoMetry): IPolyLine;
    //获得字段列表
    function GetFieldNameList(pFeatureClass: IFeatureClass; List: TstringList):
        integer;
    //获得字段index列表
    
    function GetFieldNameIdxList(pFeatureClass: IFeatureClass; List: TstringList):
        integer;
    //获得线的中点
    function GetLineCenterPoint(Polyline: IPolyLine): IPoint;
    //按字段(目标码)排序
    
    function SortByMBBSM(pFeatureClass: IFeatureClass; FileName: string):
        IFeatureCursor;
    //获得Workspace
    function GetWorkspace(FeatureLayer: IFeatureLayer): IWorkspace; overload;
    //获得Workspace
    function GetWorkspace(FeatureClass: IFeatureClass): IWorkspace; overload;
    
    //判断一个多边形是否IEnvelope
    function PolygonISEnvelope(PPolygon: IPolygon): boolean;
    //获得多边形的最小x,y
    function GetGeoMetryMinXy(pgeometry: IGeoMetry; var Minx, Miny: double):
        boolean;
    //取得对象LabelPoint坐标
    
    procedure GetGeoMetryLabelPoint(pGeom: IGeoMetry;
        var cx, cy: double);
    //执行sql返回值
    function ExecSQLResult(FWorkspace: IWorkspace;
        Sqlstr: string): olevariant; overload;
    //执行sql返回值
    function ExecSQLResult(FeatureLayer: IFeatureLayer;
        Sqlstr, FieldName: string): olevariant; overload;
    
    //获得由中文字段的英文 ,字段别名与字段名相互转换
    
    function GetFieldNameByAlias(FeatureLayer: IFeatureLayer; FieldName:
        widestring; ISAlias: boolean = False): string; overload;
    //获得由中文字段的英文 ,字段别名与字段名相互转换
    
    function GetFieldNameByAlias(pFeatClass: IFeatureClass; FieldName:
        widestring; ISAlias: boolean = False): widestring; overload;
    //根据图层名获得图层,支持影像
    
    function GetMapControlLayer(LayerName: string; MapControl: IMapControl2):
        ILayer;
    //判断一个GeoMetry是否为矩形
    function GeoMetryIsEnvelope(pgeometry: IGeoMetry): boolean;
    //获得选择的Feature
    function GetSelectFeature(pFeatureLayer: IFeatureLayer): IFeature;
    //获得一个FeatureLayer的extent
    
    function GetFeatureLayerGeoMetryExtent(PFLayer: IFeatureLayer): IEnvelope;
    overload;
    function GetFeatureLayerGeoMetryExtent(PFLayer: IFeatureClass): IEnvelope;
    overload;
    function GetSelectionsetByFeatureLayer(pFeatureLayer: ILayer): ISelectionSet;
    function GetFeatureCursorByFeatureLayer(pFeatureLayer: ILayer): IFeatureCursor;
    function GetIntersectsNotTouches(FFeatureLayer: IFeatureLayer;
        pgeometry: IGeoMetry; MaxD: double): IFeatureCursor;  //相交不接触的 ,数据太多不行
    //执行sql
    
    function ExecuteSQL(Pworkspace: IWorkspace; Sqlstr: string;
        HintUser: boolean = true): string;
    //中心不变,按新的高,宽设置
    function SetNewEnvelope(pEnvelope: IEnvelope; w, h: double): IEnvelope;
    //按照窗口设置新的地图entent;
     //winW是窗户的宽度, winW是窗户的高度
    function getNewEnvelopeByWindows(pEnvelope: IEnvelope; WinW, WinH: integer):
        IEnvelope;
    //获得表字段集合,ISNum:Boolean=True表示所有字段,为false表示数字字段不考虑
    
    function GetFieldSt(FeatureLayer: IFeatureLayer;
        FieldList: TstringList; ISNum: boolean = true;
        IsChinese: boolean = true): integer;
    //获得字段列表,中英文都要
    function GetFieldList(FeatureLayer: IFeatureLayer;
        FieldList: TstringList): integer;
    
    //考虑空
    
    procedure SetvalueBySpace(pFeature: IFeature; idx: integer; value: string;
        Space: boolean = False);
    //获得文件路径和名称
    
    procedure GetPathFileName(pFeatureLayer: IFeatureLayer; var path, FileName:
        widestring); overload;
    //获得文件路径和名称
    procedure GetPathFileName(pFeatureClass: IFeatureClass; var path, FileName:
        widestring); overload;
    
    //获得数据类型
    function GetDataType(pFeatureLayer: IFeatureLayer): integer;
    //更新字段值
    procedure updateFieldValue(pFeatureLayer: IFeatureLayer; FieldName, value:
        string);
    //判断
    function IsEmpty(pgeometry: IGeoMetry): boolean;
    //根据原始GeoMetry拷贝GeoMetry
    function CopyGeoMetry(pgeometry: IGeoMetry): IGeoMetry;
    //判断一个FeatureClass的类型,是否为注记
    
    function FeatureClassIsAnnotation(pFeatureClass: IFeatureClass): boolean;
    //修改FeatureClass的投影
    function AlterFeatureClassSpatialReference(pFeatureClass: IFeatureClass;
        PSpatialReference: ISpatialReference): boolean;
    //由于有些城镇的图太小,修改的原来的缓冲取函数 by yl 2007.7.20
    
    function GetNewBuffer(pgeometry: IGeoMetry; Dis: double): IGeoMetry;
    //删除shp文件
    function deleteshpFileName(shpFileName: string): boolean;
    // 判断是否交叉
    //1为交叉,2,前者包括后者,3,后者包含前者,0为不相交
    function iscross(Envelope1, Envelope2: IEnvelope): integer;
    //转到shp
    function ConvertFeatureClassToShapesFile(pFeatureClass: IFeatureClass;
        pFilePath, pFileName: string): boolean; overload;
    //转到shp
    function ConvertFeatureClassToShapesFile(pFeatureClass: IFeatureClass;
        pOutWorkspace: IWorkspace): boolean; overload;
    //根据图层名获得图层,支持影像
    
    function GetLayer(pMap: Imap; LayerName: string): ILayer;
    //4点矩形
    function Point4(x1, y1, x2, y2: double): IGeoMetry;
    //把标注转换注记
    
    procedure ConvertLabelsToGDBAnnotationSingleLayer(pMap: Imap;
        pFeatureLayer: IFeatureLayer; pannworkspace: IWorkspace;
        AnnLayername: string; featureLinked: bool);
    
    implementation
    
    uses utYGpub, Math;
    
    function Point4(x1, y1, x2, y2: double): IGeoMetry;
    var
        pEnv                                : IEnvelope;
    begin
        pEnv := CoEnvelope.create as IEnvelope;
        pEnv.PutCoords(x1, y1, x2, y2);
        result := EnvToPoly(pEnv) as IGeoMetry;
    
    end;
    //判断
    
    function IsEmpty(pgeometry: IGeoMetry): boolean;
    var
        e                                   : wordbool;
    begin
        result := true;
    
        if pgeometry = nil then exit;
        pgeometry.Get_IsEmpty(e);
        result := e;
    end;
    //根据原始GeoMetry拷贝GeoMetry
    
    function CopyGeoMetry(pgeometry: IGeoMetry): IGeoMetry;
    var
    
        pClone                              : IClone;
        CopyClone                           : IClone;
    
    begin
        pClone := pgeometry as IClone;
        pClone.Clone(CopyClone);
        result := CopyClone as IGeoMetry;
    
    end;
    //对于线了,获得长度,对于面了,获得面积,其他为0
    
    function GetValue(pgeometry: IGeoMetry): double;
    var
        pObj                                : IUnKnown;
    begin
        result := 0;
        if pgeometry = nil then exit;
        if pgeometry.QueryInterface(IID_IPOLYLINE, pObj) = s_Ok then
        begin
            result := GetLineLength(pgeometry);
        end
        else if pgeometry.QueryInterface(IID_IPOLYGON, pObj) = s_Ok then
        begin
            result := GetArea(pgeometry as IPolygon);
        end;
    end;
    //获得一个对象的面积
    
    function GetArea(PPolygon: IPolygon): double;
    var
        pArea                               : IArea;
    begin
        result := 0;
        if PPolygon = nil then
            exit;
    
        pArea := PPolygon as IArea;
        pArea.Get_Area(result);
    end;
    //获得一个对象的长度
    
    function GetLineLength(pgeometry: IGeoMetry): double;
    var
        pObj                                : IUnKnown;
        PPolyLine                           : IPolyLine;
    begin
        result := 0;
        if pgeometry = nil then
            exit;
    
        if pgeometry.QueryInterface(IID_IPOLYLINE, pObj) = s_Ok then
        begin
            PPolyLine := pgeometry as IPolyLine;
            PPolyLine.Get_Length(result);
        end;
    
    end;
    
    //按照SourceFeature的字段属性,插入图形AGeometry
    
    function InsertNewFeature(const AfeatureClass: IFeatureClass;
        const AGeometry: IGeoMetry; const SourceFeature: IFeature): integer;
    //判断数据类型是否一致
        function GeoMetryTypeIsSame(): boolean;
        var
            ShapeType1, ShapeType2          : Toleenum;
        begin
            AfeatureClass.Get_ShapeType(ShapeType1);
            AGeometry.Get_GeometryType(ShapeType2);
    
            result := ShapeType1 = ShapeType2;
            if not result then
            begin
                raise exception.create('数据类型不一致');
            end;
        end;
    
    var
        pFeatureBuffer                      : IFeatureBuffer;
        PFeatureCursor                      : IFeatureCursor;
        id, pvalue                          : olevariant;
        pFeature                            : IFeature;
        pFs, pNewFs                         : IFields;
        pF                                  : IField;
        I, Findex, index, OIndex, Fcount    : integer;
        Fname                               : widestring;
        pRow                                : Irow;
    begin
        result := -1;
        if (AGeometry = nil) or (AfeatureClass = nil) then exit;
        GeoMetryTypeIsSame();
    
        AfeatureClass.Insert(true, PFeatureCursor);
        AfeatureClass.CreateFeatureBuffer(pFeatureBuffer);
        pFeatureBuffer._Set_Shape(AGeometry); //设置图形
    
        pFeature := pFeatureBuffer as IFeature; //复制属性
        pRow := pFeature as Irow;
        (SourceFeature as Irow).Get_Fields(pFs);
        pFs.Get_FieldCount(Fcount);
        pRow.Get_Fields(pNewFs);
    
        AfeatureClass.Get_ShapeFieldName(Fname); //获得shape字段名
        pFs.FindField(Fname, Findex);       //忽略OID和shap字段
        AfeatureClass.Get_OIDFieldName(Fname); //FID字段名
        pFs.FindField(Fname, OIndex);
        for I := 0 to Fcount - 1 do
        begin
            if (I = OIndex) or (I = Findex) then Continue;
            pFs.Get_Field(I, pF);
            pF.Get_Name(Fname);
            pNewFs.FindField(Fname, index);
            SourceFeature.Get_Value(I, pvalue);
            pRow.set_Value(index, pvalue);
        end;
    
        PFeatureCursor.InsertFeature(pFeatureBuffer, id);
        PFeatureCursor.Flush;
        result := id;
    end;
    
    //删除所有字段
    
    procedure DeleteField(pFeatureClass: IObjectClass);
    var
        pFields                             : IFields;
        Field                               : IField;
        I, num                              : Longint;
        FieldType                           : Toleenum;
    begin
        pFeatureClass.Get_Fields(pFields);
        pFields.Get_FieldCount(num);
        for I := num - 1 downto 0 do
        begin
            pFields.Get_Field(I, Field);
            Field.Get_type_(FieldType);
            if (FieldType <> esriFieldTypeOID) and (FieldType <>
                esriFieldTypeGeometry) then
                pFeatureClass.DeleteField(Field);
        end;
    end;
    
    //增加一个对象PGeoMetry到图层
    
    procedure AddGeoMetry(pOClass: IObjectClass; pgeometry: IGeoMetry);
    var
        pFClass                             : IFeatureClass;
        pfeat                               : IFeature;
    begin
    
        pFClass := pOClass as IFeatureClass;
        pFClass.CreateFeature(pfeat);
    
        pfeat._Set_Shape(pgeometry);
        pfeat.Store;
        //Refresh(esriViewGeography);
    
    end;
    
    function GetObjectClass(FileName: widestring): IFeatureClass;
    var
        pWFactory                           : IWorkspaceFactory;
        pPropertySet                        : IPropertySet;
        Pworkspace                          : IWorkspace;
        pFWorkspace                         : IFeatureWorkspace;
        pFClass                             : IFeatureClass;
        //V: olevariant;
        FilePath                            : string;
    begin
        try
            FilePath := ExtractFilePath(FileName);
            pWFactory := CoShapefileWorkspaceFactory.create as
                IWorkspaceFactory;
            pPropertySet := CoPropertySet.create as IPropertySet;
            pPropertySet.SetProperty('DATABASE', FilePath);
            pWFactory.Open(pPropertySet, 0, Pworkspace);
            pFWorkspace := Pworkspace as IFeatureWorkspace;
            FileName := Getonlyfilename(FileName);
    
            //Delete(FileName, Length(FileName) - 3, 4);
            pFWorkspace.OpenFeatureClass(FileName, pFClass);
            if pFClass = nil then
                raise exception.create('错误:文件不存在或则图形类型不对');
            result := pFClass;
    
        except
            on e: exception do result := nil;
        end;
    end;
    //根据shp文件路径获得workspace
    
    function GetShpWorkSpace(FilePath: widestring): IWorkspace;
    var
        pWFactory                           : IWorkspaceFactory;
        pPropertySet                        : IPropertySet;
        Pworkspace                          : IWorkspace;
    
    begin
        try
    
            pWFactory := CoShapefileWorkspaceFactory.create as
                IWorkspaceFactory;
            pPropertySet := CoPropertySet.create as IPropertySet;
            pPropertySet.SetProperty('DATABASE', FilePath);
            pWFactory.Open(pPropertySet, 0, Pworkspace);
    
            result := Pworkspace;
        except
            on e: exception do result := nil;
        end;
    end;
    
    function EnvToPoly(pEnv: IEnvelope): IPolygon;
    var
        pPointsColl                         : IPointCollection;
        P1, p2, p3, p4                      : IPoint;
        pTopo                               : ITopologicalOperator;
    begin
        pPointsColl := CoPolygon.create as IPointCollection;
    
        pEnv.Get_LowerLeft(P1);
        pEnv.Get_UpperLeft(p2);
        pEnv.Get_UpperRight(p3);
        pEnv.Get_LowerRight(p4);
        pPointsColl.AddPoints(1, P1);
        pPointsColl.AddPoints(1, p2);
        pPointsColl.AddPoints(1, p3);
        pPointsColl.AddPoints(1, p4);
        pTopo := pPointsColl as ITopologicalOperator;
        pTopo.Simplify();
    
        result := pPointsColl as IPolygon;
    
    end;
    
    function GeoMetryToPolygon(pgeometry: IGeoMetry): IPolygon;
    var
        pPointsColl                         : IPointCollection;
        pTopo                               : ITopologicalOperator;
    begin
        pPointsColl := CoPolygon.create as IPointCollection;
    
        pPointsColl.AddPointCollection(pgeometry as IPointCollection);
    
        pTopo := pPointsColl as ITopologicalOperator;
        pTopo.Simplify();
    
        result := pPointsColl as IPolygon;
    
    end;
    
    function EnvToLine(pEnv: IEnvelope): IPolyLine;
    var
        pPointsColl                         : IPointCollection;
        P1, p2, p3, p4                      : IPoint;
        pTopo                               : ITopologicalOperator;
    begin
        pPointsColl := CoPolyLine.create as IPointCollection;
        pEnv.Get_LowerLeft(P1);
        pEnv.Get_UpperLeft(p2);
        pEnv.Get_UpperRight(p3);
        pEnv.Get_LowerRight(p4);
        pPointsColl.AddPoints(1, P1);
        pPointsColl.AddPoints(1, p2);
        pPointsColl.AddPoints(1, p3);
        pPointsColl.AddPoints(1, p4);
        pPointsColl.AddPoints(1, P1);
        pTopo := pPointsColl as ITopologicalOperator;
        pTopo.Simplify();
        result := pPointsColl as IPolyLine;
    
    end;
    
    //两点线
    
    function PointToLine(P1, p2: IPoint): IPolyLine; overload;
    var
        pPointsColl                         : IPointCollection;
        pTopo                               : ITopologicalOperator;
    begin
        pPointsColl := CoPolyLine.create as IPointCollection;
        pPointsColl.AddPoints(1, P1);
        pPointsColl.AddPoints(1, p2);
        pTopo := pPointsColl as ITopologicalOperator;
        pTopo.Simplify();
        result := pPointsColl as IPolyLine;
    
    end;
    
    function PointToLine(x1, y1, x2, y2: double): IPolyLine;
    var
        P1, p2                              : IPoint;
    begin
        P1 := CoPoint.create as IPoint;
        p2 := CoPoint.create as IPoint;
        try
            P1.PutCoords(x1, y1);
            p2.PutCoords(x2, y2);
            result := PointToLine(P1, p2);
        finally
            P1 := nil;
            p2 := nil;
        end;
    
    end;
    
    function SetRGBColor(Color: Icolor): Tcolor;
    
    var
        pRGB                                : IRgbColor;
        Red, Blue, Green                    : integer;
        pObj                                : IUnKnown;
    
    begin
        result := -1;
        if Color = nil then exit;
        if Color.QueryInterface(IID_IRgbColor, pObj) = s_Ok then
        begin
            pRGB := Color as IRgbColor;
            pRGB.Get_Red(Red);
            pRGB.Get_Blue(Blue);
            pRGB.Get_Green(Green);
            result := RGB(Red, Green, Blue);
        end;
    
    end;
    
    function GetRGBColor(Color: Tcolor): IRgbColor;
    var
        pRGB                                : IRgbColor;
    
    begin
    
        pRGB := CoRgbColor.create as IRgbColor;
        if Color < 0 then
        begin
            result := pRGB;
            exit;
        end;
    
        pRGB.Set_Red(getRvalue(Color));
        pRGB.Set_Green(getGvalue(Color));
        pRGB.Set_Blue(getbvalue(Color));
        pRGB.Set_UseWindowsDithering(true);
        result := pRGB;
    
    end;
    
    function GetRGBColor(Red, Green, Blue: integer): IRgbColor;
    var
        pRGB                                : IRgbColor;
    begin
    
        pRGB := CoRgbColor.create as IRgbColor;
        pRGB.Set_Red(Red);
        pRGB.Set_Green(Green);
        pRGB.Set_Blue(Blue);
        pRGB.Set_UseWindowsDithering(true);
        result := pRGB;
    
    end;
    //屏幕的像素转化为地图
    
    function ConvertPixelsToMapUnits(pAView: IActiveView; pixelUnits: double):
        double;
    var
        pScreen                             : IScreenDisplay;
        pDisplay                            : IDisplayTransformation;
        pBounds                             : tagRect;
        realWorldDisplayExtent              : double;
        pixelExtent                         : integer;
        sizeOfOnePixel                      : double;
        pTemp                               : IEnvelope;
    begin
        try
            pAView.Get_ScreenDisplay(pScreen);
            pScreen.Get_DisplayTransformation(pDisplay);
            pDisplay.Get_DeviceFrame(pBounds);
            pixelExtent := pBounds.Right - pBounds.Left;
            pDisplay.Get_VisibleBounds(pTemp);
            pTemp.Get_Width(realWorldDisplayExtent);
            sizeOfOnePixel := realWorldDisplayExtent / pixelExtent;
            result := pixelUnits * sizeOfOnePixel;
        finally
            pScreen := nil;
            pDisplay := nil;
            pTemp := nil;
        end;
    end;
    //buffer
    
    function buffer(pgeometry: IGeoMetry; BufferDistance: double): IGeoMetry;
    var
        pTopoOp                             : ITopologicalOperator;
    begin
        pTopoOp := pgeometry as ITopologicalOperator;
        pTopoOp.buffer(BufferDistance, result);
    
    end;
    //Boundary获得,边缘,线边缘是端点,面的为线
    
    function Boundary(pgeometry: IGeoMetry): IGeoMetry;
    var
        pTopoOp                             : ITopologicalOperator;
    begin
        pTopoOp := pgeometry as ITopologicalOperator;
        pTopoOp.Get_Boundary(result);
    
    end;
    //ConvexHull,外界凸多边性
    
    function ConvexHull(pgeometry: IGeoMetry): IGeoMetry;
    var
        pTopoOp                             : ITopologicalOperator;
    begin
        pTopoOp := pgeometry as ITopologicalOperator;
        pTopoOp.ConvexHull(result);
    
    end;
    
    function Erase(PGeoMetry1, PGeoMetry2: IGeoMetry): IGeoMetry; overload;
    var
        pTopoOp                             : ITopologicalOperator;
    begin
        pTopoOp := PGeoMetry1 as ITopologicalOperator;
        pTopoOp.SymmetricDifference(PGeoMetry2, result);
    
    end;
    
    //合并对象
    
    function Combine(PGeoMetry1, PGeoMetry2: IGeoMetry): IGeoMetry;
    begin
        result := UnionGeometry(PGeoMetry1, PGeoMetry2);
    end;
    
    function UnionGeometry(SGeometry, TGeometry: IGeoMetry): IGeoMetry;
    begin
        if (TGeometry = nil) and (SGeometry = nil) then exit;
        if SGeometry = nil then
            result := TGeometry
        else
            if TGeometry = nil then
                result := SGeometry
            else
            begin
                (SGeometry as ITopologicalOperator).union(TGeometry,
                    result);
                IsSimple(result);
    
            end;
    end;
    
    //求两个对象的相交点
    
    function IntersectPoint(PGeoMetry1, PGeoMetry2: IGeoMetry): IPointCollection;
    var
        pTopoOp                             : ITopologicalOperator;
        InterSectGeo                        : IGeoMetry;
    begin
    
        pTopoOp := PGeoMetry1 as ITopologicalOperator;
    
        pTopoOp.Intersect(PGeoMetry2, esriGeometry0Dimension,
            InterSectGeo);
        //Intersect是相交部分
        if InterSectGeo <> nil then
            result := InterSectGeo as IPointCollection
        else
            result := nil;
    
    end;
    
    //求两个对象的相交部分
    
    function Intersect(PGeoMetry1, PGeoMetry2: IGeoMetry): IGeoMetry;
    //根据对象类型返回交叉的参数
        function IntersectParamByGeoMetryType(ShapeType: Toleenum):
                Toleenum;
    
        begin
    
            case ShapeType of
                esriGeometryPoint:
                    begin
                        result := esriGeometry0Dimension;
                    end;
    
                esriGeometryPolyline:
                    begin
                        result := esriGeometry1Dimension;
                    end;
                esriGeometryPolygon:
                    begin
                        result := esriGeometry2Dimension;
                    end;
            else
                begin
                    result := esriGeometryNoDimension;
                end;
    
            end;
        end;
    
    var
        pTopoOp                             : ITopologicalOperator;
        ShapeType                           : Toleenum;
        ShapeType1, ShapeType2              : Toleenum;
        PSpatialReference                   : ISpatialReference;
    
    begin
        if (PGeoMetry1 = nil) or (PGeoMetry2 = nil) then
        begin
            result := nil;
            exit;
        end;
        PGeoMetry1.Get_GeometryType(ShapeType1);
        PGeoMetry2.Get_GeometryType(ShapeType2);
        PGeoMetry1.Get_SpatialReference(PSpatialReference);
        PGeoMetry2._Set_SpatialReference(PSpatialReference);
        ShapeType := Min(ShapeType1, ShapeType2);
        pTopoOp := PGeoMetry1 as ITopologicalOperator;
        pTopoOp.Intersect(PGeoMetry2, IntersectParamByGeoMetryType(ShapeType),
            result);                        //Intersect是相交部分
    
    end;
    //擦除对象的,PGeoMetry1是要察除对象,PGeoMetry2是擦除工具对象
    
    function Difference(PGeoMetry1, PGeoMetry2: IGeoMetry): IGeoMetry;
    var
        pTopoOp                             : ITopologicalOperator;
    begin
        IsSimple(PGeoMetry1);
        IsSimple(PGeoMetry2);
        pTopoOp := PGeoMetry1 as ITopologicalOperator;
        pTopoOp.Difference(PGeoMetry2, result); //Intersect是相交部分
    
    end;
    
    //返回两个对象的最近距离
    
    function ReturnDistance(PGeoMetry1, PGeoMetry2: IGeoMetry): double;
    var
        P                                   : IProximityOperator;
    begin
        if (PGeoMetry1 = nil) or (PGeoMetry2 = nil) then
        begin
            result := 99999999;
            exit;
        end;
        P := PGeoMetry1 as IProximityOperator;
        P.ReturnDistance(PGeoMetry2, result)
    
    end;
    
    //返回对象距离Pt最近的点
    
    function ReturnNearPoint(pgeometry: IGeoMetry; Pt: IPoint): IPoint;
    var
        P                                   : IProximityOperator;
    begin
        P := pgeometry as IProximityOperator;
        P.ReturnNearestPoint(Pt, esriNoExtension, result);
    
    end;
    
    //WD是扩张的宽度
    
    function PolygontoPloyLine(Polygon: IPolygon; wd: double): IPolyLine;
    var
        pPointsColl                         : IPointCollection;
        plColl                              : IPointCollection;
        I, num                              : integer;
        pPt                                 : IPoint;
        x, Y                                : double;
    begin
        pPointsColl := Polygon as IPointCollection;
        plColl := CoPolyLine.create as IPointCollection;
        pPointsColl.Get_PointCount(num);
        for I := 0 to num - 1 do
        begin
            pPointsColl.Get_Point(I, pPt);
            pPt.Get_X(x);
            pPt.Get_Y(Y);
            pPt.Set_X(x + wd);
            pPt.Set_Y(Y + wd);
            plColl.AddPoints(1, pPt);
    
        end;
    
        result := plColl as IPolyLine;
    
    end;
    
    function PolygontoPloyLine(Polygon: IPolygon): IPolyLine;
    {var
        pGeoms_Polygon: IGeometryCollection;
    
        i, num: Integer;
    
        outPart: IGeoMetry;
    
        ResultGeo: IGeometryCollection;
        d:double;
    begin
        ResultGeo := CoPolyLine.Create as IGeometryCollection;
    
        pGeoms_Polygon := Polygon as IGeometryCollection;
        pGeoms_Polygon.Get_GeometryCount(num);
        for i := 0 to num - 1 do
        begin
    
            pGeoms_Polygon.Get_Geometry(i, outPart);
    
            ResultGeo.AddGeometries(1,outPart);
        end;
        Result := ResultGeo as IPolyLine;
        Result.Get_Length(d);showmessage(floattostr(d));
    
    end;
    }
    var
        pPointsColl                         : IPointCollection;
        plColl                              : IPointCollection;
    begin
        pPointsColl := Polygon as IPointCollection;
        plColl := CoPolyLine.create as IPointCollection;
        plColl.AddPointCollection(pPointsColl);
        result := plColl as IPolyLine;
    
    end;
    
    function ConvertFeatureToElement(pFeature: IFeature): IElement;
    var
        Shape                               : IGeoMetry;
        ShapeType                           : Toleenum;
        pElement                            : IElement;
        FeatureType                         : Toleenum;
        PAnnotationFeature                  : IAnnotationFeature;
    begin
        pFeature.Get_ShapeCopy(Shape);
    
        pFeature.Get_FeatureType(FeatureType);
        if esriFTAnnotation = FeatureType then
        begin
            PAnnotationFeature := pFeature as IAnnotationFeature;
            PAnnotationFeature.Get_Annotation(pElement);
        end
        else
        begin
            Shape.Get_GeometryType(ShapeType);
    
            case ShapeType of
                esriGeometryPoint:
                    pElement := CoMarkerElement.create as IElement;
                esriGeometryPolyline:
                    pElement := CoLineElement.create as IElement;
                esriGeometryPolygon:
                    pElement := CoPolygonElement.create as IElement;
            end;
            pElement.Set_Geometry(Shape);
        end;
    
        result := pElement;
    
    end;
    
    //三点弧线
    
    function CreateCArcThreePoint(FromPoint: IPoint; ThruPoint: IPoint; ToPoint:
        IPoint; var angle: double): IPolyLine;
    var
        ConstCArc                           : IConstructCircularArc;
        PCircularArc                        : ICircularArc;
        PSegment                            : ISegment;
        PSegmentCollection                  : ISegmentCollection;
    
    begin
    
        ConstCArc := CoCircularArc.create as IConstructCircularArc;
        ConstCArc.ConstructThreePoints(FromPoint, ThruPoint, ToPoint, False);
    
        PCircularArc := ConstCArc as ICircularArc;
        //PCircularArc.Get_Radius(r);
        PCircularArc.Get_CentralAngle(angle);
    
        PSegment := PCircularArc as ISegment;
        PSegmentCollection := CoPolyLine.create as ISegmentCollection;
        PSegmentCollection.AddSegments(1, PSegment);
        result := PSegmentCollection as IPolyLine;
    
        //mymapcontrol.FlashShape(result);
    end;
    
    //点集转化为PloyLine
    
    function PointsColltoPolyLine(PointsColl: IPointCollection): IPolyLine;
    var
        pTopo                               : ITopologicalOperator;
        PColl                               : IPointCollection;
    begin
    
        PColl := CoPolyLine.create as IPointCollection;
        PColl.AddPointCollection(PointsColl);
    
        pTopo := PColl as ITopologicalOperator;
        pTopo.Simplify();
        result := PColl as IPolyLine;
    
    end;
    //去掉前面的大数
    
    function PointstoPoly(Tst: TstringList;
        XShift: integer = 0;
        YShift: integer = 0): IPolygon;
    //去掉数值的大数
        function TakeOutFrontDigit(InputFloat: double; TakeNum: Smallint): double;
        var
            TmpVal                          : double;
            TmpStr                          : string;
        begin
            TmpVal := Trunc(InputFloat);
            TmpStr := Floattostr(TmpVal);
            if TakeNum < length(TmpStr) then
                TmpStr := copy(TmpStr, TakeNum + 1, length(TmpStr) - TakeNum)
            else
                if TakeNum = length(TmpStr) then
                    TmpStr := '0';
            result := StrToInt(TmpStr) + InputFloat - TmpVal;
        end;
    
    var
        pPointsColl                         : IPointCollection;
        pTopo                               : ITopologicalOperator;
        I, num                              : integer;
        PPoint                              : IPoint;
        x, Y                                : double;
    begin
        pPointsColl := CoPolygon.create as IPointCollection;
        num := Tst.count;
        PPoint := CoPoint.create as IPoint;
        for I := 0 to num - 1 do
        begin
            x := strtofloat(copy(Tst[I], 1, pos(',', Tst[I]) - 1));
            Y := strtofloat(copy(Tst[I], pos(',', Tst[I]) + 1, 100));
            if XShift > 0 then
                x := TakeOutFrontDigit(x, XShift);
            if YShift > 0 then
                Y := TakeOutFrontDigit(Y, YShift);
    
            PPoint.Set_X(x);
            PPoint.Set_Y(Y);
            pPointsColl.AddPoints(1, PPoint)
    
        end;
        pTopo := pPointsColl as ITopologicalOperator;
        pTopo.Simplify();
        result := pPointsColl as IPolygon;
    end;
    //获得点集的坐标
    
    function getPointsCollCoord(pPointsColl: IPointCollection; List: TstringList):
        integer;
    var
        I, num                              : integer;
        x, Y                                : double;
        PPoint                              : IPoint;
    begin
        pPointsColl.Get_PointCount(num);
        for I := 0 to num - 1 do
        begin
            pPointsColl.Get_Point(I, PPoint);
            PPoint.Get_X(x);
            PPoint.Get_Y(Y);
            List.Add(Format('%.4f,%.4f', [x, Y]));
    
        end;
        result := List.count;
    
    end;
    
    procedure PolytoPoints(PPolygon: IPolyLine; Tst: TstringList; idx: integer = 0);
    begin
        GetPartPoints(PPolygon, idx, Tst);
    end;
    //获得一个对象有几组成
    
    function GetPartNum(pgeometry: IGeoMetry): integer;
    var
        PGeometryCollection                 : IGeoMetryCollection;
    begin
        PGeometryCollection := pgeometry as IGeoMetryCollection;
        PGeometryCollection.Get_GeometryCount(result);
    end;
    //获得对应部分
    
    function GetPart(pgeometry: IGeoMetry; Partindex: integer): IGeoMetry;
    var
        num                                 : integer;
        PGeometryCollection                 : IGeoMetryCollection;
        OutPart                             : IGeoMetry;
        //pPointsColl: IPointCollection;
        NewGeoMetry                         : IGeoMetryCollection;
    begin
    
        num := GetPartNum(pgeometry);
        if Partindex + 1 > num then
            exit;
        if num = 1 then                     //只有一个部分
        begin
            result := pgeometry;
            exit;
        end;
        PGeometryCollection := pgeometry as IGeoMetryCollection;
        PGeometryCollection.Get_Geometry(Partindex, OutPart);
        //pPointsColl := OutPart as IPointCollection;
        NewGeoMetry := CreateGeoMetryByGeoMetryType(pgeometry);
        NewGeoMetry.AddGeometries(1, OutPart);
        result := NewGeoMetry as IGeoMetry;
    end;
    
    //获得一个对象对应部分的坐标
    
    function GetPartPoints(pgeometry: IGeoMetry; Partindex: integer;
        List: TstringList): integer;
    var
        num                                 : integer;
        PGeometryCollection                 : IGeoMetryCollection;
        OutPart                             : IGeoMetry;
        pPointsColl                         : IPointCollection;
    begin
        result := 0;
        num := GetPartNum(pgeometry);
        if Partindex + 1 > num then exit;
        PGeometryCollection := pgeometry as IGeoMetryCollection;
        PGeometryCollection.Get_Geometry(Partindex, OutPart);
        pPointsColl := OutPart as IPointCollection;
        getPointsCollCoord(pPointsColl, List);
        result := List.count;
    
    end;
    
    function RemovePart(pgeometry: IGeoMetry; Partindex: integer): IGeoMetry;
    var
    
        PGeometryCollection                 : IGeoMetryCollection;
    begin
    
        PGeometryCollection := pgeometry as IGeoMetryCollection;
        PGeometryCollection.RemoveGeometries(Partindex, 1);
    
        result := PGeometryCollection as IGeoMetry;
    
    end;
    //替换一个GeoMetry的第几部分
    
    function ReplaceGeoMetryPartIndex(SourceGeoMetry, ReplaceGeoMetry: IGeoMetry;
        Partindex: integer): IGeoMetry;
    var
        PGeometryCollection                 : IGeoMetryCollection;
        num                                 : integer;
    begin
        PGeometryCollection := SourceGeoMetry as IGeoMetryCollection;
    
        num := GetPartNum(SourceGeoMetry);
    
        if Partindex + 1 > num then         //表示新增
        begin
            raise exception.create('替换位置索引大于对象总的组成');
        end
        else
        begin
            PGeometryCollection.InsertGeometryCollection(Partindex, ReplaceGeoMetry
                as IGeoMetryCollection);
            PGeometryCollection.RemoveGeometries(Partindex + 1, 1);
        end;
        result := PGeometryCollection as IGeoMetry;
    
    end;
    
    //修改一个对象对应部分的坐标,其他部分不变
    //返回值为新的图形对象
    //Partindex是对应的修改部分,List为坐标点
    
    function SetPartPoints(pgeometry: IGeoMetry; Partindex: integer;
        List: TstringList): IGeoMetry;
    var
        num                                 : integer;
        PGeometryCollection                 : IGeoMetryCollection;
    
        pPointsColl                         : IPointCollection;
        NewGeoMetry                         : IGeoMetry;
    
    begin
    
        PGeometryCollection := pgeometry as IGeoMetryCollection;
    
        num := GetPartNum(pgeometry);
        pPointsColl := CreatePointscollByList(pgeometry, List);
        NewGeoMetry := pPointsColl as IGeoMetry;
    
        if Partindex + 1 > num then         //表示新增
        begin
            PGeometryCollection.AddGeometryCollection(NewGeoMetry as
                IGeoMetryCollection);
        end
        else
        begin
    
            PGeometryCollection.InsertGeometryCollection(Partindex, NewGeoMetry as
                IGeoMetryCollection);
            PGeometryCollection.RemoveGeometries(Partindex + 1, 1);
        end;
        result := PGeometryCollection as IGeoMetry;
    end;
    //根据对象类型建立GeoMetry对象
    
    function CreateGeoMetryByGeoMetryType(pgeometry: IGeoMetry):
        IGeoMetryCollection;
    var
        ShapeType                           : Toleenum;
    begin
        pgeometry.Get_GeometryType(ShapeType);
        case ShapeType of
            esriGeometryPolyline:
                begin
                    result := CoPolyLine.create as IGeoMetryCollection;
                end;
            esriGeometryPolygon:
                begin
                    result := CoPolygon.create as IGeoMetryCollection;
                end;
            esriGeometryPoint:
                begin
                    result := CoPoint.create as IGeoMetryCollection;
                end;
        end;
    end;
    
    //根据对象类型建立点集
    
    function CreatePointscollByGeoMetryType(pgeometry: IGeoMetry): IPointCollection;
    var
        ShapeType                           : Toleenum;
    begin
        pgeometry.Get_GeometryType(ShapeType);
        case ShapeType of
            esriGeometryPolyline:
                begin
                    result := CoPolyLine.create as IPointCollection;
                end;
            esriGeometryPolygon:
                begin
                    result := CoPolygon.create as IPointCollection;
                end;
            esriGeometryPoint:
                begin
                    result := CoPoint.create as IPointCollection;
                end;
        end;
    end;
    
    //根据坐标点生成点集
    
    function CreatePointscollByList(pgeometry: IGeoMetry; List: TstringList):
        IPointCollection;
    var
    
        x, Y                                : double;
        I                                   : integer;
        pPt                                 : IPoint;
    
    begin
        result := CreatePointscollByGeoMetryType(pgeometry);
        for I := 0 to List.count - 1 do
        begin
            x := strtofloat(copy(List[I], 1, pos(',', List[I]) - 1));
            Y := strtofloat(copy(List[I], pos(',', List[I]) + 1, length(List[I])));
            pPt := CoPoint.create as IPoint;
            pPt.Set_X(x);
            pPt.Set_Y(Y);
            result.AddPoints(1, pPt);
        end;
    
    end;
    
    procedure PolytoPoints(PPolygon: IPolygon; Tst: TstringList; idx: integer = 0);
    begin
        GetPartPoints(PPolygon, idx, Tst);
    end;
    
    //将一个字体转化为IFormattedTextSymbol
    
    function GetTextSymbolBtyFont(Font: TFont): IFormattedTextSymbol;
    var
        pTxtSym                             : IFormattedTextSymbol;
        oleFt                               : variant;
    begin
        ////*****字体符号的设置**********////
    
        oleFt := FontToOleFont(Font);
        pTxtSym := CoTextSymbol.create as IFormattedTextSymbol;
        pTxtSym.Set_Font(IFontDisp(IDispatch(oleFt)));
        pTxtSym.Set_color(GetRGBColor(Font.Color));
        pTxtSym.Set_Angle(0);
        pTxtSym.Set_RightToLeft(False);
        pTxtSym.Set_VerticalAlignment(esriTVABaseline);
        pTxtSym.Set_HorizontalAlignment(esriTHAFull);
        pTxtSym.Set_CharacterSpacing(25);
        pTxtSym.Set_Case_(esriTCNormal);
        pTxtSym.Set_Size(Font.Size);
        result := pTxtSym;
    
    end;
    
    //SymbolType为1点,2线,3为面
    
    function GetSymbol(SymbolType: integer; Color: Tcolor;
        Size: integer; Style: Toleenum): ISymbol;
    var
        pFillSym                            : ISimpleFillSymbol;
        pLineSym                            : ISimpleLineSymbol;
        pMarkerSym                          : ISimpleMarkerSymbol;
        MyColor                             : Icolor;
    
    begin
    
        MyColor := GetRGBColor(Color) as Icolor;
        case SymbolType of
            2:
                begin
                    pLineSym := CoSimpleLineSymbol.create as ISimpleLineSymbol;
                    pLineSym.Set_color(MyColor);
                    pLineSym.Set_Width(Size);
                    pLineSym.Set_Style(Style);
                    result := pLineSym as ISymbol;
                end;
            3:
                begin
                    pFillSym := CoSimpleFillSymbol.create as ISimpleFillSymbol;
                    pFillSym.Set_color(MyColor);
    
                    pFillSym.Set_Style(Style);
                    result := pFillSym as ISymbol;
    
                end;
            1:
                begin
                    pMarkerSym := CoSimpleMarkerSymbol.create as
                        ISimpleMarkerSymbol;
                    pMarkerSym.Set_Style(Style);
                    pMarkerSym.Set_color(MyColor);
                    pMarkerSym.Set_Size(Size);
                    result := pMarkerSym as ISymbol;
    
                end;
        else
            begin
                result := nil;
                showmessage('错误');
            end;
        end;
    
    end;
    //面符号
    
    function GetSimpleFillSymbol(Color: Tcolor; Style: Toleenum;
        LineSize: integer; LineColor: Tcolor; LineStyle: Toleenum): ISymbol;
    var
        pFillSym                            : ISimpleFillSymbol;
        pLineSym                            : ISimpleLineSymbol;
        MyColor                             : Icolor;
    begin
    
        MyColor := GetRGBColor(LineColor) as Icolor;
        pLineSym := CoSimpleLineSymbol.create as ISimpleLineSymbol;
        try
            pLineSym.Set_color(MyColor);
            pLineSym.Set_Width(LineSize);
            pLineSym.Set_Style(LineStyle);
            MyColor := GetRGBColor(Color) as Icolor;
    
            pFillSym := CoSimpleFillSymbol.create as ISimpleFillSymbol;
            pFillSym.Set_color(MyColor);
    
            pFillSym.Set_Style(Style);
            pFillSym.Set_Outline(pLineSym);
            result := pFillSym as ISymbol;
        finally
            pLineSym := nil;
        end;
    
    end;
    
    function DistanceofTwoPoints(FirstPt, SecondPt: IPoint): double;
    var
        FX, FY, SX, SY                      : double;
    begin
        FirstPt.Get_X(FX);
        FirstPt.Get_Y(FY);
        SecondPt.Get_X(SX);
        SecondPt.Get_Y(SY);
        result := Sqrt(Sqr(FX - SX) + Sqr(FY - SY));
    end;
    
    function PolygonToPolyLine(pPoly: IPolygon): IPolyLine;
    var
        I, count                            : integer;
        pSegs, pAddSegs                     : ISegmentCollection;
        pGeosPoly, pGeoms                   : IGeoMetryCollection;
        pClone, pClone2                     : IClone;
        pGeom                               : IGeoMetry;
    begin
        pClone := pPoly as IClone;
        pClone.Clone(pClone2);
        pGeosPoly := pClone2 as IGeoMetryCollection;
    
        pGeosPoly.Get_GeometryCount(count);
        pGeoms := CoPolyLine.create as IGeoMetryCollection;
        for I := 0 to count - 1 do
        begin
            pSegs := coPath.create as ISegmentCollection;
            pGeosPoly.Get_Geometry(I, pGeom);
            pAddSegs := pGeom as ISegmentCollection;
            pSegs.AddSegmentCollection(pAddSegs);
            pGeom := pSegs as IGeoMetry;
            pGeoms.AddGeoMetry(pGeom, EmptyParam, EmptyParam);
        end;
        result := pGeoms as IPolyLine;
    end;
    
    function PolyLineToPolygon(pPoly: IPolyLine): IPolygon;
    var
        I, count                            : integer;
        pSegs, pAddSegs                     : ISegmentCollection;
        pGeosPoly, pGeoms                   : IGeoMetryCollection;
        pClone, pClone2                     : IClone;
        pGeom                               : IGeoMetry;
    begin
        pClone := pPoly as IClone;
        pClone.Clone(pClone2);
        pGeosPoly := pClone2 as IGeoMetryCollection;
    
        pGeosPoly.Get_GeometryCount(count);
        pGeoms := CoPolygon.create as IGeoMetryCollection;
        for I := 0 to count - 1 do
        begin
            pSegs := coPath.create as ISegmentCollection;
            pGeosPoly.Get_Geometry(I, pGeom);
            pAddSegs := pGeom as ISegmentCollection;
            pSegs.AddSegmentCollection(pAddSegs);
            pGeom := pSegs as IGeoMetry;
            pGeoms.AddGeoMetry(pGeom, EmptyParam, EmptyParam);
        end;
        result := pGeoms as IPolygon;
    end;
    
    //获得选择集的对象
    
    function GetSelectFeatures(FFeatureLayer: IFeatureLayer;
        var FID: integer; Intersected: boolean = False): IGeoMetry;
    var
        pFeature                            : IFeature;
        ObjClass                            : IFeatureClass;
        pFeatureLayer                       : IFeatureLayer;
        num                                 : integer;
    
        PSelectionSet                       : ISelectionSet;
        PCursor                             : ICursor;
        PFCursor                            : IFeatureCursor;
        pgeometry                           : IGeoMetry;
    begin
        pFeatureLayer := FFeatureLayer;
        pFeatureLayer.Get_FeatureClass(ObjClass);
        PSelectionSet := GetSelectionsetByFeatureLayer(pFeatureLayer);
        if PSelectionSet = nil then exit;
        PSelectionSet.Get_Count(num);
        if num > 0 then
        begin
            PSelectionSet.Search(nil, False, PCursor);
            PFCursor := PCursor as IFeatureCursor;
            PFCursor.NextFeature(pFeature);
            pFeature.Get_Shape(result);
            pFeature.Get_OID(FID);
            while (pFeature <> nil) do
            begin
    
                if result = nil then exit;
                PFCursor.NextFeature(pFeature);
                if (pFeature = nil) then Break;
                pFeature.Get_Shape(pgeometry);
                if pgeometry <> nil then
                begin
                    if result = nil then
                        result := pgeometry
                    else
                    begin
                        if Intersected then
                            result := Intersect(result, pgeometry)
                        else
                            result := Combine(pgeometry, result);
                    end;
                end;
    
            end;
    
        end;
    end;
    //获得对象坐标
    
    function getGeoMetryCoord(pgeometry: IGeoMetry; List: TstringList;
        Clear: boolean = true; idx: integer = 0): integer;
    var
        PGeometryType                       : Toleenum;
        PPoint                              : IPoint;
        x, Y                                : double;
    begin
        if Clear then
            List.Clear;
        pgeometry.Get_GeometryType(PGeometryType);
        case PGeometryType of
            esriGeometryPolyline:
                begin
                    PolytoPoints(pgeometry as IPolyLine, List, idx);
                end;
            esriGeometryPoint:
                begin
                    PPoint := pgeometry as IPoint;
                    PPoint.Get_X(x);
                    PPoint.Get_Y(Y);
    
                    List.Add(Format('%.4f,%.4f', [x, Y]));
                end;
            esriGeometryPolygon:
                begin
                    PolytoPoints(pgeometry as IPolygon, List, idx);
                end;
    
        end;
        if PGeometryType = esriGeometryPoint then
            result := 1
        else
            result := GetPartNum(pgeometry);
    end;
    //获得图层类型
    
    function GetLayerType(FFeatureLayer: IFeatureLayer): Toleenum;
    {var
        PFCursor: IFeatureCursor;
        pFeature: IFeature;
        Shape: IGeoMetry;
    begin
        FFeatureLayer.Search(nil, False, PFCursor);
        PFCursor.NextFeature(pFeature);
        pFeature.Get_Shape(Shape);
        Shape.Get_GeometryType(result);
    
    end;
    }
    var
        Layer                               : IFeatureLayer2;
    begin
        Layer := FFeatureLayer as IFeatureLayer2;
        Layer.Get_ShapeType(result);        //更快的方法 by yl 2005.8.6
    
    end;
    
    //获得图层和Splitter相交的对象,注释yl add
    
    function GetIntersetedFeatures(const Splitter: IPolyLine;
        pFeatLayer: IFeatureLayer): IFeatureCursor;
    var
        pFilter                             : ISpatialFilter;
        pFc                                 : IFeatureClass;
        PCursor                             : IFeatureCursor;
        pFeature                            : IFeature;
        pFID                                : integer;
        Fname                               : widestring;
        temp                                : string;
    begin
        if pFeatLayer = nil then exit;
        pFeatLayer.Get_FeatureClass(pFc);
        pFc.Get_OIDFieldName(Fname);
    
        pFilter := CoSpatialFilter.create as ISpatialFilter;
        pFilter._Set_Geometry(Splitter as IGeoMetry);
        pFilter.Set_SpatialRel(esriSpatialRelIntersects);
        pFilter.Set_GeometryField('SHAPE');
        pFeatLayer.Search(pFilter as IQueryFilter, False, PCursor);
        PCursor.NextFeature(pFeature);
        while pFeature <> nil do
        begin
            pFeature.Get_OID(pFID);
            temp := temp + IntToStr(pFID) + ',';
            PCursor.NextFeature(pFeature);
        end;
        temp := copy(temp, 1, length(temp) - 1);
    
        (pFilter as IQueryFilter).Set_WhereClause(Fname + ' in (' + temp + ')');
        pFc.Search(pFilter as IQueryFilter, False, result);
    end;
    //将合并到一起并分离的对象分解成一个对象
    
    function decomposeobj(pgeometry: IGeoMetry; var FeaArray: array of IGeoMetry):
        integer;
    //对于非区域,直接转化为IGeoMetryCollection,由于面有岛存在必须处理
    var
        ShapeType                           : Toleenum;
        I, j, num, m, n                     : integer;
        OutPart                             : IGeoMetry;
        PPolygon                            : IPolygon;
        pArea                               : IArea;
        Area                                : double;
        RR                                  : IGeoMetryCollection;
        minusPGeo                           : array of IGeoMetry; //岛图
    begin
        pgeometry.Get_GeometryType(ShapeType);
        RR := pgeometry as IGeoMetryCollection;
        RR.Get_GeometryCount(num);
    
        result := num;
        case ShapeType of
            esriGeometryPolygon:
                begin
                    n := 0;
                    m := 0;
                    for I := 0 to num - 1 do
                    begin
                        OutPart := GetPart(RR as IGeoMetry, I);
                        PPolygon := OutPart as IPolygon;
                        pArea := PPolygon as IArea;
                        pArea.Get_Area(Area);
                        if Area < 0 then    //岛图面积为负
                        begin
                            Setlength(minusPGeo, m + 1);
                            minusPGeo[m] := OutPart;
                            inc(m);
    
                        end
                        else
                        begin
                            FeaArray[n] := OutPart;
                            inc(n);
                        end;
                    end;
    
                    //擦除岛图
                    if m = 0 then exit;
    
                    for I := 0 to n - 1 do
                    begin
                        for j := 0 to m - 1 do
                        begin
                            FeaArray[I] := Difference(FeaArray[I], minusPGeo[j]);
                        end;
    
                    end;
                    result := n;
    
                end;
        else
            begin
                for I := 0 to num - 1 do
                begin
                    OutPart := GetPart(RR as IGeoMetry, I);
                    FeaArray[I] := OutPart;
    
                end;
    
            end;
        end;
    end;
    //获得一个Feature的图层名称
    
    function GetLayerName(pFeature: IFeature): widestring;
    var
        pObjClass                           : IObjectClass;
    begin
        result := '';
        if pFeature = nil then exit;
        pFeature.Get_Class_(pObjClass);
        pObjClass.Get_AliasName(result)
    end;
    //按长度分割线
    
    function SplitLineByLength(PPolyLine: IPolyLine; Distance: double;
        var outLine1, outLine2: IPolyLine): boolean;
    var
        PPolycurve                          : IPolycurve;
        PSegmnet                            : ISegment;
        fromSegment, toSegment              : ISegment;
        PGeoColl                            : IGeoMetryCollection;
        PSegmentColl                        : ISegmentCollection;
        I, count                            : integer;
        LineLen, SumLineLen                 : double;
        PColl1, PColl2                      : IPointCollection;
        PPoint                              : IPoint;
        B                                   : boolean; //表示是否已打断
    begin
        result := False;
        try
            PPolycurve := PPolyLine as IPolycurve;
            PGeoColl := PPolyLine as IGeoMetryCollection;
            PGeoColl.Get_GeometryCount(count);
            if count <> 1 then raise exception.create('不是一个条线段无法分割');
            PSegmentColl := PGeoColl as ISegmentCollection;
            PSegmentColl.Get_SegmentCount(count);
            SumLineLen := 0;
            PColl1 := CoPolyLine.create as IPointCollection;
            PColl2 := CoPolyLine.create as IPointCollection;
            B := False;
            for I := 0 to count - 1 do
            begin
                PSegmentColl.Get_Segment(I, PSegmnet);
                PSegmnet.Get_FromPoint(PPoint);
                if B then
                begin
                    PColl2.AddPoints(1, PPoint);
                    if I = count - 1 then   //插入最后一个点
                    begin
                        PSegmnet.Get_ToPoint(PPoint);
                        PColl2.AddPoints(1, PPoint);
                    end;
    
                end
                else
                    PColl1.AddPoints(1, PPoint);
    
                if not B then
                begin
                    PSegmnet.Get_Length(LineLen);
                    if (SumLineLen + LineLen) >= Distance then
                    begin
                        PSegmnet.SplitAtDistance(Distance - SumLineLen, False,
                            fromSegment, toSegment);
                        fromSegment.Get_ToPoint(PPoint);
                        PColl1.AddPoints(1, PPoint);
                        toSegment.Get_FromPoint(PPoint);
                        PColl2.AddPoints(1, PPoint);
                        if (count = 1) or (I = count - 1) then
                            //只有一段,或最后一段
                        begin
                            toSegment.Get_ToPoint(PPoint);
                            PColl2.AddPoints(1, PPoint);
    
                        end;
                        B := true;
                    end;
                    SumLineLen := SumLineLen + LineLen;
                end;
            end;
            outLine1 := PointsColltoPolyLine(PColl1);
            outLine2 := PointsColltoPolyLine(PColl2);
            //mymapcontrol.FlashShape(outLine1);
            //mymapcontrol.FlashShape(outLine2);
            result := true;
        finally
    
        end;
    
    end;
    //按点分割线
    
    function SplitLineByPoint(PPolyLine: IPolyLine; P: IPoint;
        var outLine1, outLine2: IPolyLine): boolean;
    var
        PPolycurve                          : IPolycurve;
        SplitHappened                       : wordbool;
        newPartIndex                        : integer;
        newSegmentIndex                     : integer;
        PGeoColl                            : IGeoMetryCollection;
        count                               : integer;
    begin
    
        PPolycurve := PPolyLine as IPolycurve;
        PPolycurve.SplitAtPoint(P, true, true, SplitHappened,
            newPartIndex, newSegmentIndex);
        PGeoColl := PPolycurve as IGeoMetryCollection;
        PGeoColl.Get_GeometryCount(count);
        if count = 2 then
        begin
            outLine1 := GetPart(PGeoColl as IGeoMetry, 0) as IPolyLine;
            outLine2 := GetPart(PGeoColl as IGeoMetry, 1) as IPolyLine;
            //mymapcontrol.FlashShape(outLine1);
            //mymapcontrol.FlashShape(outLine2);
            result := true;
        end
        else
        begin
            //原对象不是一个整体
            raise exception.create('原对象不是一个整体,暂无法分割');
        end;
    
    end;
    //线的首尾节点交换
    
    function ReversePolyLine(PPolyLine: IPolyLine): IPolyLine;
    var
        PCurve                              : ICurve;
    begin
        PCurve := PPolyLine as ICurve;
        PCurve.ReverseOrientation;
        result := PCurve as IPolyLine;
    
    end;
    
    //一个对象分线分割
    
    function SplitGeoMetryByPolyLine(pgeometry: IGeoMetry;
        PPolyLine: IPolyLine; var FeaArray: array of IGeoMetry): integer;
    var
        pSplitPoints                        : IPointCollection; //交叉分割点
        pEnumVertex                         : IEnumVertex;
        PCurve                              : IPolycurve2;
        SplitInfo                           : IEnumSplitPoint;
        pGC                                 : IGeoMetryCollection;
        I, count                            : integer;
        pGeom                               : IGeoMetry;
    
    begin
        result := 0;
        pSplitPoints := IntersectPoint(pgeometry, PPolyLine as IGeoMetry);
        if pSplitPoints = nil then exit;
        pSplitPoints.Get_EnumVertices(pEnumVertex);
        PCurve := pgeometry as IPolycurve2;
        PCurve.SplitAtPoints(pEnumVertex, true, true, -1, SplitInfo);
        pGC := PCurve as IGeoMetryCollection;
    
        pGC.Get_GeometryCount(count);
        result := count;
        if count > 100 then raise exception.create('分割后的对象太多');
        for I := 0 to count - 1 do
        begin
            pGeom := GetPart(pGC as IGeoMetry, I);
            //mymapcontrol.FlashShape(pGeom);
            FeaArray[I] := pGeom;
        end;
    end;
    
    function CheckTouch(const SGeometry, TGeometry: IGeoMetry): boolean;
    var
        pRelationalOperator                 : IRelationalOperator;
        tmpResult                           : wordbool;
    begin
        result := False;
        if (SGeometry = nil) or (TGeometry = nil) then exit;
        pRelationalOperator := SGeometry as IRelationalOperator;
        pRelationalOperator.Touches(TGeometry, tmpResult);
        if not tmpResult then
            pRelationalOperator.Overlaps(TGeometry, tmpResult);
        result := tmpResult;
    end;
    
    function CanSplit(const Splitter: IPolyLine;
        Poly: IGeoMetry): boolean;
    var
        pNewGeometry                        : IGeoMetry;
        tmpResult                           : wordbool;
        TCount, I, pCount                   : integer;
        Fpoint                              : IPoint;
        Points                              : IPointCollection;
    begin
        result := False;
        (Splitter as ITopologicalOperator).Intersect(Poly, esriGeometry1Dimension,
            pNewGeometry);
        if pNewGeometry = nil then exit;
        (pNewGeometry as IRelationalOperator).Touches(Poly, tmpResult);
        //若切割线与面的相交部分为面的边界,则不能切割
        if not tmpResult then
        begin
            //判断切割线与面边界的交点个数,若大于等于2,则认为切割线穿过面,可以切割
            Points := pNewGeometry as IPointCollection;
            Points.Get_PointCount(pCount);
            TCount := 0;
            for I := 0 to pCount - 1 do
            begin
                Points.Get_Point(I, Fpoint);
                (Fpoint as IRelationalOperator).Touches(Poly, tmpResult);
                if tmpResult then inc(TCount);
                if TCount >= 2 then
                begin
                    result := true;
                    exit;
                end;
            end;
        end;
    end;
    
    function CanSplitEx(const Splitter: IPolyLine;
        PLayer: IFeatureLayer): integer;
    var
        pFilter                             : ISpatialFilter;
        PFeatureCursor                      : IFeatureCursor;
        pFeature                            : IFeature;
        pgeometry                           : IGeoMetry;
    begin
        result := 0;
        if PLayer = nil then exit;
        pFilter := CoSpatialFilter.create as ISpatialFilter; //获取与切割线相交的宗地
        pFilter._Set_Geometry(Splitter as IGeoMetry);
        pFilter.Set_SpatialRel(esriSpatialRelIntersects);
        pFilter.Set_GeometryField('SHAPE');
        PLayer.Search(pFilter as IQueryFilter, False, PFeatureCursor);
    
        PFeatureCursor.NextFeature(pFeature);
        if pFeature = nil then result := -1;
        while pFeature <> nil do
        begin
            pFeature.Get_Shape(pgeometry);
            if CanSplit(Splitter, pgeometry) then
            begin
                result := 1;
                exit;
            end;
            PFeatureCursor.NextFeature(pFeature);
        end;
    end;
    //获得一个图层FID字段名,shp和sde文件不一样,shp是fid,sde是objectid
    
    function GetFIDFieldName(FeatureClass: IFeatureClass): string; overload;
    var
        FieldName                           : widestring;
    begin
        FeatureClass.Get_OIDFieldName(FieldName);
        result := FieldName;
    
    end;
    
    //获得一个图层FID字段名,shp和sde文件不一样,shp是fid,sde是objectid
    
    function GetFIDFieldName(FeatureLayer: IFeatureLayer): string;
    
    var
        ObjClass                            : IFeatureClass;
    
    begin
        FeatureLayer.Get_FeatureClass(ObjClass);
        result := GetFIDFieldName(ObjClass);
    
    end;
    //获得shape字段的索引 by yl 2004.12.1
    
    function GetShapeFieldIdx(FeatureLayer: IFeatureLayer): integer;
    var
        InFC                                : IFeatureClass;
        ObjClass                            : IFeatureClass;
        FieldName                           : widestring;
    
    begin
        FeatureLayer.Get_FeatureClass(ObjClass);
        InFC := ObjClass as IFeatureClass;
    
        InFC.Get_ShapeFieldName(FieldName);
        InFC.FindField(FieldName, result);
    
    end;
    
    function GeoMetryColltoPolyLine(PointsColl: IPointCollection): IPolyLine;
    var
        pgeometry                           : IGeoMetry;
        ShapeType                           : Toleenum;
    begin
        pgeometry := PointsColl as IGeoMetry;
        pgeometry.Get_GeometryType(ShapeType);
        if ShapeType = esriGeometryPolygon then //面要转化为线
        begin
            result := PolygonToPolyLine(pgeometry as IPolygon);
        end
        else
            result := pgeometry as IPolyLine;
    
    end;
    //删除一个GeoMetry的第几部分第几个点
    
    function DelGeoMetry(pgeometry: IGeoMetry; Partindex: integer; index: integer):
        IGeoMetry;
    //判断一个GeoMetry是否正常,对于线最少两个点,面最少三个点
    //处理后返回GeoMetry,Onlyone为true表示原只有一个对象,就不许删除,
    //false表示多个对象,则返回为nil,
    //
        function doWithGeoMetry(pgeometry: IGeoMetry; ShapeType: Toleenum;
            Onlyone: boolean):
                IGeoMetry;
        var
            num                             : integer;
            pPointColl                      : IPointCollection;
    
        begin
    
            pPointColl := pgeometry as IPointCollection;
            pPointColl.Get_PointCount(num);
            result := nil;
            if ShapeType = esriGeometryPolygon then //面最少三个点(节点是4个)
            begin
                if num < 4 then
                begin
                    if Onlyone then
                        raise exception.create('面不能少于三个点,该点不能删除');
                    exit;
                end;
    
            end
            else
                if ShapeType = esriGeometryPolyline then //线最少两个点
                begin
                    if num < 2 then
                    begin
                        if Onlyone then
                            raise exception.create('线不能少于两个点,该点不能删除');
                        exit;
                    end;
    
                end
                else
                    raise exception.create('数据类型错误');
            result := pgeometry;
    
        end;
    
    var
        num                                 : integer;
        PGeoMetryCol                        : IGeoMetryCollection;
        pPointColl                          : IPointCollection;
        DelGeoMetry                         : IGeoMetry;
        ShapeType                           : Toleenum;
    begin
        pgeometry.Get_GeometryType(ShapeType);
        PGeoMetryCol := pgeometry as IGeoMetryCollection;
        PGeoMetryCol.Get_GeometryCount(num);
        if num = 1 then
        begin
            pPointColl := pgeometry as IPointCollection;
    
            pPointColl.RemovePoints(index, 1);
            pgeometry := pPointColl as IGeoMetry;
            result := doWithGeoMetry(pgeometry, ShapeType, true);
        end
        else
        begin
            if Partindex > num then
                result := nil;
            PGeoMetryCol.Get_Geometry(Partindex, DelGeoMetry);
            pPointColl := DelGeoMetry as IPointCollection;
    
            pPointColl.RemovePoints(index, 1);
            DelGeoMetry := pPointColl as IGeoMetry;
            DelGeoMetry := doWithGeoMetry(DelGeoMetry, ShapeType, False);
            if DelGeoMetry <> nil then
            begin
                PGeoMetryCol.InsertGeometries(Partindex, 1, DelGeoMetry);
                PGeoMetryCol.RemoveGeometries(Partindex + 1, 1);
            end
            else
            begin
                PGeoMetryCol.RemoveGeometries(Partindex, 1);
            end;
            result := PGeoMetryCol as IGeoMetry;
        end;
    
    end;
    //插入一个节点,在GeoMetry的第几部分的那个位置插入节点
    
    function InsertPointToGeometry(SourceGeoMetry: IGeoMetry; Partindex: integer;
        vertexIndex: integer; Pt: IPoint): IGeoMetry;
    var
        num                                 : integer;
        PGeoMetryCol                        : IGeoMetryCollection;
        partGeoMetry                        : IGeoMetry;
        pPointColn                          : IPointCollection;
        valbefore, pVertexIndex             : olevariant;
    begin
        PGeoMetryCol := SourceGeoMetry as IGeoMetryCollection;
        PGeoMetryCol.Get_GeometryCount(num);
        if Partindex + 1 > num then
        begin
            raise exception.create('替换位置索引大于对象总的组成');
        end;
    
        partGeoMetry := GetPart(SourceGeoMetry, Partindex);
        pPointColn := partGeoMetry as IPointCollection;
    
        if vertexIndex = 0 then
        begin
            valbefore := 1;
            pPointColn.AddPoint(Pt, valbefore, EmptyParam);
        end
        else
        begin
            pVertexIndex := vertexIndex;
            pPointColn.AddPoint(Pt, EmptyParam, pVertexIndex);
        end;
        partGeoMetry := pPointColn as IGeoMetry;
    
        result := ReplaceGeoMetryPartIndex(SourceGeoMetry, partGeoMetry,
            Partindex);
    
    end;
    
    function CreatePolygonfromRing(ExRing: IRing): IGeoMetry;
    var
        newSegCol, SegCol                   : ISegmentCollection;
        PPolygon                            : IPolygon;
    begin
        SegCol := ExRing as ISegmentCollection;
    
        PPolygon := CoPolygon.create as IPolygon;
        newSegCol := PPolygon as ISegmentCollection;
        newSegCol.AddSegmentCollection(SegCol);
    
        result := PPolygon as IGeoMetry;
    end;
    
    function CreatePolyLinefromPath(ExPath: IPath): IGeoMetry;
    var
        newSegCol, SegCol                   : ISegmentCollection;
        PPolyLine                           : IPolyLine;
    begin
        SegCol := ExPath as ISegmentCollection;
    
        PPolyLine := CoPolyLine.create as IPolyLine;
        newSegCol := PPolyLine as ISegmentCollection;
        newSegCol.AddSegmentCollection(SegCol);
    
        result := PPolyLine as IGeoMetry;
    end;
    
    //线切割面,根据小曾的修改
    
    function PolygonSpiltbyPolyLine(PPolygon: IPolygon; PPolyLine: IPolyLine;
        var FeaArray: array of IGeoMetry): integer;
    var
        CurIdx                              : integer;
        procedure SpiltPolygon(SPolygon: IPolygon);
        var
            I, num                          : integer;
            ExRings                         : array of IRing;
            pgeometry, pNewGeometry         : IGeoMetry;
        begin
            (SPolygon as ITopologicalOperator2).Set_IsKnownSimple(true);
            SPolygon.Get_ExteriorRingCount(num);
            Setlength(ExRings, num);
            SPolygon.QueryExteriorRings(ExRings[0]); //获取left所有的ExteriorRing
            for I := 0 to num - 1 do
            begin
    
                //用每个ExteriorRing创建一个polygon,
                pgeometry := CreatePolygonfromRing(ExRings[I]);
                //查询出left和该polygon相交的部分,
                (PPolygon as ITopologicalOperator).Intersect(pgeometry,
                    esriGeometry2Dimension, pNewGeometry); //用这个部分创建新的面
                FeaArray[CurIdx] := pNewGeometry;
                inc(CurIdx);
            end;
    
        end;
    
    var
        pLeft, pRight                       : IGeoMetry;
    
        pTopOper                            : ITopologicalOperator;
    begin
        pTopOper := PPolygon as ITopologicalOperator;
        pTopOper.Cut(PPolyLine, pLeft, pRight); //分成左右两部分
        result := 0;
    
        //分解left和rightGeometry(若分割线多次穿过面,则left或right有可能有多个ExteriorRing)
        if (pLeft = nil) or (pRight = nil) then exit;
        CurIdx := 0;
        SpiltPolygon(pLeft as IPolygon);
        SpiltPolygon(pRight as IPolygon);
        result := CurIdx;
    
    end;
    //获得选择集合并后矩形
    
    function GetSelectEnvelope(PSelectionSet: ISelectionSet): IEnvelope;
    var
        pEnumGeom                           : IEnumGeometry;
        pEnumGeomBind                       : IEnumGeometryBind;
        pGeomFactory                        : IGeometryFactory;
        pGeom                               : IGeoMetry;
    
        Envelope                            : IEnvelope;
    begin
    
        pEnumGeom := CoEnumFeatureGeometry.create as IEnumGeometry;
        pEnumGeomBind := pEnumGeom as IEnumGeometryBind;
        pEnumGeomBind.BindGeometrySource(nil, PSelectionSet);
        pGeomFactory := CoGeometryEnvironment.create as IGeometryFactory;
    
        pGeomFactory.CreateGeometryFromEnumerator(pEnumGeom, pGeom);
    
        pGeom.Get_Envelope(Envelope);
        result := Envelope;
    
    end;
    //获得选择集合并后对象
    
    function GetSelectUnion(PSelectionSet: ISelectionSet): IGeoMetry;
    var
        pFeature                            : IFeature;
    
        PCursor                             : ICursor;
        PFCursor                            : IFeatureCursor;
        pgeometry                           : IGeoMetry;
    begin
        PSelectionSet.Search(nil, False, PCursor);
        PFCursor := PCursor as IFeatureCursor;
        PFCursor.NextFeature(pFeature);
    
        while (pFeature <> nil) do
        begin
    
            pFeature.Get_Shape(pgeometry);
            if pgeometry <> nil then
            begin
                if result = nil then
                    result := pgeometry
                else
                begin
                    result := Combine(pgeometry, result);
                end;
            end;
            PFCursor.NextFeature(pFeature);
    
        end;
    end;
    
    function Combine(PFCursor: IFeatureCursor): IGeoMetry;
    var
        pFeature                            : IFeature;
        pgeometry                           : IGeoMetry;
    begin
        PFCursor.NextFeature(pFeature);
        result := nil;
        while (pFeature <> nil) do
        begin
    
            pFeature.Get_Shape(pgeometry);
            if pgeometry <> nil then
            begin
                if result = nil then
                    result := pgeometry
                else
                begin
                    result := Combine(pgeometry, result);
                end;
            end;
            PFCursor.NextFeature(pFeature);
    
        end;
    end;
    
    //将GeoMetry转化为点对象,以便捕捉
    
    function GetPointCollByGeoMetry(pgeometry: IGeoMetry): IPointCollection;
    begin
        result := CoMultipoint.create as
            IPointCollection;
        result.AddPointCollection(pgeometry as IPointCollection);
    
    end;
    //获得图层和PGeoMetry相交的对象,节点最近距离小于MinDist,yl add 2004.12.07
    
    function GetIntersetedMinDistpoint(const pEnvelope: IGeoMetry;
        pFeatLayer: IFeatureLayer; YPt: IPoint; MinDist: double): IPoint;
    var
        pFilter                             : ISpatialFilter;
        PCursor                             : IFeatureCursor;
        pFeature                            : IFeature;
        PShape                              : IGeoMetry;
        pPointColl                          : IPointCollection;
        D                                   : double;
        LayerType                           : Toleenum;
    begin
        if pFeatLayer = nil then exit;
    
        pFilter := CoSpatialFilter.create as ISpatialFilter;
        pFilter._Set_Geometry(pEnvelope);
        pFilter.Set_SpatialRel(esriSpatialRelIntersects);
        pFilter.Set_GeometryField('SHAPE');
        pFeatLayer.Search(pFilter as IQueryFilter, False, PCursor);
        result := nil;
        PCursor.NextFeature(pFeature);
        LayerType := GetLayerType(pFeatLayer);
    
        while pFeature <> nil do
        begin
            pFeature.Get_Shape(PShape);
            if LayerType <> esriGeometryPoint then //
            begin
                pPointColl := GetPointCollByGeoMetry(PShape);
                PShape := pPointColl as IGeoMetry;
    
            end;
            result := ReturnNearPoint(PShape, YPt);
    
            if result <> nil then
            begin
    
                D := ReturnDistance(YPt, result);
    
                if D < MinDist then         //找到就退出
                begin
    
                    exit;
                end;
            end;
    
            PCursor.NextFeature(pFeature);
    
        end;
        // ShowMessage(Format('%f,%f,%d', [D, MinDist, num]));
    end;
    //转化一个图层到IFeatureLayer
    
    function LayerToFeatureLayer(FLayer: ILayer): IFeatureLayer;
    var
        pObj                                : IUnKnown;
    begin
        result := nil;
        if FLayer = nil then
            exit;
    
        if FLayer.QueryInterface(IID_IFeatureLayer, pObj) <> s_Ok then
            exit;
        result := FLayer as IFeatureLayer;
    
    end;
    //获得一个图层extent
    //IsAll是否为整个图层,确省取图层数据
    
    function GetLayerExtent(PLayer: ILayer; IsAll: boolean = False): IEnvelope;
    var
        pObj                                : IUnKnown;
        pRasterLayer                        : IRasterLayer;
        PGeoDataset                         : IGeoDataset;
    
    begin
        if IsAll then
        begin
            PGeoDataset := PLayer as IGeoDataset;
            PGeoDataset.Get_Extent(result);
        end
        else
        begin
            if PLayer.QueryInterface(IID_IFeatureLayer, pObj) = s_Ok then
            begin
                result := GetFeatureLayerExtent(PLayer as IFeatureLayer);
            end
            else
                if PLayer.QueryInterface(IID_IRasterLayer, pObj) = s_Ok then
                begin
                    pRasterLayer := PLayer as IRasterLayer;
                    pRasterLayer.Get_VisibleExtent(result);
                end
                else
                begin
                    raise exception.create('图层类型错误');
                end;
        end;
    end;
    
    {
    var
        PGeoDataset                         : IGeoDataset;
        x1, y1, x2, y2                      : Double;
    begin
        PGeoDataset := PLayer as IGeoDataset;
        PGeoDataset.Get_Extent(result);
        result.QueryCoords(x1, y1, x2, y2);
    
    end;
    }
    //获得一个FeatureLayer的extent
    
    function GetFeatureLayerExtent(PFLayer: IFeatureLayer): IEnvelope;
    {var
        pEnumGeom                           : IEnumGeometry;
        pEnumGeomBind                       : IEnumGeometryBind;
        pGeomFactory                        : IGeometryFactory;
        pGeom                               : IGeoMetry;
        // pFClass                             : IFeatureclass;
        }
    
    begin
        result := GetFeatureLayerGeoMetryExtent(PFLayer);
        { result := nil;
         if PFLayer = nil then Exit;
         //PFLayer.Get_FeatureClass(pFClass);
    
         pEnumGeom := CoEnumFeatureGeometry.Create as IEnumGeometry;
         pEnumGeomBind := pEnumGeom as IEnumGeometryBind;
         pEnumGeomBind.BindGeometrySource(nil, ILayer(PFLayer));
         pGeomFactory := CoGeometryEnvironment.Create as IGeometryFactory;
    
         pGeomFactory.CreateGeometryFromEnumerator(pEnumGeom, pGeom);
    
         pGeom.Get_Envelope(result);
    
         pEnumGeom := nil;
         pGeomFactory := nil;
         }
    
    end;
    //获得一个FeatureLayer的extent
    
    function GetFeatureLayerGeoMetryExtent(PFLayer: IFeatureLayer): IEnvelope;
    var
    
        pFeature                            : IFeature;
        PFeatureCursor                      : IFeatureCursor;
        pEnvelope                           : IEnvelope;
        MaxX, MaxY, Minx, Miny              : double;
        x1, x2, y1, y2                      : double;
        //PQueryFilter :IQueryFilter;
    
    begin
    
        result := nil;
        if PFLayer = nil then exit;
        MaxX := -1;
        MaxY := -1;
        Minx := -1;
        Miny := -1;
    
        //PQueryFilter :=CoQueryFilter.create as IQueryFilter;
        //PQueryFilter.Set_WhereClause('shape.area>1000');
    
        PFLayer.Search(nil, False, PFeatureCursor);
        if PFeatureCursor = nil then exit;
        PFeatureCursor.NextFeature(pFeature);
    
        while pFeature <> nil do
        begin
            pFeature.Get_Extent(pEnvelope);
            if pEnvelope = nil then Continue;
            pEnvelope.QueryCoords(x1, y1, x2, y2);
            if MaxX < 0 then
            begin
                MaxX := x2;
                MaxY := y2;
                Minx := x1;
                Miny := y1;
    
            end
            else
            begin
                if x1 < Minx then
                    Minx := x1;
                if y1 < Miny then
                    Miny := y1;
                if x2 > MaxX then
                    MaxX := x2;
                if y2 > MaxY then
                    MaxY := y2;
    
            end;
    
            {PGeoMetry := EnvToPoly(PEnvelope);
            if ResultGeoMetry = nil then
            begin
                ResultGeoMetry := PGeoMetry;
            end
            else
            begin
                ResultGeoMetry := Combine(ResultGeoMetry, PGeoMetry);
    
                ResultGeoMetry.Get_Envelope(result);
                ResultGeoMetry := EnvToPoly(result);
    
            end;}
    
            PFeatureCursor.NextFeature(pFeature);
    
        end;
        if MaxX < 0 then
            result := nil
        else
        begin
            result := CoEnvelope.create as IEnvelope;
            result.PutCoords(Minx, Miny, MaxX, MaxY);
        end;
    
    end;
    
    function GetFeatureLayerGeoMetryExtent(PFLayer: IFeatureClass): IEnvelope;
        overload;
    var
    
        pFeature                            : IFeature;
        PFeatureCursor                      : IFeatureCursor;
        pEnvelope                           : IEnvelope;
        MaxX, MaxY, Minx, Miny              : double;
        x1, x2, y1, y2                      : double;
        //PQueryFilter :IQueryFilter;
    
    begin
    
        result := nil;
        if PFLayer = nil then exit;
        MaxX := -1;
        MaxY := -1;
        Minx := -1;
        Miny := -1;
    
        //PQueryFilter :=CoQueryFilter.create as IQueryFilter;
        //PQueryFilter.Set_WhereClause('shape.area>1000');
    
        PFLayer.Search(nil, False, PFeatureCursor);
        if PFeatureCursor = nil then exit;
        PFeatureCursor.NextFeature(pFeature);
    
        while pFeature <> nil do
        begin
            pFeature.Get_Extent(pEnvelope);
            if pEnvelope = nil then Continue;
            pEnvelope.QueryCoords(x1, y1, x2, y2);
            if MaxX < 0 then
            begin
                MaxX := x2;
                MaxY := y2;
                Minx := x1;
                Miny := y1;
    
            end
            else
            begin
                if x1 < Minx then
                    Minx := x1;
                if y1 < Miny then
                    Miny := y1;
                if x2 > MaxX then
                    MaxX := x2;
                if y2 > MaxY then
                    MaxY := y2;
    
            end;
    
            {PGeoMetry := EnvToPoly(PEnvelope);
            if ResultGeoMetry = nil then
            begin
                ResultGeoMetry := PGeoMetry;
            end
            else
            begin
                ResultGeoMetry := Combine(ResultGeoMetry, PGeoMetry);
    
                ResultGeoMetry.Get_Envelope(result);
                ResultGeoMetry := EnvToPoly(result);
    
            end;}
    
            PFeatureCursor.NextFeature(pFeature);
    
        end;
        if MaxX < 0 then
            result := nil
        else
        begin
            result := CoEnvelope.create as IEnvelope;
            result.PutCoords(Minx, Miny, MaxX, MaxY);
        end;
    
    end;
    
    //
    
    function LayerToFeatureSelection(PLayer: ILayer): IFeatureSelection;
    var
        pObj                                : IUnKnown;
    
    begin
        if PLayer.QueryInterface(IID_IFeatureLayer, pObj) = s_Ok then
        begin
            result := PLayer as IFeatureSelection;
        end
        else
        begin
            result := nil;
        end;
    end;
    //根据图层类型加载到地图窗口 by yl 2005.8.8
    
    function AddLayerByType(pFeatureLayer: IFeatureLayer; pMap: Imap):
        IFeatureLayer;
    //后加的面,应在以前的面之前
        //获得最上面面的位置
        function GetMinPolygonIdx(): integer;
        var
            I, count                        : integer;
            PLayer                          : ILayer;
            PFLayer                         : IFeatureLayer;
            pObj                            : IUnKnown;
            ptype                           : Toleenum;
        begin
            pMap.Get_LayerCount(count);
            result := -1;
            if count <= 1 then exit;
            for I := count - 1 downto 0 do
            begin
                pMap.Get_Layer(I, PLayer);
                if PLayer.QueryInterface(IID_IFeatureLayer, pObj) = s_Ok then
                begin
                    PFLayer := PLayer as IFeatureLayer;
                    ptype := GetLayerType(PFLayer);
                    if ptype <> esriGeometryPolygon then
                    begin
                        result := I;
                        exit;
                    end;
    
                end;
            end;
    
        end;
    var
        ptype                               : Toleenum;
    
        idx                                 : integer;
    begin
    
        ptype := GetLayerType(pFeatureLayer);
        pMap.AddLayer(pFeatureLayer);
    
        if (ptype = esriGeometryPolygon) or (ptype = esriGeometryEnvelope) then
        begin
            idx := GetMinPolygonIdx();
            if idx > -1 then
            begin
                pMap.MoveLayer(pFeatureLayer, idx);
            end;
    
        end;
        result := pFeatureLayer;
    
    end;
    //根据图层类型加载到地图窗口 by yl 2005.8.8
    
    function AddLayerByType(pMap: Imap; PLayer: ILayer): ILayer;
    var
    
        pObj                                : IUnKnown;
    begin
    
        if PLayer.QueryInterface(IID_IFeatureLayer, pObj) <> s_Ok then
        begin
            pMap.AddLayer(PLayer);
            exit;
        end;
        result := AddLayerByType(PLayer as IFeatureLayer, pMap);
    
    end;
    
    //根据图层类型加载到地图窗口,按面线点注记的顺序加载
    
    procedure AddLayerByType(pFeatureLayers: array of IFeatureLayer; pMap: Imap);
    var
    
        pFeatLyr                            : IFeatureLayer;
        I, j                                : integer;
        ptype                               : Toleenum;
        count                               : integer;
        pObj                                : IFDOGraphicsLayer;
        DataType                            : array of integer;
    
    begin
    
        count := High(pFeatureLayers);
        if count = 0 then
        begin
            pMap.AddLayer(ILayer(pFeatureLayers[0]));
            exit;
        end;
    
        Setlength(DataType, count + 1);
        for I := 0 to count do
        begin
            IFeatureLayer(pFeatureLayers[I]).QueryInterface(IID_IFDOGraphicsLayer,
                pObj);
            if pObj = nil then
            begin
                pFeatLyr := IFeatureLayer(pFeatureLayers[I]);
                ptype := GetLayerType(pFeatLyr);
    
                if (ptype = esriGeometryPolygon) or (ptype =
                    esriGeometryEnvelope) then
                    DataType[I] := 1
                else
                    if (ptype = esriGeometryLine) or (ptype = esriGeometryPath)
                        or (ptype = esriGeometryBezier3Curve) or (ptype =
                        esriGeometryCircularArc) or
                        (ptype = esriGeometryEllipticArc) or (ptype =
                        esriGeometryPath) or
                        (ptype = esriGeometryPolyline) then
                        DataType[I] := 2
                    else
                        if (ptype = esriGeometryMultipoint) or (ptype =
                            esriGeometryPoint) then
                            DataType[I] := 3
                        else
                            raise exception.create('错误的图层类型');
            end
            else
            begin
                DataType[I] := 4;
            end;
    
        end;
        for j := 1 to 4 do
        begin
            for I := 0 to count do
            begin
                if DataType[I] = j then
                    pMap.AddLayer(ILayer(pFeatureLayers[I]));
            end;
        end;
        Setlength(DataType, 0);
    end;
    //根据 Featureclass创建图层
    
    function CreateLayerFeatureclass(pFeatCls: IFeatureClass):
        IFeatureLayer;
    {var
        pFDOGraphicsLayerFactory: IFDOGraphicsLayerFactory;
        pFDt: IFeatureDataset;
        pWorkspace: IWorkspace;
        Str: widestring;
        pType2: TOleEnum;
    begin
    
        pFeatCls.Get_FeatureType(pType2);
        if pType2 = esriFTAnnotation then
        begin
            pFDOGraphicsLayerFactory :=
                coFDOGraphicsLayerFactory.Create as
                IFDOGraphicsLayerFactory;
            OleCheck(pFeatCls.Get_FeatureDataset(pFDt));
            OleCheck(pFDt.Get_Workspace(pWorkspace));
            OleCheck(pFeatCls.Get_AliasName(Str));
            pFDOGraphicsLayerFactory.OpenGraphicsLayer(IFeatureWorkspace(pWorkspace),
                pFDt, Str, ILayer(result));
        end
        else
        begin
            result := coFeatureLayer.Create as IFeatureLayer;
            OleCheck(result._Set_FeatureClass(pFeatCls));
            OleCheck(pFeatCls.Get_AliasName(Str));
            OleCheck(result.Set_Name(Str));
        end;
        pFDOGraphicsLayerFactory := nil;
    
    end;
    }
    {//张工改后代码
    var
        pFDOGraphicsLayerFactory: IFDOGraphicsLayerFactory;
        pFDt: IFeatureDataset;
        pWorkspace: IWorkSpace;
        PLayer: ILayer;
        Str, TableName: widestring;
        pType2: TOleEnum;
    begin
        pFeatCls.Get_FeatureType(pType2);
        if pType2 = esriFTAnnotation then
        begin
            pFDOGraphicsLayerFactory := coFDOGraphicsLayerFactory.Create as
                IFDOGraphicsLayerFactory;
            OleCheck(pFeatCls.Get_FeatureDataset(pFDt));
            if pFDt <> nil then
            begin
                OleCheck(pFDt.Get_Workspace(pWorkspace));
                OleCheck(pFeatCls.Get_AliasName(Str));
                OleCheck((pFeatCls as IDataSet).Get_Name(TableName));
                PLayer := CoFeatureLayer.Create as ILayer;
                //pFDOGraphicsLayerFactory.OpenGraphicsLayer(IFeatureWorkspace(pWorkspace),
                //    pFDt, Str, ILayer(Result));
                pFDOGraphicsLayerFactory.OpenGraphicsLayer(IFeatureWorkspace(pWorkspace),
                    pFDt, TableName, PLayer); //ILayer(Result)
                result := PLayer as IFeatureLayer;
                OleCheck(result.Set_Name(Str));
            end;
        end
        else
        begin
            result := CoFeatureLayer.Create as IFeatureLayer;
            OleCheck(result._Set_FeatureClass(pFeatCls));
            OleCheck(pFeatCls.Get_AliasName(Str));
            OleCheck(result.Set_Name(Str));
        end;
        pFDOGraphicsLayerFactory := nil;
    end;
    }
    //简化原有的程序,by yl 2006.2.7  同时原来的程序,对注记层有问题
    var
    
        str                                 : widestring;
        pType2                              : Toleenum;
    begin
        pFeatCls.Get_FeatureType(pType2);
        if pType2 = esriFTAnnotation then
        begin
            result := coFDOGraphicsLayer.create as IFeatureLayer;
        end
        else
        begin
            result := CoFeatureLayer.create as IFeatureLayer;
        end;
        OleCheck(result._Set_FeatureClass(pFeatCls));
        OleCheck(pFeatCls.Get_AliasName(str));
        OleCheck(result.Set_Name(str));
    
    end;
    
    //根据条件加载图层
    
    function FeatureLayerBywhere(pFeatureLayer: IFeatureLayer; Where: string):
        IFeatureLayer;
    var
        PFLayerDefinition                   : IFeatureLayerDefinition;
    begin
        PFLayerDefinition := pFeatureLayer as IFeatureLayerDefinition;
        PFLayerDefinition.Set_DefinitionExpression(Where);
        result := PFLayerDefinition as IFeatureLayer;
    
    end;
    //加宽一个
    
    function WidenEnvelope(pEnv: IEnvelope; wd: double): IGeoMetry;
    var
        XMin, YMin, XMax, YMax              : double;
    
    begin
        pEnv.QueryCoords(XMin, YMin, XMax, YMax);
        pEnv.PutCoords(XMin - wd, YMin - wd, XMax + wd, YMax + wd);
        result := EnvToLine(pEnv);
    
    end;
    
    function WidenEnvelopeToPolygon(pEnv: IEnvelope; wd: double): IGeoMetry;
    var
        XMin, YMin, XMax, YMax              : double;
        pEnvelope                           : IEnvelope;
    begin
        pEnv.QueryCoords(XMin, YMin, XMax, YMax);
        pEnvelope := CoEnvelope.create as IEnvelope;
        pEnvelope.PutCoords(XMin - wd, YMin - wd, XMax + wd, YMax + wd);
        result := EnvToPoly(pEnvelope);
    
    end;
    //给一个图层增加一个字段 by yl 2005.8.11
    
    function LayerAddField(pFeatureLayer: IFeatureLayer; Field: IField): boolean;
    var
        pFcc                                : IFeatureClass;
    begin
    
        pFeatureLayer.Get_FeatureClass(pFcc);
        pFcc.AddField(Field);
        result := true;
    end;
    //获得图层的纪录的个数   by yl 2005.8.11
    
    function GetRecordcount(FFeatureLayer: IFeatureLayer): integer;
    var
        FeatureClass                        : IFeatureClass;
    begin
        FFeatureLayer.Get_FeatureClass(FeatureClass);
        result := GetRecordcount(FeatureClass);
    end;
    //获得图层的纪录的个数   by yl 2007.7.25,真正的获得个数
    
    function GetRecordcount2(FFeatureLayer: IFeatureLayer): integer;
    var
        pData                               : IDataStatistics;
        PFeatureCursor                      : IFeatureCursor;
        pStatResults                        : IStatisticsResults;
    begin
        pData := CoDataStatistics.create as IDataStatistics;
        FFeatureLayer.Search(nil, False, PFeatureCursor);
        try
            pData.Set_Field('objectID');
            pData._Set_Cursor(PFeatureCursor as ICursor);
            pData.Get_Statistics(pStatResults);
            pStatResults.Get_Count(result);
        finally
            pData := nil;
        end;
    end;
    //获得图层的纪录的个数   by yl 2007.7.25,真正的获得个数
    
    function GetshpRecordcount2(FFeatureLayer: IFeatureLayer): integer;
    var
        pData                               : IDataStatistics;
        PFeatureCursor                      : IFeatureCursor;
        pStatResults                        : IStatisticsResults;
    begin
        pData := CoDataStatistics.create as IDataStatistics;
        FFeatureLayer.Search(nil, False, PFeatureCursor);
        if PFeatureCursor = nil then
        begin
            result := 0;
            exit;
        end;
        try
            pData.Set_Field('FID');
            pData._Set_Cursor(PFeatureCursor as ICursor);
            pData.Get_Statistics(pStatResults);
            pStatResults.Get_Count(result);
        finally
            pData := nil;
        end;
    end;
    
    //获得图层的纪录的个数   by yl 2005.8.11
    
    function GetRecordcount(FFeatureClass: IFeatureClass): integer; overload;
    
    begin
    
        FFeatureClass.FeatureCount(nil, result);
    end;
    //获得图层的空间查询   by yl 2005.8.11
    
    function Searchbyshape(FFeatureLayer: IFeatureLayer; pgeometry: IGeoMetry;
        SearchMode: Toleenum = esriSpatialRelIntersects): IFeatureCursor;
    var
    
        pFilter                             : ISpatialFilter;
        PCursor                             : IFeatureCursor;
        SHPFieldName                        : string;
    begin
    
        //获得相交对象
        pFilter := CoSpatialFilter.create as ISpatialFilter;
        pFilter._Set_Geometry(pgeometry);
        pFilter.Set_SpatialRel(SearchMode);
        SHPFieldName := GetShapeFieldName(FFeatureLayer);
        pFilter.Set_GeometryField(SHPFieldName);
    
        FFeatureLayer.Search(pFilter as IQueryFilter, False, PCursor);
        result := PCursor;
        pFilter := nil;
    
    end;
    //获得图层的空间查询   by yl 2006.8.4
    
    function Searchbyshape(FFeatureLayer: IFeatureLayer; pgeometry: IGeoMetry;
        WhereStr: string; SearchMode: Toleenum = esriSpatialRelIntersects):
        IFeatureCursor; overload;
    var
    
        pFilter                             : ISpatialFilter;
        PCursor                             : IFeatureCursor;
        SHPFieldName                        : string;
        pFeatureClass                       : IFeatureClass;
    
    begin
    
        //获得相交对象
        pFilter := CoSpatialFilter.create as ISpatialFilter;
    
        pFilter.Set_WhereClause(WhereStr);
        if SearchMode > 0 then
        begin
            pFilter._Set_Geometry(pgeometry);
            pFilter.Set_SpatialRel(SearchMode);
            SHPFieldName := GetShapeFieldName(FFeatureLayer);
            pFilter.Set_GeometryField(SHPFieldName);
        end;
        FFeatureLayer.Get_FeatureClass(pFeatureClass);
        pFeatureClass.Search(pFilter as IQueryFilter, False, PCursor);
        result := PCursor;
        pFilter := nil;
    
    end;
    //获得图层的空间查询   by yl 2006.9.20
    
    function Searchbyshape(pFeatureClass: IFeatureClass; WhereStr: string;
        var count: integer): IFeatureCursor; overload;
    var
    
        pQueryFilter                        : IQueryFilter;
        PCursor                             : IFeatureCursor;
    begin
    
        pQueryFilter := CoQueryFilter.create as IQueryFilter;
    
        pQueryFilter.Set_WhereClause(WhereStr);
    
        pFeatureClass.FeatureCount(pQueryFilter, count);
        pFeatureClass.Search(pQueryFilter, False, PCursor);
        result := PCursor;
        pQueryFilter := nil;
    
    end;
    
    //获得图层的空间查询   by yl 2005.8.11
    
    function Searchbyshape(pFeatureClass: IFeatureClass; pgeometry: IGeoMetry; var
        count: integer; Update: boolean = False; SearchMode: Toleenum =
        esriSpatialRelIntersects): IFeatureCursor; overload;
    var
    
        pFilter                             : ISpatialFilter;
        PCursor                             : IFeatureCursor;
        SHPFieldName                        : string;
    begin
        count := 0;
        //获得相交对象
        pFilter := CoSpatialFilter.create as ISpatialFilter;
        pFilter._Set_Geometry(pgeometry);
        pFilter.Set_SpatialRel(SearchMode);
        SHPFieldName := GetShapeFieldName(pFeatureClass);
        pFilter.Set_GeometryField(SHPFieldName);
        pFeatureClass.FeatureCount(pFilter as IQueryFilter, count);
        if Update then
            pFeatureClass.Update(pFilter as IQueryFilter, False, PCursor)
        else
    
            pFeatureClass.Search(pFilter as IQueryFilter, False, PCursor);
        result := PCursor;
        pFilter := nil;
    
    end;
    //获得图层的空间查询   by yl 2005.8.11
    
    function SearchbySql(pFeatureClass: IFeatureClass; sql: string;
        var count: integer; Update: boolean = False):
        IFeatureCursor; overload;
    var
    
        pFilter                             : IQueryFilter;
        PCursor                             : IFeatureCursor;
    
    begin
    
        pFilter := CoQueryFilter.create as IQueryFilter;
        pFilter.Set_WhereClause(sql);
    
        pFeatureClass.FeatureCount(pFilter as IQueryFilter, count);
        if Update then
            pFeatureClass.Update(pFilter as IQueryFilter, False, PCursor)
        else
    
            pFeatureClass.Search(pFilter as IQueryFilter, False, PCursor);
        result := PCursor;
        pFilter := nil;
    
    end;
    
    //获得shape字段的索引 by yl 2005.8.11
    
    function GetShapeFieldName(FeatureLayer: IFeatureLayer): string;
    var
        pFeatureClass                       : IFeatureClass;
    
    begin
        FeatureLayer.Get_FeatureClass(pFeatureClass);
        result := GetShapeFieldName(pFeatureClass);
    
    end;
    
    function GetShapeFieldName(FeatureClass: IFeatureClass): string;
    var
        FieldName                           : widestring;
    begin
        FeatureClass.Get_ShapeFieldName(FieldName);
        result := FieldName;
    
    end;
    //有Feature获得图层名称
    
    function GetLayerNameByFeature(pFeature: IFeature): string;
    var
        Table                               : IObjectClass;
        wname                               : widestring;
    begin
        pFeature.Get_Class_(Table);
        Table.Get_AliasName(wname);
        result := wname;
    
    end;
    //根据FID获得对象
    
    function GetFeature(pFeatureClass: IFeatureClass; FID: integer): IFeature;
        overload;
    var
        FIDFieldName                        : widestring;
    begin
    
        pFeatureClass.Get_OIDFieldName(FIDFieldName);
    
        result := GetFeature(pFeatureClass, FID, FIDFieldName);
    
    end;
    //根据FID获得对象
    
    function GetFeature(pFeatureClass: IFeatureClass; FID: integer;
        FIDFieldName: widestring): IFeature; overload;
    var
        pQF                                 : IQueryFilter;
        PFCursor                            : IFeatureCursor;
        pFeature                            : IFeature;
    
        Sqlstr                              : string;
        num                                 : integer;
    begin
    
        pQF := CoQueryFilter.create as IQueryFilter;
        try
    
            Sqlstr := FIDFieldName + '=' + Format('%d', [FID]);
            //Sqlstr := 'FID = 2';
            pQF.Set_WhereClause(Sqlstr);
            pFeatureClass.FeatureCount(pQF, num);
    
            pFeatureClass.Search(pQF, False, PFCursor);
            PFCursor.NextFeature(pFeature);
            result := pFeature;
        finally
            pQF := nil;
        end;
    
    end;
    //根据FID获得对象
    
    function GetFeature(FeatureLayer: IFeatureLayer; FID: integer;
        FIDFieldName: widestring): IFeature; overload;
    var
        pQF                                 : IQueryFilter;
        PFCursor                            : IFeatureCursor;
        pFeature                            : IFeature;
        Sqlstr                              : string;
    
    begin
    
        pQF := CoQueryFilter.create as IQueryFilter;
        try
    
            Sqlstr := FIDFieldName + '=' + Format('%d', [FID]);
            //Sqlstr := 'FID = 2';
            pQF.Set_WhereClause(Sqlstr);
    
            FeatureLayer.Search(pQF, False, PFCursor);
            PFCursor.NextFeature(pFeature);
            result := pFeature;
        finally
            pQF := nil;
        end;
    
    end;
    
    //根据FID获得对象
    
    function GetFeature(FeatureLayer: IFeatureLayer; FID: integer): IFeature;
    var
        pFeatureClass                       : IFeatureClass;
    
    begin
    
        FeatureLayer.Get_FeatureClass(pFeatureClass);
        result := GetFeature(pFeatureClass, FID);
    
    end;
    //获得字段的类型
    
    function GetFieldType(FeatureLayer: IFeatureLayer; FieldName:
        widestring): Toleenum;
    var
        pFcc                                : IFeatureClass;
    begin
        FeatureLayer.Get_FeatureClass(pFcc);
        result := GetFieldType(pFcc, FieldName);
    
    end;
    //获得字段的类型
    
    function GetFieldType(pFcc: IFeatureClass; FieldName:
        widestring): Toleenum;
    var
        Fields                              : IFields;
        PField                              : IField;
        idx                                 : integer;
    begin
    
        pFcc.Get_Fields(Fields);
        Fields.FindField(FieldName, idx);
        if idx > -1 then
        begin
            Fields.Get_Field(idx, PField);
            PField.Get_type_(result);
    
        end;
    end;
    
    //获得字段的位置
    
    function GetFieldPos(FeatureLayer: IFeatureLayer; FieldName:
        widestring; ISAlias: boolean = False): integer;
    var
        pFcc                                : IFeatureClass;
    
    begin
        FeatureLayer.Get_FeatureClass(pFcc);
        result := GetFieldPos(pFcc, FieldName, ISAlias);
    
    end;
    //获得字段的位置
    
    function GetFieldPos(pFeatClass: IFeatureClass; FieldName:
        widestring; ISAlias: boolean = False): integer;
    var
        Fields                              : IFields;
    begin
        pFeatClass.Get_Fields(Fields);
        if ISAlias then
            Fields.FindFieldByAliasName(FieldName, result)
        else
            Fields.FindField(FieldName, result);
    end;
    
    //获得字段的位置
    
    function GetField(pFeatClass: IFeatureClass; FieldName:
        widestring): IField;
    var
        Fields                              : IFields;
        idx                                 : integer;
    begin
        pFeatClass.Get_Fields(Fields);
        Fields.FindField(FieldName, idx);
        Fields.Get_Field(idx, result);
    
    end;
    
    //返回对应索引字段的值,ptype主要解决空值(null)转换,没有空值就不需要
    
    function getfieldvalue(pFeature: IFeature; idx: integer;
        ptype: TVarType = varString): variant;
    var
        v                                   : olevariant;
        pout                                : variant;
    begin
        pFeature.Get_Value(idx, v);
    
        if VarIsNull(v) then
        begin
            if ptype = varString then       //主要是字符和数字,日期还没有考虑
                pout := ''
            else
                pout := 0;
    
        end
        else
            pout := v;
        result := pout;
    end;
    //获得字段的位置
    
    function GetFieldPos(pFeature: IFeature; FieldName:
        widestring): integer;
    var
    
        Fields                              : IFields;
    begin
        pFeature.Get_Fields(Fields);
    
        Fields.FindField(FieldName, result);
    end;
    
    function getfieldvalue(pFeature: IFeature; FieldName: string): variant;
    
    var
        idx                                 : integer;
    begin
        idx := GetFieldPos(pFeature, FieldName);
    
        if idx > -1 then
        begin
            result := getfieldvalue(pFeature, idx);
            end
        else
        begin
            showMessage('找不到对应字段'+FieldName);
            result := '';
        end;
    
    end;
    
    function SetFieldValue(pFeature: IFeature; FieldName: string; value:
        string): boolean;
    
    var
        idx                                 : integer;
    begin
        idx := GetFieldPos(pFeature, FieldName);
        if idx > -1 then
        begin
            pFeature.set_Value(idx, value);
            result := true;
    
        end
        else
            result := False;
    
    end;
    
    //判断对象自相交
    
    function IsSelfCross(pgeometry: IGeoMetry): boolean;
    var
        pTopo                               : ITopologicalOperator2;
        B                                   : wordbool;
    begin
        pTopo := pgeometry as ITopologicalOperator2;
        pTopo.Set_IsKnownSimple(False);
        pTopo.Get_IsSimple(B);
        result := B;
    
    end;
    //增加影像图,Filename含路径
    
    function AddRasterFile(FileName: string): IRasterLayer;
    //'sFileName: the filename of the raster dataset
    //'sPath: the directory where the raster dataset resides
    var
        pRasterLayer                        : IRasterLayer;
    begin
        // if not FileExists(FileName) then ,有些影像就是一个路径
        //begin
        //     raise exception.Create(FileName + ':文件不存在');
        //end;
        pRasterLayer := CoRasterLayer.create as IRasterLayer;
        //'This is only one of the three ways to create a RasterLayer object.
        //'If there is already a Raster or RasterDataset object, then
        //'method CreateFromDataset or CreateFromRaster can be used.
        pRasterLayer.CreateFromFilePath(FileName);
        result := pRasterLayer;
    end;
    //获得字段的唯一值
    
    procedure listUniqueValue(PLayer: IFeatureLayer;
        pFieldName: string; List: TstringList; Isthread: boolean = False; ISmark:
        string = '');
    var
        PCursor                             : IFeatureCursor;
    
    begin
        PLayer.Search(nil, False, PCursor);
        listUniqueValue(PCursor, pFieldName, List, Isthread, ISmark);
    
    end;
    //获得字段的唯一值
    
    procedure listUniqueValue(pFeatureClass: IFeatureClass;
        pFieldName: string; List: TstringList; Isthread: boolean = False); overload;
    var
        PCursor                             : IFeatureCursor;
        num                                 : integer;
    
    begin
        pFeatureClass.Search(nil, False, PCursor);
        pFeatureClass.FeatureCount(nil, num);
        if num > 0 then
        begin
            listUniqueValue(PCursor, pFieldName, List, Isthread);
            if List.count = 0 then
                List.Add('');
        end;
    
    end;
    //获得失量图层查询
    
    function Get_FeatureLayer(pMap: Imap; var FtLayerArr: array of
        IFeatureLayer):
        integer;
    var
        I, num                              : integer;
        Layer                               : ILayer;
        pObj                                : IUnKnown;
        j                                   : integer;
    
    begin
    
        pMap.Get_LayerCount(num);
    
        j := 0;
        for I := 0 to num - 1 do
        begin
            pMap.Get_Layer(I, Layer);
    
            if Layer.QueryInterface(IID_IFeatureLayer, pObj) = s_Ok then
            begin
    
                FtLayerArr[j] := Layer as IFeatureLayer;
                j := j + 1;
    
            end;
    
        end;
    
        result := j;
    end;
    
    //选择图层查询
    
    function Get_SelectLayer(pMap: Imap; List: TstringList): integer; overload;
    var
        I, num, selnum                      : integer;
        Layer                               : ILayer;
        pObj                                : IUnKnown;
        j                                   : integer;
        v                                   : wordbool;
    
        PSelectionSet                       : ISelectionSet;
        LayerName                           : widestring;
    begin
        pMap.Get_SelectionCount(num);
        result := 0;
        if num = 0 then
        begin
    
            exit;
        end;
        pMap.Get_LayerCount(num);
    
        j := 0;
        for I := 0 to num - 1 do
        begin
            pMap.Get_Layer(I, Layer);
            Layer.Get_Visible(v);
            if v then
            begin
                if Layer.QueryInterface(IID_IFeatureLayer, pObj) = s_Ok then
                begin
    
                    PSelectionSet := GetSelectionsetByFeatureLayer(Layer);
                    if PSelectionSet <> nil then
                    begin
    
                        PSelectionSet.Get_Count(selnum);
                        if selnum > 0 then
                        begin
                            Layer.Get_Name(LayerName);
                            List.Add(LayerName);
                            j := j + 1;
                        end;
                    end;
    
                end;
            end;
    
        end;
        result := j;
    end;
    //选择图层查询
    
    function Get_SelectLayer(pMap: Imap; var FtLayerArr: array of
        IFeatureLayer): integer; overload;
    
    var
        I, num, selnum                      : integer;
        Layer                               : ILayer;
        pObj                                : IUnKnown;
        j                                   : integer;
        v                                   : wordbool;
    
        PSelectionSet                       : ISelectionSet;
    begin
        pMap.Get_SelectionCount(num);
        result := 0;
        if num = 0 then
        begin
    
            exit;
        end;
        pMap.Get_LayerCount(num);
    
        j := 0;
        for I := 0 to num - 1 do
        begin
            pMap.Get_Layer(I, Layer);
            Layer.Get_Visible(v);
            if v then
            begin
                if Layer.QueryInterface(IID_IFeatureLayer, pObj) = s_Ok then
                begin
    
                    PSelectionSet := GetSelectionsetByFeatureLayer(Layer);
                    if PSelectionSet <> nil then
                    begin
    
                        PSelectionSet.Get_Count(selnum);
                        if selnum > 0 then
                        begin
                            FtLayerArr[j] := Layer as IFeatureLayer;
                            j := j + 1;
                        end;
                    end;
    
                end;
            end;
    
        end;
        result := j;
    end;
    //获得选择集合并后对象
    
    function GetSelectUnion(pMap: Imap): IGeoMetry; overload
    var
        FtLayerArr                          : array of IFeatureLayer;
        num                                 : integer;
        PSelectionSet                       : ISelectionSet;
    begin
        pMap.Get_LayerCount(num);
        Setlength(FtLayerArr, num);
        num := Get_SelectLayer(pMap, FtLayerArr);
    
        if num > 1 then
        begin
            raise exception.create('选择对象不在一个图层');
        end;
        Setlength(FtLayerArr, num);
        PSelectionSet := GetSelectionsetByFeatureLayer(FtLayerArr[0]);
        if PSelectionSet = nil then exit;
        result := GetSelectUnion(PSelectionSet);
    
    end;
    //获得点在矩形八个点的位置,dis是最小距离大于,最小距离返回-1
    
    function GetPosINEnvelope(pEnvelope: IEnvelope; x, Y: double; Dis: double):
        integer;
    var
    
        x1, y1, x2, y2                      : double;
        Pt                                  : array[0..7] of IPoint;
        SPt                                 : IPoint;
        D, Mind                             : double;
        I, P                                : integer;
    begin
    
        pEnvelope.QueryCoords(x1, y1, x2, y2);
        for I := 0 to 7 do
        begin
            Pt[I] := CoPoint.create as IPoint;
        end;
        Pt[0].PutCoords(x1, y1);            //左下为第一点
        Pt[1].PutCoords(x1, (y1 + y2) / 2); //左下为第二点
        Pt[2].PutCoords(x1, y2);            //左下为第三点
        Pt[3].PutCoords((x1 + x2) / 2, y2); //左下为第四点
        Pt[4].PutCoords(x2, y2);            //左下为第五点
        Pt[5].PutCoords(x2, (y1 + y2) / 2); //左下为第六点
        Pt[6].PutCoords(x2, y1);            //左下为第七点
        Pt[7].PutCoords((x1 + x2) / 2, y1); //左下为第八点
        SPt := CoPoint.create as IPoint;
        SPt.PutCoords(x, Y);
        Mind := 9999999999999;
        P := -1;
        for I := 0 to 7 do
        begin
            D := ReturnDistance(Pt[I], SPt);
            if Mind > D then
            begin
                Mind := D;
                P := I;
            end;
    
        end;
    
        for I := 0 to 7 do
        begin
            Pt[I] := nil;
        end;
        SPt := nil;
    
        if Mind > Dis then
        begin
            result := -1;
    
        end
        else
        begin
            result := P;
        end;
    
    end;
    //根据当前表的结构创立,一个shp文件
    
    function CreateLayerFeatureclass(pFeatCls: IFeatureClass;
        FileName: string): IFeatureClass; overload;
    var
        pWFactory                           : IWorkspaceFactory;
        pPropertySet                        : IPropertySet;
        pFWorkspace                         : IFeatureWorkspace;
        Pworkspace                          : IWorkspace;
        pFields                             : IFields;
        pTableCls                           : IFeatureClass;
        pOle                                : Toleenum;
        path                                : string;
        ShapeFieldName                      : widestring;  //和Objectid一致,因为不一定就是Objectid
    begin
        //pFeatCls.Get_OIDFieldName(OIDFieldName);
        pFeatCls.Get_ShapeFieldName(ShapeFieldName);
        pFeatCls.Get_FeatureType(pOle);
        pWFactory := CoShapefileWorkspaceFactory.create as
            IWorkspaceFactory;
        pPropertySet := CoPropertySet.create as IPropertySet;
        path := ExtractFilePath(FileName);
    
        pPropertySet.SetProperty('DATABASE', path);
        pWFactory.Open(pPropertySet, 0, Pworkspace);
        pFWorkspace := Pworkspace as IFeatureWorkspace;
        pFeatCls.Get_Fields(pFields);
    
        pFWorkspace.CreateFeatureClass(ExtractFileName(FileName), pFields,
            nil, nil, pOle, ShapeFieldName, 'ObjectID', pTableCls);
        pFWorkspace.OpenFeatureClass(ExtractFileName(FileName), result);
    end;
    //OleDrop中增加图层
    
    function CreateLayer(pName: IName; pMap: Imap): boolean;
    var
        //'Get the ILayerFactoryHelper interface
        pLayerFactoryHelper                 : ILayerFactoryHelper;
        pEnumLayer                          : IEnumLayer;
        PLayer                              : ILayer;
    begin
        pLayerFactoryHelper := CoLayerFactoryHelper.create as
            ILayerFactoryHelper;
    
        //'Get the IEnumLayer interface through the ILayerFatcoryHelper interface
    
        pLayerFactoryHelper.CreateLayersFromName(pName, pEnumLayer);
        pEnumLayer.Reset;
    
        //'Get the ILayer interface
        pEnumLayer.Next(PLayer);
        try
    
            while PLayer <> nil do
            begin
                //'Add the layer to the map
                pMap.AddLayer(PLayer);
                pEnumLayer.Next(PLayer);
            end;
            result := true;
        except
            result := False;
        end;
    
    end;
    
    //将地图拷贝(SMap)到地图上(TMap),
    
    procedure CopyMap(SMap: Imap; TMap: Imap);
    
    var
        I, num                              : integer;
        Layer                               : ILayer;
    
    begin
        if (SMap = nil) then exit;
    
        SMap.Get_LayerCount(num);
        for I := num - 1 downto 0 do
        begin
            SMap.Get_Layer(I, Layer);
            TMap.AddLayer(Layer);
        end;
    
    end;
    //
    
    procedure CopyElement(SGraphicsContainer, TGraphicsContainer:
        IGraphicsContainer);
    var
        pElement                            : IElement;
    
    begin
        if (SGraphicsContainer = nil) then exit;
        SGraphicsContainer.Reset;
        SGraphicsContainer.Next(pElement);
        while pElement <> nil do
        begin
            TGraphicsContainer.AddElement(pElement, 0);
            SGraphicsContainer.Next(pElement);
        end;
    
    end;
    //获得一个图层的坐标
    
    function GetSpatialReference(FeatureLayer: IFeatureLayer):
        ISpatialReference;
    var
        PGeoDataset                         : IGeoDataset;
    begin
    
        result := nil;
        if FeatureLayer <> nil then
        begin
            PGeoDataset := FeatureLayer as IGeoDataset;
            PGeoDataset.Get_SpatialReference(result);
    
        end;
    
    end;
    //获得一个图层的坐标
    
    function GetSpatialReference(FeatureClass: IFeatureClass):
        ISpatialReference;
    var
        PGeoDataset                         : IGeoDataset;
    begin
    
        result := nil;
        if FeatureClass <> nil then
        begin
            PGeoDataset := FeatureClass as IGeoDataset;
            PGeoDataset.Get_SpatialReference(result);
    
        end;
    
    end;
    
    //根据FID获得值
    
    procedure GetSelectFID(FIDTST: TstringList; PSelectionSet: ISelectionSet);
    var
    
        PCursor                             : ICursor;
        PFCursor                            : IFeatureCursor;
        pFeature                            : IFeature;
        FID                                 : integer;
    begin
    
        PSelectionSet.Search(nil, False, PCursor);
        PFCursor := PCursor as IFeatureCursor;
        PFCursor.NextFeature(pFeature);
        while pFeature <> nil do
        begin
            pFeature.Get_OID(FID);
            FIDTST.Add(IntToStr(FID));
    
            PFCursor.NextFeature(pFeature);
        end;
    
    end;
    //获得选择的Feature
    
    function GetSelectFeature(pFeatureLayer: IFeatureLayer): IFeature;
    var
    
        PCursor                             : ICursor;
        PFCursor                            : IFeatureCursor;
        pFeature                            : IFeature;
        PSelectionSet                       : ISelectionSet;
        num                                 : integer;
    begin
    
        PSelectionSet := GetSelectionsetByFeatureLayer(pFeatureLayer);
        if PSelectionSet = nil then exit;
        PSelectionSet.Get_Count(num);
        if num = 0 then exit;
    
        PSelectionSet.Search(nil, False, PCursor);
        PFCursor := PCursor as IFeatureCursor;
        PFCursor.NextFeature(pFeature);
        result := pFeature;
    
    end;
    
    //把一个图层的选择对象装入TTreeView
    
    function LoadTreeByselectobj(FeatureLayer: IFeatureLayer; TV: TTreeView):
        boolean;
        procedure loadFID(Node: TTreeNode; FIDTST: TstringList; tvData:
            TTreeView);
        var
            FID                             : integer;
            I, num                          : integer;
        begin
            num := FIDTST.count;
            for I := 0 to num - 1 do
            begin
                FID := StrToInt(FIDTST[I]);
                tvData.Items.AddChildObject(Node, FIDTST[I], ptr(FID));
            end;
        end;
    var
        LayerName                           : widestring;
        Node                                : TTreeNode;
        PSelectionSet                       : ISelectionSet;
        count                               : integer;
        FIDTST                              : TstringList;
    
    begin
        result := False;
        PSelectionSet := GetSelectionsetByFeatureLayer(FeatureLayer);
        if PSelectionSet = nil then exit;
        PSelectionSet.Get_Count(count);
    
        if count = 0 then exit;
        FIDTST := TstringList.create;
        try
            FeatureLayer.Get_Name(LayerName);
            Node := TV.Items.AddChild(nil, LayerName);
            GetSelectFID(FIDTST, PSelectionSet);
            loadFID(Node, FIDTST, TV);
            result := true;
        finally
            FIDTST.Free;
        end;
    end;
    //获得图斑层选择对象的集合
    
    function getSelectGeoMetry(PFLayer: ILayer): IEnvelope;
    var
        PSelectionSet                       : ISelectionSet;
        Envelope                            : IEnvelope;
    begin
    
        PSelectionSet := GetSelectionsetByFeatureLayer(PFLayer);
        if PSelectionSet = nil then exit;
        Envelope := GetSelectEnvelope(PSelectionSet);
        result := Envelope;
    
    end;
    //获得选择对象,字段的唯一值
    
    procedure listSelectUniqueValue(PLayer: IFeatureLayer;
        pFieldName: string; List: TstringList; Isthread: boolean = False);
    var
        PCursor                             : ICursor;
        PFCursor                            : IFeatureCursor;
        PSelectionSet                       : ISelectionSet;
    begin
    
        PSelectionSet := GetSelectionsetByFeatureLayer(PLayer);
        if PSelectionSet = nil then exit;
        PSelectionSet.Search(nil, False, PCursor);
        PFCursor := PCursor as IFeatureCursor;
        listUniqueValue(PFCursor, pFieldName, List, Isthread);
    
    end;
    //获得唯一值
    //是否考虑引号 ISmark
    
    procedure listUniqueValue(PCursor: IFeatureCursor;
        pFieldName: string; List: TstringList;
        Isthread: boolean = False; ISmark: string = ''); overload;
    var
    
        pDataStat                           : IDataStatistics;
        pvalue                              : olevariant;
        pEnumVar                            : IEnumVariantSimple;
        pEV                                 : IEnumVariant;
    
    begin
        pDataStat := CoDataStatistics.create as IDataStatistics;
        pDataStat.Set_Field(pFieldName);
        pDataStat._Set_Cursor(PCursor as ICursor);
        pDataStat.Get_UniqueValues(pEV);
        if pEV = nil then exit;
    
        pEnumVar := pEV as IEnumVariantSimple;
        pEnumVar.Next(pvalue);
        while pvalue <> Unassigned do
        begin
            List.Add(Format('%s%s%s', [ISmark, pvalue, ISmark]));
            if Isthread then
                Application.ProcessMessages;
    
            pEnumVar.Next(pvalue);
        end;
        List.Sort;
    
    end;
    
    procedure SetFilter(var pTSF: ISpatialFilter; pgeometry: IGeoMetry;
        WhereStr: string = '');
    begin
    
        pTSF.Set_SpatialRel(esriSpatialRelIntersects);
        if WhereStr <> '' then
        begin
            pTSF.Set_WhereClause(WhereStr);
            pTSF.Set_SearchOrder(esriSearchOrderAttribute);
        end;
        pTSF._Set_Geometry(pgeometry);
    end;
    //获得图层的空间查询   Count是相交的个数
    
    function Searchbyshape(FFeatureLayer: IFeatureLayer; pgeometry: IGeoMetry;
        var count: integer): IFeatureCursor; overload;
    var
        pSpatialFilter                      : ISpatialFilter;
        pFeatureClass                       : IFeatureClass;
    begin
        pSpatialFilter := CoSpatialFilter.create as ISpatialFilter;
        try
            SetFilter(pSpatialFilter, pgeometry);
            FFeatureLayer.Get_FeatureClass(pFeatureClass);
            pFeatureClass.Search(pSpatialFilter, False, result);
            pFeatureClass.FeatureCount(pSpatialFilter, count);
    
        finally
            pSpatialFilter := nil;
        end;
    end;
    //获得图层的空间查询   Count是相交的个数
    
    function Searchbyshape(FFeatureClass: IFeatureClass; pgeometry: IGeoMetry;
        WhereStr: string; var count: integer): IFeatureCursor; overload;
    var
        pSpatialFilter                      : ISpatialFilter;
    begin
        pSpatialFilter := CoSpatialFilter.create as ISpatialFilter;
        try
            SetFilter(pSpatialFilter, pgeometry, WhereStr);
    
            FFeatureClass.Search(pSpatialFilter, False, result);
            FFeatureClass.FeatureCount(pSpatialFilter, count);
    
        finally
            pSpatialFilter := nil;
        end;
    end;
    
    //============================
    //名称:DeleteSplitObjFeat
    //说明:删除对象分割后旧的要素
    //传入:FID: Integer; FFeatureLayer: IFeatureLayer
    //返回:None
    //作者:zp
    //时间:2005-09-26
    //版本:v1.0.0
    //更新:(说明更新人、更新时间、更新后的版本号和修改简单说明)
    //============================
    //说明:删除对象分割后旧的要素
    
    procedure DeleteSplitObjFeat(FID: integer; pFClass: IFeatureClass);
    var
        pFeature                            : IFeature;
        PFCursor                            : IFeatureCursor;
        pFilter                             : IQueryFilter;
        sql                                 : string;
        CFID                                : integer;
    begin
        sql := Format('ObjectID = %d', [FID]);
        pFilter := CoQueryFilter.create as IQueryFilter;
        pFilter.Set_WhereClause(sql);
        pFClass.Search(pFilter, False, PFCursor);
        if PFCursor = nil then exit;
        PFCursor.NextFeature(pFeature);
        while pFeature <> nil do
        begin
            pFeature.Get_OID(CFID);
            if CFID = FID then
                pFeature.Delete;
    
            PFCursor.NextFeature(pFeature);
        end;
    end;
    //分解对象
    
    function decomposeobj(pFeature: IFeature; pFeatureClass: IFeatureClass):
        integer;
    var
        pGeom                               : IGeoMetry;
        pGeomColl                           : IGeoMetryCollection;
        I, count                            : integer;
        FeaArray                            : array of IGeoMetry;
        FID                                 : integer;
        pgeometry                           : IGeoMetry;
    begin
        pFeature.Get_Shape(pGeom);
    
        result := 1;
        if pGeom <> nil then
        begin
    
            pGeomColl := pGeom as IGeoMetryCollection;
            pGeomColl.Get_GeometryCount(count);
            if count < 2 then
            begin
                exit;
            end;
    
            Setlength(FeaArray, count);
            count := decomposeobj(pGeom, FeaArray);
            pFeature.Get_OID(FID);
    
            for I := 0 to count - 1 do
            begin
                pgeometry := FeaArray[I];
                IsSimple(pgeometry);
    
                if I = 0 then
                    UpdateFeature(pFeature, FeaArray[I])
                else
                    CreateFeature(pFeature, FeaArray[I], pFeatureClass);
    
            end;
    
            result := count;
            Setlength(FeaArray, 0);
    
        end;
    
    end;
    
    procedure CreateFeature(SourceFeature: IFeature; pGeom: IGeoMetry;
        pFeatureClass: IFeatureClass);
    
    {var
        //pNewFeature                         : IFeature;
        List                                : TstringList;
        value                               : string;
        i, num                              : Integer;
        idx                                 : Integer;
        pFeatureBuffer                      : IFeatureBuffer;
        PFeatureCursor                      : IFeatureCursor;
        id                                  : olevariant;
    begin
    
        if (pGeom = nil) or (SourceFeature = nil) then Exit;
        if (pFeatureClass = nil) then Exit;
        pFeatureClass.Insert(True, PFeatureCursor);
        if PFeatureCursor = nil then
        begin
            ShowMessage('空间数据有问题,创立对象失败');
            Exit;
        end;
    
        pFeatureClass.CreateFeatureBuffer(pFeatureBuffer);
        //CreateFeature(pNewFeature);
        if pFeatureBuffer = nil then
        begin
            ShowMessage('空间数据有问题,创立对象失败');
            Exit;
        end;
    
        pFeatureBuffer._Set_Shape(pGeom);   //设置图形
        List := TstringList.Create;
        try
            num := GetFieldNameIdxList(pFeatureClass, List);
            for i := 0 to num - 1 do
            begin
                idx := StrToInt(List[i]);
                value := GetFieldValue(SourceFeature, idx);
                pFeatureBuffer.set_Value(idx, value);
    
            end;
            //pNewFeature.Store;
            PFeatureCursor.InsertFeature(pFeatureBuffer, id);
        finally
            List.Free;
        end;
    
    end;
    }
    var
    
        List                                : TstringList;
        value                               : string;
        I, num                              : integer;
        idx                                 : integer;
        pFeatureBuffer                      : IFeature;
    
    begin
    
        if (pGeom = nil) or (SourceFeature = nil) then exit;
        if (pFeatureClass = nil) then exit;
        pFeatureClass.CreateFeature(pFeatureBuffer);
        if pFeatureBuffer = nil then
        begin
            showmessage('空间数据有问题,创立对象失败');
            exit;
        end;
    
        pFeatureBuffer._Set_Shape(pGeom);   //设置图形
        List := TstringList.create;
        try
            num := GetFieldNameIdxList(pFeatureClass, List);
            for I := 0 to num - 1 do
            begin
                idx := StrToInt(List[I]);
                value := getfieldvalue(SourceFeature, idx);
                pFeatureBuffer.set_Value(idx, value);
    
            end;
            pFeatureBuffer.Store;
    
        finally
            List.Free;
        end;
    
    end;
    
    function UpdateFeature(FID: integer; pGeom: IGeoMetry;
        pFeatClass: IFeatureClass): boolean; overload;
    var
        pFeature                            : IFeature;
    begin
        result := true;
        pFeature := GetFeature(pFeatClass, FID);
        if pFeature = nil then exit;
        UpdateFeature(pFeature, pGeom);
    
    end;
    
    function UpdateFeature(FID: integer; pGeom: IGeoMetry; pFeatLayer:
        IFeatureLayer): boolean;
    var
        pFeature                            : IFeature;
    begin
        result := true;
        pFeature := GetFeature(pFeatLayer, FID);
        if pFeature = nil then exit;
        UpdateFeature(pFeature, pGeom);
    
    end;
    
    function UpdateFeature(pFeature: IFeature; pGeom: IGeoMetry): boolean;
    begin
        result := False;
        if pGeom = nil then exit;
        pFeature._Set_Shape(pGeom);
        if pFeature.Store <> s_Ok then
        begin
            showmessage('空间数据有问题,保存失败');
        end;
        result := true;
    
    end;
    
    function PointIsGeom(pGeom: IGeoMetry; x, Y: double): boolean;
    var
        PPoint                              : IPoint;
    begin
    
        PPoint := CoPoint.create as IPoint;
        try
            PPoint.Set_X(x);
            PPoint.Set_Y(Y);
            result := not (ReturnDistance(PPoint, pGeom) > 0);
        finally
            PPoint := nil;
        end;
    end;
    
    function PointIsGeom(PPoint: IPoint; pGeom: IGeoMetry): boolean;
    begin
        result := not (ReturnDistance(PPoint, pGeom) > 0);
    end;
    
    //传入一个对象,创建线 ,返回相交部分
    
    procedure Createline(XMin, YMin, XMax, YMax: double; pGeom:
        IGeoMetry; var pGeomLine: IGeoMetry);
    var
        pLine                               : IPolyLine;
        PGLine                              : IGeoMetry;
        pPointSta, pPointEnd                : IPoint;
    begin
        try
            //新建线起点,设置其X,Y的值
            pPointSta := CoPoint.create as IPoint;
            pPointSta.Set_X(XMin);
            pPointSta.Set_Y(YMin);
    
            //新建线的终点,设置其X,Y的值
            pPointEnd := CoPoint.create as IPoint;
            pPointEnd.Set_X(XMax);
            pPointEnd.Set_Y(YMax);
    
            pLine := CoPolyLine.create as IPolyLine;
            pLine.Set_FromPoint(pPointSta);
            pLine.Set_ToPoint(pPointEnd);
            PGLine := pLine as IGeoMetry;
            pGeomLine := utGISPub.Intersect(pGeom, PGLine);
        finally
            pPointSta := nil;
            pPointEnd := nil;
            pLine := nil;
            PGLine := nil;
        end;
    end;
    //取得对象中心坐标
    
    procedure GetGeomCenterXY(pGeom: IGeoMetry; var cx, cy:
        double);
    var
        pEnvelope                           : IEnvelope;
        XMin, XMax, YMin, YMax              : double;
    begin
        if pGeom = nil then exit;
        pGeom.Get_Envelope(pEnvelope);
        pEnvelope.QueryCoords(XMin, YMin, XMax, YMax);
    
        cx := (XMax - XMin) / 2 + XMin;
        cy := (YMax - YMin) / 2 + YMin;
    end;
    //取得对象LabelPoint坐标
    
    procedure GetGeoMetryLabelPoint(pGeom: IGeoMetry; var cx, cy:
        double);
    var
        ShapeType                           : Toleenum;
        PPoint                              : IPoint;
        pArea                               : IArea;
        pEnvelope                           : IEnvelope;
    begin
    
        pGeom.Get_GeometryType(ShapeType);
        if ShapeType = esriGeometryPolygon then
        begin
            pArea := pGeom as IArea;
            pArea.Get_LabelPoint(PPoint);
            if PPoint = nil then            // //各别图形找不到LabelPoint
            begin
                pGeom.Get_Envelope(pEnvelope);
                if pEnvelope <> nil then
                    pEnvelope.CenterAt(PPoint);
            end;
            if PPoint = nil then            //各别图形找不到LabelPoint
            begin
                //ShowMessage('错误');
                cx := 0;
                cy := 0;
                exit;
            end;
    
            PPoint.QueryCoords(cx, cy);
    
        end
    
    end;
    //取得对象中心坐标
    
    procedure GetGeoMetryCenterXY(pGeom: IGeoMetry; var cx, cy:
        double);
    var
        PointColl                           : IPointCollection;
        x, Y                                : double;
        I, num                              : integer;
        PPoint                              : IPoint;
    begin
        PointColl := GetPointCollByGeoMetry(pGeom);
        try
            PointColl.Get_PointCount(num);
            cx := 0;
            cy := 0;
            for I := 0 to num - 1 do
            begin
                PointColl.Get_Point(I, PPoint);
                PPoint.QueryCoords(x, Y);
                cx := cx + x;
                cy := cy + Y;
    
            end;
            cx := cx / num;
            cy := cy / num;
    
        finally
            PointColl := nil;
        end;
    end;
    
    function StartEdit(FWorkspace: IWorkspace): boolean;
    var
        pWorkSpaceEdit                      : IWorkSpaceEdit;
        r                                   : HRESULT;
    
    begin
    
        pWorkSpaceEdit := FWorkspace as IWorkSpaceEdit;
    
        r := pWorkSpaceEdit.StartEditing(true);
        result := true;
        if r <> s_Ok then
        begin
            result := False;
        end;
        if result then
        begin
            r := pWorkSpaceEdit.StartEditOperation;
            if r <> s_Ok then
            begin
                result := False;
            end;
        end;
        if result then
        begin
            r := pWorkSpaceEdit.DisableUndoRedo; //可能加快所度  by yl 2006.2.6
            if r <> s_Ok then
            begin
                result := False;
            end;
        end;
        if not result then
        begin
            Info_showmessage('数据编辑锁定,无法开始编辑');
            StopEdit(FWorkspace);
        end;
    
    end;
    //结束编辑
    
    function StopEdit(FWorkspace: IWorkspace): boolean;
    var
        pWorkSpaceEdit                      : IWorkSpaceEdit;
        r                                   : HRESULT;
        B                                   : wordbool;
    begin
        result := False;
        pWorkSpaceEdit := FWorkspace as IWorkSpaceEdit;
        pWorkSpaceEdit.IsBeingEdited(B);
        if not B then
        begin
            showmessage('数据没有开始编辑---失败');
            exit;
        end;
    
        r := pWorkSpaceEdit.StopEditOperation;
        if r <> s_Ok then
        begin
            showmessage('不在编辑状态--失败');
            exit;
        end;
        r := pWorkSpaceEdit.StopEditing(true);
        if r <> s_Ok then
        begin
            showmessage('结束编辑---失败');
            exit;
        end;
    
        r := pWorkSpaceEdit.EnableUndoRedo; //可能加快所度  by yl 2006.2.6
        if r <> s_Ok then
        begin
            showmessage('设置可以UndoRedo---失败');
            exit;
        end;
    
        result := true;
    end;
    //简单拓扑一个对象
    
    procedure IsSimple(var pgeometry: IGeoMetry);
    var
        pTopo                               : ITopologicalOperator;
        PGeoMetryCollect                    : IGeoMetryCollection;
        ShapeType                           : Toleenum;
        OldGeoMetry                         : IGeoMetry;
    
    begin
        if IsEmpty(pgeometry) then exit;
        OldGeoMetry := CopyGeoMetry(pgeometry);  //拷贝一个原始的对象,因为 有些IsSimple后,原来不为空,处理后为空
        pgeometry.Get_GeometryType(ShapeType);
        if ShapeType = esriGeometryPoint then exit;
        if ShapeType = esriGeometryRing then
        begin
            pgeometry := CreatePolygonfromRing(pgeometry as IRing);
    
        end;
    
        PGeoMetryCollect := pgeometry as IGeoMetryCollection;
        try
            PGeoMetryCollect.GeometriesChanged;
    
            pTopo := pgeometry as ITopologicalOperator;
    
            pTopo.Simplify;
            if IsEmpty(pgeometry) then
            begin
                pgeometry := OldGeoMetry;
            end;
        except
        end;
    
    end;
    //获得图层的纪录的选择记录个数   by yl 2005.8.11
    
    function GetSelectRecordcount(FFeatureLayer: IFeatureLayer): integer;
    var
        PSelectionSet                       : ISelectionSet;
    begin
        result := 0;
        PSelectionSet := GetSelectionsetByFeatureLayer(FFeatureLayer);
        if PSelectionSet = nil then exit;
        PSelectionSet.Get_Count(result);
    end;
    
    function Move(pgeometry: IGeoMetry; x, Y: double): IGeoMetry;
    var
        pTrans                              : ITransform2D;
        pClone                              : IClone;
        NewClone                            : IClone;
        NewGeoMetry                         : IGeoMetry;
    begin
        pClone := pgeometry as IClone;
        pClone.Clone(NewClone);
        NewGeoMetry := NewClone as IGeoMetry;
    
        pTrans := NewGeoMetry as ITransform2D;
        pTrans.Move(x, Y);
        result := NewGeoMetry;
    end;
    
    function RingtoPolyLine(PRing: IRing): IPolyLine;
    var
        pGeoCollection                      : ISegmentCollection;
        pPointsColl                         : IPointCollection;
        I, num                              : integer;
        PSegment                            : ISegment;
        pgeometry                           : IGeoMetry;
        pGeoPolygon                         : IGeoMetryCollection;
        pTopo                               : ITopologicalOperator;
    
    begin
        pGeoCollection := PRing as ISegmentCollection;
        pPointsColl := CoPolyLine.create as IPointCollection;
        pGeoPolygon := pPointsColl as IGeoMetryCollection;
        pGeoCollection.Get_SegmentCount(num);
    
        for I := 0 to num - 1 do
        begin
            pGeoCollection.Get_Segment(I, PSegment);
            pgeometry := PSegment as IGeoMetry;
            pGeoPolygon.AddGeometries(1, pgeometry);
        end;
        pTopo := pPointsColl as ITopologicalOperator;
        pTopo.Simplify();
        result := pPointsColl as IPolyLine;
    end;
    
    function RingtoPolygon(PRing: IRing): IPolygon;
    var
        pGeoCollection                      : ISegmentCollection;
        pPointsColl                         : IPointCollection;
        I, num                              : integer;
        PSegment                            : ISegment;
        pgeometry                           : IGeoMetry;
        pGeoPolygon                         : IGeoMetryCollection;
        pTopo                               : ITopologicalOperator;
    
    begin
        pGeoCollection := PRing as ISegmentCollection;
        pPointsColl := CoPolygon.create as IPointCollection;
        pGeoPolygon := pPointsColl as IGeoMetryCollection;
        pGeoCollection.Get_SegmentCount(num);
    
        for I := 0 to num - 1 do
        begin
            pGeoCollection.Get_Segment(I, PSegment);
            pgeometry := PSegment as IGeoMetry;
            pGeoPolygon.AddGeometries(1, pgeometry);
        end;
        pTopo := pPointsColl as ITopologicalOperator;
        pTopo.Simplify();
        result := pPointsColl as IPolygon;
    end;
    
    function PathtoPolyLine(PPath: IPath): IPolyLine;
    var
        pGeoPolyLine                        : IGeoMetryCollection;
        PPolyLine                           : IPolyLine;
        pgeometry                           : IGeoMetry;
    
    begin
        PPolyLine := CoPolyLine.create as IPolyLine;
        pGeoPolyLine := PPolyLine as IGeoMetryCollection;
        pgeometry := PPath as IGeoMetry;
        pGeoPolyLine.AddGeometries(1, pgeometry);
        result := PPolyLine;
    end;
    
    function GeoMetrytoPolyLine(pgeometry: IGeoMetry): IPolyLine;
    var
        pGeoPolyLine                        : IGeoMetryCollection;
        PPolyLine                           : IPolyLine;
    
    begin
        PPolyLine := CoPolyLine.create as IPolyLine;
        pGeoPolyLine := PPolyLine as IGeoMetryCollection;
    
        pGeoPolyLine.AddGeometries(1, pgeometry);
        result := PPolyLine;
    end;
    //获得字段名列表
    
    function GetFieldNameList(pFeatureClass: IFeatureClass; List: TstringList):
        integer;
    var
        DelFieldList                        : TstringList; //应删除的字段
        pFields                             : IFields;
        I, num, idx                         : integer;
        FeatureType                         : Toleenum;
        PField                              : IField;
        FieldName                           : widestring;
    
    begin
    
        pFeatureClass.Get_Fields(pFields);
        pFeatureClass.Get_FeatureType(FeatureType);
        pFields.Get_FieldCount(num);
        DelFieldList := TstringList.create;
        try
            DelFieldList.Add('SHAPE_LENGTH');
            DelFieldList.Add('SHAPE_LENG');
            DelFieldList.Add('SHAPE_AREA');
            DelFieldList.Add('SHAPE');
            DelFieldList.Add('OBJECTID');
            if esriFTAnnotation = FeatureType then
            begin
                DelFieldList.Add('FEATUREID');
    
                //注记层的关键字段
                DelFieldList.Add('ELEMENT');
                DelFieldList.Add('ANNOTATIONCLASSID');
                DelFieldList.Add('ZORDER');
            end;
            for I := 0 to num - 1 do
            begin
                pFields.Get_Field(I, PField);
                PField.Get_Name(FieldName);
                FieldName := UpperCase(FieldName);
                idx := DelFieldList.IndexOf(FieldName);
                if idx = -1 then
                begin
                    List.Add(FieldName);
                end;
            end;
        finally
            DelFieldList.Free;
        end;
        result := List.count;
    
    end;
    //获得字段index列表
    
    function GetFieldNameIdxList(pFeatureClass: IFeatureClass; List:
        TstringList): integer;
    var
        DelFieldList                        : TstringList; //应删除的字段
        pFields                             : IFields;
        I, num, idx                         : integer;
        FeatureType                         : Toleenum;
        PField                              : IField;
        FieldName                           : widestring;
    
    begin
    
        pFeatureClass.Get_Fields(pFields);
        pFeatureClass.Get_FeatureType(FeatureType);
        pFields.Get_FieldCount(num);
        DelFieldList := TstringList.create;
        try
            DelFieldList.Add('SHAPE_LENGTH');
            DelFieldList.Add('SHAPE_LENG');
            DelFieldList.Add('SHAPE_AREA');
            DelFieldList.Add('SHAPE');
            DelFieldList.Add('OBJECTID');
            if esriFTAnnotation = FeatureType then
            begin
                DelFieldList.Add('FEATUREID');
    
                //注记层的关键字段
                DelFieldList.Add('ELEMENT');
                DelFieldList.Add('ANNOTATIONCLASSID');
                DelFieldList.Add('ZORDER');
            end;
            for I := 0 to num - 1 do
            begin
                pFields.Get_Field(I, PField);
                PField.Get_Name(FieldName);
                FieldName := UpperCase(FieldName);
                idx := DelFieldList.IndexOf(FieldName);
                if idx = -1 then
                begin
                    List.Add(IntToStr(I));
                end;
            end;
        finally
            DelFieldList.Free;
        end;
        result := List.count;
    
    end;
    //获得线的中点
    
    function GetLineCenterPoint(Polyline: IPolyLine): IPoint;
    var
        D                                   : double;
        B                                   : wordbool;
        pidx, sidx                          : integer;
    var
        PointColl                           : IPointCollection; //点集
        num                                 : integer;
    begin
        D := GetLineLength(Polyline);
        D := D / 2;
        Polyline.SplitAtDistance(D, False, False, B, pidx, sidx);
        if pidx > 0 then
        begin
            showmessage('错误');
            exit;
        end;
        PointColl := GetPointCollByGeoMetry(Polyline);
        PointColl.Get_PointCount(num);
        num := num div 2;
        PointColl.Get_Point(num, result);
    
    end;
    //按字段(目标码)排序
    
    function SortByMBBSM(pFeatureClass: IFeatureClass; FileName: string):
        IFeatureCursor;
    
    var
        pTableSort                          : ITableSort;
        PCursor                             : ICursor;
    begin
        pTableSort := CoTableSort.create as ITableSort;
        pTableSort.Set_Fields(FileName);
    
        pTableSort._Set_Table(pFeatureClass as ITable);
        pTableSort.Set_Ascending(FileName, true);
        pTableSort._Set_QueryFilter(nil);
    
        pTableSort.Sort(nil);
        pTableSort.Get_Rows(PCursor);
    
        result := PCursor as IFeatureCursor;
    
    end;
    
    //获得Workspace
    
    function GetWorkspace(FeatureLayer: IFeatureLayer): IWorkspace;
    var
        ObjClass                            : IFeatureClass;
    begin
        FeatureLayer.Get_FeatureClass(ObjClass);
        result := GetWorkspace(ObjClass);
    
    end;
    //获得Workspace
    
    function GetWorkspace(FeatureClass: IFeatureClass): IWorkspace;
    var
        pDataset                            : IDataSet;
    begin
    
        pDataset := FeatureClass as IDataSet;
        pDataset.Get_Workspace(result);
    end;
    
    //判断一个多边形是否IEnvelope
    
    function PolygonISEnvelope(PPolygon: IPolygon): boolean;
    var
        num                                 : integer;
        PointColl                           : IPointCollection;
        x1, y1, x2, y2                      : double;
    
        PPoint                              : IPoint;
        w, h, Area                          : double;
    begin
        result := False;
        num := GetPartNum(PPolygon);
        if num > 1 then exit;
        PointColl := GetPointCollByGeoMetry(PPolygon);
        try
            PointColl.Get_PointCount(num);
            if (num < 3) or (num > 5) then exit;
            PointColl.Get_Point(0, PPoint);
            PPoint.QueryCoords(x1, y1);
    
            PointColl.Get_Point(2, PPoint);
            PPoint.QueryCoords(x2, y2);
            w := abs(x2 - x1);
            h := abs(y2 - y1);
    
            Area := GetArea(PPolygon);
    
            if abs(w * h - abs(Area)) / (w * h) < 0.01 then
                result := true;
        finally
            PointColl := nil;
        end;
    
    end;
    //获得多边形的最小x,y
    
    function GetGeoMetryMinXy(pgeometry: IGeoMetry; var Minx, Miny: double):
        boolean;
    var
        I, num                              : integer;
        PointColl                           : IPointCollection;
        x, Y                                : double;
        PPoint                              : IPoint;
    
    begin
        result := False;
    
        PointColl := GetPointCollByGeoMetry(pgeometry);
        try
            PointColl.Get_PointCount(num);
            if num = 0 then
                exit;
    
            for I := 0 to num - 1 do
            begin
                PointColl.Get_Point(I, PPoint);
                PPoint.QueryCoords(x, Y);
                if I = 0 then
                begin
                    Minx := x;
                    Miny := Y;
                end
                else
                begin
                    if x < Minx then
                    begin
                        Minx := x;
                    end;
                    if Y < Miny then
                    begin
                        Miny := Y;
                    end;
                end;
    
            end;
            result := true;
        finally
            PointColl := nil;
        end;
    
    end;
    //执行sql返回值
    
    function ExecSQLResult(FWorkspace: IWorkspace; Sqlstr: string): olevariant;
    
    var
        TableName                           : string;
        SubFields                           : string;
        WhereClause                         : string;
        P                                   : integer;
        pFeatureWorkspace                   : IFeatureWorkspace;
        pQueryDef                           : IQueryDef;
        PCursor                             : ICursor;
        pRow                                : Irow;
    
    begin
        P := upperpos('select ', Sqlstr);
        result := NULL;
        if P = 0 then exit;
        Delete(Sqlstr, P, 7);
        P := upperpos(' from ', Sqlstr);
        if P = 0 then exit;
    
        SubFields := copy(Sqlstr, 1, P - 1);
        Delete(Sqlstr, 1, P + 5);
        P := upperpos(' where ', Sqlstr);
        if P = 0 then
        begin
            TableName := Sqlstr;
            WhereClause := '';
        end
        else
        begin
    
            TableName := copy(Sqlstr, 1, P - 1);
            Delete(Sqlstr, 1, P + 6);
            WhereClause := Sqlstr;
    
        end;
        pFeatureWorkspace := FWorkspace as IFeatureWorkspace;
        pFeatureWorkspace.CreateQueryDef(pQueryDef);
        pQueryDef.Set_Tables(TableName);
        pQueryDef.Set_SubFields(SubFields);
        pQueryDef.Set_WhereClause(WhereClause);
        pQueryDef.Evaluate(PCursor);
        if PCursor = nil then exit;
        PCursor.NextRow(pRow);
        if pRow = nil then exit;
        pRow.Get_Value(0, result);
    
    end;
    //执行sql返回值
    
    function ExecSQLResult(FeatureLayer: IFeatureLayer;
        Sqlstr, FieldName: string): olevariant; overload;
    var
        pQueryFilter                        : IQueryFilter;
        PFeatureCursor                      : IFeatureCursor;
        pFeature                            : IFeature;
    begin
        pQueryFilter := CoQueryFilter.create as IQueryFilter;
        try
            pQueryFilter.Set_WhereClause(Sqlstr);
            FeatureLayer.Search(pQueryFilter, False, PFeatureCursor);
            PFeatureCursor.NextFeature(pFeature);
            result := '';
            if pFeature = nil then exit;
            result := getfieldvalue(pFeature, FieldName);
    
        finally
            pQueryFilter := nil;
        end;
    end;
    
    function StartEdit(FeatureLayer: IFeatureLayer): boolean;
    var
        Pworkspace                          : IWorkspace;
        pDataset                            : IDataSet;
        ObjClass                            : IFeatureClass;
    begin
        FeatureLayer.Get_FeatureClass(ObjClass);
        pDataset := ObjClass as IDataSet;
        pDataset.Get_Workspace(Pworkspace);
        result := StartEdit(Pworkspace);
    
    end;
    //结束编辑
    
    function StopEdit(FeatureLayer: IFeatureLayer): boolean;
    var
        Pworkspace                          : IWorkspace;
        pDataset                            : IDataSet;
        ObjClass                            : IFeatureClass;
    begin
        FeatureLayer.Get_FeatureClass(ObjClass);
        pDataset := ObjClass as IDataSet;
        pDataset.Get_Workspace(Pworkspace);
        result := StopEdit(Pworkspace);
    
    end;
    //获得由中文字段的英文 ,字段别名与字段名相互转换
    //ISAlias为True,字段名为中文,返回英文
    
    function GetFieldNameByAlias(pFeatClass: IFeatureClass; FieldName:
        widestring; ISAlias: boolean = False): widestring; overload;
    
    var
        Fields                              : IFields;
        Field                               : IField;
        idx                                 : integer;
    begin
        pFeatClass.Get_Fields(Fields);
        result := '';
        if ISAlias then
            Fields.FindFieldByAliasName(FieldName, idx)
        else
            Fields.FindField(FieldName, idx);
        if idx > -1 then
        begin
            Fields.Get_Field(idx, Field);
            if ISAlias then
                Field.Get_Name(result)
            else
                Field.Get_AliasName(result);
        end;
    end;
    
    //获得由中文字段的英文 ,字段别名与字段名相互转换
    //ISAlias为True,字段名为中文,返回英文
    
    function GetFieldNameByAlias(FeatureLayer: IFeatureLayer; FieldName:
        widestring; ISAlias: boolean = False): string; overload;
    var
        pFcc                                : IFeatureClass;
    
    begin
        FeatureLayer.Get_FeatureClass(pFcc);
        result := GetFieldNameByAlias(pFcc, FieldName, ISAlias);
    end;
    //根据图层名获得图层,支持影像
    
    function GetMapControlLayer(LayerName: string; MapControl: IMapControl2):
        ILayer;
    var
        I, num                              : integer;
        PLayer                              : ILayer;
        Layer_Name                          : widestring;
    begin
        num := MapControl.LayerCount;
        result := nil;
        for I := 0 to num - 1 do
        begin
    
            PLayer := MapControl.Layer[I];
    
            PLayer.Get_Name(Layer_Name);
            if UpperCase(Layer_Name) = UpperCase(LayerName) then
            begin
                result := PLayer;
                exit;
            end;
    
        end;
    
    end;
    //判断一个GeoMetry是否为矩形
    
    function GeoMetryIsEnvelope(pgeometry: IGeoMetry): boolean;
    var
        ShapeType                           : Toleenum;
    
    begin
        pgeometry.Get_GeometryType(ShapeType);
        result := ShapeType = esriGeometryEnvelope;
        if result then exit;
        result := ShapeType = esriGeometryPolygon;
        if not result then exit;
        result := PolygonISEnvelope(pgeometry as IPolygon);
    
    end;
    
    function GetSelectionsetByFeatureLayer(pFeatureLayer: ILayer):
        ISelectionSet;
    var
        pFeatureSelection                   : IFeatureSelection;
        pObj                                : IUnKnown;
    begin
        result := nil;
        if pFeatureLayer.QueryInterface(IID_IFeatureLayer, pObj) <> s_Ok then
            exit;
        pFeatureSelection := LayerToFeatureSelection(pFeatureLayer);
        if pFeatureSelection = nil then exit;
        pFeatureSelection.Get_SelectionSet(result);
    end;
    
    function GetFeatureCursorByFeatureLayer(pFeatureLayer: ILayer): IFeatureCursor;
    var
        PSelectionSet                       : ISelectionSet;
        PCursor                             : ICursor;
    begin
        PSelectionSet := GetSelectionsetByFeatureLayer(pFeatureLayer);
        PSelectionSet.Search(nil, False, PCursor);
        result := PCursor as IFeatureCursor;
    
    end;
    
    //重新修改 by yl 2007.3.13
    
    function GetIntersectsNotTouches(FFeatureLayer: IFeatureLayer;
        pgeometry: IGeoMetry; MaxD: double): IFeatureCursor;  //相交不接触的 ,数据太多不行
    
    var
        PFeatureCursor                      : IFeatureCursor;
        GeoMetryType                        : Toleenum;
        BufferShape                         : IGeoMetry;
    
        //wname                               : widestring;
    
        //获得线相交
        procedure GetLineTouches();
        var
            pFeature                        : IFeature;
            Shape                           : IGeoMetry;
            function IsExists(FID: integer): boolean;
            var
                D                           : double;
            begin
    
                D := GetLineLength(Shape as IPolyLine);
                result := D < MaxD;
    
            end;
        var
            FID                             : integer;
            str                             : string;
        begin
            PFeatureCursor.NextFeature(pFeature);
            str := '';
            while pFeature <> nil do
            begin
    
                pFeature.Get_ShapeCopy(Shape);
                Shape := Intersect(pgeometry, Shape);
                pFeature.Get_OID(FID);
                if IsExists(FID) then       //相交太短排除
                begin
                    str := Format('%s%d,', [str, FID]);
                end;
                PFeatureCursor.NextFeature(pFeature);
            end;
            if str = '' then
            begin
                //PFeatureCursor循环到了尾部,只有重新执行一次才可以到开头
                PFeatureCursor := Searchbyshape(FFeatureLayer, pgeometry,
                    esriSpatialRelIntersects);
            end
            else
            begin
                str := copy(str, 1, length(str) - 1);
    
                PFeatureCursor := Searchbyshape(FFeatureLayer, pgeometry,
                    'not objectid in (' + str + ')',
                    esriSpatialRelIntersects);
            end;
        end;
    
    begin
        pgeometry.Get_GeometryType(GeoMetryType);
        //ShowMessage(Format('%d', [GeometryType]));
        if GeoMetryType <> esriGeometryPolygon then //面不用建缓冲,by yl 2007.1.5
            BufferShape := pgeometry
        else
            BufferShape := buffer(pgeometry, -0.1); //小一点
    
        if GeoMetryType <> esriGeometryPolygon then //点相交
        begin
            PFeatureCursor := Searchbyshape(FFeatureLayer, BufferShape,
                esriSpatialRelIntersects);
    
            if (GeoMetryType = esriGeometryPolyline) then //线是交叉
            begin
                GetLineTouches();
            end;
    
        end
        else                                //面相交
        begin
            PFeatureCursor := Searchbyshape(FFeatureLayer, BufferShape,
                esriSpatialRelIntersects);
    
        end;
        result := PFeatureCursor;
    end;
    //获得一个PFeaturCursor个数据
    
    //执行sql
    
    function ExecuteSQL(Pworkspace: IWorkspace; Sqlstr: string;
        HintUser: boolean = true): string;
    
    begin
        result := '';
        if Pworkspace.ExecuteSQL(Sqlstr) <> s_Ok then
            if HintUser then
                raise exception.create(Sqlstr + '无法执行')
            else
                result := Sqlstr + '无法执行';
    end;
    //中心不变,按新的高,宽设置
    
    function SetNewEnvelope(pEnvelope: IEnvelope; w, h: double): IEnvelope;
    var
        x1, y1, x2, y2                      : double;
        cx, cy                              : double;
    begin
        pEnvelope.QueryCoords(x1, y1, x2, y2);
        cx := (x1 + x2) / 2;
        cy := (y1 + y2) / 2;
        x1 := cx - w / 2;
        x2 := cx + w / 2;
        y1 := cy - h / 2;
        y2 := cy + h / 2;
        pEnvelope.PutCoords(x1, y1, x2, y2);
        result := pEnvelope;
    
    end;
    //按照窗口设置新的地图entent;
    //winW是窗户的宽度, winW是窗户的高度
    
    function getNewEnvelopeByWindows(pEnvelope: IEnvelope; WinW, WinH: integer):
        IEnvelope;
    var
        w                                   : double;
        h                                   : double;
    begin
        pEnvelope.Get_Width(w);
        pEnvelope.Get_Height(h);
    
        if (w / h) > (WinW / WinH) then     //调整高度
        begin
            h := w * WinH / WinW;
    
        end
        else
        begin
    
            w := h * WinW / WinH;
    
        end;
        result := SetNewEnvelope(pEnvelope, w, h);
    end;
    //获得字段列表,中英文都要
    
    function GetFieldList(FeatureLayer: IFeatureLayer;
        FieldList: TstringList): integer;
    var
        pFcc                                : IFeatureClass;
        Fields                              : IFields;
        Field                               : IField;
        I, num                              : integer;
        EFieldName, CFieldName              : widestring;
    begin
        FieldList.Clear;
    
        FeatureLayer.Get_FeatureClass(pFcc);
        pFcc.Get_Fields(Fields);
        Fields.Get_FieldCount(num);
        for I := 0 to num - 1 do
        begin
            Fields.Get_Field(I, Field);
            //中文
            Field.Get_AliasName(CFieldName);
    
            Field.Get_Name(EFieldName);
            if UpperCase(EFieldName) <> 'SHAPE' then
            begin
    
                FieldList.Add(Format('[%s]%s', [EFieldName, CFieldName]));
            end;
        end;
        result := FieldList.count;
    end;
    
    //获得表字段集合,ISNum:Boolean=True表示所有字段,为false表示数字字段不考虑
    
    function GetFieldSt(FeatureLayer: IFeatureLayer;
        FieldList: TstringList; ISNum: boolean = true;
        IsChinese: boolean = true): integer;
    var
        pFcc                                : IFeatureClass;
        Fields                              : IFields;
        Field                               : IField;
        I, num                              : integer;
        FieldName                           : widestring;
        FType                               : Toleenum;
        B                                   : boolean;
    begin
        FieldList.Clear;
    
        FeatureLayer.Get_FeatureClass(pFcc);
        pFcc.Get_Fields(Fields);
        Fields.Get_FieldCount(num);
        for I := 0 to num - 1 do
        begin
            Fields.Get_Field(I, Field);
            if IsChinese then               //中文
                Field.Get_AliasName(FieldName)
            else
                Field.Get_Name(FieldName);
            if UpperCase(FieldName) <> 'SHAPE' then
            begin
                B := ISNum;
                if not ISNum then
                begin
                    Field.Get_type_(FType);
                    B := (FType = 4) or (FType = 5);
    
                end;
    
                if B then
                    FieldList.Add(FieldName);
            end;
        end;
        result := FieldList.count;
    end;
    //考虑空
    
    procedure SetvalueBySpace(pFeature: IFeature; idx: integer; value: string;
        Space: boolean = False);
    var
        B                                   : boolean;
    begin
        B := true;
        if Space then
        begin
            if (value = '') or (value = '0') then
                B := False;
        end;
    
        if B then
    
            pFeature.set_Value(idx, value);
    end;
    //获得数据类型
    
    function GetDataType(pFeatureLayer: IFeatureLayer): integer;
    var
        Text                                : widestring;
    begin
        pFeatureLayer.Get_DataSourceType(Text);
        Text := UpperCase(Text);
        if pos(UpperCase('SDE Feature Class'), Text) > 0 then //SDE文件
        begin
    
            result := 1;
        end
        else if pos('SHAPE', Text) > 0 then
        begin
            result := 2;
        end
        else if pos(UpperCase('Personal '), Text) > 0 then
        begin
            result := 3;
        end
        else
        begin
            //DataType := 4;
            raise exception.create('数据格式不支持');
        end;
    
    end;
    //获得文件路径和名称
    
    procedure GetPathFileName(pFeatureLayer: IFeatureLayer; var path, FileName:
        widestring);
    var
        pFeatureClass                       : IFeatureClass;
    
    begin
    
        pFeatureLayer.Get_FeatureClass(pFeatureClass);
        GetPathFileName(pFeatureClass, path, FileName);
    
    end;
    //获得文件路径和名称
    
    procedure GetPathFileName(pFeatureClass: IFeatureClass; var path, FileName:
        widestring); overload;
    var
    
        Pworkspace                          : IWorkspace;
        pDataset                            : IDataSet;
    begin
        //DataType := GetDataType(pFeatureLayer);
        Pworkspace := GetWorkspace(pFeatureClass);
        Pworkspace.Get_PathName(path);
        pDataset := pFeatureClass as IDataSet;
        pDataset.Get_BrowseName(FileName);
    
    end;
    //更新字段值
    
    procedure updateFieldValue(pFeatureLayer: IFeatureLayer;
        FieldName, value: string);
    var
        PFeatureCursor                      : IFeatureCursor;
        pFeature                            : IFeature;
        idx                                 : integer;
    begin
        idx := GetFieldPos(pFeatureLayer, FieldName);
        if idx = -1 then exit;
        pFeatureLayer.Search(nil, False, PFeatureCursor);
        PFeatureCursor.NextFeature(pFeature);
        while pFeature <> nil do
        begin
            pFeature.set_Value(idx, value);
            pFeature.Store;
            PFeatureCursor.NextFeature(pFeature);
        end;
    end;
    //判断一个FeatureClass的类型,是否为注记
    
    function FeatureClassIsAnnotation(pFeatureClass: IFeatureClass): boolean;
    var
        pType2                              : Toleenum;
    begin
        pFeatureClass.Get_FeatureType(pType2);
        result := pType2 = esriFTAnnotation;
    
    end;
    //修改FeatureClass的投影
    
    function AlterFeatureClassSpatialReference(pFeatureClass: IFeatureClass;
        PSpatialReference: ISpatialReference): boolean;
    var
        PGeoDataset                         : IGeoDataset;
        pGeoDatasetEdit                     : IGeoDatasetSchemaEdit;
        CanAlter                            : wordbool;
    
    begin
        PGeoDataset := pFeatureClass as IGeoDataset;
        pGeoDatasetEdit := PGeoDataset as IGeoDatasetSchemaEdit;
        pGeoDatasetEdit.Get_CanAlterSpatialReference(CanAlter);
        result := CanAlter;
        if CanAlter then
        begin
            pGeoDatasetEdit.AlterSpatialReference(PSpatialReference);
        end;
    
    end;
    //由于有些城镇的图太小,修改的原来的缓冲取函数 by yl 2007.7.20
    
    function GetNewBuffer(pgeometry: IGeoMetry; Dis: double): IGeoMetry;
    var
        NewGeoMetry                         : IGeoMetry;
    begin
        NewGeoMetry := buffer(pgeometry, Dis);
        if GetArea(NewGeoMetry as IPolygon) < 50 then
        begin
            NewGeoMetry := pgeometry;
        end;
        result := NewGeoMetry;
    end;
    
    //删除shp文件
    
    function deleteshpFileName(shpFileName: string): boolean;
    var
        searchrec                           : TSearchRec;
        res                                 : Word;
        Directory                           : string;
        onlyshpFileName                     : string;
    begin
        result := False;
        Directory := ExtractFilePath(shpFileName);
        onlyshpFileName := UpperCase(Getonlyfilename(shpFileName));
        if Directory[length(Directory)] <> '\' then
            Directory := Directory + '\';
        res := FindFirst(Directory + '*.*', faAnyFile, searchrec);
        while res = 0 do
        begin
            if searchrec.Name[1] <> '.' then
            begin
    
                if UpperCase(Getonlyfilename(searchrec.Name)) = onlyshpFileName then
                begin
                    if not DeleteFile(Directory + searchrec.Name) then
                        exit;
                end;
    
            end;
            res := FindNext(searchrec);
            Application.ProcessMessages;
        end;
        FindClose(searchrec);
        result := true;
    end;
    //判断是否交叉
    //1为交叉,2,前者包括后者,3,后者包含前者,0为不相交
    
    function iscross(Envelope1, Envelope2: IEnvelope): integer;
    const
        MinValue                            = 0.00001;
    var
        x1, y1, x2, y2                      : double;
        xx1, yy1, xx2, yy2                  : double;
        Minx, Miny, MaxX, MaxY              : double;
    begin
        result := 0;
        if Envelope1 = nil then
        begin
            exit;
        end;
        if Envelope2 = nil then
        begin
            exit;
        end;
        Envelope1.QueryCoords(x1, y1, x2, y2);
        Envelope2.QueryCoords(xx1, yy1, xx2, yy2);
    
        Minx := max(x1, xx1);
        Miny := max(y1, yy1);
        MaxX := Min(x2, xx2);
        MaxY := Min(y2, yy2);
        if (Minx > MaxX) or (Miny > MaxY) then
        begin
            result := 0;
    
        end
        else if (abs(x1 - Minx) < MinValue) and (abs(y1 - Miny) < MinValue) and
            (abs(x2 - MaxX) < MinValue) and (abs(y2 - MaxY) < MinValue) then
        begin
            result := 2;
    
        end
        else if (abs(xx1 - Minx) < MinValue) and (abs(yy1 - Miny) < MinValue)
            and
            (abs(xx2 - MaxX) < MinValue) and (abs(yy2 - MaxY) < MinValue) then
        begin
            result := 3;
    
        end
        else
        begin
            result := 1;
        end;
    end;
    
    function ConvertFeatureClassToShapesFile(pFeatureClass: IFeatureClass;
        pFilePath, pFileName: string): boolean;
    var
        pInDataSet, pOutDataSet             : IDataSet;
        pInWorkSpace                        : IWorkspace;
        pInFeatureClassName, pOutFeatureClassName: IFeatureClassName;
        pOutWorkspaceFactory                : IWorkspaceFactory;
        pOutWorkerspace                     : IFeatureWorkspace;
        pOutWorkspaceName                   : IWorkspaceName;
        pOutDataSetName                     : IDatasetName;
        pFieldChecker                       : IFieldChecker;
        pEnumFieldError                     : IEnumFieldError;
        pOutFields                          : IFields;
        pFeatureDataConvert                 : IFeatureDataConverter;
        pQueryFilter                        : IQueryFilter;
        pName, poutname                     : IName;
        pOutWorkspace                       : IWorkspace;
        pFields                             : IFields;
        pEnumInvalidObject                  : IEnumInvalidObject;
    begin
        result := False;
        if pFeatureClass = nil then
        begin
            exit;
        end;
        //得到输入
        pInDataSet := pFeatureClass as IDataSet;
        pInDataSet.Get_Workspace(pInWorkSpace);
    
        pInDataSet.Get_FullName(pName);
    
        pInFeatureClassName := pName as IFeatureClassName;
    
        //定义输出
        pOutWorkspaceFactory := CoShapefileWorkspaceFactory.create as
            IWorkspaceFactory;
        pOutWorkspaceFactory.OpenFromFile(pFilePath, 0, pOutWorkspace);
        pOutWorkerspace := pOutWorkspace as IFeatureWorkspace;
        pOutDataSet := pOutWorkerspace as IDataSet;
        pOutDataSet.Get_FullName(poutname);
    
        pOutWorkspaceName := poutname as IWorkspaceName;
        pOutFeatureClassName := coFeatureClassName.create as IFeatureClassName;
    
        pOutDataSetName := pOutFeatureClassName as IDatasetName;
        pOutDataSetName.Set_Name(pFileName);
        pOutDataSetName._Set_WorkspaceName(pOutWorkspaceName);
    
        //检查字段
        pFieldChecker := coFieldChecker.create as IFieldChecker;
        pFieldChecker.Set_InputWorkspace(pInWorkSpace);
    
        pFieldChecker._Set_ValidateWorkspace(pOutWorkerspace as IWorkspace);
        pFeatureClass.Get_Fields(pFields);
        pFieldChecker.Validate(pFields, pEnumFieldError, pOutFields);
    
        //要素筛选
        pQueryFilter := CoQueryFilter.create as IQueryFilter;
        pQueryFilter.Set_WhereClause('');
    
        //转换输出
        pFeatureDataConvert := coFeatureDataConverter.create as
            IFeatureDataConverter;
        result := pFeatureDataConvert.ConvertFeatureClass(pInFeatureClassName,
            pQueryFilter,
            nil, pOutFeatureClassName, nil, pOutFields, '', 100, 0,
            pEnumInvalidObject) = s_Ok;
    end;
    //转到shp
    
    function ConvertFeatureClassToShapesFile(pFeatureClass: IFeatureClass;
        pOutWorkspace: IWorkspace): boolean; overload;
    
    var
        pInDataSet, pOutDataSet             : IDataSet;
        pInWorkSpace                        : IWorkspace;
        pInFeatureClassName, pOutFeatureClassName: IFeatureClassName;
        pOutWorkerspace                     : IFeatureWorkspace;
        pOutWorkspaceName                   : IWorkspaceName;
        pOutDataSetName                     : IDatasetName;
        pFieldChecker                       : IFieldChecker;
        pEnumFieldError                     : IEnumFieldError;
        pOutFields                          : IFields;
        pFeatureDataConvert                 : IFeatureDataConverter;
        pQueryFilter                        : IQueryFilter;
        pName, poutname                     : IName;
    
        pFields                             : IFields;
        pEnumInvalidObject                  : IEnumInvalidObject;
        pFileName                           : widestring;
    begin
        result := False;
        if pFeatureClass = nil then
        begin
            exit;
        end;
        //得到输入
        pInDataSet := pFeatureClass as IDataSet;
        pInDataSet.Get_Workspace(pInWorkSpace);
    
        pInDataSet.Get_FullName(pName);
    
        pInFeatureClassName := pName as IFeatureClassName;
    
        //定义输出
        pOutWorkerspace := pOutWorkspace as IFeatureWorkspace;
        pOutDataSet := pOutWorkerspace as IDataSet;
        pOutDataSet.Get_FullName(poutname);
    
        pOutWorkspaceName := poutname as IWorkspaceName;
        pOutFeatureClassName := coFeatureClassName.create as IFeatureClassName;
        pFeatureClass.Get_AliasName(pFileName);
        pOutDataSetName := pOutFeatureClassName as IDatasetName;
        pOutDataSetName.Set_Name(pFileName);
        pOutDataSetName._Set_WorkspaceName(pOutWorkspaceName);
    
        //检查字段
        pFieldChecker := coFieldChecker.create as IFieldChecker;
        pFieldChecker.Set_InputWorkspace(pInWorkSpace);
    
        pFieldChecker._Set_ValidateWorkspace(pOutWorkerspace as IWorkspace);
        pFeatureClass.Get_Fields(pFields);
        pFieldChecker.Validate(pFields, pEnumFieldError, pOutFields);
    
        //要素筛选
        pQueryFilter := CoQueryFilter.create as IQueryFilter;
        pQueryFilter.Set_WhereClause('');
    
        //转换输出
        pFeatureDataConvert := coFeatureDataConverter.create as
            IFeatureDataConverter;
        result := pFeatureDataConvert.ConvertFeatureClass(pInFeatureClassName,
            pQueryFilter,
            nil, pOutFeatureClassName, nil, pOutFields, '', 100, 0,
            pEnumInvalidObject) = s_Ok;
    end;
    //根据图层名获得图层,支持影像
    
    function GetLayer(pMap: Imap; LayerName: string): ILayer;
    var
        I, num                              : integer;
        PLayer                              : ILayer;
        Layer_Name                          : widestring;
    begin
        pMap.Get_LayerCount(num);
        result := nil;
        for I := 0 to num - 1 do
        begin
    
            pMap.Get_Layer(I, PLayer);
    
            PLayer.Get_Name(Layer_Name);
            if UpperCase(Layer_Name) = UpperCase(LayerName) then
            begin
    
                result := PLayer;
                exit;
            end;
    
        end;
    
    end;
    //把标注转换注记
    
    procedure ConvertLabelsToGDBAnnotationSingleLayer(pMap: Imap;
        pFeatureLayer: IFeatureLayer; pannworkspace: IWorkspace;
        AnnLayername: string; featureLinked: bool);
    var
        pConvertLabelsToAnnotation          : IConvertLabelsToAnnotation;
        pTrackCancel                        : ITrackCancel;
        pGeoFeatureLayer                    : IGeoFeatureLayer;
        pFeatureClass                       : IFeatureClass;
        pFeatureWorkspace                   : IFeatureWorkspace;
    begin
    
        pConvertLabelsToAnnotation := CoConvertLabelsToAnnotation.create as
            IConvertLabelsToAnnotation;
        pTrackCancel := CoCancelTracker.create as ITrackCancel;
        pConvertLabelsToAnnotation.Initialize(pMap, esriDatabaseAnnotation,
            esriAllFeatures, true, pTrackCancel, nil);
    
        pGeoFeatureLayer := pFeatureLayer as IGeoFeatureLayer;
        if (pGeoFeatureLayer <> nil) then
        begin
            pGeoFeatureLayer.Get_FeatureClass(pFeatureClass);
            pFeatureWorkspace := pannworkspace as IFeatureWorkspace;
            pConvertLabelsToAnnotation.AddFeatureLayer(pGeoFeatureLayer,
                AnnLayername, pFeatureWorkspace,
                nil, featureLinked, False, False, true,
                true, '');
            pConvertLabelsToAnnotation.ConvertLabels();
        end;
    
    end;
    
    end.
  • 相关阅读:
    thinkphp---部署在IIS8.0服务器上
    程序员撩妹小技巧
    php---进行签名验证
    php---进行RSA进行非对称加密
    python---使用md5加密
    (原创)大数据时代:基于微软案例数据库数据挖掘知识点总结(Microsoft 顺序分析和聚类分析算法)
    (原创)大数据时代:基于微软案例数据库数据挖掘知识点总结(Microsoft 关联规则分析算法)
    (原创)大数据时代:基于微软案例数据库数据挖掘知识点总结(Microsoft 时序算法——结果预算+下期彩票预测篇)
    (原创)大数据时代:基于微软案例数据库数据挖掘知识点总结(Microsoft 时序算法)
    (原创)大数据时代:基于微软案例数据库数据挖掘知识点总结(结果预测篇)
  • 原文地址:https://www.cnblogs.com/gisoracle/p/16014598.html
Copyright © 2020-2023  润新知