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.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
2020-03-16 ArcGIS Pro二次开发-插入文本,图例和指北针
2020-03-16 ArcGIS Pro二次开发地图MapSeries序列设置
2020-03-16 ArcGIS Pro二次开发-获得Objectid字段
2012-03-16 一些名言