• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

gisoracle

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

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.

 

posted on 2022-03-16 21:29  gisai  阅读(85)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3