unit ShuiZhun;
{-------------------------------------------------
水准点平差算法单元
== ◎◎◎ 作者:陈明 ◎◎◎ ==
--------------------------------------------------}
interface
uses SysUtils,Dialogs,PerlRegEx,classes,matrice;
type SZPoint=record //水准点记录类型
isKnown:boolean; //是否为已知点
name:string; //点名
High:extended; //点的(近似)高程值
Unkown_ID:integer; //如果为未知点,则其序号
HasH:boolean; //是否已求出近似值
end;
var num_known,num_unknown,num_ce,rows:integer;
var pList: array of SZPoint;
var splitStr:string=' *'; //正则表达式的分隔符
//Q[num_Ce,num_Ce] B[num_ce,num_unknown] L[num_Ce,1]
var B,L,Q:RCOMat;
//************************************完善PList信息,初始化矩阵维数*************
procedure PointFromText(filename:string);
//************************************获取文本共有多少行************************
//function GetRows(filename:String):integer;
//************************************获取所有点的(近似)高程********************
procedure GetAllH(filename:string);
//function isAllHasH:boolean; ********是不是所有的都有高程值了
//************************************判断是不是已知的点************************
function isKnownP(pname:string):boolean;
//************************************获取未知点在所有未知点中的点序号 ,从0开始
function GetUnknownID(pname:string):integer;
//************************************获取点在所有点中的序号,从0开始***********
function GetPID(pname:string):integer;
//************************************获取矩阵B和Q******************************
procedure GetBAndQ(filename:String);
//************************************判断点是否有(近似)高程值******************
function IsPHasH(pname:string):boolean;
//************************************获取矩阵L*********************************
procedure GetL(filename:string);
{=====顺序,先PointFromText,再GetBAndQ,GetAllH,GetL等=====}
implementation
//************************************获取矩阵L*********************************
procedure GetL(filename:string);
var i,j,temp,temp1:integer;
f:textfile;
Reg:TPerlRegEx;
s:string;
List:TStrings;
begin
setlength(L,num_Ce,1);
for I := 0 to num_Ce - 1 do
for j := 0 to 0 do
L[i,j]:=0;
Reg:=TPerlRegEx.Create(nil);
List:=TStringList.Create;
temp:=0;
assignfile(f,filename);
reset(f);
while temp<>3 do //向下读三行(非空行)
begin
readln(f,s); s:=trim(s); if s<>'' then temp:=temp+1;
end; //从第四行开始读了
for temp1 := 0 to num_ce - 1 do
begin
readln(f,s); s:=trim(s);
while s='' do begin readln(f,s); s:=trim(s); end; //如果行为空则一直向下读到不为空为止
if not (s='') then //该行不为空
begin
reg.Subject:=UTF8string(s); reg.RegEx:=UTF8string(splitStr);
reg.Split(list,maxint);
L[temp1,0]:=pList[GetPID(list[1])].High-pList[GetPID(list[0])].High-strtofloat(list[2]);
end;
list.Clear;
end;
end;
//************************************判断点是否有(近似)高程值******************
function IsPHasH(pname:string):boolean;
var i:integer;
begin
result:=false;
for I := 0 to num_known+num_unknown - 1 do
if pList[i].name=pname then //是要找的点
if plist[i].HasH then
result:=true;
end;
//************************************获取点在所有点中的序号,从0开始***********
function GetPID(pname:string):integer;
var i:integer;
begin
result:=0;
for I := 0 to num_known+num_unknown - 1 do
if pList[i].name=pname then
begin result:=i; exit; end;
end;
//************************************获取所有点的(近似)高程********************
procedure GetAllH(filename:string);
var f:textfile;
Reg:TPerlRegEx;
s:string;
List:TStrings;
temp,temp1,i,j:integer;
begin
for I := 0 to 0 do //先根据已知点算一些近似高程,再算那些不能根据已知点算的那些点
begin
Reg:=TPerlRegEx.Create(nil);
List:=TStringList.Create;
temp:=0;
assignfile(f,filename);
reset(f);
while temp<>3 do //向下读三行(非空行)
begin
readln(f,s); s:=trim(s); if s<>'' then temp:=temp+1;
end; //从第四行开始读了
for temp1 := 0 to num_ce - 1 do
begin
readln(f,s); s:=trim(s);
while s='' do begin readln(f,s); s:=trim(s); end; //如果行为空则一直向下读到不为空为止
if not (s='') then //该行不为空
begin
//showmessage(s);
reg.Subject:=UTF8string(s); reg.RegEx:=UTF8string(splitStr);
reg.Split(list,maxint);
if IsKnownP(list[0]) then
begin
if (not IsKnownP(list[1])) and (not isPHasH(list[1])) then //前知后不知
begin
pList[GetPID(list[1])].High:=pList[GetPID(list[0])].High+strtofloat(list[2]);
pList[GetPID(list[1])].HasH:=true;
//showmessage('求得'+list[1]+'的高程:'+floattostr(pList[GetPID(list[1])].High));
if pList[GetPID(list[1])].HasH then
//showmessage(list[1]+'高程'+'已知');
end
end else
if IsKnownP(list[1]) then
begin
if (not IsKnownP(list[0])) and (not isPHasH(list[0])) then //后知前不知
begin
pList[GetPID(list[0])].High:=pList[GetPID(list[1])].High-strtofloat(list[2]);
pList[GetPID(list[0])].HasH:=true;
//showmessage('求得'+list[0]+'的高程:'+floattostr(pList[GetPID(list[0])].High));
end;
end;
list.Clear;
end;
end;
list.Free;
closefile(f);
end;
for I := 0 to num_unknown - 1 do
for j := 0 to num_known+num_unknown - 1 do
begin
Reg:=TPerlRegEx.Create(nil);
List:=TStringList.Create;
temp:=0;
assignfile(f,filename);
reset(f);
while temp<>3 do //向下读三行(非空行)
begin
readln(f,s); s:=trim(s); if s<>'' then temp:=temp+1;
end; //从第四行开始读了
for temp1 := 0 to num_ce - 1 do
begin
readln(f,s); s:=trim(s);
while s='' do begin readln(f,s); s:=trim(s); end; //如果行为空则一直向下读到不为空为止
if not (s='') then //该行不为空
begin
//showmessage(s);
reg.Subject:=UTF8string(s); reg.RegEx:=UTF8string(splitStr);
reg.Split(list,maxint);
if IsPHasH(list[0]) then
begin
if not IsPHasH(list[1]) then //前知后不知
begin
pList[GetPID(list[1])].High:=pList[GetPID(list[0])].High+strtofloat(list[2]);
pList[GetPID(list[1])].HasH:=true;
//showmessage('求得'+list[1]+'的高程:'+floattostr(pList[GetPID(list[1])].High));
if pList[GetPID(list[1])].HasH then
//showmessage(list[1]+'高程'+'已知');
end
end else
if IsPHasH(list[1]) then
begin
if not IsPHasH(list[0]) then //后知前不知
begin
pList[GetPID(list[0])].High:=pList[GetPID(list[1])].High-strtofloat(list[2]);
pList[GetPID(list[0])].HasH:=true;
//showmessage('求得'+list[0]+'的高程:'+floattostr(pList[GetPID(list[0])].High));
end;
end;
list.Clear;
end;
end;
list.Free;
closefile(f);
end;
end;
//************************************获取矩阵B和Q******************************
procedure GetBAndQ(filename:String);
var f:textfile;
Reg:TPerlRegEx;
s:string;
List:TStrings;
temp,temp1,i,j:integer;
begin
setlength(Q,num_Ce,num_Ce); //初始Q
for I := 0 to num_Ce - 1 do
for j := 0 to num_ce - 1 do
Q[i,j]:=0;
setlength(B,num_ce,num_unknown); //初始B
for I := 0 to num_Ce - 1 do
for j := 0 to num_unknown - 1 do
B[i,j]:=0;
Reg:=TPerlRegEx.Create(nil);
List:=TStringList.Create;
temp:=0;
assignfile(f,filename);
reset(f);
while temp<>3 do //向下读三行(非空行)
begin
readln(f,s); s:=trim(s); if s<>'' then temp:=temp+1;
end; //从第四行开始读了
for temp1 := 0 to num_Ce - 1 do
begin
readln(f,s); s:=trim(s);
//showmessage(s);
while s='' do begin readln(f,s); s:=trim(s); end; //如果行为空则一直向下读到不为空为止
if not (s='') then //该行不为空
begin
reg.Subject:=UTF8string(s); reg.RegEx:=UTF8string(splitStr);
reg.Split(list,maxint);
if not isKnownP(list[0]) then B[temp1,GetUnknownID(list[0])]:=-1;
//showmessage(list[0]+' '+inttostr(temp1)+','+inttostr(GetUnknownID(list[0])));
if not isKnownP(list[1]) then B[temp1,GetUnknownID(list[1])]:=1;
//showmessage(list[1]+' '+inttostr(temp1)+','+inttostr(GetUnknownID(list[1])));
Q[temp1,temp1]:=strtofloat(list[3]);
//showmessage(floattostr(Q[temp1,temp1]));
end;
list.Clear;
//showmessage('for');
end;
//showmessage('OK');
list.Free;
//showmessage('ListOK');
closefile(f);
end;
{=====================================是不是所有的都有高程值了
function isAllHasH:boolean;
var i:integer;
begin
result:=true;
for I := 0 to num_known+num_unknown - 1 do
if not pList[i].HasH then begin result:=false; exit;end;
end;
=================================================}
//************************************获取未知点在所有未知点中的点序号 ,从0开始
function GetUnknownID(pname:string):integer;
var j:integer;
begin
result:=0;
for j := num_known to num_known+num_unknown - 1 do
if pList[j].name=pname then
begin result:=pList[j].Unkown_ID; exit;end;
end;
function isKnownP(pname:string):boolean;
var i:integer;
begin
result:=false;
for I := 0 to num_known - 1 do
if pList[i].name=pname then
begin result:=true; exit; end;
end;
//************************************获取文本共有多少行************************
{
function GetRows(filename:String):integer;
var f:TextFile;
i:integer;
s:string;
begin
i:= 0;
assignfile(f,filename);
reset(f);
while not eof(f) do
begin
readln(f,s);
if not (trim(s)='') then //空行情况的处理
i:=i+1;
end;
closefile(f);
result:=i;
end; }
//************************************完善PList信息,初始化矩阵维数*************
procedure PointFromText(filename:string);
var f:TextFile;
Reg:TPerlRegEx;
s:string;
List:TStrings;
m:integer;
begin
Reg:=TPerlRegEx.Create(nil);
List:=TStringList.Create;
//showmessage(inttostr(rows));
assignfile(f,filename);
reset(f);
s:='';
Readln(f,s); s:=trim(s); //第一行
while s='' do begin readln(f,s); s:=trim(s); end;
if not (s='') then //空行情况的处理
begin
reg.Subject := UTF8string(s);
reg.RegEx :=UTF8string(splitStr); //以空格为分隔符(空格个数不限)
reg.Split(list,MaxInt);
num_known:=strtoint(list[0]);
num_unknown:=strtoint(list[1]);
num_ce:=strtoint(list[2]);
end;
Setlength(pList,num_known+num_unknown); //构选点记录组长度
list.Clear;
Readln(f,s); s:=trim(s); //第二行
while s='' do begin readln(f,s); s:=trim(s); end;
if not (s='') then //空行情况的处理
begin
reg.Subject := UTF8string(s);
reg.RegEx := UTF8string(splitStr); //以空格为分隔符(空格个数不限)
reg.Split(list,MaxInt);
for m := 0 to num_known - 1 do //已知点
begin
pList[m].isKnown:=true;
pList[m].name:=list[m];
pList[m].HasH:=true;
end;
for m := num_known to num_known+num_unknown - 1 do //未知点
begin
pList[m].isKnown:=false;
pList[m].name:=list[m];
pList[m].Unkown_ID:=m-num_known; //未知点的序号,从0开始
pList[m].HasH:=false;
end;
list.Clear;
Readln(f,s); s:=trim(s); //第三行
while s='' do begin readln(f,s); s:=trim(s); end;
if not (s='') then //空行情况的处理
begin
reg.Subject := UTF8string(s);
reg.RegEx := UTF8string(splitStr); //以空格为分隔符(空格个数不限)
reg.Split(list,MaxInt);
for m := 0 to num_known - 1 do
pList[m].High:=strtofloat(list[m]);
end;
list.Clear;
end;
list.Free;
closefile(f);
end;
end.