由delphi语言写的mapinfo算法

作者:小范  引用地址http://blog.csdn.net/guyehanxinlei/archive/2007/03/14/1528777.aspx

unit MapFunctionEx;

interface

uses
  SysUtils, Windows, ADODB, Classes, Types, Contnrs, MapFunction, ComCtrls,
  StrUtils, KD_MAPBASIC;

type
  TKDPoint = class(TObject)
  Public
    X: double;
    Y: double;
    constructor Create(); Overload;
    constructor Create(X: double; Y: double); Overload;
    constructor Create(pt: TKDPoint); Overload;
    function IsEqual(pt: TKDPoint): boolean; Overload;
    function IsEqual(pt: TKDPoint; tolerace : double): boolean; Overload;
  end;

  TKDSegmentPoint = class(TObject)
  Public
    X: double;
    Y: double;
    SegmentInedex: integer;
    constructor Create(); Overload;
    constructor Create(pt: TKDPoint); Overload;
    constructor Create(gpt: TKDSegmentPoint); Overload;
    function Copy(): TKDSegmentPoint;
    function ToPoint(): TKDPoint;
  end;

type
  TKDTrackTable = class(TObject)
  Private
    m_TrackTableName: string;
    m_FilePath: string;
    m_WinID: integer;
  Public
    constructor Create(WinID: integer);
    property TrackTableName: string Read m_TrackTableName;
    procedure CreateTrack(structTable: string);
    procedure ClearTrack();
    procedure DropTrack();
    procedure PackTrack();
    function TrackLine(): string;
    function TrackPolygon(): string;
    function TrackPoint(): string;
  end;

type
  /// 图形数据类型
  TGrapiDataType = set of (gdtPoint, gdtPolygon, gdtLine, gdtText);

type
  TKDMapinfoProxy = class(TObject)
  Private
    MapInfo: Variant;

    procedure GetOrderIntersectNodes(tagetMapinfoGeo: string; mapinfoGeo: string; intersectNodes: TObjectList);
    procedure QueryNodesOfGeomety(mapinfoGeo: string; partIndex: integer; nodeList: TObjectList); Overload;

  Public
    constructor Create(oleMapinfo: Variant);
    procedure AddTable(tableName: string; mapId: integer);
    function TableExists(tableName: string): boolean;
    function CreateMap(tableName: string; mapName: string; hwnd: integer): integer;
    procedure OpenTable(tablePath: string; tableAlias: string);
    procedure CloneTableStructure(sourceTabla: string; destTablePath: string);
    procedure SaveTableToFile(sourceTabla: string; destTablePath: string; whereClause: string);
    procedure DropTable(tabName: string);
    procedure DeleteTable(tableName: string);
    function QueryTableRecordCount(tableName: string): integer;
    function QueryTableColumnCount(tableName: string): integer;
    function QueryTableColumnName(tableName: string; colIndex: integer): string;
    function QueryTableColumnIndex(tableName: string; colName: string): integer;
    function QueryTableColumnType(tableName: string; colName: string): integer;
    procedure CloseTable(tableName: string);
    procedure ClearTable(tableName: string);
    procedure SaveAllTable();
    function TableIsSaved(slName: string): boolean;
    procedure PackTable(tabName: string);
    procedure SplitLineTable(tableName: string; splitTableName: string);
    procedure RepeatPoints(tagetTable: string; repeatTable: string);
    procedure SplitLineTableEx(tableName: string; splitTableName: string);
    procedure SplitLineByRegion(lineTableName: string; regionTableName: string);
    function QueryNodeOfGeomety(mapinfoGeo: string; partIndex: integer; nodeIndex: integer): TKDPoint;
    function QueryPartsOfGeomety(mapinfoGeo: string): integer;
    function QueryNodesOfGeomety(mapinfoGeo: string; partIndex: integer): TObjectList; Overload;
    function QueryNodeCount(mapinfoGeo: string; partIndex: integer): integer; Overload;
    function QueryNodeCount(mapinfoGeo: string): integer; Overload;
    procedure QueryNodePoint(mapinfoGeo: string; Polygon_num, node_num: integer; var X, Y: double);
    function ObjectCvtPolygon(bm1, bm2: string): string;
    procedure ObjectCvtPolygonEx(sourceTable, destTable: string);
    function ObjectCvtLine(bm1, bm2: string; ProBar: TProgressBar = nil): string;
    function GetObjType(objName: string): integer;
    function CheckTableObject(TableType: TGrapiDataType; bm: string): integer;
    procedure SaveTable(tableName: string);
    procedure CommitTable(tableName: string);
    procedure RollbackTable(tableName: string);
    procedure CopyTableData(srcTableName: string; destTableName: string; whereClause: string);
    procedure CopyTableDataEx(srcTableName: string; destTableName: string; whereClause: string; fieldList: string);
    procedure CopyTableGhraphData(srcTableName: string; destTableName: string; whereClause: string);
    procedure EraseObjects(srcTableName: string; eraseTableName: string);
    function EmnuTableColumn(tableName: string; withName: boolean = true): string;
    function QuerySourceTableName(selectionName: string): string;
    function QuerySelctionCount(): integer;
    function QuerySelctionTableName(): string;
    procedure UnitePolygon(strYTableName: string; strMBTableName: string; CurWinID: integer);
    procedure SetProgressBar(bOn: boolean = true);
    procedure SetTableEnable(tableName: string; bUserBrowse: boolean = true; bUserMap: boolean = true; bUserClose: boolean = true; bUserRemove: boolean = true; bUserDisplayMap: boolean = true);
    procedure LineSplitPolygon(strLineTableName: string; strPolygonTableName: string);
    procedure EarsureObj(strYTableName: string; strMBTableName: string; bBosom: boolean = true);
    function CheckRepeatPolygon(checkedTable, errorViewTable : string; toleranceArea: double; units: string) : boolean;
    function CheckPolygonState(strTableName: string; var rowId : string ): boolean;
    procedure AutoSnap(tableName: string; tolerance: double; units: string; whereClause: string);
    procedure SimplePLine(tableName: string; distance: double; units: string; whereClause: string);
    procedure SimplePLine_2(tableName: string; bend: double; distance: double; units: string; whereClause: string);
    procedure RemoveRegion(tableName: string; area: double; units: string; whereClause: string);
    function GetIntersectNodes(tagetMapinfoGeo: string; mapinfoGeo: string): TObjectList;
    function GetBevelRate(pt1: TKDPoint; pt2: TKDPoint; precision: integer): double;
    function BetweenOnPointsX(targetPt: TKDPoint; fromPt: TKDPoint; toPt: TKDPoint): boolean;
    function BetweenOnPointsY(targetPt: TKDPoint; fromPt: TKDPoint; toPt: TKDPoint): boolean;
    function BetweenOnPoints(targetPt: TKDPoint; fromPt: TKDPoint; toPt: TKDPoint): boolean;
    procedure ConvertPolyongToSimplePline(polyTable, polyUidField, plineTable, plineUidFiled: string);
    //重新排序图层
    procedure ReOrderAllLayer(CurWinID: integer; OrderNumString: string);
    procedure LayerToLayerIndex(CurWinID: integer; LayerIndex, ToLayerIndex: integer);
    function GetLayerCount(WinID: integer): integer;
    function GetLayerIndex(WinID: integer; strTabName: string): integer;
    function GetLayerName(WinID: integer; strTabIndex: integer): string;
    function CheckTableObjec(X, Y: double; strTableName: string; radius: double; flag: integer): boolean;
    //分解图层中的对象
    procedure Disaggregate(strTableName: string; bAll: boolean);
    procedure UnitePiecePolygon(strTableName: string; intArea: double = 100);
    procedure UonionObject(tableName: string; whereClause: string);
    procedure LineSplitPolyong_2(lineTable: string; polyTable: string);
    procedure LineAntitone(strTableName: string; RowID: integer);
    procedure ShowArrows(LayerName: string; bShow: boolean = true);
    function GetSelectionLayerName(): string;
    //将图形转换为折线对象
    procedure CvtToPLine(mapinfoGeo: string);
    procedure CvtToRegion(mapinfoGeo: string);
    //面层分割面层
    procedure SplitByPolygon(tableName: string; splitTableName: string);
    procedure CvtToPLineTable(strTableName: string; strTableName2: string; CurWinID: integer); Overload;
    procedure CvtToPLineTable(srcTable: string; destTable: string; whereClause: string); Overload;
    procedure CvtToPLineTableEx(srcTable: string; destTable: string; whereClause: string; fieldList: string);
    procedure RemoveMapInWindow(WinID: integer);
    procedure CloseMapinfoTable();
    procedure CloseMapinfoTempTable();
    procedure CloseTempTable();
    function QueryOpenedTable(): integer;
    function TrackLine(): string;
    function TrackPolygon(): string;
    function TrackPoint(): string;

    procedure DoMapinfoSql(sql: string);
    {
    //2006-3-27 变更图形处理函数    ma
    procedure SplitLineTable(tableName : string; splitTableName : string);
    procedure UnitePolygon(strYTableName:String;strMBTableName:String);
    procedure LineSplitPolygon(strLineTableName:String;strPolygonTableName:String);
    }
  end;

implementation

uses
  Math, BasicFunction;

///------------------Type TKDPoint method------------------

constructor TKDPoint.Create();
begin
  self.X := 0;
  self.Y := 0;
end;

constructor TKDPoint.Create(X: double; Y: double);
begin
  self.X := X;
  self.Y := Y;
end;

constructor TKDPoint.Create(pt: TKDPoint);
begin
  self.X := pt.X;
  self.Y := pt.Y;
end;

function TKDPoint.IsEqual(pt: TKDPoint): boolean;
begin
  if (self.X = pt.X) and (self.Y = pt.Y) then
    result := true
  else
    result := false;
end;

function TKDPoint.IsEqual(pt: TKDPoint; tolerace : double): boolean;
begin
  if (self.X + tolerace < pt.X)
  and (self.X - tolerace > pt.X)
  and (self.Y + tolerace < pt.Y)
  and (self.Y - tolerace > pt.Y) then
    result := true
  else
    result := false;
end;

///------------------Type TKDSegmentPoint method------------------
constructor TKDSegmentPoint.Create();
begin
  self.X := 0;
  self.Y := 0;
  self.SegmentInedex := -1;
end;

constructor TKDSegmentPoint.Create(pt: TKDPoint);
begin
  self.X := pt.X;
  self.Y := pt.Y;
  self.SegmentInedex := -1;
end;

constructor TKDSegmentPoint.Create(gpt: TKDSegmentPoint);
begin
  self.X := gpt.X;
  self.Y := gpt.Y;
  self.SegmentInedex := gpt.SegmentInedex;
end;

function TKDSegmentPoint.Copy(): TKDSegmentPoint;
var
  point: TKDSegmentPoint;
begin
  point := TKDSegmentPoint.Create();
  point.X := self.X;
  point.Y := self.Y;
  point.SegmentInedex := self.SegmentInedex;
end;

function TKDSegmentPoint.ToPoint(): TKDPoint;
begin
  result := TKDPoint.Create(self.X, self.Y);
end;


///------------------Type TKDTrackTable method------------------

constructor TKDTrackTable.Create(WinID: integer);
begin
  self.m_FilePath := AppPath;
  self.m_TrackTableName := 'KDTrackingTable';
  self.m_WinID := WinID;
end;

procedure TKDTrackTable.CreateTrack(structTable: string);
var
  path: string;
begin
  path := m_FilePath + '\' + m_TrackTableName + '.TAB';
  goMapinfoProxy.CloneTableStructure(structTable, path);
  goMapinfoProxy.OpenTable(path, m_TrackTableName);
  goMapinfoProxy.AddTable(m_TrackTableName, m_WinID);
end;

procedure TKDTrackTable.ClearTrack();
begin
  goMapinfoProxy.DeleteTable(m_TrackTableName);
end;

procedure TKDTrackTable.DropTrack();
begin
  goMapinfoProxy.DropTable(m_TrackTableName);
end;

procedure TKDTrackTable.PackTrack();
begin
  goMapinfoProxy.PackTable(m_TrackTableName);
end;

function TKDTrackTable.TrackLine(): string;
var
  mapinfoObj: string;
begin
  mapinfoObj := goMapinfoProxy.TrackLine();
  goMapinfoProxy.DoMapinfoSql('insert into ' + m_TrackTableName + ' (obj) Values(' + mapinfoObj + ')');
  goMapinfoProxy.CommitTable(m_TrackTableName);
  result := mapinfoObj;
end;

function TKDTrackTable.TrackPolygon(): string;
var
  mapinfoObj: string;
begin
  mapinfoObj := goMapinfoProxy.TrackPolygon();
  goMapinfoProxy.DoMapinfoSql('insert into ' + m_TrackTableName + ' (obj) Values(' + mapinfoObj + ')');
  goMapinfoProxy.CommitTable(m_TrackTableName);
  result := mapinfoObj;
end;

function TKDTrackTable.TrackPoint(): string;
var
  mapinfoObj: string;
begin
  mapinfoObj := goMapinfoProxy.TrackPoint();
  goMapinfoProxy.DoMapinfoSql('insert into ' + m_TrackTableName + ' (obj) Values(' + mapinfoObj + ')');
  goMapinfoProxy.CommitTable(m_TrackTableName);
  result := mapinfoObj;
end;

///------------------Type TKDMapinfoProxy method------------------
///@author: yzhou
///@date: 2006.3.20
///@description: TKDMapinfoProxy构造函数

constructor TKDMapinfoProxy.Create(oleMapinfo: Variant);
begin
  MapInfo := oleMapinfo;
end;

///@author: ma
///@date: 2006.04.4.9
///@description: 将图形分割。
///@para tableName: 要被分割的层
// @para splitTableName: 分割层

procedure TKDMapinfoProxy.SplitByPolygon(tableName: string; splitTableName: string);
var
  colNum: integer;
  i: integer;
  mapinfoSql: string;
  whereClause: string;
  colStr: string;
  Tempstr: string;
  str1: string;
  IntersectRow: integer;
  recordCnt: integer;
  RowID: string;
  cutterId: string;
  rowTemp: integer;
begin
  colNum := self.QueryTableColumnCount(tableName);
  for i := 1 to colNum do
  begin
    str1 := self.QueryTableColumnName(tableName, i);
    Tempstr := Tempstr + str1 + '=' + str1 + ',';
  end;
  colStr := LeftStr(Tempstr, Length(Tempstr) - 1);

  whereClause := ' where obj Intersects Aobj ';
  whereClause := whereClause + ' and (str$(obj)<>"Point" and str$(obj)<>"Text")';
  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select obj from ' + tableName;
  mapinfoSql := mapinfoSql + whereClause;
  mapinfoSql := mapinfoSql + ' into Temp';

  MapInfo. do ('select * from ' + splitTableName + ' where object into Temp2');
  recordCnt := self.QueryTableRecordCount('Temp2');
  //循环分割层
  for i := 1 to recordCnt do
  begin
    MapInfo. do ('fetch rec ' + Inttostr(i) + ' from Temp2');
    //mapinfo.do('select * from temp2 where rowid='+inttostr(i));
    MapInfo. do ('Aobj = Temp2.Obj');
    RowID := MapInfo.Eval('Temp2.rowid');
    MapInfo. do (mapinfoSql);
    //选中面层所有面图形 执行分解、保存
    rowTemp := self.QueryTableRecordCount('Temp');
    if rowTemp > 0 then
    begin
      MapInfo. do ('Set Target On');
      MapInfo. do ('select obj from Temp2 where rowid=' + RowID);
      MapInfo. do ('Objects Split Into Target Data ' + colStr);
    end;
  end;
  self.CommitTable(tableName);
  //分解
  self.Disaggregate(tableName, false);
  self.CloseTable('Temp');
  self.CloseTable('Temp2');
end;

/// 功能:返回选择对象有层名
/// 作者:姚箫
/// 日期:2006.4.9

function TKDMapinfoProxy.GetSelectionLayerName(): string;
begin
  result := MapInfo.Eval('Selectioninfo(' + Inttostr(SEL_INFO_TABLENAME) + ')');
end;

/// 功能:返回地图窗口上的图层数
/// 作者:姚箫
/// 日期:2006.3.29
/// 参数说明:strWinID->窗口ID

function TKDMapinfoProxy.GetLayerCount(WinID: integer): integer;
begin
  result := MapInfo.Eval('MapperInfo(' + Inttostr(WinID)
    + ', ' + Inttostr(MAPPER_INFO_LAYERS) + ')');
end;

/// 功能:返回地图窗口上指定层名的层索引
/// 作者:姚箫
/// 日期:2006.3.29
/// 参数说明:strTabName->层名
///                        WinID            ->窗口句柄

function TKDMapinfoProxy.GetLayerIndex(WinID: integer; strTabName: string): integer;
var
  i, LayerCount: integer;
  LayerName: string;
begin
  result := -1;
  LayerCount := GetLayerCount(WinID);
  for i := 1 to LayerCount do
  begin
    LayerName := MapInfo.Eval('LayerInfo(' + Inttostr(WinID)
      + ', ' + Inttostr(i) + ', ' + Inttostr(LAYER_INFO_NAME) + ')');
    if UpperCase(Trim(LayerName)) = UpperCase(Trim(strTabName)) then
    begin
      result := i;
      Break;
    end;
  end;
end;

/// 功能:返回地图窗口上指定层索引的层名
/// 作者:姚箫
/// 日期:2006.3.29
/// 参数说明:strTabIndex->层名
///                        WinID             ->窗口句柄

function TKDMapinfoProxy.GetLayerName(WinID: integer; strTabIndex: integer): string;
begin
  result := MapInfo.Eval('LayerInfo(' + Inttostr(WinID)
    + ', ' + Inttostr(strTabIndex) + ', ' + Inttostr(LAYER_INFO_NAME) + ')');
end;

///@author: yzhou
///@date: 2006.04.28
///@description: 将指定表中的对象捕捉到一起
///@para tableName: 要捕捉的表名
///@para tolerance: 捕捉容差
///@para units: 捕捉容差的度量单位
///@para whereClause: where条件

procedure TKDMapinfoProxy.AutoSnap(tableName: string; tolerance: double; units: string; whereClause: string);
var
  mapinfoSql: string;
begin

  mapinfoSql := 'select * from ' + tableName;
  if (Trim(whereClause) <> '') then
    mapinfoSql := mapinfoSql + ' where ' + whereClause;
  MapInfo. do (mapinfoSql);

  if (self.QuerySelctionCount() > 0) then
  begin
    mapinfoSql := 'Objects Snap From Selection Tolerance Node ' + FloatToStr(tolerance) + ' Units "' + units + '"';
    MapInfo. do (mapinfoSql);
  end;

end;

///@author: yzhou
///@date: 2006.04.28
///@description: 去除指定表中的交叠的线对象
///@para tableName: 要操作的表名
///@para distance: 交叠点的容差
///@para units: 容差值的度量单位
///@para whereClause: where条件
///@remark: 只对表中的Line和PLine对象进行操作

procedure TKDMapinfoProxy.SimplePLine(tableName: string; distance: double; units: string; whereClause: string);
var
  mapinfoSql: string;
begin

  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from ' + tableName;
  mapinfoSql := mapinfoSql + ' where (int(ObjectInfo(obj, 1)) = 3 or int(ObjectInfo(obj, 1)) = 4)'; // 3 : const OBJ_TYPE_LINE;  4 : OBJ_TYPE_PLINE
  if (Trim(whereClause) <> '') then
    mapinfoSql := mapinfoSql + ' and ' + whereClause;
  mapinfoSql := mapinfoSql + ' into selection';
  MapInfo. do (mapinfoSql);

  if (self.QuerySelctionCount() > 0) then
  begin
    mapinfoSql := 'Objects Snap From Selection Thin Distance ' + FloatToStr(distance) + ' Units "' + units + '"';
    MapInfo. do (mapinfoSql);
  end;

end;

///@author: yzhou
///@date: 2006.09.25
///@description: 去除指定表中的交叠的线对象
///@para tableName: 要操作的表名
///@para distance: 交叠点的容差
///@para units: 容差值的度量单位
///@para whereClause: where条件
///@remark: 只对表中的Line和PLine对象进行操作

procedure TKDMapinfoProxy.SimplePLine_2(tableName: string; bend: double; distance: double; units: string; whereClause: string);
var
  mapinfoSql: string;
begin

  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from ' + tableName;
  mapinfoSql := mapinfoSql + ' where (int(ObjectInfo(obj, 1)) = 3 or int(ObjectInfo(obj, 1)) = 4)'; // 3 : const OBJ_TYPE_LINE;  4 : OBJ_TYPE_PLINE
  if (Trim(whereClause) <> '') then
    mapinfoSql := mapinfoSql + ' and ' + whereClause;
  mapinfoSql := mapinfoSql + ' into selection';
  MapInfo. do (mapinfoSql);

  if (self.QuerySelctionCount() > 0) then
  begin
    mapinfoSql := 'Objects Snap From Selection Thin Bend ' + FloatToStr(bend) + ' Distance ' + FloatToStr(distance) + ' Units "' + units + '"';
    MapInfo. do (mapinfoSql);
  end;

end;

///@author: yzhou
///@date: 2006.04.28
///@description: 删除除表中面积小于指定值的区域对象
///@para tableName: 要操作的表名
///@para area: 区域对象的面积上限
///@para units: 面积上限的度量单位
///@para whereClause: where条件

procedure TKDMapinfoProxy.RemoveRegion(tableName: string; area: double; units: string; whereClause: string);
var
  mapinfoSql: string;
begin

  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from ' + tableName;
  if (Trim(whereClause) <> '') then
    mapinfoSql := mapinfoSql + ' and ' + whereClause;
  MapInfo. do (mapinfoSql);

  if (self.QuerySelctionCount() > 0) then
  begin
    mapinfoSql := 'Objects Snap From Selection Cull Area ' + FloatToStr(area) + ' Units "' + units + '"';
    MapInfo. do (mapinfoSql);
  end;

end;

///@author: yzhou
///@date: 2006.05.13
///@description: 获取两个mapinfo对象的交点,并按顺序插入到点集intersectNodes中
///@para: tagetMapinfoGeo: 目标对象
///@para: mapinfoGeo: mapinfo对象
///@para intersectNodes: 点集合(要求按tagetMapinfoGeo对象的方向有序排列)
///@remark: (1)此函数用到了mapinfo中定义的变量'Fobj',在调用函数时会修改原'Fobj'中的值
///(2) 若两条线在首尾相交,则在首尾处的交点不包含在返回的点集中

procedure TKDMapinfoProxy.GetOrderIntersectNodes(tagetMapinfoGeo: string; mapinfoGeo: string; intersectNodes: TObjectList);
var
  mapinfoSql: string;
  tempObj: string;
  i, j, k: integer;
  inetersectPt, fromPt, toPt: TKDPoint;
  fristNode, lastNode: TKDPoint;
  ptSegment: TKDSegmentPoint;
  isInsert: boolean;
begin

  tempObj := 'FObj';

  mapinfoSql := tempObj + ' = intersectNodes(' + tagetMapinfoGeo + ', ' + mapinfoGeo + ', 7)';
  MapInfo. do (mapinfoSql);

  if (self.QueryNodeCount(tempObj) < 1) then
    Exit;

  fristNode := self.QueryNodeOfGeomety(tagetMapinfoGeo, 1, 1);
  lastNode := self.QueryNodeOfGeomety(tagetMapinfoGeo, 1, self.QueryNodeCount(tagetMapinfoGeo, 1));

  for i := 1 to self.QueryNodeCount(tempObj, 1) do
  begin
    inetersectPt := self.QueryNodeOfGeomety(tempObj, 1, i);

    //排除交点等于首尾节点的情况
    if (inetersectPt.IsEqual(fristNode) or inetersectPt.IsEqual(lastNode)) then
      continue;

    for j := 1 to self.QueryNodeCount(tagetMapinfoGeo, 1) - 1 do
    begin
      fromPt := self.QueryNodeOfGeomety(tagetMapinfoGeo, 1, j);
      toPt := self.QueryNodeOfGeomety(tagetMapinfoGeo, 1, j + 1);

      {
      //排除交点与与原有节点重合的情况
      if (inetersectPt.IsEqual(fromPt) or inetersectPt.IsEqual(toPt)) then
        break;
      }

      //判断交点是否在线段上
      if (BetweenOnPoints(inetersectPt, fromPt, toPt) = true) then
      begin
        ptSegment := TKDSegmentPoint.Create(inetersectPt);
        ptSegment.SegmentInedex := j;

        //按次序插入交点集
        isInsert := false;
        for k := 0 to intersectNodes.Count - 1 do
        begin

          if (ptSegment.SegmentInedex = TKDSegmentPoint(intersectNodes.Items[k]).SegmentInedex) then
          begin
            if (BetweenOnPoints(ptSegment.ToPoint(), fromPt, TKDSegmentPoint(intersectNodes.Items[k]).ToPoint())) then
            begin
              intersectNodes.Insert(k, ptSegment);
              isInsert := true;
            end;
          end;

          if (ptSegment.SegmentInedex < TKDSegmentPoint(intersectNodes.Items[k]).SegmentInedex) then
          begin
            intersectNodes.Insert(k, ptSegment);
            isInsert := true;
          end;

          if (isInsert = true) then
            Break;
        end; // for k := 0 to intersectNodes.Count - 1 do

        //未定位到相应的索引位置则加入到最后一个位置
        if (isInsert = false) then
          intersectNodes.Add(ptSegment);

        // 找到交点所在的线段时,应该退出循环
        Break;
      end; // if (BetweenOnPoints(inetersectPt, fromPt, toPt)) then

    end; // for j := 1 to self.QueryNodeCount(tagetMapinfoGeo, 1) do
  end; // for i := 1 to self.QueryNodeCount(tempObj, 1) do

end;

///@author: yzhou
///@date: 2006.05.13
///@description: 获取两个mapinfo对象的交点
///@para: tagetMapinfoGeo: 目标对象
///@para: mapinfoGeo: mapinfo对象
///@remark: 此函数用到了mapinfo中定义的变量'Fobj',在调用函数时会修改原'Fobj'中的值

function TKDMapinfoProxy.GetIntersectNodes(tagetMapinfoGeo: string; mapinfoGeo: string): TObjectList;
var
  intersectNodes: TObjectList;
begin
  intersectNodes := TObjectList.Create();

  self.GetOrderIntersectNodes(tagetMapinfoGeo, mapinfoGeo, intersectNodes);
  result := intersectNodes;
end;

///@author: yzhou
///@date: 2006.05.13
///@description: 获取两个点构成直线的斜率
///@para: pt1, pt2: 计算斜率的两点
///@para: precision: 斜率的精度(即保留小数的位数)

function TKDMapinfoProxy.GetBevelRate(pt1: TKDPoint; pt2: TKDPoint; precision: integer): double;
var
  bevelRate: double;
begin

  if (abs(pt1.X - pt2.X) < 5E-100) then
  begin
    bevelRate := Infinity;
  end
  else
  begin
    precision := 0 - precision;
    bevelRate := abs((pt1.Y - pt2.Y) / (pt1.X - pt2.X));
    bevelRate := RoundTo(bevelRate, precision);
  end;

  result := bevelRate;
end;

///@author: yzhou
///@date: 2006.05.15
///@description: 判断一个点按X方向是否在另外两点之间

function TKDMapinfoProxy.BetweenOnPointsX(targetPt: TKDPoint; fromPt: TKDPoint; toPt: TKDPoint): boolean;
var
  fromX, toX: double;
begin

  if (fromPt.X <= toPt.X) then
  begin
    fromX := fromPt.X;
    toX := toPt.X;
  end
  else
  begin
    fromX := toPt.X;
    toX := fromPt.X;
  end;

  if ((targetPt.X >= fromX) and (targetPt.X <= toX)) then
    result := true
  else
    result := false;

end;

///@author: yzhou
///@date: 2006.05.15
///@description: 判断一个点按Y方向是否在另外两点之间

function TKDMapinfoProxy.BetweenOnPointsY(targetPt: TKDPoint; fromPt: TKDPoint; toPt: TKDPoint): boolean;
var
  fromY, toY: double;
begin

  if (fromPt.Y <= toPt.Y) then
  begin
    fromY := fromPt.Y;
    toY := toPt.Y;
  end
  else
  begin
    fromY := toPt.Y;
    toY := fromPt.Y;
  end;

  if ((targetPt.Y >= fromY) and (targetPt.Y <= toY)) then
    result := true
  else
    result := false;

end;

///@author: yzhou
///@date: 2006.05.15
///@description: 判断一个点是否在另外两点所构成的线段上

function TKDMapinfoProxy.BetweenOnPoints(targetPt: TKDPoint; fromPt: TKDPoint; toPt: TKDPoint): boolean;
var
  rate1, rate2: double;
  rateEqual: boolean;
begin
  rate1 := self.GetBevelRate(fromPt, toPt, 5);
  rate2 := self.GetBevelRate(fromPt, targetPt, 5);

  if ((rate1 = Infinity) or (rate2 = Infinity)) then
  begin
    if ((rate1 = Infinity) and (rate2 = Infinity)) then
      rateEqual := true
    else
      rateEqual := false;
  end
  else
  begin
    if abs(rate1 - rate2) < 1E-4 then
      rateEqual := true
    else
      rateEqual := false;
  end;

  if (rateEqual = true)
    and (self.BetweenOnPointsX(targetPt, fromPt, toPt) = true)
    and (self.BetweenOnPointsY(targetPt, fromPt, toPt) = true) then
    result := true
  else
    result := false;

  {
   if (abs(self.GetBevelRate(fromPt, ToPt, 3) - self.GetBevelRate(fromPt, targetPt, 3)) < 0.01)
    and (self.BetweenOnPointsX(targetPt, fromPt, toPt) = true)
     and (self.BetweenOnPointsY(targetPt, fromPt, toPt) = true)  then
   begin
    result := true;
   end
   else
   begin
    result := false;
   end;
  }

end;


///@author: yzhou
///@date: 2006.09.27
///@description: 此函数算法有问题,未经过测试

procedure TKDMapinfoProxy.ConvertPolyongToSimplePline(polyTable, polyUidField, plineTable, plineUidFiled: string);
var
  mapinfoSql: string;
  i: integer;
  RowID, tempID: string;
  tagetIdList: string;
begin
  self.CvtToPLineTable(polyTable, plineTable, '');

  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select polyTable.polyUidField "polyUid", plineTable.plineUidFiled "plineUid"';
  mapinfoSql := mapinfoSql + ' from polyTable, plineTable';
  mapinfoSql := mapinfoSql + ' where polyTable.obj intersects plineTable.obj';
  //mapinfoSql := mapinfoSql + ' and int(ObjectInfo(plineTable.obj, 20)) = int(ObjectInfo(IntersectNodes(plineTable.obj, polyTable.obj, 6), 20)) + 1';
  mapinfoSql := mapinfoSql + ' and int(ObjectInfo(plineTable.obj, 20)) = int(ObjectInfo(polyTable.obj, 20))';
  mapinfoSql := mapinfoSql + ' into kd_line_temp_table';

  mapinfoSql := StringReplace(mapinfoSql, 'polyTable', polyTable, [rfReplaceAll]);
  mapinfoSql := StringReplace(mapinfoSql, 'polyUidField', polyUidField, [rfReplaceAll]);
  mapinfoSql := StringReplace(mapinfoSql, 'plineTable', plineTable, [rfReplaceAll]);
  mapinfoSql := StringReplace(mapinfoSql, 'plineUidFiled', plineUidFiled, [rfReplaceAll]);
  MapInfo. do (mapinfoSql);

  mapinfoSql := 'update kd_line_temp_table set plineUid = polyUid';
  MapInfo. do (mapinfoSql);
  self.CloseTable('kd_line_temp_table');

  self.Disaggregate(plineTable, true);
  for i := 1 to self.QueryTableRecordCount(polyTable) do
  begin
    MapInfo. do ('fetch rec ' + Inttostr(i) + ' from ' + polyTable);
    RowID := MapInfo.Eval(polyTable + '.rowid');

    if (tagetIdList <> '') then
      tagetIdList := tagetIdList + ',' + RowID
    else
      tagetIdList := RowID;

    mapinfoSql := ' select * from ' + polyTable + ' where rowid = ' + RowID + 'into kd_poly_temp_table';
    MapInfo. do (mapinfoSql);

    mapinfoSql := '';
    mapinfoSql := mapinfoSql + ' select * from ' + plineTable;
    mapinfoSql := mapinfoSql + ' where ' + plineUidFiled + ' not in (' + tagetIdList + ')';
    mapinfoSql := mapinfoSql + ' into kd_line_temp_table';
    MapInfo. do (mapinfoSql);

    self.EraseObjects('kd_line_temp_table', 'kd_poly_temp_table');
    self.CloseTable('kd_poly_temp_table');
    self.CloseTable('kd_line_temp_table');
  end;

  //whereCluase := polyUidField + ' in (' + tagetIdList + ')';
  //self.CvtToPLineTable(polyTable, plineTable, whereCluase);
  self.Disaggregate(plineTable, true);
  //self.SaveTable(plineTable);
  //self.SplitLineTableEx(plineTable, plineTable);

end;

procedure TKDMapinfoProxy.RemoveMapInWindow(WinID: integer);
var
  i: integer;
begin
  for i := 1 to GetLayerCount(WinID) do
    MapInfo. do ('Remove Map Window ' + Inttostr(WinID) + ' Layer ' + GetLayerName(WinID, i) + ' Interactive');
end;

///@author: yzhou
///@date: 2006.06.14
///@description: 关闭MapInfo中所有打开的表

procedure TKDMapinfoProxy.CloseMapinfoTable();
begin
  MapInfo. do ('Close All');
end;
{
var
  mapinfoSql, tableName: string;
  tables : TStringList;
  i: integer;
begin

tables := TStringList.Create();
  for i := 1 to self.QueryOpenedTable() do
  begin
    tableName := MapInfo.Eval('TABLEINFO(' + Inttostr(i) + ',' + Inttostr(TAB_INFO_NAME) + ')');
  tables.Add(tableName);
  end;


  for i := 0 to tables.Count - 1 do
   self.CloseTable(tables.Strings[i]);

end;
}

///@author: yzhou
///@date: 2006.5.8
///@description: 关闭由MapInfo产生的临时表

procedure TKDMapinfoProxy.CloseMapinfoTempTable();
var
  mapinfoSql, tableName: string;
  tables: TStringList;
  i: integer;
begin
  tables := TStringList.Create();
  for i := 1 to self.QueryOpenedTable() do
  begin
    tableName := MapInfo.Eval('TABLEINFO(' + Inttostr(i) + ',' + Inttostr(TAB_INFO_NAME) + ')');

    if Pos('_', tableName) <= 0 then
    begin
      if MapInfo.Eval('TableInfo(' + tableName + ',' + Inttostr(TAB_INFO_TEMP) + ')') = 'T' then
        tables.Add(tableName);
    end;
  end;

  for i := 0 to tables.Count - 1 do
    self.CloseTable(tables.Strings[i]);
end;

///@author: yzhou
///@date: 2006.5.8
///@description: 关闭由MapInfo产生的以Query开头的临时表
procedure TKDMapinfoProxy.CloseTempTable();
var
  mapinfoSql, tableName: string;
  i: integer;
  tmpStrList: TStringList;
begin
  try
    tmpStrList := TStringList.Create;
    for i := 1 to self.QueryOpenedTable() do
    begin
      tableName := MapInfo.Eval('TABLEINFO(' + Inttostr(i) + ',' + Inttostr(TAB_INFO_NAME) + ')');
      //记录临时表
      if UpperCase(LeftStr(tableName, 5)) = 'QUERY' then
        tmpStrList.Add(tableName);
    end;
    //关闭临时表
    for i := 0 to tmpStrList.Count - 1 do
      self.CloseTable(tmpStrList.Strings[i]);
  finally
    tmpStrList.Free;
  end;
end;

///@author: yzhou
///@date: 2006.5.8
///@description: 查询在所有MapInfo中打开的表的个数
///@return: 表的个数
function TKDMapinfoProxy.QueryOpenedTable(): integer;
begin
  result := MapInfo.Eval('NumTables()');
end;

///@author: yzhou
///@date: 2006.07.03
///@description: 用户鼠标坐标输入创建一条折线
///@return: Mapinfo线对象
///@remark: ***************未实现******************
function TKDMapinfoProxy.TrackLine(): string;
begin
  {
    Mapinfo. do ('Run Menu Command ID 2065');
  }
  result := 'PLineTrackerObj';
end;

///@author: yzhou
///@date: 2006.07.03
///@description: 用户鼠标坐标输入创建一个面
///@return: Mapinfo面对象
///@remark: ***************未实现******************
function TKDMapinfoProxy.TrackPolygon(): string;
begin
  {
   Mapinfo. do ('Run Menu Command ID 2066');
  }
  result := 'PolygonTrackerObj';
end;

///@author: yzhou
///@date: 2006.07.03
///@description: 用户鼠标坐标输入创建一个点
///@return: Mapinfo点对象
///@remark: ***************未实现******************
function TKDMapinfoProxy.TrackPoint(): string;
begin
  {
   Mapinfo. do ('Run Menu Command ID 2067');
  }
  result := 'PointTrackerObj';

end;

/// 功能:重新排序图层
/// 作者:姚箫
/// 日期:2006.3.29
/// 参数说明:OrderNumString->层索引字符串如('2, 3, 4, 1, 5')
///                        WinID                ->窗口句柄
procedure TKDMapinfoProxy.ReOrderAllLayer(CurWinID: integer; OrderNumString: string);
var
  dSql: string;
begin
  if OrderNumString <> '' then
  begin
    dSql := 'Set Map window ' + Inttostr(CurWinID) + ' order '
      + OrderNumString;
    MapInfo. do (dSql);
  end;
end;

/// 功能:把指定序号的层放到指定序号上
/// 作者:姚箫
/// 日期:2006.3.29
/// 参数说明:LayerIndex    ->层索引
///                        ToLayerIndex    ->目标层索引
///                        WinID                ->窗口句柄

procedure TKDMapinfoProxy.LayerToLayerIndex(CurWinID: integer; LayerIndex, ToLayerIndex: integer);
var
  OrderNumStr: string;
  i: integer;
begin
  for i := 1 to GetLayerCount(CurWinID) do
  begin
    if (i <> LayerIndex) and (i <> ToLayerIndex) then
      OrderNumStr := OrderNumStr + ',' + Inttostr(i)
    else
    begin
      if i = ToLayerIndex then
      begin
        OrderNumStr := OrderNumStr + ',' + Inttostr(ToLayerIndex);
        OrderNumStr := OrderNumStr + ',' + Inttostr(LayerIndex);
      end;
    end;
  end;
  OrderNumStr := RightStr(OrderNumStr, Length(OrderNumStr) - 1);
  ReOrderAllLayer(CurWinID, OrderNumStr);
end;

///@author: yzhou
///@date: 2006.3.16
///@description: 添加表到地图窗口
///@para tableName: 添加的表名
///@para mapId: 地图窗口ID

procedure TKDMapinfoProxy.AddTable(tableName: string; mapId: integer);
begin
  if not TableExists(tableName) then
  begin
    //raise Exception.Create('"' + tableName + '"没有打开,请先打开后再做相关操作!');
    Exit;
  end;

  MapInfo. do ('Add Map Window ' + Inttostr(mapId) + 'Layer ' + tableName);
  //如果是变更图斑层则显示样式
  if RightStr(tableName, 5) = 'BGTBP' then
  begin
    MapInfo. do ('Set Map Layer ' + tableName + ' Label Font ("Arial",288,8,16711680,16776960) With DLDM Auto On');
    MapInfo. do ('Set Map Layer ' + tableName + ' Label Position Center');
  end;
end;

///@author: yzhou
///@date: 2006.3.16
///@description: 判断表是否已经打开
///@para tableName: tab表名
///@return: 返回true表示已经打开,反之。

function TKDMapinfoProxy.TableExists(tableName: string): boolean;
begin
  result := EXISTTABLEs(tableName);
end;

///@author: yzhou
///@date: 2006.3.16
///@description: 创建地图窗口
///@para tableName: 初始表名
///@para mapName: 地图窗口名称
///@para hwnd: 地图窗口绑定的hwnd
///@return: 返回地图窗口ID

function TKDMapinfoProxy.CreateMap(tableName: string; mapName: string; hwnd: integer): integer;
var
  mapId: integer;
begin
  mapId := 0;
  MapInfo. do ('Set Next Document Parent ' + Inttostr(hwnd) + ' Style 1');
  MapInfo. do ('Map From ' + tableName);
  mapId := StrToInt(MapInfo.Eval('FrontWindow()'));
  MapInfo. do ('set window frontwindow() title "' + mapName + '"');
  MapInfo. do ('set paper units "cm"');
  MapInfo. do ('set distance units "m"');
  MapInfo. do ('SET MAP CoordSys  Table ' + tableName);
  result := mapId;
end;

///@author: yzhou
///@date: 2006.3.16
///@description: 打开一个tab表
///@para tablePath: 表的路径
///@para tableAlias: 打开表的别名

procedure TKDMapinfoProxy.OpenTable(tablePath: string; tableAlias: string);
begin
  MapInfo. do ('Open Table "' + tablePath + '" As ' + tableAlias);
end;

///@author: yzhou
///@date: 2006.05.19
///@description: 将表另存为table文件
///@para tablePath: 源表表名
///@para destTablePath: 文件名及其路径
///@para whereClause: where条件

procedure TKDMapinfoProxy.SaveTableToFile(sourceTabla: string; destTablePath: string; whereClause: string);
var
  mapinfoSql: string;
begin
  mapinfoSql := mapinfoSql + ' select * from ' + sourceTabla;
  if (Trim(whereClause) <> '') then
    mapinfoSql := mapinfoSql + ' where ' + whereClause;
  mapinfoSql := mapinfoSql + ' into TempTableCopy';
  MapInfo. do (mapinfoSql);

  MapInfo. do ('Commit Table TempTableCopy as "' + destTablePath + '"');
  MapInfo. do ('Close table TempTableCopy');
end;

///@author: yzhou
///@date: 2006.3.16
///@description: 复制表结构
///@para tablePath: 源表表名
///@para destTablePath: 目标表的路径

procedure TKDMapinfoProxy.CloneTableStructure(sourceTabla: string; destTablePath: string);
begin
  MapInfo. do ('select * from ' + sourceTabla + ' into TempTableStructure where 1 <> 1');
  MapInfo. do ('Commit Table TempTableStructure as "' + destTablePath + '"');
  MapInfo. do ('Close table TempTableStructure');
end;

///@author: yzhou
///@date: 2006.3.16
///@description: 查询表中的记录数
///@para tableName: tab表名
///@return: 表中的记录数

function TKDMapinfoProxy.QueryTableRecordCount(tableName: string): integer;
begin
    //if tableName<>'' then
    result := StrToInt(MapInfo.Eval('tableinfo(' + tableName + ',' + Inttostr(TAB_INFO_NROWS) + ')'));
end;

///@author: yzhou
///@date: 2006.3.16
///@description: 查询表中的记录数
///@para tableName: tab表名
///@return: 表中的字段数

function TKDMapinfoProxy.QueryTableColumnCount(tableName: string): integer;
begin
  result := StrToInt(MapInfo.Eval('tableinfo("' + tableName + '",' + Inttostr(TAB_INFO_NCOLS) + ')'));
end;

///@author: yzhou
///@date: 2006.3.16
///@description: 查询表中指定索引的字段名
///@para tableName: tab表名
///@para colIndex: 字段索引
///@return: 指定索引的字段名,为空表示未找到。

function TKDMapinfoProxy.QueryTableColumnName(tableName: string; colIndex: integer): string;
begin
  if (colIndex < 1) or (colIndex > self.QueryTableColumnCount(tableName)) then
    result := ''
  else
    result := Trim(MapInfo.Eval('ColumnInfo("' + tableName + '","col' + Inttostr(colIndex) + '",' + Inttostr(COL_INFO_NAME) + ')'));
end;

///@author: yzhou
///@date: 2006.4.10
///@description: 查询表中指定字段名的索引值
///@para tableName: tab表名
///@para colIndex: 字段名
///@return: 指定字段名的索引值,未找到时返回0。

function TKDMapinfoProxy.QueryTableColumnIndex(tableName: string; colName: string): integer;
var
  i: integer;
  temp: string;
begin
  result := 0;

  colName := UpperCase(Trim(colName));
  for i := 1 to self.QueryTableColumnCount(tableName) do
  begin
    temp := Trim(self.QueryTableColumnName(tableName, i));
    if UpperCase(temp) = colName then
    begin
      result := i;
      Exit;
    end;
  end;
end;

function TKDMapinfoProxy.QueryTableColumnType(tableName: string; colName: string): integer;
var
  i: integer;
begin
  result := -1;
  for i := 1 to QueryTableColumnCount(tableName) do
  begin
    if UpperCase(Trim(QueryTableColumnName(tableName, i))) = UpperCase(colName) then
    begin
      result := MapInfo.Eval('ColumnInfo(' + tableName + ', ' + colName + ', ' + Inttostr(COL_INFO_TYPE) + ')');
    end;
  end;
end;

///@author: yzhou
///@date: 2006.3.17
///@description: 关闭已打开的表
///@para tableName: tab表名

procedure TKDMapinfoProxy.CloseTable(tableName: string);
begin
  if TableExists(tableName) then
    MapInfo. do ('Close table ' + tableName);
end;

procedure TKDMapinfoProxy.SaveAllTable();
var
  i, lCount: integer;
  slName: string;
begin
  lCount := MapInfo.Eval('NumTables()');
  for i := 1 to lCount do
  begin
    slName := MapInfo.Eval('TableInfo(' + Inttostr(i) + ', ' + Inttostr(TAB_INFO_NAME) + ')');
    if not TableIsSaved(slName) then
      CommitTable(slName);
  end;

  self.CloseMapinfoTempTable();
end;

function TKDMapinfoProxy.TableIsSaved(slName: string): boolean;
var
  tS: string;
begin
  result := true;
  if TableExists(slName) then
  begin
    if Pos('_', slName) <= 0 then
    begin
      tS := MapInfo.Eval('TableInfo(' + slName + ', ' + Inttostr(TAB_INFO_EDITED) + ')');
      if Trim(tS) = 'T' then
        result := false
      else
        result := true;
    end;
  end;
end;

///@author: yzhou
///@date: 2006.3.27
///@description: 删除指定层中的所有记录,并压缩表后提交
///@para tableName: tab表名

procedure TKDMapinfoProxy.ClearTable(tableName: string);
begin
  if TableExists(tableName) and (self.QueryTableRecordCount(tableName) > 0) then
  begin
    self.DeleteTable(tableName);
    self.CommitTable(tableName);
    self.PackTable(tableName);
  end;
end;

///@author: yzhou
///@date: 2006.4.2
///@description: 删除指定层中的所有记录
///@para tableName: tab表名

procedure TKDMapinfoProxy.DeleteTable(tableName: string);
begin
  if TableExists(tableName) then
    MapInfo. do ('delete from ' + tableName);
end;

procedure TKDMapinfoProxy.DropTable(tabName: string);
begin
  if TableExists(tabName) then
    MapInfo. do ('Drop Table ' + tabName);
end;

procedure TKDMapinfoProxy.PackTable(tabName: string);
begin
  if TableExists(tabName) then
    MapInfo. do ('Pack Table ' + tabName + ' Graphic Data');
end;

{///@author: yzhou
///@date: 2006.3.17
///@description: 打断将线层中的对象全部打断,并删除原来的对象
///@para tableName: 被打断的tab表名
///@para splitTableName: 用于打断操作的tab表名
///@remark: (1)不支持自相交的线对象;
/// (2)不支持对mapinfo中临时表的操作;
/// (3)不能对两条线共线进行打断
procedure TKDMapinfoProxy.SplitLineTable(tableName : string; splitTableName : string);
var
    sourceNodesList, dirtyNodesList : TObjectList;
    pt : TKDPoint;
    recordCnt : integer;
    i, j, k : integer;
    rowId : string;
    newRowId : integer;
    mapinfoSql : string;
    SplitObjsId : TStringList;
    tagetMapinfoObj, resultMapinfoObj : string;
    whereClause : string;
begin
    tagetMapinfoObj := 'aobj';
    resultMapinfoObj := 'bobj';

    if not TableExists(tableName) then
        begin
        raise Exception.Create('"' + tableName + '"没有打开,请先打开后再做相关操作!');
        Exit;
    end;

  try
    sourceNodesList := TObjectList.Create();
    dirtyNodesList := TObjectList.Create();
    SplitObjsId := TStringList.Create();

    recordCnt := QueryTableRecordCount(tableName);
    newRowId := recordCnt + 1;
    for i := 1 to recordCnt do
    begin
        Mapinfo. do ('fetch rec ' + Inttostr(i) + ' from ' + tableName);
        rowId := Mapinfo.Eval(tableName + '.rowid');

        //选择当前线对象
        mapinfoSql := '';
        mapinfoSql := mapinfoSql + ' select * from ' + tableName;
        mapinfoSql := mapinfoSql + ' where rowid = ' + rowId;
        mapinfoSql := mapinfoSql + ' into Selection';
        Mapinfo.do (mapinfoSql);

        //设置为目标
        Mapinfo.do (tagetMapinfoObj + ' = Selection.Obj');
        Mapinfo.do ('Set Target On');
        //查询节点
        QueryNodesOfGeomety(tagetMapinfoObj, 1, sourceNodesList);


        //选取相交的线对象
        if trim(tableName) = trim(splitTableName) then
        begin
            //选择自相交
            mapinfoSql := '';
            mapinfoSql := mapinfoSql + ' select * from ' + splitTableName;
            mapinfoSql := mapinfoSql + ' where rowid <> ' + rowId;
            mapinfoSql := mapinfoSql + ' and rowid <= ' + IntToStr(recordCnt);
            mapinfoSql := mapinfoSql + ' and Obj Intersects ' + tagetMapinfoObj;
            mapinfoSql := mapinfoSql + ' and (str$(obj)<>"Point" and str$(obj)<>"Text")';
            mapinfoSql := mapinfoSql + ' into Selection';
        end
        else
        begin
            //选择与其它层相交
            mapinfoSql := '';
            mapinfoSql := mapinfoSql + ' select * from ' + splitTableName;
            mapinfoSql := mapinfoSql + ' where Obj Intersects ' + tagetMapinfoObj;
            mapinfoSql := mapinfoSql + ' and (str$(obj)<>"Point" and str$(obj)<>"Text")';
            mapinfoSql := mapinfoSql + ' into Selection';
        end;
        Mapinfo.do (mapinfoSql);

        if QuerySelctionCount() > 0 then
        begin
            Mapinfo.do ('Objects Overlay Into Target');

            //加入交点后的源线对象
            mapinfoSql := '';
            mapinfoSql := mapinfoSql + ' select * from ' + tableName;
            mapinfoSql := mapinfoSql + ' where rowid = ' + rowId;
            mapinfoSql := mapinfoSql + ' into Selection';
            Mapinfo.do (mapinfoSql);
            Mapinfo.do (tagetMapinfoObj + ' = Selection.Obj');
            //查询节点
            QueryNodesOfGeomety(tagetMapinfoObj, 1, dirtyNodesList);

            if sourceNodesList.Count < dirtyNodesList.Count then
            begin

                //创建Pline对象
                mapinfoSql := 'Create pline into variable ' + resultMapinfoObj + ' 0 ';
                Mapinfo.do (mapinfoSql);

                k := 0;
                j := 0;
                while (j < sourceNodesList.Count) and (k < dirtyNodesList.Count) do
                begin

                    pt := TKDPoint(dirtyNodesList.Items[k]);
                    if pt.IsEqual(TKDPoint(sourceNodesList.Items[j])) then
                        begin
                            //加入节点
                            mapinfoSql := 'Alter Object  ' + resultMapinfoObj + '  Node  Add (' + FloatToStr(pt.X) + ',' + FloatToStr(pt.Y) +  ')';
                            Mapinfo. do (mapinfoSql);

                            inc(k);
                            inc(j);
                        end
                    else
                        begin
                            //加入节点
                            mapinfoSql := 'Alter Object  ' + resultMapinfoObj + '  Node  Add (' + FloatToStr(pt.X) + ',' + FloatToStr(pt.Y) +  ')';
                            Mapinfo. do (mapinfoSql);

                            //复制加入交点后的源线对象
                            mapinfoSql := '';
                            mapinfoSql := mapinfoSql + ' insert into ' + tableName;
                            mapinfoSql := mapinfoSql + ' select * from Selection';
                            Mapinfo. do (mapinfoSql);

                            //修改为断后的线对象
                            mapinfoSql := 'update ' + tableName + ' set obj = ' + resultMapinfoObj + ' where rowid = ' + IntToStr(newRowId);
                            Mapinfo. do (mapinfoSql);

                            inc(newRowId);

                            //创建Pline对象
                            mapinfoSql := 'Create pline into variable ' + resultMapinfoObj + ' 0';
                            Mapinfo. do (mapinfoSql);

                            //加入节点
                            mapinfoSql := 'Alter Object  ' + resultMapinfoObj + '  Node  Add (' + FloatToStr(pt.X) + ',' + FloatToStr(pt.Y) +  ')';
                            Mapinfo. do (mapinfoSql);

                            inc(k);
                        end; // end if pt.IsEqual(TKDPoint(sourceNodesList.Items[k]))
                end; // end while j < sourceNodesList.Count

                //复制源线对象
                mapinfoSql := '';
                mapinfoSql := mapinfoSql + ' insert into ' + tableName;
                mapinfoSql := mapinfoSql + ' select * from Selection';
                Mapinfo. do (mapinfoSql);

                //修改为断后的线对象
                mapinfoSql := 'update ' + tableName + ' set obj = ' + resultMapinfoObj + ' where rowid = ' + IntToStr(newRowId);
                Mapinfo. do (mapinfoSql);

                inc(newRowId);

                //记录被打断的源线对象
                SplitObjsId.Add(rowId);

            end; // sourceNodesList.Count < dirtyNodesList.Coun
        end; // end if QuerySelctionCount() > 0

        //清除为目标
        Mapinfo.do ('Set Target Off');
    end;

    //删除被打断的源线对象
    if SplitObjsId.Count > 0 then
    begin
        for i := 0 to SplitObjsId.Count - 1 do
        begin
            mapinfoSql := 'delete from ' + tableName + ' where rowid = ' + SplitObjsId.Strings[i];
            Mapinfo.do (mapinfoSql);
        end;
    end;

    //提交结果
    self.SaveTable(tableName);

  finally
    begin
        sourceNodesList.Free();
        dirtyNodesList.Free();
        SplitObjsId.Free();
    end;
  end;

end;}

///@author: yzhou
///@date: 2006.3.17
///@description: 查询mapinfo图形对象所包含的点。
///@para tableName: mapinfo图形对象名称
///@para partIndex: mapinfo图形对象的片断索引
///@para nodeList:  存放返回的点的列表

procedure TKDMapinfoProxy.QueryNodesOfGeomety(mapinfoGeo: string; partIndex: integer; nodeList: TObjectList);
var
  pt: TKDPoint;
  i, nodesCnt: integer;
begin

  nodesCnt := QueryNodeCount(mapinfoGeo, partIndex);
  nodeList.clear();

  for i := 1 to nodesCnt do
  begin
    pt := self.QueryNodeOfGeomety(mapinfoGeo, partIndex, 1);
    nodeList.Add(pt);
  end;

end;

function TKDMapinfoProxy.QueryNodesOfGeomety(mapinfoGeo: string; partIndex: integer): TObjectList;
var
  nodeList: TObjectList;
begin
  nodeList := TObjectList.Create();
  self.QueryNodesOfGeomety(mapinfoGeo, partIndex, nodeList);

  result := nodeList;
end;

///@author: yzhou
///@date: 2006.3.17
///@description: 查询mapinfo图形对象所包含的指定索引位置的点。
///@para tableName: mapinfo图形对象名称
///@para partIndex: mapinfo图形对象的片断索引
///@para nodeIndex:  要查询点的索引位置

function TKDMapinfoProxy.QueryNodeOfGeomety(mapinfoGeo: string; partIndex: integer; nodeIndex: integer): TKDPoint;
var
  point: TKDPoint;
  floatX, floatY, intX, intY: double;
begin
  CvtToPLine(mapinfoGeo);

  MapInfo. do ('xx=objectnodex(' + mapinfoGeo + ',' + Inttostr(partIndex) + ',' + Inttostr(nodeIndex) + ')');
  MapInfo. do ('yy=objectnodey(' + mapinfoGeo + ',' + Inttostr(partIndex) + ',' + Inttostr(nodeIndex) + ')');
  floatX := MapInfo.Eval('Format$((xx-fix(xx)),"##.######")');
  floatY := MapInfo.Eval('Format$((yy-fix(yy)),"##.######")');
  intX := MapInfo.Eval('fix(xx)');
  intY := MapInfo.Eval('fix(yy)');

  point := TKDPoint.Create();
  point.X := intX + floatX;
  point.Y := intY + floatY;

  {
point := TKDPoint.Create();
  point.X := MapInfo.Eval('objectnodex(' + mapinfoGeo + ',' + Inttostr(partIndex) + ',' + Inttostr(nodeIndex) + ')');
  point.Y := MapInfo.Eval('objectnodey(' + mapinfoGeo + ',' + Inttostr(partIndex) + ',' + Inttostr(nodeIndex) + ')');
  }
  result := point;
end;

///@author: ma
///@date: 2006.04.21
///@description: 查询mapinfo图形对象所包含的片断数。
///@para mapinfoGeo: mapinfo图形对象名称
///@return: 片断个数

function TKDMapinfoProxy.QueryPartsOfGeomety(mapinfoGeo: string): integer;
var
  info: string;
begin
  info := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ', ' + Inttostr(OBJ_INFO_NPOLYGONS) + ')');
  if (Trim(info) = '') then
    result := 1
  else
    result := StrToInt(info);
end;

///@author: ma
///@date: 2006.04.4.9
///@description: 查询mapinfo图形对象的某个片断所包含的节点的个数。
///@para mapinfoGeo: mapinfo图形对象名称
///@para partIndex: mapinfo图形对象的片断索引
///@return: 节点的个数

function TKDMapinfoProxy.QueryNodeCount(mapinfoGeo: string; partIndex: integer): integer;
var
  geoType: integer;
begin
  geoType := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ',  ' + Inttostr(OBJ_INFO_TYPE) + ')');
  case geoType of
    OBJ_TYPE_POINT: //point
      begin
        result := 1;
      end;
    OBJ_TYPE_TEXT: //text
      begin
        result := 0;
      end;
    OBJ_TYPE_PLINE, OBJ_TYPE_REGION: //pline regetion
      begin
        //try
        result := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ', ' + Inttostr(OBJ_INFO_NPOLYGONS + partIndex) + ')');
        //except
         //result := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ', ' + Inttostr(OBJ_INFO_NPNTS) + ')');
          //WarningBox(Inttostr(result));
        //end;
      end;
    OBJ_TYPE_LINE, OBJ_TYPE_ARC: //Line, arc
      begin
        CvtToPLine(mapinfoGeo);
        result := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ', ' + Inttostr(OBJ_INFO_NPOLYGONS + partIndex) + ')');
      end; +

    OBJ_TYPE_ELLIPSE, OBJ_TYPE_RECT, OBJ_TYPE_ROUNDRECT: //ellipse, rectangle, amphitheatral
      begin
        CvtToRegion(mapinfoGeo);
        result := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ', ' + Inttostr(OBJ_INFO_NPOLYGONS + partIndex) + ')');
      end;
  end;

end;

procedure TKDMapinfoProxy.QueryNodePoint(mapinfoGeo: string; Polygon_num, node_num: integer; var X, Y: double);
begin
  X := MapInfo.Eval('ObjectNodeX(' + mapinfoGeo + ', ' + Inttostr(Polygon_num) + ', ' + Inttostr(node_num) + ')');
  Y := MapInfo.Eval('ObjectNodeY(' + mapinfoGeo + ', ' + Inttostr(Polygon_num) + ', ' + Inttostr(node_num) + ')');
end;

///@author: ma
///@date: 2006.04.4.9
///@description: 查询mapinfo图形对象所包含的节点的个数。
///@para mapinfoGeo: mapinfo图形对象名称
///@return: 节点的个数

function TKDMapinfoProxy.QueryNodeCount(mapinfoGeo: string): integer;
var
  geoType: integer;
begin
  geoType := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ',  ' + Inttostr(OBJ_INFO_TYPE) + ')');
  case geoType of
    OBJ_TYPE_POINT: //point
      begin
        result := 1;
      end;
    OBJ_TYPE_TEXT: //text
      begin
        result := 0;
      end;
    OBJ_TYPE_PLINE, OBJ_TYPE_REGION: //pline regetion
      begin
        result := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ', ' + Inttostr(OBJ_INFO_NPNTS) + ')');
      end;
    OBJ_TYPE_LINE, OBJ_TYPE_ARC: //Line, arc
      begin
        CvtToPLine(mapinfoGeo);
        result := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ', ' + Inttostr(OBJ_INFO_NPNTS) + ')');
      end;
    OBJ_TYPE_ELLIPSE, OBJ_TYPE_RECT, OBJ_TYPE_ROUNDRECT: //ellipse, rectangle, amphitheatral
      begin
        CvtToRegion(mapinfoGeo);
        result := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ', ' + Inttostr(OBJ_INFO_NPNTS) + ')');
      end;
  end;
  {
    geoType := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ',  ' + Inttostr(OBJ_INFO_TYPE) + ')');
    case geoType of
      OBJ_TYPE_POINT:
        begin
          result := 1; //point
          Exit;
        end;
      OBJ_TYPE_TEXT:
        begin
          result := 0; //text
          Exit;
        end;
      OBJ_TYPE_PLINE, OBJ_TYPE_REGION: MapInfo. do ('Bobj = ' + mapinfoGeo + ''); //pline regetion
      OBJ_TYPE_LINE: MapInfo. do ('Bobj = ConvertToPline(' + mapinfoGeo + ')'); //Line
      OBJ_TYPE_ARC: MapInfo. do ('Bobj = ConvertToPline(' + mapinfoGeo + ')'); //arc
      OBJ_TYPE_ELLIPSE: MapInfo. do ('Bobj = ConvertToPline(' + mapinfoGeo + ')'); //ellipse
      OBJ_TYPE_RECT: MapInfo. do ('Bobj = ConvertToPline(' + mapinfoGeo + ')'); //rectangle
      OBJ_TYPE_ROUNDRECT: MapInfo. do ('Bobj = ConvertToPline(' + mapinfoGeo + ')'); //amphitheatral
    end;

    result := MapInfo.Eval('ObjectInfo(Bobj, ' + Inttostr(OBJ_INFO_NPNTS) + ')');
    }
end;

///@author: ma
///@date: 2006.04.4.9
///@description: 将图形转换为折线对象。
///@para mapinfoGeo: mapinfo图形对象名称

procedure TKDMapinfoProxy.CvtToPLine(mapinfoGeo: string);
var
  geoType: integer;
begin
  geoType := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ',  ' + Inttostr(OBJ_INFO_TYPE) + ')');

  if (geoType <> OBJ_TYPE_POINT) and (geoType <> OBJ_TYPE_TEXT) and (geoType <> OBJ_TYPE_PLINE) then
    MapInfo. do (mapinfoGeo + ' = ConvertToPline(' + mapinfoGeo + ')');

  {
  if (geoType <> OBJ_TYPE_POINT) and (geoType <> OBJ_TYPE_TEXT) then
   raise Exception.Create('不能将点和文本对象转换成折线对象!');

  if (geoType <> OBJ_TYPE_PLINE) then
    MapInfo. do (mapinfoGeo + ' = ConvertToPline(' + mapinfoGeo + ')');
  }
end;

///@author: yzhou
///@date: 2006.04.21
///@description: 将图形转换为区域对象。
///@para mapinfoGeo: mapinfo图形对象名称

procedure TKDMapinfoProxy.CvtToRegion(mapinfoGeo: string);
var
  geoType: integer;
begin
  geoType := MapInfo.Eval('ObjectInfo(' + mapinfoGeo + ',  ' + Inttostr(OBJ_INFO_TYPE) + ')');

  if (geoType <> OBJ_TYPE_LINE) then
    CvtToPLine(mapinfoGeo);

  if (geoType <> OBJ_TYPE_POINT) and (geoType <> OBJ_TYPE_TEXT) then
    MapInfo. do (mapinfoGeo + ' = ConvertToRegion(' + mapinfoGeo + ')');

  {
if (geoType <> OBJ_TYPE_POINT) and (geoType <> OBJ_TYPE_TEXT) then
  raise Exception.Create('不能将点和文本对象转换成区域对象!');

  if (geoType <> OBJ_TYPE_LINE) then
   CvtToPLine(mapinfoGeo);

  MapInfo. do (mapinfoGeo + ' = ConvertToPline(' + mapinfoGeo + ')');
  }
end;

///@author: ma
///@date: 2006.4.6
///@description: 将线层中的线转节点反序
///@para strTableName: 图层名称
///@para rowID: 折线图形ID  (注:不能是复合线)

procedure TKDMapinfoProxy.LineAntitone(strTableName: string; RowID: integer);
var
  sourceNodesList: TObjectList;
  mapinfoSql: string;
  pt: TKDPoint;
  pLastIndex: integer;
  k: integer;
begin
  sourceNodesList := TObjectList.Create();
  MapInfo. do ('select * from ' + strTableName + ' where object and rowid=' + Inttostr(RowID) + ' into Temp');
  if self.QueryTableRecordCount('Temp') >= 1 then
  begin
    MapInfo. do ('fetch rec 1 from Temp');
    MapInfo. do ('Aobj = Temp.Obj');
    //查询节点
    QueryNodesOfGeomety('Aobj', 1, sourceNodesList);
    pLastIndex := sourceNodesList.IndexOf(sourceNodesList.Last()); //Mapinfo.EVAL('ObjectInfo(Aobj, 20)')-1;
    k := 1;
    while (pLastIndex >= 0) do
    begin
      pt := TKDPoint(sourceNodesList.Items[pLastIndex]);
      //修改节点
      mapinfoSql := 'Alter Object Aobj Node Set Position 1,' + Inttostr(k) + '(' + FloatToStr(pt.X) + ',' + FloatToStr(pt.Y) + ')';
      MapInfo. do (mapinfoSql);
      pLastIndex := pLastIndex - 1;
      k := k + 1;
    end;
    MapInfo. do ('update Temp set obj=Aobj where rowid=' + Inttostr(RowID));
    self.CommitTable(strTableName);
  end;
  self.CloseTable('Temp');
end;

function TKDMapinfoProxy.GetObjType(objName: string): integer;
begin
  result := MapInfo.Eval('ObjectInfo(' + objName + ', ' + Inttostr(OBJ_INFO_TYPE) + ')');
end;

///@author: yx
///@date:
///@description: 折线转换为区域。
///@para bm1: 源表
///@para bm2: 目标表

function TKDMapinfoProxy.ObjectCvtLine(bm1, bm2: string; ProBar: TProgressBar = nil): string;
var
  i, RecNum: Longint;
begin
  MapInfo. do ('SELECT * FROM ' + bm1);
  MapInfo. do ('SELECT * FROM ' + bm1 + ' INTO TmpTable'); // + ' WHERE 1<>1');
  RecNum := self.QueryTableRecordCount(bm1);
  if ProBar <> nil then
  begin
    ProBar.Min := 0;
    ProBar.Max := RecNum;
  end;

  for i := 1 to RecNum do
  begin
    if ProBar <> nil then
      ProBar.Position := i;

    MapInfo. do ('Fetch Rec ' + Inttostr(i) + ' From TmpTable');
    MapInfo. do ('Bobj = TmpTable.Obj');
    //MapInfo. do ('Bobj = ConvertToPline(Bobj)');
    CvtToPLine('BObj');
    MapInfo. do ('Insert Into ' + bm2 + '(Obj) Values (Bobj)');
  end;
  //MapInfo. do ('select * from TmpTable where Str$(Obj)="Line" or Str$(Obj)="Polyline" or Str$(Obj)="Arc" into selection');
  //MapInfo. do ('insert into ' + bm2 + ' (obj) select obj from selection');
  //MapInfo.do('select * from TmpTable where Str$(Obj)="Line" or Str$(Obj)="Polyline" or Str$(Obj)="Arc" into ' + bm2);
  result := '';
end;

///@author: yx
///@date:
///@description: 折线转换为区域。
///@para bm1: 源表
///@para bm2: 目标表

function TKDMapinfoProxy.ObjectCvtPolygon(bm1, bm2: string): string;
begin
  //MapInfo. do ('select * from ' + bm1);

  MapInfo. do ('select * from ' + bm1 + ' into TmpTable');
  if self.QuerySelctionCount() < 1 then
    Exit;

  MapInfo. do ('Objects Enclose Into Table TmpTable');
  MapInfo. do ('select * from TmpTable Where Str$(Obj)="Region" or Str$(Obj)="Ellpse" or Str$(Obj)="Rectangle" or Str$(Obj)="Rounded Rectangle" into selection');
  MapInfo. do ('insert into ' + bm2 + ' (obj) select obj from selection');

  self.CloseTable('TmpTable');
  //MapInfo.do('select * from TmpTable Where Str$(Obj)="Region" or Str$(Obj)="Ellpse" or Str$(Obj)="Rectangle" or Str$(Obj)="Rounded Rectangle" into ' + bm2);
  //MapInfo.do('Rollback Table ' + bm1);
  result := '';
end;

///@author: yzhou
///@date: 2006.06.02
///@description: 用源层中的线构面放入目标层中。
///@para sourceTable: 源表
///@para destTable: 目标表

procedure TKDMapinfoProxy.ObjectCvtPolygonEx(sourceTable, destTable: string);
var
  mapinfoSql: string;
begin
  mapinfoSql := 'select * from ' + sourceTable + ' into selection';
  MapInfo. do (mapinfoSql);

  if (self.QuerySelctionCount() > 0) then
  begin
    mapinfoSql := 'Objects Enclose Into Table ' + destTable;
    MapInfo. do (mapinfoSql);
  end;
end;

/// 功能:返回点、线、面、文本层中不属于本层的对象个数
/// 作者:姚箫
/// 日期:2006.3.29
/// 参数说明:TableType ->检查类型
///                        bm2                ->表名

function TKDMapinfoProxy.CheckTableObject(TableType: TGrapiDataType; bm: string): integer;
//var
//  RecNum: integer;
begin
  if TableType = [gdtPoint] then
    MapInfo. do ('select * from ' + bm + ' Where Str$(Obj)<>"Point" into TmpTable')
  else
    if TableType = [gdtLine] then
      MapInfo. do ('select * from ' + bm + ' Where Str$(Obj)<>"Line" and Str$(Obj)<>"Polyline" and Str$(Obj)<>"Arc" into TmpTable')
    else
      if TableType = [gdtPolygon] then
        MapInfo. do ('select * from ' + bm + ' where Str$(Obj)<>"Region" and Str$(Obj)<>"Ellpse" and Str$(Obj)<>"Rectangle" and Str$(Obj)<>"Rounded Rectangle" into TmpTable')
      else
        if TableType = [gdtText] then
          MapInfo. do ('select * from ' + bm + ' Where Str$(Obj)<>"Text" into TmpTable');
  //RecNum := MapInfo.Eval('TableInfo(TmpTable, 8)');
  result := self.QueryTableRecordCount('TmpTable');
end;

///@author: yzhou
///@date: 2006.3.21
///@description: 提交对mapinfo表的修改并紧缩表
///@para tableName: tab表名

procedure TKDMapinfoProxy.SaveTable(tableName: string);
begin
  if TableExists(tableName) then
  begin
    self.CommitTable(tableName);
    MapInfo. do ('Pack Table ' + tableName + ' Graphic Data');
  end;
end;

///@author: yzhou
///@date: 2006.3.27
///@description: 提交对mapinfo表的修改
///@para tableName: tab表名

procedure TKDMapinfoProxy.CommitTable(tableName: string);
begin
  if TableExists(tableName) then
    MapInfo. do ('commit table ' + tableName);
end;

///@author: yzhou
///@date: 2006.4.5
///@description: 放弃对mapinfo表的修改
///@para tableName: tab表名

procedure TKDMapinfoProxy.RollbackTable(tableName: string);
begin
  if TableExists(tableName) then
    MapInfo. do ('Rollback table ' + tableName);
end;


///@author: yzhou
///@date: 2006.4.25
///@description: 将源表中除文本、点外的图形转换为折线放入目标表
///@para srcTableName: 源表名
///@para destTableName: 目标表名
///@para whereClause: where条件
///@fieldList: 要保留的属性字段列表(此参数要求两源表和目标表都包含此参数中的属性)

procedure TKDMapinfoProxy.CopyTableDataEx(srcTableName: string; destTableName: string; whereClause: string; fieldList: string);
var
  mapinfoSql: string;
begin

  if QuerySourceTableName(srcTableName) = QuerySourceTableName(destTableName) then
  begin
    raise Exception.Create('不能对同一张表进行复制操作!' + srcTableName + ' <> ' + destTableName);
    Exit;
  end;

  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select *';
  mapinfoSql := mapinfoSql + ' from ' + srcTableName;
  if Trim(whereClause) <> '' then
    mapinfoSql := mapinfoSql + ' where' + whereClause;
  mapinfoSql := mapinfoSql + ' into selection';
  MapInfo. do (mapinfoSql);

  if self.QuerySelctionCount() > 0 then
  begin
    mapinfoSql := '';
    mapinfoSql := mapinfoSql + ' insert into ' + destTableName;
    mapinfoSql := mapinfoSql + ' (obj';
    if Trim(fieldList) <> '' then
      mapinfoSql := mapinfoSql + ', ' + fieldList;
    mapinfoSql := mapinfoSql + ' )';
    mapinfoSql := mapinfoSql + ' select obj';
    if Trim(fieldList) <> '' then
      mapinfoSql := mapinfoSql + ', ' + fieldList;
    mapinfoSql := mapinfoSql + ' from selection';

    MapInfo. do (mapinfoSql);
  end;

end;

///@author: yzhou
///@date: 2006.3.22
///@description: 根据条件复制源表中的数据到目标表
///@para srcTableName: 源表
///@para destTableName: 目标表
///@para whereClause: where条件
///@remark: 要求源表和目标表有相同的表结构

procedure TKDMapinfoProxy.CopyTableData(srcTableName: string; destTableName: string; whereClause: string);
var
  mapinfoSql: string;
begin

  if QuerySourceTableName(srcTableName) = QuerySourceTableName(destTableName) then
  begin
    raise Exception.Create('不能对同一张表进行复制操作!' + srcTableName + ' <> ' + destTableName);
    Exit;
  end;

  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from ' + srcTableName;
  if (Trim(whereClause) <> '') then
    mapinfoSql := mapinfoSql + ' where ' + whereClause;
  mapinfoSql := mapinfoSql + ' into selection';
  MapInfo. do (mapinfoSql);

  if self.QuerySelctionCount() > 0 then
  begin
    mapinfoSql := 'insert into ' + destTableName;
    mapinfoSql := mapinfoSql + ' select * from selection';
    MapInfo. do (mapinfoSql);
  end;

  {
  srcCols := self.EmnuTableColumn(srcTableName, false);
  destCols := self.EmnuTableColumn(destTableName, false);

  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select ' + srcCols + ' from ' + srcTableName;
  mapinfoSql := mapinfoSql + whereClause;
  mapinfoSql := mapinfoSql + ' into selection';
  Mapinfo.do(mapinfoSql);

  if self.QuerySelctionCount() > 0 then
  begin
      srcCols := self.EmnuTableColumn('selection', false);
      mapinfoSql := '';
      mapinfoSql := mapinfoSql + ' insert into ' + destTableName + ' (' + destCols + ')';
      mapinfoSql := mapinfoSql + ' select ' + srcCols + ' from selection';
      Mapinfo.do(mapinfoSql);
  end;
  }

end;

///@author: yzhou
///@date: 2006.3.23
///@description: 根据条件复制源表中的图形数据到目标表
///@para srcTableName: 源表
///@para destTableName: 目标表
///@para whereClause: where条件

procedure TKDMapinfoProxy.CopyTableGhraphData(srcTableName: string; destTableName: string; whereClause: string);
var
  mapinfoSql: string;
begin

  if QuerySourceTableName(srcTableName) = QuerySourceTableName(destTableName) then
  begin
    raise Exception.Create('不能对同一张表进行复制操作!' + srcTableName + ' <> ' + destTableName);
    Exit;
  end;

  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select obj from ' + srcTableName;
  if Trim(whereClause) <> '' then
    mapinfoSql := mapinfoSql + ' where' + whereClause;
  mapinfoSql := mapinfoSql + ' into selection';
  MapInfo. do (mapinfoSql);

  if self.QuerySelctionCount() > 0 then
  begin
    mapinfoSql := '';
    mapinfoSql := mapinfoSql + ' insert into ' + destTableName + '(obj)';
    mapinfoSql := mapinfoSql + ' select obj from selection';
    MapInfo. do (mapinfoSql);
  end;

end;

///@author: yzhou
///@date: 2006.3.23
///@description: 用指定层中的对象擦除源表中的对象(内部擦除)
///@para srcTableName: 源表名 (不能是临时表)
///@para eraseTableName: 用于擦除操作的表名

procedure TKDMapinfoProxy.EraseObjects(srcTableName: string; eraseTableName: string);
var
  mapinfoSql: string;
  cols, Tempstr: string;
  i: integer;
begin

  if QuerySourceTableName(srcTableName) = QuerySourceTableName(eraseTableName) then
  begin
    raise Exception.Create('不能对同一张表进行擦除操作!');
    Exit;
  end;

  //源表上没有对象
  if (self.QueryTableRecordCount(srcTableName) < 1) then
    Exit;

  //选择源对象
  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from ' + srcTableName;
  mapinfoSql := mapinfoSql + ' into selection';
  MapInfo. do (mapinfoSql);
  MapInfo. do ('Set Target On');

  //擦除源对象
  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from ' + eraseTableName;
  mapinfoSql := mapinfoSql + ' into selection';
  MapInfo. do (mapinfoSql);

  if self.QuerySelctionCount() > 0 then
  begin
    //选择全部的列
    for i := 1 to self.QueryTableColumnCount(srcTableName) do
    begin
      Tempstr := self.QueryTableColumnName(srcTableName, i); //MapInfo.Eval('ColumnInfo (' + srcTableName + ',"COL' + Inttostr(i) + '",1)');
      cols := cols + Tempstr + '=' + Tempstr + ',';
    end;
    cols := LeftStr(cols, Length(cols) - 1);

    //擦除源对象
    MapInfo. do ('Objects Erase Into Target Data ' + cols);
    MapInfo. do ('Set Target Off');
  end;

end;

///@author: yzhou
///@date: 2006.3.27
///@description: 枚举指定表中的所有字段
///@para tableName: tab表名
///@para withName: 枚举时是否用表名作前缀

function TKDMapinfoProxy.EmnuTableColumn(tableName: string; withName: boolean = true): string;
var
  Columns: string;
  i: integer;
begin

  for i := 1 to self.QueryTableColumnCount(tableName) do
  begin
    if withName then
      Columns := Columns + ',' + tableName + '.' + Trim(self.QueryTableColumnName(tableName, i)) {MapInfo.Eval('ColumnInfo("' + tableName + '","col' + Inttostr(i) + '",1)'))}
    else
      Columns := Columns + ',' + Trim(self.QueryTableColumnName(tableName, i)); //MapInfo.Eval('ColumnInfo("' + tableName + '","col' + Inttostr(i) + '",1)'))
  end;

  result := Copy(Columns, 2, Length(Columns));
end;

///@author: yzhou
///@date: 2006.3.27
///@description: 获取临时表的源表名
///@para tableName: mapinfo临时表名
///@return: 源tab表名

function TKDMapinfoProxy.QuerySourceTableName(selectionName: string): string;
var
  srcName: string;
begin

  //srcName := trim(Mapinfo.EVAL('SelectionInfo(1)'));

  if (srcName = '') then
    srcName := selectionName;

  result := srcName;
end;

///@author: yzhou
///@date: 2006.3.27
///@description: 查询mapinfo当前选择集中的记录数
///@return: 记录数

function TKDMapinfoProxy.QuerySelctionTableName(): string;
begin
  result := Trim(MapInfo.Eval('SelectionInfo(1)'));
end;

function TKDMapinfoProxy.QuerySelctionCount(): integer;
begin
  result := StrToIntDef(MapInfo.Eval('SelectionInfo(' + Inttostr(SEL_INFO_NROWS) + ')'), -1);
end;

/// 功能:设置层编辑、浏览等属性
/// 作者:姚箫
/// 日期:2006.4.9
/// 参数说明:tableName                ->表名
///                        bUserBrowse            ->浏览
///                        bUserMap        ->
///                        bUserClose      ->关闭
///                        bUserRemove     ->移除
///                        bUserDisplayMap    ->显示

procedure TKDMapinfoProxy.SetTableEnable(tableName: string; bUserBrowse: boolean = true; bUserMap: boolean = true; bUserClose: boolean = true; bUserRemove: boolean = true; bUserDisplayMap: boolean = true);
var
  sUserBrowse, sUserClose, sUserMap, sUserRemoveMap, sUserDisplayMap: string;
begin
  sUserBrowse := 'ON';
  sUserClose := sUserBrowse;
  sUserMap := sUserBrowse;
  sUserRemoveMap := sUserBrowse;
  sUserDisplayMap := sUserBrowse;
  if not bUserBrowse then
    sUserBrowse := 'OFF';
  if not bUserMap then
    sUserClose := 'OFF';
  if not bUserClose then
    sUserMap := 'OFF';
  if not bUserRemove then
    sUserRemoveMap := 'OFF';
  if not bUserDisplayMap then
    sUserDisplayMap := 'OFF';
  MapInfo. do ('Set Table ' + tableName + ' UserBrowse ' + sUserBrowse
    + ' UserMap ' + sUserMap + ' UserClose ' + sUserClose + ' UserRemoveMap '
    + sUserRemoveMap + ' UserDisplayMap ' + sUserDisplayMap)
end;

/// 功能:设置进度条是否显示
/// 作者:姚箫
/// 日期:2006.4.9
/// 参数说明:bOn                ->进度条是否显示

procedure TKDMapinfoProxy.SetProgressBar(bOn: boolean = true);
begin
  if bOn then
    MapInfo. do ('Set ProgressBars On')
  else
    MapInfo. do ('Set ProgressBars Off');
end;

///@author: ma
///@date: 2006.3.27
///@description: 将多个相邻的面合并成一个对象
///@para strYTableName: 提供原有区域的图层
///@para strMBTableName: 目标图层

procedure TKDMapinfoProxy.UnitePolygon(strYTableName: string; strMBTableName: string; CurWinID: integer);
var
  colNum: integer;
  colStr: string;
  Tempstr: string;
  str1: string;
  recordCnt: integer;
  i, j, k: integer;
  RowID: string;
  newRowId: integer;
  mapinfoSql: string;
  whereClause: string;
  BgStr3: string;
  IntersectRow: integer;
  whereClause2: string;
  Notouch: integer;
  rowTest: integer;
begin
  if not TableExists(strYTableName) then
  begin
    raise Exception.Create('"' + strYTableName + '"没有打开,请先打开后再做相关操作!');
    Exit;
  end;
  if not TableExists(strMBTableName) then
  begin
    raise Exception.Create('"' + strMBTableName + '"没有打开,请先打开后再做相关操作!');
    Exit;
  end;

  //原图层另存为  YTabTemp
  self.CloseTable('YTabTemp');
  self.CloseTable('YTabTemp2');
  self.CloseTable('YTabTemp3');

  BgStr3 := 'C:\YTabTemp.TAB';
  MapInfo. do ('Commit Table ' + strYTableName + ' As "' + BgStr3 + '"');
  MapInfo. do ('Open Table  "' + BgStr3 + '" AS YTabTemp');
  MapInfo. do ('Add Map Window ' + Inttostr(CurWinID) + ' Layer YTabTemp');
  MapInfo. do ('Alter Table YTabTemp (Add HandFlag Smallint)');

  BgStr3 := 'C:\YTabTemp2.TAB';
  MapInfo. do ('Commit Table ' + strYTableName + ' As "' + BgStr3 + '"');
  MapInfo. do ('Open Table  "' + BgStr3 + '" AS YTabTemp2');
  MapInfo. do ('delete from YTabTemp2'); //清除中间层

  BgStr3 := 'C:\YTabTemp3.TAB';
  MapInfo. do ('Commit Table ' + strYTableName + ' As "' + BgStr3 + '"');
  MapInfo. do ('Open Table  "' + BgStr3 + '" AS YTabTemp3');
  MapInfo. do ('delete from YTabTemp3'); //清除中间层

  recordCnt := QueryTableRecordCount('YTabTemp');
  //逐一判断面层对象
  whereClause := ' where obj Intersects Aobj ';
  whereClause := whereClause + ' and (str$(obj)<>"Point" and str$(obj)<>"Text")';
  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select obj from YTabTemp ';
  mapinfoSql := mapinfoSql + whereClause;
  mapinfoSql := mapinfoSql + ' into Temp';

  whereClause2 := ' where (YTabTemp.obj Intersects Aobj) and not(YTabTemp.obj Entirely Within Aobj) and YTabTemp.HandFlag<>1';
  whereClause2 := whereClause2 + ' and (str$(YTabTemp.obj)<>"Point" and str$(YTabTemp.obj)<>"Text")';
  for i := 1 to recordCnt do
  begin
    Notouch := 1;
    MapInfo. do ('fetch rec ' + Inttostr(i) + ' from YTabTemp');
    MapInfo. do ('Aobj = YTabTemp.Obj');
    RowID := MapInfo.Eval('YTabTemp.rowid');
    MapInfo. do ('select * from YTabTemp3 where obj Intersects Aobj into Temp');
    IntersectRow := self.QueryTableRecordCount('Temp'); //MapInfo.Eval('tableinfo(Temp,8)');
    //判断是否是已经合并过的图形对象,如是则不在处理此图形
    if IntersectRow = 1 then
      continue;

    MapInfo. do (mapinfoSql);
    IntersectRow := self.QueryTableRecordCount('Temp'); //MapInfo.Eval('tableinfo(Temp,8)');
    //没有相邻的则直接插入到结果层,有则直接插入到结果层再合并,插入到结果层
    if IntersectRow = 1 then
    begin
      MapInfo. do ('insert into ' + strMBTableName + '(obj) select obj from Temp');
      MapInfo. do ('update YTabTemp set HandFlag=1 where rowid=' + RowID);
    end
    else
      if IntersectRow > 1 then
      begin
        MapInfo. do ('insert into YTabTemp2(obj) select obj from Temp');
        while (Notouch = 1) do
        begin
          goMapinfoProxy.SaveTable('YTabTemp2');
          MapInfo. do ('select * from YTabTemp2');
          if self.QuerySelctionCount() > 1 then
          begin
            MapInfo. do ('Objects Combine');
          end;
          self.SaveTable('YTabTemp2');
          MapInfo. do ('Add Map Window ' + Inttostr(CurWinID) + ' Layer YTabTemp2');

          MapInfo. do ('select obj from YTabTemp2');
          MapInfo. do ('fetch rec 1 from YTabTemp2');
          //MapInfo. do ('Aobj = YTabTemp2.Obj');
          //Mapinfo.do ('select YTabTemp.obj from YTabTemp,YTabTemp2 '+ whereClause2 +' into Temp2');
          MapInfo. do ('select * from YTabTemp' + whereClause2 + ' into Temp2');
          MapInfo. do ('update Temp2 set HandFlag=1');
          rowTest := self.QueryTableRecordCount('Temp2'); //MapInfo.Eval('tableinfo(Temp2,8)');
          if rowTest = 0 then //连续的区域已搜索完毕
            Notouch := 0;
          MapInfo. do ('insert into YTabTemp2(obj) select obj from Temp2');
          MapInfo. do ('insert into ' + strMBTableName + '(obj) select obj from YTabTemp2');
          MapInfo. do ('insert into  YTabTemp3(obj)  select obj from YTabTemp2');
          MapInfo. do ('delete from YTabTemp2'); //清除中间层
        end;
      end;
    //fenjie
    MapInfo. do ('commit Table ' + strMBTableName);
    self.Disaggregate(strMBTableName, false);
    self.CloseTable('Temp');
    self.CloseTable('Temp2');
  end;
  MapInfo. do ('Drop Table YTabTemp3');
  MapInfo. do ('Drop Table YTabTemp2');
  MapInfo. do ('Drop Table YTabTemp');
end;


///@author: yzhou
///@date: 2006.9.22
///@description: 线层分割面层
///@para lineTable: 线图层
///@para polyTable: 面图层

procedure TKDMapinfoProxy.LineSplitPolyong_2(lineTable: string; polyTable: string);
var
  tempTable: string;
  mapinfoSql: string;
  redCnt, newRowId, i, j, k: integer;
  RowID: string;
  colStr: string;
  str1, Tempstr, strFields: string;
  fPoint: TKDPoint;
  lPoint: TKDPoint;
begin
  if not self.TableExists(lineTable) then
  begin
    raise Exception.Create('"' + lineTable + '"没有打开,请先打开后再做相关操作!');
    Exit;
  end;
  if not self.TableExists(polyTable) then
  begin
    raise Exception.Create('"' + polyTable + '"没有打开,请先打开后再做相关操作!');
    Exit;
  end;

  tempTable := 'ApplicationTempTable';
  if (not self.TableExists(tempTable)) then
  begin
    self.CloneTableStructure(polyTable, AppPath + 'ApplicationTempTable.Tab');
    self.OpenTable(AppPath + 'ApplicationTempTable.Tab', 'ApplicationTempTable');
  end;
  //self.AddTable(tempTable, CurWinID);
  //MapInfo. do ('Set Map Window  ' + Inttostr(CurWinID) + ' Layer ' + tempTable + ' Editable On');

  MapInfo. do ('select * from ' + lineTable + ' where str$(obj)="Polyline" into Temp');
  //循环线层
  redCnt := self.QuerySelctionCount();
  newRowId := redCnt + 1;
  for i := 1 to redCnt do
  begin
    MapInfo. do ('fetch rec ' + Inttostr(i) + ' from Temp');
    MapInfo. do ('Aobj = Temp.Obj');

    fPoint := goMapinfoProxy.QueryNodeOfGeomety('Aobj', 1, 1);
    lPoint := goMapinfoProxy.QueryNodeOfGeomety('Aobj', 1, goMapinfoProxy.QueryNodeCount('Aobj', 1));

    mapinfoSql := ' select * from RegionTable';
    mapinfoSql := mapinfoSql + ' where RegionTable.obj Intersects Aobj ';
    mapinfoSql := mapinfoSql + ' and (str$(RegionTable.obj)<>"Point" and str$(RegionTable.obj)<>"Text")';
    mapinfoSql := mapinfoSql + ' and not (Buffer(RegionTable.obj, 100, -0.6, "M") contains CreatePoint(' + FloatToStr(fPoint.X) + ', ' + FloatToStr(fPoint.Y) + '))';
    mapinfoSql := mapinfoSql + ' and not (Buffer(RegionTable.obj, 100, -0.6, "M") contains CreatePoint(' + FloatToStr(lPoint.X) + ', ' + FloatToStr(lPoint.Y) + '))';
    mapinfoSql := mapinfoSql + ' and (ObjectLen(Overlap(RegionTable.obj, Aobj), "M") > 0.01)';
    mapinfoSql := mapinfoSql + ' and int(objectinfo(IntersectNodes(Buffer(RegionTable.obj, 100, -0.6, "M"), Aobj, 7), 20)) > 1';
    //    mapinfoSql := mapinfoSql + ' and int(objectinfo(IntersectNodes(ExtractNodes(RegionTable.obj, 1, 1, 1, 1), Aobj, 7), 20)) > 1';
    mapinfoSql := mapinfoSql + ' into tbp_temp_table';
    mapinfoSql := StringReplace(mapinfoSql, 'RegionTable', polyTable, [rfReplaceAll]);

    MapInfo. do (mapinfoSql);

    for k := 1 to self.QuerySelctionCount() do
    begin
      MapInfo. do ('fetch rec ' + Inttostr(k) + ' from tbp_temp_table');
      self.DeleteTable(tempTable);

      RowID := MapInfo.Eval('tbp_temp_table.rowid');
      MapInfo. do ('Bobj = ConvertToPLine(tbp_temp_table.obj)');
      MapInfo. do ('insert into ' + tempTable + ' (obj) values(Bobj)');

      MapInfo. do ('insert into ' + tempTable + ' (obj) values(Aobj)');
      //可能会变形(产生拓扑问题)
      self.AutoSnap(tempTable, 1E-2, 'm', '');

      self.ObjectCvtPolygonEx(tempTable, tempTable);
      //Mapinfo. do ('select * from ' + tempTable + ' Objects Enclose Into Table' + tempTable);

      MapInfo. do ('select * from ' + tempTable + ' where str$(obj)="Polyline"');
      MapInfo. do ('delete from selection');

      for j := 1 to self.QueryTableColumnCount(tempTable) do
      begin
        str1 := self.QueryTableColumnName(tempTable, j);
        if (self.QueryTableColumnType(tempTable, str1) = COL_INFO_NAME) then
          Tempstr := Tempstr + str1 + '="' + MapInfo.Eval('tbp_temp_table.' + str1) + '",'
        else
          Tempstr := Tempstr + str1 + '=' + MapInfo.Eval('tbp_temp_table.' + str1) + ',';
      end;
      colStr := LeftStr(Tempstr, Length(Tempstr) - 1);
      MapInfo. do ('update ' + tempTable + ' set ' + colStr);

      MapInfo. do ('Bobj = tbp_temp_table.obj');
      self.CopyTableData(tempTable, polyTable, ' (obj Intersects Bobj) and Area(Overlap(obj, Bobj), "sq m") > 0.1');

      MapInfo. do ('select * from tbp_temp_table where rowid = ' + RowID);
      MapInfo. do ('delete from selection');
    end;
  end;
  self.DropTable(tempTable);
end;

///@author: ma
///@date: 2006.3.27
///@description: 线层分割面层
///@para strLineTableName: 线图层
///@para strPolygonTableName: 面图层

procedure TKDMapinfoProxy.LineSplitPolygon(strLineTableName: string; strPolygonTableName: string);
var
  colNum: integer;
  i: integer;
  mapinfoSql: string;
  whereClause: string;
  colStr: string;
  str1, Tempstr: string;
  RowID: string;
  redCnt: integer;
  cutterId: integer;
begin
  if not TableExists(strLineTableName) then
  begin
    raise Exception.Create('"' + strLineTableName + '"没有打开,请先打开后再做相关操作!');
    Exit;
  end;
  if not TableExists(strPolygonTableName) then
  begin
    raise Exception.Create('"' + strPolygonTableName + '"没有打开,请先打开后再做相关操作!');
    Exit;
  end;

  for i := 1 to self.QueryTableColumnCount(strPolygonTableName) do
  begin
    str1 := self.QueryTableColumnName(strPolygonTableName, i);
    Tempstr := Tempstr + str1 + '=' + str1 + ',';
  end;
  colStr := LeftStr(Tempstr, Length(Tempstr) - 1);

  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select obj from RegionTable';
  mapinfoSql := mapinfoSql + ' where RegionTable.obj Intersects Aobj ';
  mapinfoSql := mapinfoSql + ' and (str$(RegionTable.obj)<>"Point" and str$(RegionTable.obj)<>"Text")';
  mapinfoSql := mapinfoSql + ' and (ObjectLen(Overlap(RegionTable.obj, Aobj), "M") > 0.01)';
  mapinfoSql := mapinfoSql + ' and int(objectinfo(IntersectNodes(ExtractNodes(RegionTable.obj, 1, 1, 1, 1), Aobj, 7), 20)) > 1';
  mapinfoSql := mapinfoSql + ' into selection';
  mapinfoSql := StringReplace(mapinfoSql, 'RegionTable', strPolygonTableName, [rfReplaceAll]);

  MapInfo. do ('select * from ' + strLineTableName + ' where str$(obj)="Polyline" into Temp');
  //循环线层
  redCnt := self.QuerySelctionCount();
  for i := 1 to redCnt do
  begin
    MapInfo. do ('fetch rec ' + Inttostr(i) + ' from Temp');
    MapInfo. do ('Aobj = Temp.Obj');
    RowID := MapInfo.Eval('Temp.rowid');

    MapInfo. do (mapinfoSql);
    if (self.QuerySelctionCount() > 0) then
    begin
      MapInfo. do ('Set Target On');

      MapInfo. do ('select obj from Temp where rowid=' + RowID + ' into selection');
      MapInfo. do ('Create Cutter Into Target');
      cutterId := self.QueryTableRecordCount(strPolygonTableName);

      MapInfo. do ('Objects Split Into Target Data ' + colStr);
      MapInfo. do ('delete from ' + strPolygonTableName + ' where rowid = ' + Inttostr(cutterId));

    end;
  end;
  //分解对象
  Disaggregate(strPolygonTableName, false);

  goMapinfoProxy.CloseTable('Temp');
end;

///@author: ma
///@date: 2006.3.29
///@description: 用源层中的对象擦除目标层中的对象,以参数传递的方式指出是内部还是外部擦除
///@para strYTableName: 面图层(擦除图层)
///@para strMBTableName: 目标层(被擦除图层)
///@para bBosom: 默认檫除内部
procedure TKDMapinfoProxy.EarsureObj(strYTableName: string; strMBTableName: string; bBosom: boolean = true);
var
  whereClause: string;
  colNum: integer;
  i: integer;
  str1: string;
  Tempstr: string;
  colStr: string;
begin
  colNum := self.QueryTableColumnCount(strMBTableName);
  for i := 1 to colNum do
  begin
    str1 := self.QueryTableColumnName(strMBTableName, i);
    Tempstr := Tempstr + str1 + '=' + str1 + ',';
  end;
  colStr := LeftStr(Tempstr, Length(Tempstr) - 1);
  whereClause := ' where str$(obj)<>"Line"  and str$(obj)<>"Polyline" ';
  whereClause := whereClause + ' and (str$(obj)<>"Point" and str$(obj)<>"Text")';
  //选中要檫除的图层所有图形,设为目标
  MapInfo. do ('select * from ' + strMBTableName);
  MapInfo. do ('Set Target On');
  //选择檫除图形
  MapInfo. do ('select * from ' + strYTableName + whereClause);
  if self.QuerySelctionCount() > 0 then
  begin
    //执行檫除,保存目标层
    if bBosom then
      MapInfo. do ('Objects Erase Into Target Data ' + colStr)
    else
      MapInfo. do ('Objects Intersect Into Target Data ' + colStr);
  end;
  //分解
  self.CommitTable(strMBTableName);
  self.Disaggregate(strMBTableName, false);
end;

///@author: yzhou
///@date: 2006.10.08
///@description: 检查一个层上是否有面相重合的情况
///@para strTableName: 被检查的层
///@para errorViewTable: 错误显示层
///@para toleranceArea: 可容忍的重复部分的面积
///@para units: 容差面积的单位
///@return: 返回真则为有重面情况,反之。

function TKDMapinfoProxy.CheckRepeatPolygon(checkedTable, errorViewTable : string; toleranceArea: double; units: string) : boolean;
var
    mapinfoSql: string;
begin
    self.ClearTable(errorViewTable);

    mapinfoSql := 'select * from ' + checkedTable + ' where str$(obj)="Region"';
    MapInfo. do (mapinfoSql);

    if self.QuerySelctionCount > 0 then
    begin
        try
            mapinfoSql := 'Objects Check From Selection Into Table ' + errorViewTable + ' Overlap Gap ' + FloatToStr(toleranceArea) + ' Units "' + units + '" Pen (1,2,0)  Brush (2,16776960,0)';
            MapInfo. do (mapinfoSql);
        except
        end;
    end;

    if self.QueryTableRecordCount(errorViewTable) > 0 then
        result := true
    else
        result := false;
end;

///@author: ma
///@date: 2006.3.29
///@description: 检查一个层上是否有面相离、相重合的情况
///@para strTableName: 面图层
///@para bIntersect: 检查标志
///@para bBosom:返回真 则为有重合面(不包括共边)

function TKDMapinfoProxy.CheckPolygonState(strTableName: string; var rowId : string ): boolean;
var
  isOverLap: boolean;
  whereClause: string;
  mapinfoSql: string;
  objType: string;
  recordCnt: integer;
  i: integer;
  queryCnt : integer;
  test : double;
begin
  if not TableExists(strTableName) then
  begin
    raise Exception.Create('"' + strTableName + '"没有打开,请先打开后再做相关操作!');
    Exit;
  end;

  whereClause := ' where obj Intersects Aobj and Area(Overlap(obj,Aobj), "sq m") > 0.1 ';
  whereClause := whereClause + ' and (str$(obj)<>"Point" and str$(obj)<>"Text")';

  recordCnt := QueryTableRecordCount(strTableName);
  isOverLap := false;
  for i := 1 to recordCnt do
  begin
      MapInfo. do ('fetch rec ' + Inttostr(i) + ' from ' + strTableName);

      rowId := MapInfo.Eval(strTableName + '.rowid');
      MapInfo. do ('Aobj = ' + strTableName + '.Obj');

      mapinfoSql := '';
      mapinfoSql := mapinfoSql + ' select Area(Overlap(obj,Aobj), "sq m") "TT" from ' + strTableName;
      mapinfoSql := mapinfoSql + whereClause;
      mapinfoSql := mapinfoSql + ' and RowId <> ' + rowId;
      mapinfoSql := mapinfoSql + ' into Temp';
      MapInfo. do (mapinfoSql);

      test := MapInfo.Eval('temp.TT');
      queryCnt := self.QuerySelctionCount();
      if queryCnt > 1 then
      begin
        isOverLap := true;
        Break;
      end;
  end;
  goMapinfoProxy.CloseTable('Temp');
  result := isOverLap;
end;

///@author: ma
///@date: 2006.3.29
///@description: 将一个面层中小于指定面积的面与其相邻的大面进行合并
///@para strTableName: 面图层
///@para intArea: 给定的面积
///注意:

procedure TKDMapinfoProxy.UnitePiecePolygon(strTableName: string; intArea: double = 100);
var
  recordCnt: integer;
  i: integer;
  whereClause: string;
  mapinfoSql: string;
  RowID: string;
  whereClause2: string;
  rowIdStr: string;
  BgStr3: string;
  oneOver: integer;
  colNum: integer;
  str1: string;
  Tempstr: string;
  colStr: string;
  handFlag: integer;
begin
  if not TableExists(strTableName) then
  begin
    raise Exception.Create('"' + strTableName + '"没有打开,请先打开后再做相关操作!');
    Exit;
  end;
  goMapinfoProxy.CloseTable('YTabTemp');
  goMapinfoProxy.CloseTable('YTabTemp3');
  BgStr3 := 'C:\YTabTemp.TAB';
  MapInfo. do ('Commit Table ' + strTableName + ' As "' + BgStr3 + '"');
  MapInfo. do ('Open Table  "' + BgStr3 + '" AS YTabTemp');
  MapInfo. do ('delete from YTabTemp'); //清除中间层

  BgStr3 := 'C:\YTabTemp3.TAB';
  MapInfo. do ('Commit Table ' + strTableName + ' As "' + BgStr3 + '"');
  MapInfo. do ('Open Table  "' + BgStr3 + '" AS YTabTemp3');
  MapInfo. do ('Alter Table YTabTemp3 (Add HandFlag Smallint)');

  whereClause := ' where obj Intersects Aobj and proportionoverlap(Aobj,obj)<>1  and handFlag<>1 and';
  whereClause := whereClause + ' Area(obj, "sq m") in any(select max(Area(obj, "sq m")) ';
  whereClause := whereClause + ' from YTabTemp3  where obj Intersects Aobj and proportionoverlap(Aobj,obj)<>1  and handFlag<>1 )';
  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from YTabTemp3';
  mapinfoSql := mapinfoSql + whereClause;
  mapinfoSql := mapinfoSql + ' into Temp2';

  //找到面积小于100 的面集合
  MapInfo. do ('select * from YTabTemp3 where HandFlag<>1 and Area(obj, "sq m")<' + FloatToStr(intArea) + ' into Temp');
  recordCnt := MapInfo.Eval('tableinfo(Temp,8)');
  if recordCnt = 0 then
  begin
    Exit;
  end;
  while (recordCnt <> 0) do
  begin
    for i := 1 to recordCnt do
    begin
      MapInfo. do ('fetch rec ' + Inttostr(i) + ' from Temp');
      MapInfo. do ('Aobj = Temp.Obj');
      RowID := MapInfo.Eval('Temp.rowid');
      //找到与其相邻的最大的面
      MapInfo. do (mapinfoSql);

      MapInfo. do ('insert into YTabTemp(Obj) values(Aobj)'); //插入到中间层
      MapInfo. do ('update Temp set HandFlag=1 where rowid=' + RowID);

      if self.QueryTableRecordCount('Temp2') < 1 then
        continue
      else
      begin
        MapInfo. do ('insert into YTabTemp(obj) select obj from Temp2'); //插入到中间层

        MapInfo. do ('update Temp2 set HandFlag=1'); //   set hand flag
        //combin
        MapInfo. do ('select * from YTabTemp where object');
        if self.QuerySelctionCount > 1 then
          MapInfo. do ('Objects Combine');
        MapInfo. do ('insert into YTabTemp3(obj) select obj from YTabTemp');
        MapInfo. do ('delete from YTabTemp');
      end;
    end;
    MapInfo. do ('select * from YTabTemp3 where HandFlag<>1 and Area(obj, "sq m")<' + FloatToStr(intArea) + ' into Temp');
    recordCnt := MapInfo.Eval('tableinfo(Temp,8)');
  end;
  //删除重叠的小面
  MapInfo. do ('commit table YTabTemp3');
  MapInfo. do ('Pack Table  YTabTemp3 Graphic Data');
  MapInfo. do ('select * from YTabTemp3 into Temp');
  recordCnt := MapInfo.Eval('tableinfo(Temp,8)');
  for i := 1 to recordCnt do
  begin
    MapInfo. do ('fetch rec ' + Inttostr(i) + ' from Temp');
    MapInfo. do ('Aobj = Temp.Obj');
    MapInfo. do ('select * from YTabTemp3 where obj intersects Aobj and proportionoverlap(obj,Aobj)=1  and Area(obj, "sq m")<>(Area(Aobj, "sq m"))  into Temp2');
    if self.QueryTableRecordCount('Temp') >= 1 then
      MapInfo. do ('update Temp2 set HandFlag=2')
  end;
  MapInfo. do ('select * from YTabTemp3 where HandFlag=2 into Temp');
  MapInfo. do ('Delete from Temp');
  //更新结果层
  MapInfo. do ('delete from ' + strTableName);
  MapInfo. do ('insert into ' + strTableName + '(obj) select obj from YTabTemp3');
  MapInfo. do ('commit table ' + strTableName);

  Disaggregate(strTableName, false);
  MapInfo. do ('Drop Table YTabTemp3');
  MapInfo. do ('Drop Table YTabTemp');
  goMapinfoProxy.CloseTable('Temp');
  goMapinfoProxy.CloseTable('Temp2');
end;

///@author: yzhou
///@date: 2006.05.18
///@description: 合并图层中指定的对象
///@para strTableName: 表名称
///@para whereClause: where条件

procedure TKDMapinfoProxy.UonionObject(tableName: string; whereClause: string);
var
  mapinfoSql: string;
  Tempstr, cols: string;
  i: integer;
begin
  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from ' + tableName;
  mapinfoSql := mapinfoSql + ' Where Str$(obj) <> "Text"';
  if (Trim(whereClause) <> '') then
    mapinfoSql := mapinfoSql + ' and ' + whereClause;
  mapinfoSql := mapinfoSql + ' into selection';
  MapInfo. do (mapinfoSql);

  if (self.QuerySelctionCount() > 1) then
  begin
    //选择全部的列
    for i := 1 to self.QueryTableColumnCount(tableName) do
    begin
      Tempstr := self.QueryTableColumnName(tableName, i);
      cols := cols + Tempstr + '=' + Tempstr + ',';
    end;
    cols := LeftStr(cols, Length(cols) - 1);

    mapinfoSql := 'Objects Combine Data ' + cols;
    MapInfo. do (mapinfoSql);
  end;

end;

///@author: ma
///@date: 2006.3.30
///@description: 分解图形
///@para strTableName: 图层名称

procedure TKDMapinfoProxy.Disaggregate(strTableName: string; bAll: boolean);
var
  colNum: integer; //列数
  str1: string; //列名
  Tempstr, ba: string; //
  colStr: string; //
  i: integer; //增量
begin
  colNum := self.QueryTableColumnCount(strTableName);
  for i := 1 to colNum do
  begin
    str1 := self.QueryTableColumnName(strTableName, i);
    Tempstr := Tempstr + str1 + '=' + str1 + ',';
  end;
  if bAll then
    ba := 'All'
  else
    ba := '';

  colStr := LeftStr(Tempstr, Length(Tempstr) - 1);
  // 分解
  MapInfo. do ('Select * From ' + strTableName + ' Where Str$(obj) <> "Text" into selection');
  if self.QuerySelctionCount > 0 then
    MapInfo. do ('Objects Disaggregate ' + ba + ' Into Table ' + strTableName + ' Data ' + colStr);
  self.CommitTable(strTableName);
end;

///@author: ma
///@date: 2006.4.3
///@description: 新添加的点是按一定范围检索,在此范围内不能有其他点、线,并且不能有图斑边界
///@para strTableName: 图层名称
///@para X,Y: 缓冲区中心
///@para radius: 缓冲区半径
///@para flag: 图层类型 1点、2线、3面
///返回为真则存在不符和条件的

function TKDMapinfoProxy.CheckTableObjec(X, Y: double; strTableName: string; radius: double; flag: integer): boolean;
var
  mapinfoSql: string;
  whereClause: string;

begin
  case flag of
    //点、线、面
    1: whereClause := ' where obj Entirely Within Bobj ';
    2: whereClause := ' where ObjectLen(overlap(obj,Bobj),"M" )>0 ';
    3: whereClause := ' where proportionoverlap(obj,Bobj)>0 ';
  end;
  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from ' + strTableName;
  mapinfoSql := mapinfoSql + whereClause;
  mapinfoSql := mapinfoSql + ' into Temp';
  MapInfo. do ('Create Point Into  Variable  Aobj(' + FloatToStr(X) + ',  ' + FloatToStr(Y) + ')');
  MapInfo. do ('Bobj= Buffer( Aobj, 100, ' + FloatToStr(radius) + ', "m")');
  MapInfo. do (mapinfoSql);

  if self.QueryTableRecordCount('Temp') >= 1 then
    result := true
  else
    result := false;

  goMapinfoProxy.CloseTable('Temp');
end;

{///@author: yzhou
///@date: 2006.3.17
///@description: 打断将线层中的对象全部打断,并删除原来的对象
///@para tableName: 被打断的tab表名
///@para splitTableName: 用于打断操作的tab表名
///@remark: (1)不支持自相交的线对象;
/// (2)不支持对mapinfo中临时表的操作;
/// (3)不能对两条线共线进行打断

procedure TKDMapinfoProxy.SplitLineTable(tableName: string; splitTableName: string);
var
  sourceNodesList, dirtyNodesList, tempNodesList: TObjectList;
  pt: TKDPoint;
  recordCnt: integer;
  i, j, k: integer;
  rowID: string;
  newRowId: integer;
  mapinfoSql: string;
  SplitObjsId: TStringList;
  tagetMapinfoObj, resultMapinfoObj: string;
  whereClause: string;
begin
  tagetMapinfoObj := 'aobj';
  resultMapinfoObj := 'bobj';

  if not TableExists(tableName) then
  begin
    raise Exception.Create('"' + tableName + '"没有打开,请先打开后再做相关操作!');
    Exit;
  end;

  try
    sourceNodesList := TObjectList.Create();
    dirtyNodesList := TObjectList.Create();
    tempNodesList := TObjectList.Create();
    SplitObjsId := TStringList.Create();

    //

    recordCnt := QueryTableRecordCount(tableName);
    newRowId := recordCnt + 1;
    for i := 1 to recordCnt do
    begin
      MapInfo. do ('fetch rec ' + IntToStr(i) + ' from ' + tableName);
      rowID := MapInfo.Eval(tableName + '.rowid');

      //选择当前线对象
      mapinfoSql := '';
      mapinfoSql := mapinfoSql + ' select * from ' + tableName;
      mapinfoSql := mapinfoSql + ' where rowid = ' + rowID;
      mapinfoSql := mapinfoSql + ' into Selection';
      MapInfo. do (mapinfoSql);

      //设置为目标
      MapInfo. do (tagetMapinfoObj + ' = Selection.Obj');
      MapInfo. do ('Set Target On');
      //查询节点
      QueryNodesOfGeomety(tagetMapinfoObj, 1, sourceNodesList);


      //选取相交的线对象
      if Trim(tableName) = Trim(splitTableName) then
      begin
        //选择自相交
        mapinfoSql := '';
        mapinfoSql := mapinfoSql + ' select * from ' + splitTableName;
        mapinfoSql := mapinfoSql + ' where rowid <> ' + rowID;
        mapinfoSql := mapinfoSql + ' and rowid <= ' + IntToStr(recordCnt);
        mapinfoSql := mapinfoSql + ' and Obj Intersects ' + tagetMapinfoObj;
        mapinfoSql := mapinfoSql + ' and (str$(obj)<>"Point" and str$(obj)<>"Text")';
        mapinfoSql := mapinfoSql + ' into Selection';
      end
      else
      begin
        //选择与其它层相交
        mapinfoSql := '';
        mapinfoSql := mapinfoSql + ' select * from ' + splitTableName;
        mapinfoSql := mapinfoSql + ' where Obj Intersects ' + tagetMapinfoObj;
        mapinfoSql := mapinfoSql + ' and (str$(obj)<>"Point" and str$(obj)<>"Text")';
        mapinfoSql := mapinfoSql + ' into Selection';
      end;
      MapInfo. do (mapinfoSql);

      if QuerySelctionCount() > 0 then
      begin
        MapInfo. do ('Objects Overlay Into Target');

        //加入交点后的源线对象
        mapinfoSql := '';
        mapinfoSql := mapinfoSql + ' select * from ' + tableName;
        mapinfoSql := mapinfoSql + ' where rowid = ' + rowID;
        mapinfoSql := mapinfoSql + ' into Selection';
        MapInfo. do (mapinfoSql);
        MapInfo. do (tagetMapinfoObj + ' = Selection.Obj');
        //查询节点
        QueryNodesOfGeomety(tagetMapinfoObj, 1, tempNodesList);

        if sourceNodesList.Count < tempNodesList.Count then
        begin
          //前后节点序不同时将dirtyNodes反向
          pt := TKDPoint(tempNodesList.Items[tempNodesList.Count - 1]);
          if pt.IsEqual(TKDPoint(sourceNodesList.Items[0])) = true then
          begin
            dirtyNodesList.Clear();
            j := tempNodesList.Count - 1;

            while j >= 0 do
            begin
                pt := TKDPoint(tempNodesList.Items[j]);
                dirtyNodesList.Add(pt);

                dec(j);
            end;
          end;

          //创建Pline对象
          mapinfoSql := 'Create pline into variable ' + resultMapinfoObj + ' 0 ';
          MapInfo. do (mapinfoSql);

          k := 0;
          j := 0;
          while (j < sourceNodesList.Count) and (k < dirtyNodesList.Count) do
          begin

            pt := TKDPoint(dirtyNodesList.Items[k]);
            if pt.IsEqual(TKDPoint(sourceNodesList.Items[j])) = true then
            begin
              //加入节点
              mapinfoSql := 'Alter Object  ' + resultMapinfoObj + '  Node  Add (' + FloatToStr(pt.X) + ',' + FloatToStr(pt.Y) + ')';
              MapInfo. do (mapinfoSql);

              inc(k);
              inc(j);
            end
            else
            begin
              //加入节点
              mapinfoSql := 'Alter Object  ' + resultMapinfoObj + '  Node  Add (' + FloatToStr(pt.X) + ',' + FloatToStr(pt.Y) + ')';
              MapInfo. do (mapinfoSql);

              //防止只含有一个节点的伪线段
              if (self.QueryNodeCount(resultMapinfoObj, 1)) > 1 then
              begin
                //复制加入交点后的源线对象
                mapinfoSql := '';
                mapinfoSql := mapinfoSql + ' insert into ' + tableName;
                mapinfoSql := mapinfoSql + ' select * from Selection';
                MapInfo. do (mapinfoSql);

                //修改为打断后的线对象
                mapinfoSql := 'update ' + tableName + ' set obj = ' + resultMapinfoObj + ' where rowid = ' + IntToStr(newRowId);
                MapInfo. do (mapinfoSql);
              end;

              inc(newRowId);

              //创建Pline对象
              mapinfoSql := 'Create pline into variable ' + resultMapinfoObj + ' 0';
              MapInfo. do (mapinfoSql);

              //加入节点
              mapinfoSql := 'Alter Object  ' + resultMapinfoObj + '  Node  Add (' + FloatToStr(pt.X) + ',' + FloatToStr(pt.Y) + ')';
              MapInfo. do (mapinfoSql);

              inc(k);
            end; // end if pt.IsEqual(TKDPoint(sourceNodesList.Items[k]))
          end; // end while j < sourceNodesList.Count

          //防止只含有一个节点的伪线段
          if (self.QueryNodeCount(resultMapinfoObj, 1)) > 1 then
          begin
            //复制源线对象
            mapinfoSql := '';
            mapinfoSql := mapinfoSql + ' insert into ' + tableName;
            mapinfoSql := mapinfoSql + ' select * from Selection';
            MapInfo. do (mapinfoSql);

            //修改为断后的线对象
            mapinfoSql := 'update ' + tableName + ' set obj = ' + resultMapinfoObj + ' where rowid = ' + IntToStr(newRowId);
            MapInfo. do (mapinfoSql);
          end;

          inc(newRowId);

          //记录被打断的源线对象
          SplitObjsId.Add(rowID);

        end; // sourceNodesList.Count < dirtyNodesList.Coun
      end; // end if QuerySelctionCount() > 0

      //清除为目标
      MapInfo. do ('Set Target Off');
    end;

    //删除被打断的源线对象
    if SplitObjsId.Count > 0 then
    begin
      for i := 0 to SplitObjsId.Count - 1 do
      begin
        mapinfoSql := 'delete from ' + tableName + ' where rowid = ' + SplitObjsId.Strings[i];
        MapInfo. do (mapinfoSql);
      end;
    end;
    //提交结果
    self.SaveTable(tableName);
  finally
    begin
      sourceNodesList.Free();
      dirtyNodesList.Free();
      SplitObjsId.Free();
    end;
  end;

end;}

///@author: yzhou
///@date: 2006.4.10
///@description: 打断将线层中的对象全部打断
///@para lineTableName: 被打断的线表名
///@para regionTableName: 区域对象表

procedure TKDMapinfoProxy.SplitLineByRegion(lineTableName: string; regionTableName: string);
var
  mapinfoSql: string;
  cols: string;
  Tempstr: string;
  i: integer;
begin
  if (self.QueryTableRecordCount(lineTableName) < 1)
    or (self.QueryTableRecordCount(regionTableName) < 1) then
    Exit;

  //选择全部的列
  for i := 1 to self.QueryTableColumnCount(lineTableName) do
  begin
    Tempstr := self.QueryTableColumnName(lineTableName, i);
    cols := cols + Tempstr + '=' + Tempstr + ',';
  end;
  cols := LeftStr(cols, Length(cols) - 1);

  //设置为目标
  mapinfoSql := 'select * from ' + lineTableName + ' into selection';
  MapInfo. do (mapinfoSql);
  if self.QuerySelctionCount > 0 then
  begin
    MapInfo. do ('Set Target On');

    //分割目标
    mapinfoSql := 'select * from ' + regionTableName + ' into selection';
    MapInfo. do (mapinfoSql);
    mapinfoSql := 'Objects Split Into Target Data ' + cols;
    MapInfo. do (mapinfoSql);
    MapInfo. do ('Set Target Off');
  end;

  //分解分割后的对象
  mapinfoSql := 'select * from ' + lineTableName + ' into selection';
  MapInfo. do (mapinfoSql);

  if self.QuerySelctionCount() > 0 then
  begin
    mapinfoSql := 'Objects Disaggregate Into Table ' + lineTableName + ' Data ' + cols;
    MapInfo. do (mapinfoSql);
    self.SaveTable(lineTableName);
  end;
end;

///@author: yzhou
///@date: 2006.05.12
///@description: 打断将线层中的对象全部打断,并删除原来的对象
///@para tableName: 被打断的tab表名
///@para splitTableName: 用于打断操作的tab表名
///@remark: (1)不支持自相交的线对象;
/// (2)不支持对mapinfo中临时表的操作;
/// (3) 此函数用到了mapinfo中定义的变量'Aobj', 'Bobj',在调用函数时会修改原'Aobj', 'Bobj'中的值
/// (6) ***在海量数据下未通过测试

procedure TKDMapinfoProxy.SplitLineTableEx(tableName: string; splitTableName: string);
var
  mapinfoSql: string;
  tagetMapinfoObj, resultMapinfoObj: string;
  recordCnt, intersectCnt, newRowId: integer;
  intersectNodesList: TObjectList;
  RowID: string;
  i, j, k: integer;
  startPtIndex, endPtIndex: integer;
  spt, preSpt: TKDSegmentPoint;
  SplitObjsId: TStringList;
begin
  SplitObjsId := TStringList.Create();
  intersectNodesList := TObjectList.Create();
  tagetMapinfoObj := 'aobj';
  resultMapinfoObj := 'bobj';

  recordCnt := QueryTableRecordCount(tableName);
  newRowId := recordCnt + 1;

  for i := 1 to recordCnt do
  begin
    MapInfo. do ('fetch rec ' + Inttostr(i) + ' from ' + tableName);

    RowID := MapInfo.Eval(tableName + '.rowid');
    MapInfo. do (tagetMapinfoObj + ' = ' + tableName + '.obj');

    //选取相交的线对象
    if Trim(tableName) = Trim(splitTableName) then
    begin
      //选择自相交
      mapinfoSql := '';
      mapinfoSql := mapinfoSql + ' select * from ' + splitTableName;
      mapinfoSql := mapinfoSql + ' where rowid <> ' + RowID;
      mapinfoSql := mapinfoSql + ' and rowid <= ' + Inttostr(recordCnt);
      mapinfoSql := mapinfoSql + ' and Obj Intersects ' + tagetMapinfoObj;
      mapinfoSql := mapinfoSql + ' and (str$(obj)<>"Point" and str$(obj)<>"Text")';
      mapinfoSql := mapinfoSql + ' into Selection';
    end
    else
    begin
      //选择与其它层相交
      mapinfoSql := '';
      mapinfoSql := mapinfoSql + ' select * from ' + splitTableName;
      mapinfoSql := mapinfoSql + ' where Obj Intersects ' + tagetMapinfoObj;
      mapinfoSql := mapinfoSql + ' and (str$(obj)<>"Point" and str$(obj)<>"Text")';
      mapinfoSql := mapinfoSql + ' into Selection';
    end;
    MapInfo. do (mapinfoSql);

    //获取交点
    intersectNodesList.clear();
    intersectCnt := self.QuerySelctionCount();
    for j := 1 to intersectCnt do
    begin
      MapInfo. do ('fetch rec ' + Inttostr(j) + ' from Selection');
      self.GetOrderIntersectNodes(tagetMapinfoObj, 'Selection.Obj', intersectNodesList);
    end; // end for j := 1 to intersectCnt

    startPtIndex := 1;
    endPtIndex := -1;
    for k := 0 to intersectNodesList.Count - 1 do
    begin
      spt := TKDSegmentPoint(intersectNodesList.Items[k]);

      //当前交点跟上一个交点不在同一弧段上
      if (endPtIndex <> spt.SegmentInedex + 1) then
      begin
        endPtIndex := spt.SegmentInedex + 1;

        mapinfoSql := resultMapinfoObj + ' = ExtractNodes(' + tagetMapinfoObj + ', 1,'
          + Inttostr(startPtIndex) + ', ' + Inttostr(endPtIndex) + ', 0)';
        MapInfo. do (mapinfoSql);

        mapinfoSql := 'Alter Object  ' + resultMapinfoObj + '  Node  Set Position 1, '
          + Inttostr(endPtIndex - startPtIndex + 1) + ' (' + FloatToStr(spt.X) + ',' + FloatToStr(spt.Y) + ')';
        MapInfo. do (mapinfoSql);

        //在当前交点的前面已有交点存在,应修改结果线段的第一个点为上一个交点
        if (k > 0) then
        begin
          //获取上一个交点
          preSpt := TKDSegmentPoint(intersectNodesList.Items[k - 1]);

          mapinfoSql := 'Alter Object  ' + resultMapinfoObj + '  Node  Set Position 1, 1'
            + ' (' + FloatToStr(preSpt.X) + ',' + FloatToStr(preSpt.Y) + ')';
          MapInfo. do (mapinfoSql);
        end;

        startPtIndex := endPtIndex - 1;
      end
        //当前交点跟上一个交点在同一弧段上,应获取两个交点创建线段
      else
      begin
        preSpt := TKDSegmentPoint(intersectNodesList.Items[k - 1]);

        mapinfoSql := 'Create pline into variable ' + resultMapinfoObj + ' 2'
          + ' (' + FloatToStr(preSpt.X) + ',' + FloatToStr(preSpt.Y) + ')'
          + ' (' + FloatToStr(spt.X) + ',' + FloatToStr(spt.Y) + ')';
        MapInfo. do (mapinfoSql);
      end; // end if (endPtIndex <> spt.SegmentInedex + 1) then

      ///加入打断后的对象
      //复制源线对象
      mapinfoSql := '';
      mapinfoSql := mapinfoSql + ' select * from ' + tableName;
      mapinfoSql := mapinfoSql + ' where rowid = ' + RowID;
      mapinfoSql := mapinfoSql + ' into Selection';
      MapInfo. do (mapinfoSql);

      mapinfoSql := '';
      mapinfoSql := mapinfoSql + ' insert into ' + tableName;
      mapinfoSql := mapinfoSql + ' select * from Selection';
      MapInfo. do (mapinfoSql);

      //修改为断后的线对象
      mapinfoSql := 'update ' + tableName + ' set obj = ' + resultMapinfoObj + ' where rowid = ' + Inttostr(newRowId);
      MapInfo. do (mapinfoSql);
      inc(newRowId);
    end; // end for k := 0 to intersectNodesList.Count - 1 do

    if (intersectNodesList.Count > 0) then
    begin
      //获取最后一个交点和剩下的节点创建线段
      spt := TKDSegmentPoint(intersectNodesList.Items[intersectNodesList.Count - 1]);

      mapinfoSql := resultMapinfoObj + ' = ExtractNodes(' + tagetMapinfoObj + ', 1,'
        + Inttostr(spt.SegmentInedex) + ', ' + Inttostr(self.QueryNodeCount(tagetMapinfoObj, 1)) + ', 0)';
      MapInfo. do (mapinfoSql);

      mapinfoSql := 'Alter Object  ' + resultMapinfoObj + ' Node Set Position 1, 1'
        + ' (' + FloatToStr(spt.X) + ',' + FloatToStr(spt.Y) + ')';
      MapInfo. do (mapinfoSql);

      //复制源线对象
      mapinfoSql := '';
      mapinfoSql := mapinfoSql + ' select * from ' + tableName;
      mapinfoSql := mapinfoSql + ' where rowid = ' + RowID;
      mapinfoSql := mapinfoSql + ' into Selection';
      MapInfo. do (mapinfoSql);

      mapinfoSql := '';
      mapinfoSql := mapinfoSql + ' insert into ' + tableName;
      mapinfoSql := mapinfoSql + ' select * from Selection';
      MapInfo. do (mapinfoSql);

      //修改为断后的线对象
      mapinfoSql := 'update ' + tableName + ' set obj = ' + resultMapinfoObj + ' where rowid = ' + Inttostr(newRowId);
      MapInfo. do (mapinfoSql);
      inc(newRowId);

      //标识需要被打断的线
      SplitObjsId.Add(RowID);
    end;
  end; // end for

  //删除被打断的源线对象
  if SplitObjsId.Count > 0 then
  begin
    for i := 0 to SplitObjsId.Count - 1 do
    begin
      mapinfoSql := 'delete from ' + tableName + ' where rowid = ' + SplitObjsId.Strings[i];
      MapInfo. do (mapinfoSql);
    end;
  end;
end;

///@author: yzhou
///@date: 2006.09.26
procedure TKDMapinfoProxy.RepeatPoints(tagetTable: string; repeatTable: string);
var
  mapinfoSql: string;
begin

  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from ' + tagetTable;
  mapinfoSql := mapinfoSql + ' where (str$(obj)<>"Point" and str$(obj)<>"Text")';
  mapinfoSql := mapinfoSql + ' into Selection';
  MapInfo. do (mapinfoSql);

  if (self.QuerySelctionCount() > 0) then
  begin
    MapInfo. do ('Set Target On');

    mapinfoSql := '';
    mapinfoSql := mapinfoSql + ' select * from ' + repeatTable;
    mapinfoSql := mapinfoSql + ' where (str$(obj)<>"Point" and str$(obj)<>"Text")';
    mapinfoSql := mapinfoSql + ' into Selection';
    MapInfo. do (mapinfoSql);
    MapInfo. do ('Objects Overlay Into Target');

    MapInfo. do ('Set Target Off');
  end;

end;


///@author: yzhou
///@date: 2006.3.17
///@description: 打断将线层中的对象全部打断,并删除原来的对象
///@para tableName: 被打断的tab表名
///@para splitTableName: 用于打断操作的tab表名
///@remark: (1)不支持自相交的线对象;
/// (2)不支持对mapinfo中临时表的操作;
/// (3)不能对两条线共线进行打断
/// (4)不能在两条线交叠的节点处进行打断
/// (5) 此函数用到了mapinfo中定义的变量'Aobj', 'Bobj',在调用函数时会修改原'Aobj', 'Bobj'中的值
/// (6) ***未经过海量数据的测试(对2741条线进行打断)
procedure TKDMapinfoProxy.SplitLineTable(tableName: string; splitTableName: string);
var
  sourceNodesList, dirtyNodesList, tempNodesList: TObjectList;
  pt: TKDPoint;
  recordCnt: integer;
  i, j, k: integer;
  RowID: string;
  newRowId: integer;
  mapinfoSql: string;
  SplitObjsId: TStringList;
  tagetMapinfoObj, resultMapinfoObj: string;
  whereClause: string;
begin
  tagetMapinfoObj := 'aobj';
  resultMapinfoObj := 'bobj';

  try
    sourceNodesList := TObjectList.Create();
    dirtyNodesList := TObjectList.Create();
    tempNodesList := TObjectList.Create();
    SplitObjsId := TStringList.Create();

    recordCnt := QueryTableRecordCount(tableName);
    newRowId := recordCnt + 1;
    for i := 1 to recordCnt do
    begin
      MapInfo. do ('fetch rec ' + Inttostr(i) + ' from ' + tableName);
      RowID := MapInfo.Eval(tableName + '.rowid');

      //选择当前线对象
      mapinfoSql := '';
      mapinfoSql := mapinfoSql + ' select * from ' + tableName;
      mapinfoSql := mapinfoSql + ' where rowid = ' + RowID;
      mapinfoSql := mapinfoSql + ' into Selection';
      MapInfo. do (mapinfoSql);

      //设置为目标
      MapInfo. do (tagetMapinfoObj + ' = Selection.Obj');
      MapInfo. do ('Set Target On');

      //查询节点
      QueryNodesOfGeomety(tagetMapinfoObj, 1, sourceNodesList);

      //选取相交的线对象
      if Trim(tableName) = Trim(splitTableName) then
      begin
        //选择自相交
        mapinfoSql := '';
        mapinfoSql := mapinfoSql + ' select * from ' + splitTableName;
        mapinfoSql := mapinfoSql + ' where rowid <> ' + RowID;
        mapinfoSql := mapinfoSql + ' and rowid <= ' + Inttostr(recordCnt);
        mapinfoSql := mapinfoSql + ' and Obj Intersects ' + tagetMapinfoObj;
        mapinfoSql := mapinfoSql + ' and (str$(obj)<>"Point" and str$(obj)<>"Text")';
        mapinfoSql := mapinfoSql + ' into Selection';
      end
      else
      begin
        //选择与其它层相交
        mapinfoSql := '';
        mapinfoSql := mapinfoSql + ' select * from ' + splitTableName;
        mapinfoSql := mapinfoSql + ' where Obj Intersects ' + tagetMapinfoObj;
        mapinfoSql := mapinfoSql + ' and (str$(obj)<>"Point" and str$(obj)<>"Text")';
        mapinfoSql := mapinfoSql + ' into Selection';
      end;
      MapInfo. do (mapinfoSql);

      if QuerySelctionCount() > 0 then
      begin
        MapInfo. do ('Objects Overlay Into Target');

        //加入交点后的源线对象
        mapinfoSql := '';
        mapinfoSql := mapinfoSql + ' select * from ' + tableName;
        mapinfoSql := mapinfoSql + ' where rowid = ' + RowID;
        mapinfoSql := mapinfoSql + ' into Selection';
        MapInfo. do (mapinfoSql);

        MapInfo. do (tagetMapinfoObj + ' = Selection.Obj');
        //查询节点
        QueryNodesOfGeomety(tagetMapinfoObj, 1, tempNodesList);

        if sourceNodesList.Count < tempNodesList.Count then
        begin
          if dirtyNodesList.Count > 0 then
            dirtyNodesList.clear();

          pt := TKDPoint(tempNodesList.Items[tempNodesList.Count - 1]);
          if pt.IsEqual(TKDPoint(sourceNodesList.Items[0])) = true then
          begin
            j := tempNodesList.Count - 1;
            while j >= 0 do
            begin
              pt := TKDPoint.Create(TKDPoint(tempNodesList.Items[j]));
              dirtyNodesList.Add(pt);
              dec(j);
            end;
          end
          else
          begin
            j := 0;
            while j < tempNodesList.Count do
            begin
              pt := TKDPoint.Create(TKDPoint(tempNodesList.Items[j]));
              dirtyNodesList.Add(pt);
              inc(j);
            end;
          end;

          //创建Pline对象
          mapinfoSql := 'Create pline into variable ' + resultMapinfoObj + ' 0 ';
          MapInfo. do (mapinfoSql);

          k := 0;
          j := 0;
          while (j < sourceNodesList.Count) and (k < dirtyNodesList.Count) do
          begin
            pt := TKDPoint(dirtyNodesList.Items[k]);
            if pt.IsEqual(TKDPoint(sourceNodesList.Items[j])) = true then
            begin
              //加入节点
              mapinfoSql := 'Alter Object  ' + resultMapinfoObj + '  Node  Add (' + FloatToStr(pt.X) + ',' + FloatToStr(pt.Y) + ')';
              MapInfo. do (mapinfoSql);

              inc(k);
              inc(j);
            end
            else
            begin
              //加入节点
              mapinfoSql := 'Alter Object  ' + resultMapinfoObj + '  Node  Add (' + FloatToStr(pt.X) + ',' + FloatToStr(pt.Y) + ')';
              MapInfo. do (mapinfoSql);

              //防止只含有一个节点的伪线段
              if (self.QueryNodeCount(resultMapinfoObj, 1)) > 1 then
              begin
                //复制加入交点后的源线对象
                mapinfoSql := '';
                mapinfoSql := mapinfoSql + ' insert into ' + tableName;
                mapinfoSql := mapinfoSql + ' select * from Selection';
                MapInfo. do (mapinfoSql);

                //修改为打断后的线对象
                mapinfoSql := 'update ' + tableName + ' set obj = ' + resultMapinfoObj + ' where rowid = ' + Inttostr(newRowId);
                MapInfo. do (mapinfoSql);
              end;

              inc(newRowId);

              //创建Pline对象
              mapinfoSql := 'Create pline into variable ' + resultMapinfoObj + ' 0';
              MapInfo. do (mapinfoSql);

              //加入节点
              mapinfoSql := 'Alter Object  ' + resultMapinfoObj + '  Node  Add (' + FloatToStr(pt.X) + ',' + FloatToStr(pt.Y) + ')';
              MapInfo. do (mapinfoSql);

              inc(k);
            end; // end if pt.IsEqual(TKDPoint(sourceNodesList.Items[k]))
          end; // end while j < sourceNodesList.Count

          //防止只含有一个节点的伪线段
          if (self.QueryNodeCount(resultMapinfoObj, 1)) > 1 then
          begin
            //复制源线对象
            mapinfoSql := '';
            mapinfoSql := mapinfoSql + ' insert into ' + tableName;
            mapinfoSql := mapinfoSql + ' select * from Selection';
            MapInfo. do (mapinfoSql);

            //修改为断后的线对象
            mapinfoSql := 'update ' + tableName + ' set obj = ' + resultMapinfoObj + ' where rowid = ' + Inttostr(newRowId);
            MapInfo. do (mapinfoSql);
          end;

          inc(newRowId);

          //记录被打断的源线对象
          SplitObjsId.Add(RowID);

        end; // sourceNodesList.Count < dirtyNodesList.Coun
      end; // end if QuerySelctionCount() > 0

      //清除为目标
      MapInfo. do ('Set Target Off');
    end;

    //删除被打断的源线对象
    if SplitObjsId.Count > 0 then
    begin
      for i := 0 to SplitObjsId.Count - 1 do
      begin
        mapinfoSql := 'delete from ' + tableName + ' where rowid = ' + SplitObjsId.Strings[i];
        MapInfo. do (mapinfoSql);
      end;
    end;

    //提交结果
    //self.SaveTable(tableName);
  finally
    begin
      sourceNodesList.Free();
      tempNodesList.Free();
      dirtyNodesList.Free();
      SplitObjsId.Free();
    end;
  end;

end;
/// 功能:设置线段方向显示
/// 作者:姚箫
/// 日期:2006.4.9
/// 参数说明:LayerName                ->层名
///                        bShow                        ->显示线段方向

procedure TKDMapinfoProxy.ShowArrows(LayerName: string; bShow: boolean = true);
begin
  if bShow then
    MapInfo. do ('Set Map Layer ' + LayerName + ' Arrows On')
  else
    MapInfo. do ('Set Map Layer ' + LayerName + ' Arrows Off');
end;


///@author: ma
///@date: 2006.4.10
///@description: 将图层中出文本、点外的图形转换为 折线
///@para strTableName: source 图层名
///@para strTableName2: save as 图层名

procedure TKDMapinfoProxy.CvtToPLineTable(strTableName: string; strTableName2: string; CurWinID: integer);
var
  mapinfoSql: string;
  whereClause: string;
  baseTab: string;
begin
  whereClause := ' where str$(obj)<>"Point" and str$(obj)<>"Text"';
  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from ' + strTableName;
  mapinfoSql := mapinfoSql + whereClause + ' into Temp'; // into Temp';

  MapInfo. do (mapinfoSql);
  MapInfo. do ('Add Map Window ' + Inttostr(CurWinID) + ' Layer ' + strTableName2);
  MapInfo. do ('insert into ' + strTableName2 + '(obj) select obj from Temp');
  MapInfo. do ('select * from ' + strTableName2 + ' into Temp');
  if MapInfo.Eval('SelectionInfo(3)') <= 0 then
    Exit;
  baseTab := MapInfo.Eval('SelectionInfo(1)');
  MapInfo. do ('Add Map Window ' + Inttostr(CurWinID) + ' Layer Temp');
  MapInfo. do ('Set Map Window  ' + Inttostr(CurWinID) + ' Layer Temp Editable On');
  MapInfo.runmenucommand(1604);
  MapInfo.runmenucommand(1604);

  MapInfo. do ('Remove Map Window ' + Inttostr(CurWinID) + ' Layer ' + strTableName2 + ' Interactive');
  self.CommitTable(strTableName2);
  self.CloseTable('Temp');
end;

///@author: yzhou
///@date: 2006.4.25
///@description: 将源表中除文本、点外的图形转换为折线放入目标表
///@para srcTable: 源表名
///@para destTable: 目标表名
///@fieldList: 要保留的属性字段列表(此参数要求两源表和目标表都包含此参数中的属性)

procedure TKDMapinfoProxy.CvtToPLineTableEx(srcTable: string; destTable: string; whereClause: string; fieldList: string);
var
  mapinfoSql: string;
begin
  if (self.QueryTableRecordCount(srcTable) < 1) then
    Exit;

  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from ' + srcTable;
  mapinfoSql := mapinfoSql + ' where str$(obj)<>"Point" and str$(obj)<>"Text"';
  if Trim(whereClause) <> '' then
    mapinfoSql := mapinfoSql + ' and ' + whereClause;
  mapinfoSql := mapinfoSql + ' into kd_temp_cvtLine_table';
  MapInfo. do (mapinfoSql);

  if self.QuerySelctionCount() > 0 then
  begin
    mapinfoSql := '';
    mapinfoSql := mapinfoSql + ' insert into ' + destTable;
    mapinfoSql := mapinfoSql + ' (obj';
    if Trim(fieldList) <> '' then
      mapinfoSql := mapinfoSql + ', ' + fieldList;
    mapinfoSql := mapinfoSql + ' )';
    mapinfoSql := mapinfoSql + ' select ConvertToPline(obj)';
    if Trim(fieldList) <> '' then
      mapinfoSql := mapinfoSql + ', ' + fieldList;
    mapinfoSql := mapinfoSql + ' from kd_temp_cvtLine_table';
    MapInfo. do (mapinfoSql);

    self.CommitTable(destTable);
  end;

  self.CloseTable('kd_temp_cvtLine_table');
end;


///@author: yzhou
///@date: 2006.4.24
///@description: 将源表中除文本、点外的图形转换为折线放入目标表
///@para srcTable: 源表名
///@para destTable: 目标表名
///@remark: 不对处理属性数据

procedure TKDMapinfoProxy.CvtToPLineTable(srcTable: string; destTable: string; whereClause: string);
var
  mapinfoSql: string;
begin

  if (self.QueryTableRecordCount(srcTable) < 1) then
    Exit;

  mapinfoSql := '';
  mapinfoSql := mapinfoSql + ' select * from ' + srcTable;
  mapinfoSql := mapinfoSql + ' where str$(obj)<>"Point" and str$(obj)<>"Text"';
  if Trim(whereClause) <> '' then
    mapinfoSql := mapinfoSql + ' and ' + whereClause;
  mapinfoSql := mapinfoSql + ' into kd_temp_cvtLine_table';
  MapInfo. do (mapinfoSql);

  if self.QuerySelctionCount() > 0 then
  begin
    mapinfoSql := '';
    mapinfoSql := mapinfoSql + ' insert into ' + destTable;
    mapinfoSql := mapinfoSql + ' (obj)';
    mapinfoSql := mapinfoSql + ' select ConvertToPline(obj) from kd_temp_cvtLine_table';
    MapInfo. do (mapinfoSql);

    self.CommitTable(destTable);
  end;

  self.CloseTable('kd_temp_cvtLine_table');
end;

procedure TKDMapinfoProxy.DoMapinfoSql(sql: string);
begin
  MapInfo. do (sql);
end;

end.


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/guyehanxinlei/archive/2007/03/14/1528777.aspx

posted @ 2011-04-06 01:23  大连思绪软件工作室  阅读(626)  评论(0编辑  收藏  举报