Разработка информационной системы для деканата высшего учебного заведения
Порядок контроля и приемки программного обеспечения, требования к документации. Текст программы: модуль Program.cs, sprav predmets.cs. Сообщения, выдаваемые программисту. Капитальные вложения по внедрению системы. Расчет годовой экономии от эксплуатации.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 29.06.2012 |
Размер файла | 7,4 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
bool rt; //режим отображения без пропусков
bool viewPoints; //отображать треки
bool net; //отображать сетку
bool counted; //сетка уже расчитана
bool isolines; //отображать изолинии
bool viewRelief; //отображать рельеф
bool visible; //отображать сетку
bool hideFar; //скрыть удалённые участки
//скрыть участки, выходящие за границу минимума и максимума
bool hideUpLimit;
bool needRecount; //требуется перерасчёт
bool difference; //является разницей между двумя батиметриями
bool blackAndWhite; //отображать в чёрнобелых тонах
bool slg; //является прочитанным slg-файлом
bool hasTide; //прилив вычтен
//методы
//Конструктор
bath();
//Чтение точек из ASCII-файла
bool LoadPoints(AnsiString, bool, bool);
//Чтение трека из slg-файла
bool LoadSlg(DoubleTable &, AnsiString);
//Очистить батиметрию
bool MakeEmpty(int);
//Расчёт прилива
void CountTide(cubic_spline &);
//Вычисление минимума и максимума
void ReCountMinMax();
//Вычисление только минимума
double ReCountMin();
//Расчёт батиметрической сетки
bool CountNet(int, point3D, point3D, double, double, double, double,
double, int, double, double, int, int, int, dinmas<double> *, bool);
//размытие
void blur(int);
//расчёт отклонения
void deviation();
//Расчёт цвета для выбранного узла сетки
inline __fastcall void CountColor(int &, int &);
//Перерасчёт цвета
void ReCountColor();
//Вычисление нормалей
inline __fastcall void CountNorm(int &, int &);
//Конструктор (в виде вызываемой функции)
void DefConstr();
//Вывод одного узла сетки на экран
void OneVertex(int &, int &);
//Вывод всей батиметрии
void view();
//Вывот треков
void ViewPoints();
//Линейная интерполяция
double cf(double &, double &, double &, bool);
//Создание одной изолинии
void makeLine(int &, int &);
//Отображение цифр-подписей
void ViewFigures(int);
//Расчёт одного слоя изолиний
void countOneIso(double);
//Расчёт всех изолиний
void countIso(double, dinmas<double> *, bool);
//Расчёт цифр-подписей
void CountFigures(int);
//Отображение изолиний
void viewIso();
//Удаление расчитанной батиметрической сетки
void EraseNet();
//Вычисление разницы между двумя батиметриями
bool GetDiffer(bath &, bath &, int, double, int);
//Вычисление
bool GetDifferPoints(bath &, double);
//Наложение текстуры
bool ReBindTexture();
//Сохранение сетки в ASCII-формате
bool SaveNet(AnsiString);
//Сохранение данных в формате.inf и.dat для программы ANI
bool SaveANI(AnsiString, double);
//Сохранение набора точек для отображения в прорамме Google Chrome
bool SavePointsGoogle(AnsiString);
//Сохранение трека для отображения в прорамме Google Chrome
bool SaveTrack(AnsiString);
//Сохранение набора точек в ASCII-формате в географических коордиантах
bool SavePoints(AnsiString);
//Сохранение набора точек в ASCII-формате в координатах меркатора
bool SavePointsMer(AnsiString);
//Сохранение батиметрической карты для отображения в прорамме Google Chrome
bool SaveNetGoogle(AnsiString, int);
//Получение всех статических переменных батиметрии из другой
void setConstantPreset(bath &);
//Полное копирование батиметрии из другой
operator=(bath &);
};
//Точка данных нивелирования
struct LevelPoint
{
double l; //расстояние от берега
double h; //высота над уровнем моря
//Координаты начальной точки
double x;
double y;
double z;
};
//Класс для работы с нивелированием
struct Levelling
{
dinmas<LevelPoint> levelPoint; //массив точек местности
};
#endif
3.4.2 Реализация chizu.cpp
#ifndef CHIZU_CPP
#define CHIZU_CPP
#include "chizu.h"
using namespace std;
//Константы малентких чисел
#define SM 0.00000001
#define SM2 0.1
//Смещение изолинии вверх
#define UE 0.001
//Коэффициенты для раскрашивания шкалы
#define RC 4.3
#define GC 1.8
#define BC 1.2
#define RD 0.0
#define GD 0.0
#define BD 0.0
//Эпсилон отклонения
#define EPS 0.0001
AnsiString ReplaceComma(AnsiString str)
{
for(int i=1;i<=str.Length();i++)
{
if(str[i]==',')
str[i]='.';
}
return str;
}
AnsiString PointDouble(double x)
{
return AnsiString(x);
}
AnsiString DegToDegMin(double x)
{
int deg=floor(x);
double min=(x-deg)*60;
return AnsiString(deg)+"° "+PointDouble(min)+"'";
}
AnsiString DegToCoord(double x)
{
int deg=floor(x);
int min=floor(fabs(x-deg)*60);
nt sec=floor(fabs((fabs(x-deg)*60)-min)*60);
int ms=floor(100*((fabs(fabs(fabs(x-deg)*60)-min)*60)-sec));
if(ms==99)
{
ms=0;
sec++;
if(sec==59 || sec==60)
{
sec=0;
min++;
if(min==59 || min==60)
{
min=0;
deg++;
}
}
}
if(min==0 && sec==0 && ms==0)
{
return AnsiString(deg)+":";
}
if(min!=0 && sec==0 && ms==0)
{
return AnsiString(deg)+":"+AnsiString(min)+"'";
}
if(min!=0 && sec!=0 && ms==0)
{
return AnsiString(deg)+":"+
AnsiString(min)+"'"+AnsiString(sec)+"\"";
}
return AnsiString(deg)+":"+AnsiString(min)+
"'"+AnsiString(sec)+"\""+AnsiString(ms);
}
AnsiString DegToDegMinI(double x, bool E)
{
int deg=floor(x);
int min=round((x-deg)*60);
return AnsiString(deg)+"° "+AnsiString(min)+"' "+((E)?"E":"N");
}
AnsiString DegToDegMinSecI(double x, bool E)
{
int deg=floor(x);
int min=floor((x-deg)*60);
int sec=floor((((x-deg)*60)-min)*60);
AnsiString secs=AnsiString(sec)+"\" ";
return AnsiString(deg)+"° "+AnsiString(min)+
"' "+((sec!=0)?(secs):AnsiString(""))+((E)?"E":"N");
}
double DegMinSecToDouble(double deg, double min, double sec)
{
return deg+(min/60.)+(sec/3600.);
}
bool point3D::ataru(point3D &p)
{
return (fabs(p.x-x)<EPS) && (fabs(p.y-y)<EPS) && (fabs(p.z-z)<EPS);
}
bool InTriangle(point3D &a, point3D &b, point3D &c, point3D &p)
{
double pl1, pl2, pl3;
pl1 = (a.x - p.x)*(b.y - a.y)-(b.x - a.x)*(a.y - p.y);
pl2 = (b.x - p.x)*(c.y - b.y)-(c.x - b.x)*(b.y - p.y);
pl3 = (c.x - p.x)*(a.y - c.y)-(a.x - c.x)*(c.y - p.y);
if ((pl1 >= 0 && pl2 >= 0 && pl3 >= 0) ||
(pl1 <= 0 && pl2 <= 0 && pl3 <= 0))
{
return true;
}
return false;
}
bool CorrectTria(point3D &a, point3D &b, point3D &c, double max)
{
if (sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))>max)
{
return 0;
}
else
{
if (sqrt(sqr(a.x-c.x)+sqr(a.y-c.y))>max)
{
return 0;
}
else
{
if (sqrt(sqr(b.x-c.x)+sqr(b.y-c.y))>max)
{
return 0;
}
else
{
return 1;
}
}
}
}
double countColor(double z, double A, double B,
unsigned __int8 color, bool difference, bool blackAndWhite)
{
if(!difference)
{
if(!blackAndWhite)
if(B<=A) return 0;
switch(color)
{
case COLOR_RED:
if(z<0)
return exp(-sqr((z)*(4.3/(-A))));
else
return exp(-sqr((z+B*(-1))*(2/(((1.6)*(B))))));
break;
case COLOR_GREEN:
if(z<0)
return exp(-sqr((z)*(1.8/(-A))));
else
return exp(-sqr((z+B*(-0.42))*(2/(((0.85)*(B))))));
break;
case COLOR_BLUE:
if(z<0)
return exp(-sqr((z)*(1.2/(-A))));
else
return exp(-sqr((z+B*(1.2))*(2/(((1.9)*(B))))));
break;
}
}
else
{
double ret=1-(z-A)/(B-A);
if(ret<0) return 0;
if(ret>1) return 1;
return ret;
}
}
else
{
if(!blackAndWhite)
{
switch(color)
{
case COLOR_RED:
return exp(-pow((z-A-(B-A)*2)*(2./(((3.3)*(B-A)))),10));
break;
case COLOR_GREEN:
return exp(-pow((z-A-(B-A)*0)*(2./(((5)*(B-A)))),4));
break;
case COLOR_BLUE:
return exp(-pow((z-A-(B-A)*(-2))*(2./(((3.5)*(B-A)))),8));
break;
}
}
else
{
double ret=z/((B-A)/8)+B;
if(ret<0) return 0;
if(ret>1) return 1;
return ret;
}
}
}
BathPoint::BathPoint()
{
t=0;
tide=0;
}
isoline::isoline(){};
void isoline::put(double &x1, double &y1, double &z1,
double &x2, double &y2, double &z2, bool &Zero)
{
a.x=x1;
a.y=y1;
a.z=z1;
b.x=x2;
b.y=y2;
b.z=z2;
zero=Zero;
}
void isoline::view(int &isolineSize)
{
if(zero)
{
glLineWidth(2*isolineSize);
glColor4d(0,0,0,1);
}
else
{
glLineWidth(1*isolineSize);
glColor4d(0,0,0,0.5);
}
glBegin(GL_LINES);
glVertex3d(a.x,a.y,a.z+UE);
glVertex3d(b.x,b.y,b.z+UE);
glEnd();
}
void figure::activate(double figh, double h)
{
if(length<figh)
{
x=line->a.x;
y=line->a.y;
z=line->a.z;
double r;
polar(line->b.x-line->a.x, line->b.y-line->a.y, r, angle);
angle=deg(angle);
exists=1;
AnsiString s=FormatFloat("0.00",h);
if(s[s.Length()]=='0')s=s.SubString(1,s.Length()-1);
if(s[s.Length()]=='0')s=s.SubString(1,s.Length()-2);
int i;
for(i=0;i<s.Length()&&i<8;i++)
{
str[i]=s[i+1];
}
strl=i;
}
else
{
exists=0;
}
}
void figure::view(int size)
{
glEnd();
if(!exists) return;
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D,0);
PutMaterial(1,1,1,0,0,0,0,0,0,0,120);
glColor3f(1,1,1);
double figsize=size*0.001875;
#define FIGCF 1.0
#define FIGDS 0.5
#define FIGSM 0.0005
double k=0;
glPushMatrix();
glTranslatef(x,y,z);
glRotatef(angle,0,0,1);
for(int i=0;i<strl;i++)
{
if(str[i]>='0' && str[i]<='9') k=str[i]-'0';
if(str[i]=='.' || str[i]==',') k=10;
if(str[i]=='-') k=11;
glBegin(GL_QUADS);
glTexCoord2f(k/16.0,0);
glVertex3d(-figsize*0.5+figsize*FIGDS*i,-figsize*0.5*FIGCF,i*FIGSM);
glTexCoord2f(k/16.0,1);
glVertex3d(-figsize*0.5+figsize*FIGDS*i,figsize*0.5*FIGCF,i*FIGSM);
glTexCoord2f((k+1)/16.0,1);
glVertex3d(figsize*0.5+figsize*FIGDS*i,figsize*0.5*FIGCF,i*FIGSM);
glTexCoord2f((k+1)/16.0,0);
glVertex3d(figsize*0.5+figsize*FIGDS*i,-figsize*0.5*FIGCF,i*FIGSM);
glEnd();
}
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glPopMatrix();
}
bool bath::triangulation()
{
ofstream file("input.txt");
if(!file.is_open()) return 0;
file<<"2 RBOX s 4 W0 c D2\n";
file<<q.size()<<"\n";
char buffer [50];
SetTitle("СОКО - сохранение точек");
for(int i=0;i<q.size();i++)
{
sprintf(buffer, "%.19f %.19f\n", q[i].m.x, q[i].m.y);
file<<buffer;
}
file.close();
SetTitle("СОКО - расчёт триангуляции");
system(AnsiString("qdelaunay TI input.txt s i Qt TO output.txt").c_str());
//ShowMessage("");
SetTitle("СОКО - чтение треугольников");
ifstream file2("output.txt");
//if(!file2.is_open()) return 0;
unsigned int n=0,x;
file2>>n;
tri.make(n);
for(int i=0;i<n;i++)
{
file2>>x;
tri[i].a=x;
file2>>x;
tri[i].b=x;
file2>>x;
tri[i].c=x;
}
SetTitle("СОКО - треугольники прочитаны");
file2.close();
remove("input.txt");
remove("output.txt");
SetTitle("СОКО - временные файлы удалены");
return 1;
}
bath::bath()
{
DefConstr();
}
bool bath::LoadPoints(AnsiString FileName, bool merkator, bool minus)
{
DefConstr();
fstream file0(AnsiString(FileName+".dat").c_str());
file0.close();
ifstream file(FileName.c_str());
char tmp[30];
double val;
int size=0;
if(!file.is_open()) return 0;
char name[32];
_splitpath(FileName.c_str(),NULL,NULL,name,NULL);
Filename=name;
SetTitle("СОКО - Чтение ASCII");
vector<double> buff;
while (!file.eof())
{
file>>val;
buff.push_back(val);
size++;
}
q.make(size/3);
file.close();
int i=0, coord=0;
for (int j=0;j<size-1;j++)
{
switch(coord)
{
case 0:
q[i].r.x=buff[j];
coord=1;
break;
case 1:
q[i].r.y=buff[j];
coord=2;
if(merkator) MerToGeo(q[i].r.x,q[i].r.y);
break;
case 2:
q[i].r.z=(-minus*2+1)*buff[j];
coord=0;
if(q[i].r.x<min.x) min.x=q[i].r.x;
if(q[i].r.x>max.x) max.x=q[i].r.x;
if(q[i].r.y<min.y) min.y=q[i].r.y;
if(q[i].r.y>max.y) max.y=q[i].r.y;
if(q[i].r.z<min.z) min.z=q[i].r.z;
if(q[i].r.z>max.z) max.z=q[i].r.z;
i++;
break;
}
}
SetTitle("СОКО");
return 1;
}
bool bath::LoadSlg(DoubleTable &table, AnsiString name)
{
#define FEET_TO_M 0.3048
int c=0,n=1,num;
double depth=0;
SetTitle("СОКО - Чтение slg");
for(int i=1;i<table.d.m;i++)
{
if(table.d[13][i]!=0) c++;
}
if(c>=table.d.m) return 0;
q.make(c);
c=0;
int i;
for(i=1;i<table.d.m;i++)
{
if(table.d[13][i]!=0)
{
if(c>0)
{
q[c-1].r.z=-(depth/n)*FEET_TO_M;
if(q[c-1].r.x<min.x) min.x=q[c-1].r.x;
if(q[c-1].r.x>max.x) max.x=q[c-1].r.x;
if(q[c-1].r.y<min.y) min.y=q[c-1].r.y;
if(q[c-1].r.y>max.y) max.y=q[c-1].r.y;
if(q[c-1].r.z<min.z) min.z=q[c-1].r.z;
if(q[c-1].r.z>max.z) max.z=q[c-1].r.z;
}
q[c].r.x=table.d[13][i];
q[c].r.y=table.d[14][i];
q[c].t=table.d[21][i];
MerToGeo(q[c].r.x,q[c].r.y);
depth=table.d[3][i];
n=1;
c++;
}
else
{
n++;
depth+=table.d[3][i];
}
}
q[c-1].r.z=-(depth/n)*FEET_TO_M;
if(q[c-1].r.x<min.x) min.x=q[c-1].r.x;
if(q[c-1].r.x>max.x) max.x=q[c-1].r.x;
if(q[c-1].r.y<min.y) min.y=q[c-1].r.y;
if(q[c-1].r.y>max.y) max.y=q[c-1].r.y;
if(q[c-1].r.z<min.z) min.z=q[c-1].r.z;
if(q[c-1].r.z>max.z) max.z=q[c-1].r.z;
Filename=name;
SetTitle("СОКО");
slg=1;
return 1;
}
bool bath::MakeEmpty(int length)
{
q.make(length);
return 1;
}
void bath::CountTide(cubic_spline &spl)
{
if(slg)
{
if((double)startDate==0.0) return;
for(int i=0;i<q.size();i++)
{
if(hasTide)
q[i].tide=spl.f(startDate+q[i].t/86400000.0);
else
q[i].tide=0;
}
}
else
{
if((double)startDate==0.0 || (double)endDate==0.0) return;
TDateTime current;
for(int i=0;i<q.size();i++)
{
if(hasTide)
q[i].tide=spl.f((double)startDate+((double)endDate-
(double)startDate)*(i/(double)q.size()));
else
q[i].tide=0;
}
}
}
void bath::ReCountMinMax()
{
min.x=MAX;
max.x=MIN;
min.y=MAX;
max.y=MIN;
min.z=MAX;
max.z=MIN;
for(int i=0;i<q.size();i++)
{
if(q[i].r.x<min.x) min.x=q[i].r.x;
if(q[i].r.x>max.x) max.x=q[i].r.x;
if(q[i].r.y<min.y) min.y=q[i].r.y;
if(q[i].r.y>max.y) max.y=q[i].r.y;
if(q[i].r.z<min.z) min.z=q[i].r.z;
if(q[i].r.z>max.z) max.z=q[i].r.z;
}
needRecount=0;
}
double bath::ReCountMin()
{
double min=MAX;
for(int i=0;i<q.size();i++)
{
if(q[i].r.z<min) min=q[i].r.z;
}
return min;
}
bool bath::CountNet(int TexNum, point3D Min, point3D Max, double Sclxy,
double Sclz, double Cfx, double Cfy, double D, int N, double rad,
double isoHABA, int maskBlurCount, int FigHaba, int IsolineSize,
dinmas<double> *Isolist, bool VarIso)
{
fighaba=FigHaba;
sclxy=Sclxy;
sclz=Sclz;
min=Min;
max=Max;
d=D;
texNum=TexNum;
isoHaba=isoHABA;
isolineSize=IsolineSize;
isolist=Isolist;
varIso=VarIso;
height=cfy*N;
width=cfx*N;
for(int i=0;i<q.size();i++)
{
q[i].m.x=sclxy*(q[i].r.x-min.x-(max.x-min.x)/2);
q[i].m.y=sclxy*(q[i].r.y-min.y-(max.y-min.y)/2);
q[i].m.z=sclz*(q[i].r.z+q[i].tide*(hasTide)-min.z-(max.z-min.z)/2);
}
rmn.z=sclz*(min.z-min.z-(max.z-min.z)/2);
rmx.z=sclz*(max.z-min.z-(max.z-min.z)/2);
SetTitle("СОКО - триангуляция");
triangulation();
SetTitle("СОКО - триангуляция завершена");
counted=0;
if(!p.make(width,height)) return 0;
SetTitle("СОКО - создана сетка");
if(!blurBuff.make(width,height))
{
SetTitle("СОКО - не создана буферная сетка");
return 0;
}
else
{
SetTitle("СОКО - создана буферная сетка");
}
if(!MakeArray(height,width)) return 0;
SetTitle("СОКО - создана текстура");
double ls,hs,ls2,l,mn,lm;
if(max.y-min.y>max.x-min.x)
lm=SphereLenght(min.x, min.y, min.x, max.y);
else
lm=SphereLenght(min.x, min.y, max.x, min.y);
int km=0;
SetTitle("СОКО - обнуление сетки");
for(int j=0;j<width;j++)
{
for(int i=0;i<height;i++)
{
p[i][j].x=-cfx/2+d*i;
p[i][j].y=-cfy/2+d*j;
p[i][j].z=0;
p[i][j].b=p[i][j].z;
blurBuff[i][j]=p[i][j].z;
p[i][j].e=0;
}
}
int ia,ib,ja,jb;
double ta=0,tb=0,tc=1,td=0;
SetTitle("СОКО - расчёт треугольников");
for(int k=0;k<tri.size();k++)
{
ia=floor((MinFrom3(q[tri[k].a].m.x,
q[tri[k].b].m.x,q[tri[k].c].m.x)+cfx/2)/d);
ib=ceil((MaxFrom3(q[tri[k].a].m.x,
q[tri[k].b].m.x,q[tri[k].c].m.x)+cfx/2)/d);
ja=floor((MinFrom3(q[tri[k].a].m.y,
q[tri[k].b].m.y,q[tri[k].c].m.y)+cfy/2)/d);
jb=ceil((MaxFrom3(q[tri[k].a].m.y,
q[tri[k].b].m.y,q[tri[k].c].m.y)+cfy/2)/d);
if(ia<0 || ja<0 || ib>height || jb>width) continue;
if(!CorrectTria(q[tri[k].a].m,
q[tri[k].b].m,q[tri[k].c].m,rad/lm)) continue;
planeSet(
q[tri[k].a].m.x,q[tri[k].b].m.x,q[tri[k].c].m.x,
q[tri[k].a].m.y,q[tri[k].b].m.y,q[tri[k].c].m.y,
q[tri[k].a].m.z,q[tri[k].b].m.z,q[tri[k].c].m.z,
ta,tb,tc,td);
for(int j=ja;j<jb;j++)
{
for(int i=ia;i<ib;i++)
{
if(InTriangle(q[tri[k].a].m,
q[tri[k].b].m,q[tri[k].c].m,p[i][j])
&& tri[k].a>=0 && tri[k].a<q.size()
&& tri[k].b>=0 && tri[k].b<q.size()
&& tri[k].b>=0 && tri[k].c<q.size()
)
{
p[i][j].z=(-ta*p[i][j].x-tb*p[i][j].y-td)/tc;
p[i][j].b=p[i][j].z;
blurBuff[i][j]=p[i][j].z;
p[i][j].e=1;
}
}
}
}
if(maskBlurCount==0)
{
SetTitle("СОКО - расчёт цвета и нормалей");
for(int j=0;j<width;j++)
{
for(int i=0;i<height;i++)
{
if(p[i][j].e)
{
CountColor(i,j);
CountNorm(i,j);
}
}
}
}
else
{
blur(maskBlurCount);
}
exsist=1;
counted=1;
SetTitle("СОКО - наложение текстуры");
BindTexture(texNum,1,0);
if(maskBlurCount==0)
{
countIso(isoHaba,isolist,varIso);
deviation();
}
SetTitle("СОКО");
return 1;
}
void bath::blur(int times)
{
for(int k=0;k<times;k++)
{
for(int j=1;j<width-1;j++)
{
for(int i=1;i<height-1;i++)
{
if(
p[i-1][j+1].e && p[i ][j+1].e && p[i+1][j+1].e &&
p[i-1][j ].e && p[i ][j ].e && p[i+1][j ].e &&
p[i-1][j-1].e && p[i ][j-1].e && p[i+1][j-1].e
)
{
blurBuff[i][j]=(
(0.0625)*p[i-1][j+1].z+(0.125)*
p[i ][j+1].z+(0.0625)*p[i+1][j+1].z+
(0.125 )*p[i-1][j ].z+(0.25 )*
p[i ][j ].z+(0.125 )*p[i+1][j ].z+
(0.0625)*p[i-1][j-1].z+(0.125)*
p[i ][j-1].z+(0.0625)*p[i+1][j-1].z
);
}
else
{
blurBuff[i][j]=p[i][j].z;
}
}
}
for(int j=1;j<width-1;j++)
{
for(int i=1;i<height-1;i++)
{
if(
p[i-1][j+1].e && p[i ][j+1].e && p[i+1][j+1].e &&
p[i-1][j ].e && p[i ][j ].e && p[i+1][j ].e &&
p[i-1][j-1].e && p[i ][j-1].e && p[i+1][j-1].e
)
{
p[i][j].z=blurBuff[i][j];
(
(0.0625)*blurBuff[i-1][j+1]+(0.125 )*
blurBuff[i ][j+1]+(0.0625)*blurBuff[i+1][j+1]+
(0.125 )*blurBuff[i-1][j ]+(0.25 )*
blurBuff[i ][j ]+(0.125 )*blurBuff[i+1][j ]+
(0.0625)*blurBuff[i-1][j-1]+(0.125 )*
blurBuff[i ][j-1]+(0.0625)*blurBuff[i+1][j-1]
);
}
else
{
p[i][j].z=blurBuff[i][j];
}
if(k==times-1)
{
CountColor(i,j);
CountNorm(i,j);
}
}
SetTitle("СОКО - размытие "+
AnsiString(FormatFloat(100*(double(k+1)/double(times)),2))+"%");
}
SetTitle("СОКО");
}
exsist=1;
BindTexture(texNum,1,0);
blurCount+=times;
countIso(isoHaba,isolist,varIso);
deviation();
SetTitle("СОКО");
}
void bath::deviation()
{
return;
SetTitle("СОКО - расчёт ошибки");
double sz=0, srz=0, z;
int nx,ny;
for(int i=0;i<q.size();i++)
{
nx=floor((q[i].m.x+cfx/2)/d);
ny=floor((q[i].m.y+cfy/2)/d);
if(nx>=height-2 || ny>=width-2) continue;
if(!p[nx][ny].e || !p[nx][ny+1].e ||
!p[nx+1][ny+1].e || !p[nx+1][ny].e) continue;
z=bilinear(p[nx][ny].z,p[nx][ny+1].z,
p[nx+1][ny].z,p[nx+1][ny+1].z,p[nx][ny].x,
p[nx+1][ny].x,p[nx][ny].y,p[nx][ny+1].y,
q[i].m.x,q[i].m.y);
sz+=fabs(q[i].m.z);
srz+=fabs(z);
}
dev=100*fabs(sz-srz)/srz;
}
inline __fastcall void bath::CountColor(int &i, int &j)
{
tmpz=p[i][j].z/sclz+min.z+(max.z-min.z)/2;
if(difference)
{
imageData[i*RealWidth+j].r=
255*countColor(tmpz,-2,2,0,1,blackAndWhite);
imageData[i*RealWidth+j].g=
255*countColor(tmpz,-2,2,1,1,blackAndWhite);
imageData[i*RealWidth+j].b=
255*countColor(tmpz,-2,2,2,1,blackAndWhite);
}
else
{
imageData[i*RealWidth+j].r=
255*countColor(tmpz,min.z,max.z,0,0,blackAndWhite);
imageData[i*RealWidth+j].g=
255*countColor(tmpz,min.z,max.z,1,0,blackAndWhite);
imageData[i*RealWidth+j].b=
255*countColor(tmpz,min.z,max.z,2,0,blackAndWhite);
}
}
void bath::ReCountColor()
{
SetTitle("СОКО - расчёт цвета");
for(int j=1;j<width-1;j++)
{
for(int i=1;i<height-1;i++)
{
if(p[i][j].e) CountColor(i,j);
}
}
exsist=1;
SetTitle("СОКО - наложение текстуры");
BindTexture(texNum,1,0);
SetTitle("СОКО");
}
inline __fastcall void bath::CountNorm(int &i, int &j)
{
if(i>0 && j>0)
{
VecNormD(
p[i][j].x, p[i][j].y, p[i][j].z,
p[i][j-1].x, p[i][j-1].y, p[i][j-1].z,
p[i-1][j-1].x, p[i-1][j-1].y, p[i-1][j-1].z,
p[i][j].nx, p[i][j].ny, p[i][j].nz, 0) ;
}
}
void bath::DefConstr()
{
//rt=1;
width=1;
height=1;
counted=0;
tex=1;
viewPoints=1;
net=0;
//fb=0;
step=1;
PixelsQnt=0;
isolines=1;
dev=0;
//dif=0;
viewRelief=1;
min.x=MAX; max.x=MIN; min.y=MAX; max.y=MIN; min.z=MAX; max.z=MIN;
visible=1;
hideFar=1;
hideUpLimit=0;
needRecount=0;
difference=0;
blackAndWhite=0;
slg=0;
hasTide=1;
startDate=0;
endDate=0;
lighting=1;
}
void bath::OneVertex(int &i, int &j)
{
//glColor3d(1,1,1);
//material1.view(1,1,1,0,1,1,1,0,0,0,60);
if(tex)
{
glTexCoord2f(((1.*j/width))*wcoeff,((1.*i/height))*hcoeff);
}
else
{
k=i*RealWidth+j;
material_color[0]=imageData[k].r/255.0;
material_color[1]=imageData[k].g/255.0;
material_color[2]=imageData[k].b/255.0;
glColor3fv(material_color);
glMaterialfv(GL_FRONT_AND_BACK,
GL_AMBIENT_AND_DIFFUSE, material_color);
}
glNormal3d(p[i][j].nx,p[i][j].ny,p[i][j].nz);
glVertex3d(p[i][j].x,p[i][j].y,p[i][j].z);
}
void bath::view()
{
if(!counted) return;
if(viewRelief)
{
exsist=0;
if(tex)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texNum);
PutMaterial(1,1,1,0,0,0,0,0,0,0,120);
}
int tc=0;
int stepBuff;
if(!rt)
{
stepBuff=step;
step=1;
}
glColor3d(1,1,1);
PutMaterial(1,1,1,0,0.5,0.5,0.5,0,0,0,60);
if(lighting) glEnable(GL_LIGHTING);
if(step<height && step<width)
{
for(int i=1;i<height-step;i+=step)
{
for(int j=1;j<width-step;j+=step)
{
if(
((hideFar && p[i][j].e && p[i][j+step].e &&
p[i+step][j+step].e && p[i+step][j].e) || !hideFar )
&&
((hideUpLimit && p[i][j].z<rmx.z && p[i][j].z>rmn.z) ||
!hideUpLimit || difference )
)
{
if(!net) glBegin(GL_QUADS); else glBegin(GL_LINE_LOOP);
OneVertex(i,j);
OneVertex(i,j+step);
OneVertex(i+step,j+step);
OneVertex(i+step,j);
glEnd();
}
}
}
}
if(lighting) glDisable(GL_LIGHTING);
glColor3d(0,0,0);
if(!rt)
{
step=stepBuff;
}
if(tex)
{
glDisable(GL_TEXTURE_2D);
}
}
if(isolines) viewIso();
}
void bath::ViewPoints()
{
if(viewPoints)
{
glPointSize(1);
glBegin(GL_POINTS);
for(int i=0;i<q.size();i++)
{
glVertex3d(q[i].r.x,q[i].r.y,q[i].r.z+q[i].tide*(hasTide));
}
glEnd();
}
}
double bath::cf(double &s, double &e, double &f, bool revert)
{
return fabs((revert)-((f-s)/(e-s)));
}
void bath::makeLine(int &i, int &j)
{
if(
(p[i][j].z< f && p[i][j+1].z>=f && p[i+1][j+1].z>=f && p[i+1][j].z>=f)||
(p[i][j].z>=f && p[i][j+1].z< f && p[i+1][j+1].z< f && p[i+1][j].z< f))
{
line.put(p[i][j].x,p[i][j].y+d*cf(p[i][j].z,p[i][j+1].z,f,0),f
,p[i][j].x+d*cf(p[i][j].z,p[i+1][j].z,f,0),p[i][j].y,f,zero);
iso.push_back(line);
//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));
return;
}
if(
(p[i][j].z>=f && p[i][j+1].z< f && p[i+1][j+1].z>=f && p[i+1][j].z>=f)||
(p[i][j].z< f && p[i][j+1].z>=f && p[i+1][j+1].z< f && p[i+1][j].z< f))
{
line.put(p[i][j].x,p[i][j].y+d*cf(p[i][j].z,p[i][j+1].z,f,0),f
,p[i][j].x+d*cf(p[i][j+1].z,p[i+1][j+1].z,f,0),p[i][j].y+d,f,zero);
iso.push_back(line);
//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));
return;
}
if(
(p[i][j].z>=f && p[i][j+1].z>=f && p[i+1][j+1].z< f && p[i+1][j].z>=f)||
(p[i][j].z< f && p[i][j+1].z< f && p[i+1][j+1].z>=f && p[i+1][j].z< f))
{
line.put(p[i][j].x+d*cf(p[i+1][j+1].z,p[i][j+1].z,f,1),p[i][j].y+d,f
,p[i][j].x+d,p[i][j].y+d*cf(p[i+1][j+1].z,p[i+1][j].z,f,1),f,zero);
iso.push_back(line);
//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));
return;
}
if(
(p[i][j].z>=f && p[i][j+1].z>=f && p[i+1][j+1].z>=f && p[i+1][j].z< f)||
(p[i][j].z< f && p[i][j+1].z< f && p[i+1][j+1].z< f && p[i+1][j].z>=f))
{
line.put(p[i][j].x+d*cf(p[i][j].z,p[i+1][j].z,f,0),p[i][j].y,f
,p[i][j].x+d,p[i][j].y+d*cf(p[i+1][j].z,p[i+1][j+1].z,f,0),f,zero);
iso.push_back(line);
//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));
return;
}
if(
(p[i][j].z< f && p[i][j+1].z< f && p[i+1][j+1].z>=f && p[i+1][j].z>=f)||
(p[i][j].z>=f && p[i][j+1].z>=f && p[i+1][j+1].z< f && p[i+1][j].z< f))
{
line.put(p[i][j].x+d*cf(p[i][j].z,p[i+1][j].z,f,0),p[i][j].y,f
,p[i][j].x+d*cf(p[i][j+1].z,p[i+1][j+1].z,f,0),p[i][j].y+d,f,zero);
iso.push_back(line);
//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));
return;
}
if(
(p[i][j].z< f && p[i][j+1].z>=f && p[i+1][j+1].z>=f && p[i+1][j].z< f)||
(p[i][j].z>=f && p[i][j+1].z< f && p[i+1][j+1].z< f && p[i+1][j].z>=f))
{
line.put(p[i][j].x,p[i][j].y+d*cf(p[i][j].z,p[i][j+1].z,f,0),f
,p[i][j].x+d,p[i][j].y+d*cf(p[i+1][j].z,p[i+1][j+1].z,f,0),f,zero);
iso.push_back(line);
//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));
return;
}
if(
(p[i][j].z>=f && p[i][j+1].z< f && p[i+1][j+1].z>=f && p[i+1][j].z< f)||
(p[i][j].z< f && p[i][j+1].z>=f && p[i+1][j+1].z< f && p[i+1][j].z>=f))
{
line.put(p[i][j].x,p[i][j].y+d*cf(p[i][j].z,p[i][j+1].z,f,0),f
,p[i][j].x+d*cf(p[i][j].z,p[i+1][j].z,f,0),p[i][j].y,f,zero);
iso.push_back(line);
//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));
line.put(p[i][j].x+d*cf(p[i+1][j+1].z,p[i][j+1].z,f,1),p[i][j].y+d,f
,p[i][j].x+d,p[i][j].y+d*cf(p[i+1][j+1].z,p[i+1][j].z,f,1),f,zero);
iso.push_back(line);
//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));
return;
}
}
void bath::ViewFigures(int size)
{
//ViewValue("-125.4",0,0,0.05,270);
if(!figures.exists) return;
glBegin(GL_LINES);
for(int i=0;i<fighaba;i++)
{
for(int j=0;j<fighaba;j++)
{
figures[i][j].view(size);
}
}
glEnd();
}
void bath::countOneIso(double k)
f=sclz*(k-min.z-(max.z-min.z)/2);
for(int i=1;i<height-1;i++)
{
for(int j=1;j<width-1;j++)
{
if(
(p[i][j].e && p[i][j+1].e && p[i+1][j+1].e && p[i+1][j].e)
&&
((hideUpLimit && p[i][j].z<rmx.z && p[i][j].z>rmn.z)
|| !hideUpLimit)
)
makeLine(i,j);
}
}
}
void bath::countIso(double IsoHaba, dinmas<double> *Isolist, bool VarIso)
{
isoHaba=IsoHaba;
varIso=VarIso;
isolist=Isolist;
if(p.n==0) return;
double k;
iso.clear();
SetTitle("СОКО - расчёт изолиний");
zero=1;
if(!difference)
{
double min=ReCountMin();
if(varIso)
{
for(k=0;k>min;k-=isoHaba)
{
countOneIso(k);
zero=0;
}
for(k=isoHaba;k<max.z;k+=isoHaba)
{
countOneIso(k);
}
}
else
{
for(int i=0;i<isolist->size();i++)
{
zero=(isolist->operator [](i)==0);
countOneIso(isolist->operator [](i));
}
}
}
else
{
for(k=0;k>-4;k-=isoHaba)
{
countOneIso(k);
zero=0;
}
for(k=isoHaba;k<4;k+=isoHaba)
{
countOneIso(k);
}
}
CountFigures(fighaba);
}
void bath::CountFigures(int figh)
{
//return;
if(p.n==0 || iso.size()==0) return;
SetTitle("СОКО - расчёт цифр");
fighaba=figh;
figures.make(fighaba,fighaba);
double l;
for(int i=0;i<fighaba;i++)
{ //0.86602540378443864676372317075294
for(int j=0;j<fighaba;j++)
{
if(cfx<cfy)
{
figures[i][j].x=-cfx/2+(cfx*i/fighaba);
if(i%2!=0)
figures[i][j].y=-cfy/2+(cfy*j/fighaba);
else
figures[i][j].y=-cfy/2+0.5*cfy/fighaba+(cfy*j/fighaba);
}
else
{
figures[i][j].y=-cfy/2+(cfy*j/fighaba);
if(j%2!=0)
figures[i][j].x=-cfx/2+(cfx*i/fighaba);
else
figures[i][j].x=-cfx/2+0.5*cfx/fighaba+(cfx*i/fighaba);
}
figures[i][j].length=MAX;
for(int k=0;k<iso.size();k++)
{
l=sqrt(sqr(iso[k].a.x-figures[i][j].x)+
sqr(iso[k].a.y-figures[i][j].y));
if(l<figures[i][j].length)
{
figures[i][j].length=l;
figures[i][j].line=&iso[k];
}
}
figures[i][j].activate(
((cfx>cfy)?(cfy/fighaba):(cfx/fighaba))/2,-
(figures[i][j].line->a.z/sclz+min.z+
(max.z-min.z)/2)*(difference?-1:1));
}
}
SetTitle("СОКО");
}
void bath::viewIso()
{
//glEnable(GL_BLEND);
for(int i=0;i<iso.size();i++)
{
iso[i].view(isolineSize);
}
//glDisable(GL_BLEND);
}
void bath::EraseNet()
{
if(!counted) return;
counted=0;
}
bool bath::GetDiffer(bath &src, bath &dst,
int TexNum, double isoHABA, int DiffBlur)
{
SetTitle("СОКО - расчёт разницы");
//DefConstr();
setConstantPreset(src);
difference=1;
Filename=src.Filename+"-"+dst.Filename;
//dif=1;
sclxy=src.sclxy;
sclz=src.sclz;
cfx=src.cfx;
cfy=src.cfy;
min=src.min;
max=src.max;
rmn=src.rmn;
rmx=src.rmx;
diffBlur=DiffBlur;
d=src.d;
texNum=TexNum;
height=src.width;
width=src.height;
isoHaba=isoHABA;
counted=0;
p.make(width,height);
blurBuff.make(width,height);
MakeArray(height,width);
for(int j=0;j<width;j++)
{
for(int i=0;i<height;i++)
{
p[i][j].x=src.p[i][j].x;
p[i][j].y=src.p[i][j].y;
p[i][j].z=
sclz*(
((src.p[i][j].z/src.sclz+src.min.z+(src.max.z-src.min.z)/2)-
(dst.p[i][j].z/dst.sclz+dst.min.z+(dst.max.z-dst.min.z)/2))
-src.min.z-(src.max.z-src.min.z)/2);
p[i][j].b=p[i][j].z;
blurBuff[i][j]=p[i][j].z;
//p[i][j].s=(src.p[i][j].s+dst.p[i][j].s)/2.;
p[i][j].e=src.p[i][j].e&&dst.p[i][j].e;
if(diffBlur==0)
{
CountColor(i,j);
CountNorm(i,j);
}
}
}
exsist=1;
counted=1;
blur(diffBlur);
BindTexture(texNum,1,0);
countIso(isoHaba,isolist,varIso);
return 1;
bool bath::GetDifferPoints(bath &dst, double Range)
{
SetTitle("СОКО - расчёт разницы");
double rx=Range*(max.x-min.x)/SphereLenght(min.x, min.y, max.x, min.y);
double ry=Range*(max.y-min.y)/SphereLenght(min.x, min.y, min.x, max.y);
vector<BathPoint> q1;
for(int i=0;i<q.size();i++)
{
for(int j=0;j<dst.q.size();j++)
{
if((fabs(q[i].r.x-dst.q[j].r.x)<=rx) &&
(fabs(q[i].r.y-dst.q[j].r.y)<=ry))
{
q1.push_back(q[i]);
goto kk;
}
}
kk:
if(i%1000==0)
SetTitle("СОКО - расчёт разницы для \""+Filename+"\" "+
AnsiString(FormatFloat(100*(double(i+1)/double(q.size())),2))+"%");
}
q.make(q1.size());
for(int i=0;i<q1.size();i++)
{
q[i]=q1[i];
}
SetTitle("СОКО");
return 1;
}
bool bath::ReBindTexture()
{
if(counted) exsist=1;
return BindTexture(texNum,1,0);
}
bool bath::SaveNet(AnsiString FileName)
{
ofstream file(FileName.c_str());
if(!file.is_open()) return 0;
SetTitle("СОКО - сохранение сетки");
char buffer [10];
int n;
file<<"0 ";
for(int i=0;i<height;i++)
{
sprintf(buffer, "%.13f", p[i][0].x/sclxy+min.x+(max.x-min.x)/2);
file<<buffer<<" ";
}
file<<"\n";
for(int j=0;j<width;j++)
{
sprintf(buffer, "%.13f", p[0][j].y/sclxy+min.y+(max.y-min.y)/2);
file<<buffer<<" ";
for(int i=0;i<height;i++)
{
sprintf(buffer, "%.13f", p[i][j].z/sclz+min.z+(max.z-min.z)/2);
file<<buffer<<" ";
}
file<<"\n";
}
file.close();
return 1;
}
bool bath::SaveANI(AnsiString FileName, double minutesStep)
{
SetTitle("СОКО - сохранение сетки");
FILE *pFile;
pFile=fopen(AnsiString(FileName.SubString(
1,FileName.Length()-4)+".dat").c_str(), "wb");
if(pFile==0) return 0;
float value;
for(int j=0;j<width;j++)
{
for(int i=0;i<height;i++)
{
if(p[i][j].e)
{
value=-p[i][j].z/sclz+min.z+(max.z-min.z)/2;
}
else
{
value=10001;
}
fwrite(&value, sizeof(float), 1, pFile);
}
}
fclose(pFile);
char buff[256];
char drive[3],direc[256],name[128],ext[8];
_splitpath(FileName.c_str(),drive,direc,name,ext);
ofstream file(FileName.c_str());
CharToOem(Filename.c_str(),buff);
file<<buff<<"\n";
file<<"Created by SOKO\n";
CharToOem(name,buff);
file<<buff<<".dat\n4\n2\n";
file<<width<<" "<<height<<"\n";
file<<"0 0 0 0\n";
file<<ReplaceComma(FormatFloat("0.000000",min.z)).c_str()<<
" "<<ReplaceComma(FormatFloat("0.000000",max.z)).c_str()<<" m\n";
file<<ReplaceComma(minutesStep).c_str()<<" "<<
ReplaceComma(minutesStep).c_str()<<" ' 0\n";
file<<"0 "<<DegToCoord(min.y).c_str()<<" "<<DegToCoord(min.x).c_str();
file<<"\n0\n";
file.close();
return 1;
}
bool bath::SavePointsGoogle(AnsiString FileName)
{
ofstream file(FileName.c_str());
if(!file.is_open()) return 0;
SetTitle("СОКО - сохранение точек");
char buffer [20];
file<< AnsiString(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\" xmlns:kml=\"http://www.opengis.net/kml/2.2\" xmlns:atom=\"http://www.w3.org/2005/Atom\"><Document><name>"+
Filename+".kml</name>\n"+
"<StyleMap id=\"msn_shaded_dot\"><Pair><key>normal</key><styleUrl>#sn_shaded_dot</styleUrl></Pair><Pair><key>highlight</key><styleUrl>#sh_shaded_dot</styleUrl></Pair></StyleMap><Style id=\"sn_shaded_dot\"><IconStyle><scale>0.2</scale><Icon><href>http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png</href></Icon></IconStyle><ListStyle></ListStyle></Style><Style id=\"sh_shaded_dot\"><IconStyle><scale>0.236364</scale><Icon><href>http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png</href></Icon></IconStyle><ListStyle></ListStyle></Style>"+
"<Folder><name>"+Filename+"</name><open>1</open>\n").c_str();
for(int i=0;i<q.size();i++)
{
file<<"<Placemark><styleUrl>#msn_shaded_dot</styleUrl><Point><altitudeMode>relativeToGround</altitudeMode><coordinates>";
sprintf(buffer, "%.13f", q[i].r.x);
file<<buffer<<",";
sprintf(buffer, "%.13f", q[i].r.y);
file<<buffer<<",";
sprintf(buffer, "%.13f", q[i].r.z+q[i].tide*(hasTide));
file<<buffer<<"\n";
file<<"\n</coordinates></Point></Placemark>";
}
file<<"</Folder></Document></kml>";
file.close();
return 1;
}
bool bath::SaveTrack(AnsiString FileName)
{
ofstream file(FileName.c_str());
if(!file.is_open()) return 0;
SetTitle("СОКО - сохранение трека");
char buffer [20];
file<<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\" xmlns:kml=\"http://www.opengis.net/kml/2.2\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n<Document>\n<name>";
file<<"track";
file<<"</name>\n<Style id=\"sn_ylw-pushpin\">\n<IconStyle>\n<scale>\n1.1</scale>\n<Icon>\n<href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>\n</Icon>\n<hotSpot x=\"20\" y=\"2\" xunits=\"pixels\" yunits=\"pixels\"/>\n</IconStyle>\n</Style>\n<StyleMap id=\"msn_ylw-pushpin\">\n<Pair>\n<key>normal</key>\n<styleUrl>#sn_ylw-pushpin</styleUrl>\n</Pair>\n<Pair>\n<key>highlight</key>\n<styleUrl>#sh_ylw-pushpin</styleUrl>\n</Pair>\n</StyleMap>\n<Style id=\"sh_ylw-pushpin\">\n<IconStyle>\n<scale>\n1.3</scale>\n<Icon>\n<href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>\n</Icon>\n<hotSpot x=\"20\" y=\"2\" xunits=\"pixels\" yunits=\"pixels\"/>\n</IconStyle>\n</Style>\n<Placemark>\n<name>";
file<<"track";
file<<"</name>\n<styleUrl>#msn_ylw-pushpin</styleUrl>\n<LineString>\n<tessellate>1</tessellate>\n<coordinates>\n";
for(int i=0;i<q.size();i++)
{
sprintf(buffer, "%.13f", q[i].r.x);
file<<buffer<<",";
sprintf(buffer, "%.13f", q[i].r.y);
file<<buffer<<",0 ";
}
file<<"</coordinates>\n</LineString>\n</Placemark>\n</Document>\n</kml>\n";
file.close();
return 1;
}
bool bath::SavePoints(AnsiString FileName)
{
ofstream file(FileName.c_str());
if(!file.is_open()) return 0;
SetTitle("СОКО - сохранение точек");
char buffer [20];
for(int i=0;i<q.size();i++)
{
sprintf(buffer, "%.13f", q[i].r.x);
file<<buffer<<" ";
sprintf(buffer, "%.13f", q[i].r.y);
file<<buffer<<" ";
sprintf(buffer, "%.13f", -q[i].r.z-q[i].tide*(hasTide));
file<<buffer<<"\n";
}
file.close();
return 1;
}
bool bath::SavePointsMer(AnsiString FileName)
{
ofstream file(FileName.c_str());
if(!file.is_open()) return 0;
SetTitle("СОКО - сохранение точек");
char buffer [20];
double x,y;
for(int i=0;i<q.size();i++)
{
x=q[i].r.x;
y=q[i].r.y;
GeoToMer(x,y);
sprintf(buffer, "%i", (int)x);
file<<buffer<<" ";
sprintf(buffer, "%i", (int)y);
file<<buffer<<" ";
sprintf(buffer, "%.13f", -q[i].r.z-q[i].tide*(hasTide));
file<<buffer<<"\n";
}
file.close();
return 1;
}
bool bath::SaveNetGoogle(AnsiString FileName, int ScaleZ)
{
ofstream file(FileName.c_str());
if(!file.is_open()) return 0;
SetTitle("СОКО - сохранение сетки");
char buffer [20];
int k;
file<< AnsiString(
<?xml version=\"1.0\" encoding=\"UTF-8\"?><kml xmlns=\"http://www.opengis.net/kml/2.2\"><Document><name>"+
Filename+"</name>\n<Style id=\"line\"><LineStyle><color>"+((viewRelief)?"4d000000":"ffffffff")+"</color><width>1</width></LineStyle><PolyStyle><color>"+((viewRelief)?"4d000000":"ffffffff")+"</color></PolyStyle></Style>\n").c_str();
if(viewRelief)
{
for(int i=1;i<height-step;i+=step)
{
for(int j=1;j<width-step;j+=step)
{
if(
((hideFar && p[i][j].e && p[i][j+step].e &&
p[i+step][j+step].e && p[i+step][j].e) || !hideFar )
&&
((hideUpLimit && p[i][j].z<rmx.z && p[i][j].z>rmn.z &&
p[i+step][j+step].e && p[i+step][j].e) ||
!hideUpLimit || difference )
)
{
file<<"<Placemark><visibility>1</visibility><Style id=\"transBluePoly\"><LineStyle><width>0</width></LineStyle><PolyStyle><color>\n";
k=i*RealWidth+j;;
sprintf(buffer, "ff%0*x%0*x%0*x",2,imageData[k].b,2,imageData[k].g,2,imageData[k].r);
file<<buffer<<"\n";
file<<"</color></PolyStyle></Style><Polygon><altitudeMode>absolute</altitudeMode><outerBoundaryIs><LinearRing><coordinates>\n";
sprintf(buffer, "%.13f",p[i][j].x/sclxy+
min.x+(max.x-min.x)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",p[i][j].y/sclxy+
min.y+(max.y-min.y)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",ScaleZ*(p[i][j].z/sclz+min.z+
(max.z-min.z)/2-min.z));
file<<buffer<<"\n";
sprintf(buffer, "%.13f",p[i+step][j].x/sclxy+min.x+
(max.x-min.x)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",p[i+step][j].y/sclxy+min.y+
(max.y-min.y)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",ScaleZ*(p[i+step][j].z/sclz+min.z+
(max.z-min.z)/2-min.z));
file<<buffer<<"\n";
sprintf(buffer, "%.13f",p[i+step][j+step].x/sclxy+min.x+
(max.x-min.x)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",p[i+step][j+step].y/sclxy+min.y+
(max.y-min.y)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",ScaleZ*
(p[i+step][j+step].z/sclz+min.z+(max.z-min.z)/2-min.z));
file<<buffer<<"\n";
sprintf(buffer, "%.13f",p[i][j].x/sclxy+min.x+
(max.x-min.x)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",p[i][j].y/sclxy+min.y+
(max.y-min.y)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",ScaleZ*(p[i][j].z/sclz+min.z+
(max.z-min.z)/2-min.z));
file<<buffer<<"\n";
file<<"</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark>\n";
file<<"<Placemark><visibility>1</visibility><Style id=\"transBluePoly\"><LineStyle><width>0</width></LineStyle><PolyStyle><color>\n";
k=i*RealWidth+j;;
sprintf(buffer, "ff%0*x%0*x%0*x",2,imageData[k].b,2,
imageData[k].g,2,imageData[k].r);
file<<buffer<<"\n";
file<<"</color></PolyStyle></Style><Polygon><altitudeMode>absolute</altitudeMode><outerBoundaryIs><LinearRing><coordinates>\n";
sprintf(buffer, "%.13f",p[i+step][j+step].x/
sclxy+min.x+(max.x-min.x)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",p[i+step][j+step].y/
sclxy+min.y+(max.y-min.y)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",ScaleZ*(p[i+step][j+step].z/
sclz+min.z+(max.z-min.z)/2-min.z));
file<<buffer<<"\n";
sprintf(buffer, "%.13f",p[i][j+step].x/
sclxy+min.x+(max.x-min.x)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",p[i][j+step].y/
sclxy+min.y+(max.y-min.y)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",ScaleZ*(p[i][j+step].z/
sclz+min.z+(max.z-min.z)/2-min.z));
file<<buffer<<"\n";
sprintf(buffer, "%.13f",p[i][j].x/
sclxy+min.x+(max.x-min.x)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",p[i][j].y/
sclxy+min.y+(max.y-min.y)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",ScaleZ*(p[i][j].z/
sclz+min.z+(max.z-min.z)/2-min.z));
file<<buffer<<"\n";
sprintf(buffer, "%.13f",p[i+step][j+step].x/
sclxy+min.x+(max.x-min.x)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",p[i+step][j+step].y/
sclxy+min.y+(max.y-min.y)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",ScaleZ*(p[i+step][j+step].z/
sclz+min.z+(max.z-min.z)/2-min.z));
file<<buffer<<"\n";
file<<"</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark>\n";
}
}
}
}
if(isolines)
{
for(int i=0;i<iso.size();i++)
{
file<<"<Placemark><name>Absolute</name><visibility>1</visibility><styleUrl>#line</styleUrl><LineString><tessellate>1</tessellate><altitudeMode>absolute</altitudeMode><coordinates>\n";
sprintf(buffer, "%.13f",iso[i].a.x/sclxy+min.x+(max.x-min.x)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",iso[i].a.y/sclxy+min.y+(max.y-min.y)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",ScaleZ*(iso[i].a.z/sclz+min.z+
(max.z-min.z)/2-min.z));
file<<buffer<<"\n";
sprintf(buffer, "%.13f",iso[i].b.x/sclxy+min.x+(max.x-min.x)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",iso[i].b.y/sclxy+min.y+(max.y-min.y)/2);
file<<buffer<<",";
sprintf(buffer, "%.13f",ScaleZ*(iso[i].b.z/sclz+min.z+
(max.z-min.z)/2-min.z));
file<<buffer<<"\n";
file<<"</coordinates></LineString></Placemark>\n";
}
}
file<<"</Document></kml>";
file.close();
return 1;
}
void bath::setConstantPreset(bath &src)
{
f=src.f;
zero=src.zero;
startDate=src.startDate;
endDate=src.startDate;
d=src.d;
sclxy=src.sclxy;
sclz=src.sclz;
cfx=src.cfx;
cfy=src.cfy;
dev=src.dev;
tmpz=src.tmpz;
isoHaba=src.isoHaba;
min=src.min;
max=src.max;
rmn=src.rmn;
rmx=src.rmx;
k=src.k;
blurCount=src.blurCount;
texNum=src.texNum+1;
Filename=src.Filename;
tex=src.tex;
step=src.step;
rt=src.rt;
viewPoints=src.viewPoints;
net=src.net;
counted=src.counted;
isolines=src.isolines;
viewRelief=src.viewRelief;
visible=src.visible;
hideFar=src.hideFar;
hideUpLimit=src.hideUpLimit;
needRecount=src.needRecount;
difference=src.difference;
blackAndWhite=src.blackAndWhite;
slg=src.slg;
hasTide=src.hasTide;
exsist=src.exsist;
binded=src.binded;
width=src.width;
height=src.height;
RealWidth=src.RealWidth;
RealHeight=src.RealHeight;
PixelsQnt=src.PixelsQnt,
hcoeff=src.hcoeff;
wcoeff=src.wcoeff;
ID=src.ID;
fighaba=src.fighaba;
isolineSize=src.isolineSize;
}
bath::operator=(bath &src)
{
setConstantPreset(src);
if(src.q.size()>0)
{
q.make(src.q.size());
for(int i=0;i<src.q.size();i++)
{
q[i]=src.q[i];
}
}
if(src.iso.size()>0)
{
for(int i=0;i<src.iso.size();i++)
{
iso.push_back(src.iso[i]);
}
}
if(src.imageData.size()>0)
{
imageData.make(src.imageData.size());
for(int i=0;i<src.imageData.size();i++)
{
imageData[i]=src.imageData[i];
}
}
if(src.p.n>0)
{
p.make(src.p.n,src.p.m);
blurBuff.make(src.p.n,src.p.m);
for(int i=0;i<src.p.n;i++)
{
for(int j=0;j<src.p.m;j++)
{
p[i][j]=src.p[i][j];
blurBuff[i][j]=src.blurBuff[i][j];
}
}
exsist=1;
BindTexture(texNum,1,0);
}
}
#endif
4. РУКОВОДСТВО ПРОГРАММИСТА
4.1 Руководство программиста для программы в целом
4.1.1 Назначение и условия применения программного обеспечения
SOKO обеспечивает выполнение следующих основных функций:
Импорт батиметрическиз данных из исходных треков, получаемых с картплоттера-эхолота;
Импорт береговых линий из GPS-навигатора;
Импорт данных, искусственно созданных с помощью приложения Google Maps;
Наглядное совмещение, компоновка и редактирование данных, исправление ошибок;
Подготовка данных к отображению и обработке: вычитание высоты прилива и сезонных колебаний уровня моря;
Выбор необходимого участка для расчёта посредством введения географических координат прямоугольника, либо в графическом режиме;
Настройка параметров отображения будущей карты: коэффициента пропорциональности высоты, частоты изолиний и других;
Построение и батиметрических карт;
Построение карт сравнения динамики рельефа;
Сохранение готовых карт в виде изображений любого размера;
Создание видеоролика, отображающего карту с различных ракурсов путём последовательной установки камеры с различных позиций;
Экспорт данных в различные форматы;
Сохранение текущего состояния системы для дальнейшей обработки.
Для работы с данным программным обеспечением необходимо перечисленное далее аппаратное и программное обеспечение.
Техническое обеспечение:
персональный компьютер совместимый с IBM PC с тактовой частотой процессора не ниже 1000 МГц;
оперативная память 1024 Мб и более;
накопитель данных со свободным объёмом не менее 3 Гб;
видеокарта и монитор, поддерживающие разрешение 1024*768 точек и выше, с частотой обновления не менее 60 Гц;
устройства ввода клавиатура и манипулятор «мышь» (стандартные);
Программное обеспечение:
операционная система - Microsoft Windows 98 или более поздняя;
интегрированная среда разработки приложений Borland C+ Builder 6
Raize Components - набор визуальных компонентов для Delphi / C++Builder версии не ниже 4.3.2;
приложение для предвычисления приливов wxtide версии не ниже 4.7;
Microsoft Office Excel 2003 или выше;
распространяемый дистрибутив приложения с пакетом дополнительных консольных программ и исполняемым файлом программы «Soko.exe» (схема зависимостей компонентов приложения показана на рисунке 1.10 в приложении №1).
4.1.2 Характеристика программного обеспечения
Программа включает в себя 74 заголовочных файла языке программирования C++, 10 файлов реализации функций, и один файл формы soko_code.dfm, где дана спецификация графического интерфейса.
Графический интерфейс приложения создан в среде разработки приложений Borland C++ Builder на основе компонентов библиотек классов VCL и библиотеки Raize.
Приложение опирается на стандартную библиотеку классов C++, библиотеку VCL, предоставляемую фирмой Borland, библиотеку OpenGL, а также на несколько консольных приложений, необходимых для преобразования данных.
При разработке программного обеспечения в проекте используются модули стандартной библиотеки C++, библиотек VCL, Raize и OpenGL, перечисленные далее в таблицах 4.1-4.3.
Таблица 4.1 - Использованные в программе заголовочные файлы стандартной библиотеки
Заголовочный файл |
Назначение в проекте программы |
|
windows.h |
Реализует доступ к API-функциям операционной системы Microsoft Windows |
|
iostream.h |
Работа с потоками и консолью операционной системы, используется для связи с консольными модулями. |
|
fstream.h |
Чтение и запись файлов |
|
stdio.h |
Стандартный ввод и вывод |
|
map |
Реализует шаблоны классов контейнеров std::map и std::multimap - Ассоциативный массив и мультиотображение. |
|
vector |
Реализует шаблон класса контейнеров std::vector - динамический массив. |
|
math |
Основные математческие операции, такие как косинус или возведение в степень |
|
stdarg.h |
Средства для перебора аргументов функции, количество и типы которых заранее не известны. |
|
ctime |
Типы и функции для работы с датой и временем. |
|
cstdlib |
Функции, занимающиеся выделением памяти, контроль процесса выполнения программы, преобразования типов и другие. |
|
limits |
Определения характеристик общих типов переменных. |
Таблица 4.2 - Использованные в программе классы стандартной библиотеки (выборочно)
Название класса |
Назначение в проекте программы |
|
vector |
Универсальный контейнер, используется редко: для хранения изолиний и уровней изолиний. В остальных случаях заменяется пользовательскими контейнерами семейства dinmas. |
|
map |
Отображение, используется во время вычисления приливов для подготовки данных к кубической интерполяции. |
|
ifstream |
Чтение файлов |
|
ofstream |
Запись файлов |
Таблица 4.3 - Использованные в программе заголовочные файлы VCL
Заголовочный файл |
Назначение в проекте программы |
|
Classes.hpp |
Стандартные классы VCL |
|
StdCtrls.hpp |
Стандартные элементы управления |
|
Forms.hpp |
Форма - окно настроек в программе |
|
Menus.hpp |
Главное меню |
|
Dialogs.hpp |
Диалоговые окна |
|
msxmldom.hpp XMLDoc.hpp xmldom.hpp XMLIntf.hpp |
Классы для работы с XMLёиспользуются для чтения файлов в формате kml (Google Earth), а также xml-файлы треков GPS-навигатора Garmin. |
Таблица 4.4 - Использованные в программе классы VCL
Название класса |
Назначение в проекте программы |
|
AnsiString |
Основной строковый класс программы, используется повсеместно. |
|
TDateTime |
Класс для работы с датой и временем. |
|
FileInfo |
Операции управления файловой структурой. |
|
DirectoryInfo |
Получение сведений о файлах и каталогах. |
|
TMainMenu |
Главное меню |
|
TTimer |
Таймер |
|
TOpenDialog |
Диалог открытия файлов |
|
TSaveDialog |
Диалог сохранения файлов |
|
TPopupMenu |
Контекстное меню |
|
TMenuItem |
Класс элемента главного меню |
|
TXMLDocument |
Класс для работы с XML |
|
TForm |
Рабочее окно программы |
Таблица 4.5 - Использованные в программе программе заголовочные файлы Raize
Заголовочный файл |
Назначение в проекте программы |
|
RzEdit.hpp |
Поля ввода |
|
RzSpnEdt.hpp |
Поля числового ввода, позволяющие изменять значение с помощью колёсика мыши |
|
RzPanel.hpp |
Панели, объединяющие несколько элементов |
|
RzTabs.hpp |
Панели управления страницами |
|
RzButton.hpp |
Кнопки |
|
RzChkLst.hpp |
Списки с выбором элеметов |
|
RzLstBox.hpp |
Списки |
|
RzCmboBx.hpp |
Выпадающие списки |
|
RzRadGrp.hpp |
Группы, позволяющие выбрать один параметр |
|
RzRadChk.hpp |
Группы, позволяющие выбрать несколько параметров |
|
RzLabel.hpp |
Текстовая строка |
|
RzTrkBar.hpp |
Информационная панель внизу |
|
RzGroupBar.hpp |
Вертикальные панели, содержащие сворачиваемые группы элементов управления |
Таблица 4.6 - Использованные в программе программе заголовочные файлы Raize
Название компонента |
Описание |
|
TRzToolbar |
Панель инструментов |
|
TRzToolbarButton |
Кнопка на панели инструментов |
|
TRzPanel |
Панель, объединяющая другие компоненты |
|
TRzSplitter |
Бегунок, разделяющий две панели |
|
TRzListBox |
Список |
|
TRzGroupBar |
Вертикальная панель со сворачиваемыми группами |
|
TRzLabel |
Текстовая подпись |
|
TRzSpinEdit |
Элемент числового ввода, позволяющий изменять значение с помощью колёсика мыи |
|
TRzStatusBar |
Строка состояния |
|
TRzSpacer |
Разделитель на панели инструментов |
|
TRzBitBtn |
Кнопка с изображением |
|
TRzComboBox |
Всплывающий список |
|
TRzCheckBox |
Группа с выбором нескольких элементов |
|
TRzRadioGroup |
Группа с выбором одного элемента |
|
TRzColorEdit |
Элемент управления цветом |
|
TRzCheckList |
Список в выбором элементов |
|
TRzEdit |
Компонент текстового ввода |
|
TRzDateTimeEdit |
Элемент отображения и задания времени и даты |
Кроме перечисленных классов в программе используются классы собственной разработки, предназначенные для чтения, хранения и обработки различных данных: как промежуточных, так и непоредственно батиметрических.
Далее в таблице 4.4 представлены названия основных таких классов, а в таблицах 4.5 и 4.6 дано описание их структуры.
Также следует отметить, что каждый модуль реализован в виде одного или нескольких классов, реализующих функциональность, возложенную на данный модуль.
Таблица 4.7 - Главные структуры данных пользователя, использованные в программе
Название класса |
Назначение в проекте программы |
|
point2d |
Структура «двумерная точка», используется как предок класса «трёхмерная точка» |
|
point3d |
Структура «трёхмерная точка», используется как предок классов Vertex и BathPoint, и поле в классах Camera, Cursor, Isoline, Figure, Lamp. |
Подобные документы
Проектирование программного обеспечения для классифицирования выпускников высшего учебного заведения. Выбор системы управления базами данных и языка программирования. Разработка структуры данных, схема базы данных. Реализация программного комплекса.
дипломная работа [2,4 M], добавлен 27.03.2013Методика расчётов показателей ликвидности предприятия. Требования к программному продукту: описание решаемых задач, внутренней структуры системы (базы данных), рекомендации программисту и пользователю. Порядок контроля и приемки программного продукта.
курсовая работа [1010,9 K], добавлен 28.05.2013Разработка подсистемы формирования комплексной оценки в системе мониторинга наукометрических показателей работников высшего учебного заведения. Виды и методы шкалирования. Исследование существующих математических моделей построения комплексных оценок.
дипломная работа [3,3 M], добавлен 10.11.2012Характеристика объектов автоматизации информационных систем. Требования к документированию. Порядок контроля и приемки системы. Описание потоков данных и бизнес процессов. Структура информационной системы, состав функциональных и обеспечивающих подсистем.
курсовая работа [1,9 M], добавлен 18.09.2013Создание технического задания на разработку информационной системы для заказа билета на самолет. Требования к документированию. Порядок контроля и приемки системы. Разработка концепции, архитектуры построения и платформы реализации информационной системы.
курсовая работа [1,8 M], добавлен 13.05.2015Основание для разработки автоматизированной информационной системы "Будущий абитуриент". Технические требования к программному изделию. Порядок контроля и приемки продукта. Рассмотрение исходной базы данных. Описание интерфейса программного обеспечения.
дипломная работа [3,3 M], добавлен 08.02.2013Создание электронного учебника, написанного на языке гипертекстовой разметки HTML. Характеристика программного обеспечения ЭВМ, необходимого для создания и эксплуатации информационной системы. Алгоритм функционирования системы, отладка программы.
курсовая работа [1,0 M], добавлен 22.12.2012Требования к программному средству. Спецификация качества программного обеспечения. Требования к эргономике и технической эстетики. Стадии и этапы разработки, порядок контроля и приемки. Проектирование архитектуры приложения, руководство пользователя.
курсовая работа [381,6 K], добавлен 20.06.2012Разработка системы управления базой данных "Структура ВУЗа". Требования к программе: функциональным характеристикам, надежности, эксплуатации, составу и параметрам технических средств. Требования к программной документации. Порядок контроля и приемки.
курсовая работа [982,7 K], добавлен 08.06.2015Реализация информационной системы для ведения документации по аренде в СУБД Access 2000. Построение функциональной и информационной модели. Описание программного обеспечения, разработанного в архитектуре "клиент-сервер", анализ операционных характеристик.
курсовая работа [637,9 K], добавлен 30.08.2010