// // CPT operator / SondeerGame // This source file is (c) by Deltares. // - October 2014 // /// jln - 14-08-2008 Column for the sondeer computer. class GUISondeerColumn_GeoMil extends GUIMultiComponent; #exec OBJ LOAD FILE=sondeermeester.utx #exec OBJ LOAD FILE=ExampleFonts_T.utx var GeoLabel TopLabel; var GeoLabel TopValueLabel; var GeoLabel BottomLabel; var GeoImage BackgroundImage; //var automated GeoFrame DialogBackground; var color color_background; var color color_lines; //var float tempoffset; var GeoPlayercontroller GeoPC; /// Number of lines in the gef file. var int GEFLines; /// Minimum depth: var int MinDepth; /// Maximum depth which we will allow before scrolling? var int MaxDepth; /// Current time var int SondeerTime; /// speed (set from parent) var float sondeerspeed; /// Colours var array Colors[]; //RedColor; var color WhiteColor; var color BlueColor; var color BlackColor; var color GreyColor; var color RedColor; var color BoxColor; var array ArrayIndex; /// Current depth value: var float CurrentDepth; /// Convert WaterSpanning from mpa to kpa? var bool WaterSpanningToKPA; /// Fonts var Font SmallFont; var Font MediumFont; var Font LargeFont; const GEF_NONE=-1; const GEF_SondeerLengte = 0; const GEF_ConusWeerstand = 1; const GEF_Wrijving = 2; const GEF_Wrijvingsgetal = 3; const GEF_Waterspanning = 4; const GEF_ResultanteHelling = 5; const GEF_HellingNZ = 6; const GEF_HellingOW = 7; const GEF_Diepte = 8; const GEF_Tijd = 9; const GEF_Snelheid = 10; const GEF_RF = 11; /// Geomil only: struct Rect { var float left; var float top; var float right; var float bottom; }; var Rect _verticalline; struct GraphRange { var float rangestart; var float rangeend; var float rangestep; }; var GraphRange rangetop, rangebottom; /// How many lines to display before we start scrolling. /// Central value used on multiple occasions. var int maxlinesvertical; /// String SondeerFile, source of the sondeer data: var string SondeerFile; struct axislabel { var string caption; /// "Rf, u2", etc... var bool istop; /// at top? var Color drawcolor; /// Drawing color var float startrange; /// Starting value at LEFT of screen var float endrange; /// End value at RIGHT of screen var float stepsize; /// Step size between steps. var bool lefttoright; /// Is the value going from left to righ? var string unit; /// Unit displayed. var array values; /// Values! var int dataindex; /// Data index; var float extraoffset; /// extra offset var float currentvalue; /// Current value; }; var array axislabels; /// jln, okay, let's try to make things easier now. /// all units in pixels. var float graph_top; /// Starting position at top of screen (offset) var float graph_left; /// Starting position at left of screen (offset, pixels) var float graph_width; var float graph_height; var float columns_per_row; var float rows_per_screen; var float rows_per_meter; var float meters_per_screen; var float graph_y_step; /// how much are we adding to the graph to match rows_per_meter? (y) var int scrolling_offset_meters; /// start scrolling at rows_per_meter - this var; var float graph_scroll; /// Graph scroll value: var float trim_right_position; /// Used to trim position at right; /// Displacement array: var array Displacements; /// Axis label wrapper function function axislabel createaxis(string caption, bool istop, color drawcolor, float startrange, float endrange, float stepsize, bool lefttoright, string unit, int dataindex, float extraoffset) { local axislabel nl; nl.caption = caption; nl.istop = istop; nl.drawcolor = drawcolor; nl.startrange = startrange; nl.endrange = endrange; nl.stepsize = stepsize; nl.lefttoright = lefttoright; nl.unit = unit; nl.dataindex = dataindex; nl.extraoffset = extraoffset; return nl; } function SetSondeerFile(string file) { SondeerFile = file; GEFLines = int(Localize("Sondering1","linecount",SondeerFile)); MinDepth = 0; MaxDepth = int(Localize("Sondering1","maxdepth",SondeerFile));; } /// Make one of the graphs (specified by index) be affected by a certain amount of displacement. function SetDisplacementFactor(int index, float displacement) { Displacements[index] = displacement; } /// Return value function float GetDisplacementFactor(int index) { return Displacements[index]; } function InitComponent(GUIController MyController, GUIComponent MyOwner) { local int i; Super.Initcomponent(MyController, MyOwner); // Create the two components graph_scroll = 0; CurrentDepth = 0; WhiteColor = class'Canvas'.static.MakeColor(255,255,225); BlackColor = class'Canvas'.static.MakeColor(20,20,20); BlueColor = class'Canvas'.static.MakeColor(0,0,129); GreyColor = class'Canvas'.static.MakeColor(128,128,128); RedColor = class'Canvas'.static.MakeColor(255,0,0); axislabels.insert(0, 5); axislabels[0] = createaxis("Rf", true, class'Canvas'.static.MakeColor(0,0,0, 255), 50, 0, -10, false, "%", GEF_Wrijvingsgetal, 0); //temp axislabels[1] = createaxis("u2", true, class'Canvas'.static.MakeColor(26,127,17, 255), -0.5, 2, 0.5, true, "MPa", GEF_Waterspanning, -0.20); axislabels[2] = createaxis("qc", true, class'Canvas'.static.MakeColor(0,0,255, 255), 0, 30, 6, true, "MPa", GEF_ConusWeerstand, 0); axislabels[3] = createaxis("fs", false, class'Canvas'.static.MakeColor(255,0,0, 255), 0, 0.2, 0.04, true, "MPa",GEF_Wrijving, 0); axislabels[4] = createaxis("ires", false, class'Canvas'.static.MakeColor(214,65,177, 255), 25, 0, -5, false, "º", GEF_ResultanteHelling, 0); /// As much entries as there are GEF columns: Displacements.Insert(0,12); /// Fill with 1's for (i = 0; i < Displacements.length; i++) { Displacements[i] = 1; } color_background = WhiteColor; color_lines = GreyColor; } function bool OnDraw(Canvas C) { graph_top = (self.Wintop + 0.1) * C.SizeY; graph_height = (self.WinHeight - 0.2) * C.SizeY; graph_left = (self.WinLeft) * C.SizeX; graph_width = (self.WinWidth) * C.SizeX; trim_right_position = graph_left + graph_width; meters_per_screen = 5; columns_per_row = 40; rows_per_meter = 5; scrolling_offset_meters = 1; /// Scroll at 4. if (sondeertime > (meters_per_screen * 10) - (scrolling_offset_meters * 10)) { graph_scroll = sondeertime - ((meters_per_screen * 10) - (scrolling_offset_meters * 10)) ; } /// 10 steps per meter. graph_y_step = (graph_height / meters_per_screen) / 10; // Log(" y step: " @ graph_y_step); Super.OnDraw(C); C.DrawColor = WhiteColor; C.Font = SmallFont; /// Draw grid: TileGrid(C, Texture'sondeermeester.sondeergrid'); /// Draw depth nr's DrawDepths(C); DrawCaptionAndUnit(C, false); DrawCaptionAndUnit(C, true); /// Draw the graph. /// Removed fro mthe for loop, so we might not have the runaway loop.. DrawGraph(C, 0); DrawGraph(C, 1); DrawGraph(C, 2); DrawGraph(C, 3); DrawGraph(C, 4); DrawCurrentValueBox(C); return true; } /// Custom tiling function, test. function TileGrid(Canvas C, Texture tex) { local int x, y; local float startindex; local int shift; local float stepsx, stepsy; local int tilesy; /// Steps per cell: stepsx = graph_width / columns_per_row; stepsy = graph_height / (meters_per_screen * rows_per_meter); tilesy = (meters_per_screen * rows_per_meter); //imaxresy + 5; //height / divider; C.DrawColor = color_background; C.SetPos(graph_left, graph_top); C.DrawTileStretched ( Texture'sondeermeester.whitesquare', graph_width , graph_height); C.DrawColor = color_lines; startindex = 0; /// Vertical: for (x = 0; x < columns_per_row; x++) { C.SetPos(graph_left + (x * stepsx), graph_top ); c.DrawLine(1, graph_height); //up } shift = 0; //(startindex % 9) * 3; startindex = graph_scroll % 2; /// Horizontal for (y = 0; y < tilesy + startindex ; y++) // + (startindex / 5) { if ( ((graph_top + (y * stepsy)) - (startindex * graph_y_step)) >= graph_top) { C.SetPos(graph_left, (graph_top + (y * stepsy)) - (startindex * graph_y_step)); //- (startindex*2.5) c.DrawLine(3, graph_width); //right } } C.DrawColor = Whitecolor; } function DrawCaptionAndUnit(Canvas C, bool isbottom) { local float topoffset, lineoffset, nextstep; local float bottomoffset; local float leftoffset; local int i, j; local float stepsize; local float x, y; local float value; local Rect r; local float outx, outy; leftoffset = 0.0; bottomoffset = 0.05; if (isbottom == false) { topoffset = (self.wintop + 0.01) * C.SizeY; } else { topoffset = (graph_top + graph_height) + (0.01 * C.SizeY); } lineoffset = 0.09; C.Font = SmallFont; stepsize = self.WinWidth / 5; nextstep = 0; for (i = 0; i < axislabels.length; i++) { x = graph_left; y = topoffset + (nextstep * C.SizeY); /// top values first: if (axislabels[i].istop == !isbottom) { value = axislabels[i].startrange; C.DrawColor = axislabels[i].drawcolor; /// Caption: C.SetPos(x - (stepsize / 2.6) * C.SizeX, y); /// Set value: C.DrawText(axislabels[i].caption); for (j = 0; j < 6; j++) { /// Set new position: C.strlen(value, outx, outy); /// Set new position: C.SetPos(x - (outx / 2) , y); /// Set value: C.DrawText(value); /// Only draw line on first iteration: if (i == 0) { /// Create x line: r.left = x; r.top = (graph_top - 5); r.right = x; r.bottom = (graph_top + graph_height + 5); DrawVerticalLine(C, r, BlackColor); } /// Prepare next value: x += (stepsize * C.SizeX); value += axislabels[i].stepsize; } /// Unit: /// Set new position: C.SetPos(x - ((stepsize / 2) * C.SizeX), y); C.DrawText(axislabels[i].unit); /// next row: nextstep += 0.02; } } C.DrawColor = WhiteColor; } function UpdateData(int time, bool bottom, optional bool usecustom, optional float customvalue) { local PlayerController pc; local int i; // local int c; // local int ypos; local SondeerLocation sl; local array strsplit1; local float f1; local int j; local float rf; local string s; /// Get active sondeerlocation: pc = PlayerOwner(); sl = GeoPlayercontroller(PC).CurrentSondeerLocation; SondeerTime = time; i = sondeertime; s = ""; if (sondeertime <= GEFLines) { strsplit1 = Split(sl.data[i], " "); //for (j = 0; j <= strsplit1.length; j++) //{ // s = s @ " - " @ strsplit1[j]; //} //log(s); for (j = 0; j < axislabels.length; j++) { f1 = float(strsplit1[ axislabels[j].dataindex ]); /// Displace (using column type constant): f1 *= Displacements[axislabels[j].dataindex]; /// Store current value: axislabels[j].currentvalue = f1; if (axislabels[j].StartRange >= axislabels[j].EndRange) { f1 = FClamp(f1, axislabels[j].EndRange, axislabels[j].StartRange); } else { f1 = FClamp(f1, axislabels[j].StartRange, axislabels[j].EndRange); } axislabels[j].values.Length = sondeertime; axislabels[j].values[sondeertime] = f1; } /// Calculate RF value afterwards: /// GEF_RF - fs (3) / qc (2) /// Division by zero fix. rf = 0; if (axislabels[2].currentvalue > 0) { rf = (axislabels[3].currentvalue / axislabels[2].currentvalue) * 100; } /// Inverse clamp? if (axislabels[0].StartRange >= axislabels[0].EndRange) { rf = FClamp(rf, axislabels[0].EndRange, axislabels[0].StartRange); } else { rf = FClamp(rf, axislabels[0].StartRange, axislabels[0].EndRange); } //Log( axislabels[3].currentvalue @ " / " @ axislabels[2].currentvalue @ " * 100 = " @ rf); axislabels[0].values[sondeertime] = rf; axislabels[0].currentvalue = rf; } } /// jln - 15-08-2008 Draw graph column headers function DrawGraphHeaders(Canvas C, int ArrayIndex, optional bool Bottom) { } function DrawVerticalLine(Canvas MyCanvas, rect _verticalline, color drawcolor) { local color GraphColor; if (_verticalline.left != 0 && _verticalline.top != 0) { GraphColor = MyCanvas.Drawcolor; MyCanvas.DrawColor = drawcolor; DrawLine(MyCanvas, _verticalline.left , _verticalline.top, _verticalline.right , _verticalline.bottom ); MyCanvas.DrawColor = GraphColor; } } function DrawGraph(Canvas MyCanvas, int j) { local int i; local float LX; local float fMaxValue, fMinValue; local float graphmultiplier; local int startindex; local float ypos; local float LX1, LX2; startindex = 0; startindex = graph_scroll; /// Loop through all labels: //for (j = 0; j < axislabels.length; j++) //{ ypos = graph_top; //((Self.WinTop + 0.1) * MyCanvas.SizeY); /// top values first: MyCanvas.DrawColor = axislabels[j].drawcolor; /// Calculate graph multiplier: fMinValue = axislabels[j].startrange; // float(Localize("Sondering1","typemin" $ arrayindex,"Sondering1")); fMaxValue = axislabels[j].endrange; //float(Localize("Sondering1","typemax" $ arrayindex,"Sondering1")); graphmultiplier = ((graph_width - 2) / (abs(fMinValue + fMaxValue))); // LX = ((self.WinLeft * MyCanvas.SizeX) + graphmultiplier) + 2; LX = graph_left + 0.01 + abs((fMinValue-0) * graphmultiplier) + 2; if (axislabels[j].lefttoright == false) { LX = (self.WinLeft + self.WinWidth) * MyCanvas.SizeX; } for (i = startindex; i < axislabels[j].values.length-1; i++) { if (axislabels[j].lefttoright == true) { /// Trim at right if necessary? LX2 = LX + ((axislabels[j].values[i+1] + axislabels[j].extraoffset)*graphmultiplier); if (LX2 > trim_right_position) LX2 = trim_right_position; LX1 = LX + ((axislabels[j].values[i] + axislabels[j].extraoffset)*graphmultiplier); if (LX1 > trim_right_position) LX1 = trim_right_position; DrawLine(MyCanvas, LX1, ypos+( (i-startindex) * graph_y_step), LX2, (ypos+( ( (i-startindex) +1)*graph_y_step))); } else { DrawLine(MyCanvas, LX- ((axislabels[j].values[i] + axislabels[j].extraoffset)*graphmultiplier), ypos+( (i-startindex) * graph_y_step), LX - ((axislabels[j].values[i+1] + axislabels[j].extraoffset)*graphmultiplier), (ypos+( ( (i-startindex) +1)*graph_y_step))); } } //} //} } /// jln - 15-08-2008 Draw depths function DrawDepths(Canvas c) { local int i, j; local float LX; local float startindex; local int counter; local float cY; /// For strlen: local float outx, outy; local float stepsy; // pixel steps mer meter: stepsy = (graph_height / meters_per_screen); C.Font = SmallFont; C.DrawColor = BlackColor; LX = graph_left - 22 ; j = 0; startindex = graph_scroll; counter = 0; // scrollto = ((meters_per_screen * 10) - (scrolling_offset_meters * 10)) + for (i = 0; i < (sondeertime/10) + (meters_per_screen + 2); i++) { /// Set new position: /// Calculate Y position pased on actual font height: /// Subtract startindex as well. C.strlen(i, outx, outy); cY = (graph_top + (counter * stepsy)) - (outy / 2) - (startindex * graph_y_step); // - ((startindex)); if ((cY + outy) >= graph_top && (cY - outy) <= (graph_top + graph_height)) { c.SetPos( LX , cY); c.DrawText(i ); } counter++; } } function SetSpeed(float v) { sondeerspeed = v; } /// jln - 15-08-2008 Draws a box displaying current value function DrawCurrentValueBox(Canvas c) { local float boxwidth, boxheight; local float topoffset; local float boxleft; local int j; local float ystepsize; local array renderorder; local int index; local float stime; /// Loop through all labels: ystepsize = 0.1; topoffset = 0.08; boxwidth = 0.08; boxheight = 0.04; boxleft = graph_left + graph_width + (0.01 * C.SizeX); j = 0; /// LENGTH /// Draw caption: C.Font = SmallFont; C.SetPos( (boxleft ) , (self.WinTop + topoffset + (ystepsize * j)) * C.SizeY); C.DrawColor = BlackColor; C.DrawText( "length [m]" ); /// Draw current value: C.Font = SmallFont; C.SetPos( (boxleft) + 10, (self.WinTop + topoffset + (ystepsize * j) + 0.04) * C.SizeY); C.DrawColor = BlackColor; stime = float(sondeertime) / 10; C.DrawText( stime ); C.SetPos( (boxleft ), (self.WinTop + topoffset + (ystepsize * j) + 0.03) * C.SizeY); C.DrawColor = WhiteCOlor; C.DrawBox(C, boxwidth *C.SizeX , boxheight * C.SizeY); // END /// SPEED j = 1; /// Draw caption: C.Font = SmallFont; C.SetPos( (boxleft), (self.WinTop + topoffset + (ystepsize * j)) * C.SizeY); C.DrawColor = BlackColor; C.DrawText( "speed [cm/s]" ); /// Draw current value: C.Font = SmallFont; C.SetPos( (boxleft) + 10, (self.WinTop + topoffset + (ystepsize * j) + 0.04) * C.SizeY); C.DrawColor = BlackColor; C.DrawText( sondeerspeed ); C.SetPos( (boxleft ), (self.WinTop + topoffset + (ystepsize * j) + 0.03) * C.SizeY); C.DrawColor = WhiteCOlor; C.DrawBox(C, boxwidth *C.SizeX , boxheight * C.SizeY); // END /// jln - 12-12-2008 Cheapo order fix: renderorder.insert(0,5); renderorder[0] = 2; renderorder[1] = 3; renderorder[2] = 1; renderorder[3] = 4; renderorder[4] = 0; for (j = 0; j < renderorder.length; j++) { index = renderorder[j]; /// Draw caption: C.Font = SmallFont; C.SetPos( (boxleft ), (self.WinTop + topoffset + (ystepsize * (j+2))) * C.SizeY); C.DrawColor = BlackColor; C.DrawText( axislabels[index].caption @ "[" $ axislabels[index].unit $ "]" ); /// Draw current value: C.Font = SmallFont; C.SetPos( (boxleft) + 10, (self.WinTop + topoffset + (ystepsize * (j+2)) + 0.04) * C.SizeY); C.DrawColor = axislabels[index].DrawColor; C.DrawText( axislabels[index].CurrentValue); C.SetPos( (boxleft ), (self.WinTop + topoffset + (ystepsize * (j+2)) + 0.03) * C.SizeY); C.DrawColor = WhiteCOlor; C.DrawBox(C, boxwidth *C.SizeX , boxheight * C.SizeY); } } /** str = input string div = divider **/ function array Split(string str, string div) { local array temp; local bool bEOL; local string tempChar; local int precount, curcount, wordcount, strLength; local int i; strLength = len(str); bEOL = false; precount = 0; curcount = 0; wordcount = 0; i = 0; if (strLength == 0) return temp; while(!bEOL) { tempChar = Mid(str, curcount, 1); //go up by 1 count if(tempChar != div) curcount++; else if(tempChar == div) { temp[wordcount] = Mid(str, precount, curcount-precount); wordcount++; precount = curcount + 1; //removes the divider. curcount++; } if(curcount == strLength)//end of string, flush out the final word. { temp[wordcount] = Mid(str, precount, curcount); bEOL = true; } /// Bail out if we get high numbers: // if (i > 500) bEOL = true; i++; } return temp; } /// Draw line on the canvas: function DrawLine(Canvas c, int x1, int y1, int x2, int y2) { local int deltax; // The difference in the x's local int deltay; // The difference in the y's local int y; // Start y off at the first pixel value local int ynum; // The starting value for the numerator local int x; local int prevx; local int prevy; local int xinc1; local int xinc2; local int yinc1; local int yinc2; local int den; local int num; local int numadd; local int numpixels; local int curpixel; curpixel = 0; deltax = abs(x2 - x1); deltay = abs(y2 - y1); y = y1; x = x1; ynum = deltax / 2; prevx = x1; prevy = y; if (x2 >= x1) // The x-values are increasing { xinc1 = 1; xinc2 = 1; } else // The x-values are decreasing { xinc1 = -1; xinc2 = -1; } if (y2 >= y1) // The y-values are increasing { yinc1 = 1; yinc2 = 1; } else // The y-values are decreasing { yinc1 = -1; yinc2 = -1; } if (deltax >= deltay) // There is at least one x-value for every y-value { xinc1 = 0; // Don't change the x when numerator >= denominator yinc2 = 0; // Don't change the y for every iteration den = deltax; num = deltax / 2; numadd = deltay; numpixels = deltax; // There are more x-values than y-values } else // There is at least one y-value for every x-value { xinc2 = 0; // Don't change the x for every iteration yinc1 = 0; // Don't change the y when numerator >= denominator den = deltay; num = deltay / 2; numadd = deltax; numpixels = deltay; // There are more y-values than x-values } for (curpixel = 0; curpixel <= numpixels; curpixel++) { c.SetPos( x, y); c.DrawLine(0, 1); //up num += numadd; // Increase the numerator by the top of the fraction prevx = x; prevy = y; if (num >= den) // Check if numerator >= denominator { num -= den; // Calculate the new numerator value x += xinc1; // Change the x as appropriate y += yinc1; // Change the y as appropriate } x += xinc2; // Change the x as appropriate y += yinc2; // Change the y as appropriate } } function InternalOnChange(GUIComponent Sender) { OnChange(self); } defaultproperties { Begin Object Class=GeoFrame name=TDialogBackground WinLeft=0 WinTop=0 WinWidth=1 WinHeight=1 End Object SmallFont=Font'GeoFonts.SmallFontTex2' MediumFont=Font'GeoFonts.NormalFontTex2' LargeFont=Font'GeoFonts.LargeFontTex2' WinWidth=0.8 WinHeight=0.85 WinLeft=0.05 WinTop=0.05 bTabStop=true PropagateVisibility=true bVisible=true RenderWeight=1 }