By Martin Cerny /
Nov 2,
2016
For parameterization of various regression models Field-Map provides with special function:
function ParameterizeRegressionModel( TableOrLayer :TObjectWrapper;
const XattributeName_,YattributeName_,
Xlabel_,Ylabel_,
ChartCaption_,
ModelType_ :string;
Options_ :string;
out P1_,P2_,P3_,Rcoef_,Syx_,Count_ :variant
) :boolean;
This function analyzes data, parameterizes linear or nonlinear model and show chart on the screen.
Source data come from layer or table, X and Y variables are defined by the user and model parameters as well as model statistics are returned.
Parameter MODELTYPE currently supports following models:
Model type
|
Equation
|
LINE
|
Y=P1+P2*X
|
RATIO
|
Y=P1*X
|
POWER
|
Y=P1*XP2
|
POWERABS
|
Y=P1+P2*XP3
|
LOG
|
Y=P1+P2*ln(X)
|
HYPER
|
Y=1/(P1+P2*X)
|
HYPERX
|
Y=X/(P1+P2*X)
|
EXP
|
Y=P1*e(P2*X)
|
EXPABS
|
Y=P1*e(P2*X)+P3
|
EXPLIN
|
Y=P1*e(P2*X)+P3*X
|
POLY2
|
Y=P1+P2*X+P3*X2
|
HCURVE
|
Y=e(P1+P2/X)
|
MIKHAYLOV
|
Y=P1*e(-P2/X)
|
FREESE
|
Y=e(P1+P2*ln(X)+P3*X)
|
PETTERSON
|
Y=(X/(P1+P2*X))3
|
Parameter OPTIONS can be used for various adjustments of model or chart:
Option
|
Description
|
Values
|
Default
|
X0
|
chart X axis origin
|
DATA or numeric value
|
0
|
Y0
|
chart Y axis origin
|
DATA or numeric value
|
0
|
YSHIFT
|
to be subtracted from Y i.e. Y=Yshift+Function(X)
|
numeric value
|
0
|
SHOWCHART
|
show chart on the screen
|
YES or NO
|
YES
|
SHOWEQUATION
|
show equation in the chart
|
YES or NO
|
YES
|
DOTSIZE
|
dot size in the chart
|
numeric value
|
3
|
DOTCOLOR
|
dot color in the chart
|
RGB values
|
100,255,255
|
LINEWIDTH
|
with of the regression line in the chart
|
numeric value
|
3
|
LINECOLOR
|
line color in the chart
|
RGB values
|
0,0,0
|
BUTTON
|
buttons of chart dialog
|
AUTO or CLOSE or OKCANCEL
(AUTO->OK+CANCEL if model is available, otherwise CLOSE
|
AUTO
|
X[index]
|
X value to be shown in the chart with respective Y value, e.g. mean diameter and mean height; more than one X is allowed; e.g. X[1]=23.4;X[2]=33.2
|
numeric value
|
|
XFORMAT[index]
|
format of X value label to be shown in chart; e.g. XFORMAT[1]=%0.1f cm
|
text
|
|
YFORMAT[index]
|
format of respective Y value label to be shown in chart, e.g. YFORMAT[1]=%0.1f m
|
text
|
|
Multiple options can be passed to the function, individual options are separated by semicolon.
example:
X0=DATA;Y0=DATA;YSHIFT=1.3;SHOWCHART=YES;DOTSIZE=9;LINEWIDTH=8;LINECOLOR=123,200,60;DOTCOLOR=255,5,255
Use of model parameterization is rather versatile. As a typical example the parameterization of tree height models can be described.
In the example project there are several sample plots with diameter at breast height for all trees and tree height measurement for subsample of tree. The aim is to find height models for individual species and use the model for tree height calculation for all trees. For those species which do not have sufficient subsample of height measurement the overall model parameterized for all species together will be used.
{a. make separate diameter-height curves for each species}
{ in the forest reserve (over all plots)}
{ and write p1 and p2 to an external file}
{b. make an overall curve with all species included}
{c. calculate height for each tree, based on those diameter-height-curves}
{d. if There are less than 4 trees of that particular species, }
{ the overall curve has to be used}
var tbSpecies, tbTrees, tbAllTrees, tbSpeciesDH :TTableWrapper;
P1_, P2_, P3_, glP1_, glP2_, Syx_, Rcoef_, Count_, h_ :variant;
ShowCharts_ :boolean;
Options_ :string;
begin
//delete previous CalcHeight values
Trees.Update('CalculatedHeight_m=NULL','IDPlots IS NOT NULL');
//create a temporary table with list off all the species in the project
//where we want to create DH-curves for (only living, intact trees, no coppice)
tbSpecies :=
Project.GetQueryResult(format( 'SELECT DISTINCT '
+'Trees.Species, '
+'qspecies.Value1 AS Species_lkp '
+'FROM Trees '
+'INNER JOIN qspecies '
+'ON Trees.Species = qspecies.ID '
+'ORDER BY Trees.Species',
[Plots.ValueAsinteger[‘ID’]]));
tbSpeciesDH :=
CreateMemTableFromDefs( 'Species:I|Species_lkp:A40|Hcurve_P1:N|'
+'Hcurve_P2:N|Height_Syx:N|Height_Rcoef:N|'
+'Height_Count:I','Species');
try
Options_ := 'YSHFT=1.3;';
ShowCharts_ := YesNoQuestion('Show charts ?');
if not ShowCharts_ then Options_:=Options_+'SHOWCHART=NO';
OpenLog('Parameterize height curves');
StartProgressBarCycle(tbSpecies.RecordCount+1);
//global model
tbTrees :=
Project.GetQueryResult( 'SELECT CAST(DBH_mm AS FLOAT)/10 AS DBH_cm, '
+'Height_m '
+'FROM Trees ');
try
StepProgressBar;
Log(format('All species n=%d',[tbTrees.RecordCount]));
ParameterizeRegressionModel( tbTrees,
'DBH_cm',
'Height_m',
'DBH, cm',
'Height, m',
'All species',
'HCURVE',
Options_,
glP1_,glP2_,P3_,Rcoef_,Syx_,Count_);
tbSpeciesDH.Append;
tbSpeciesDH[‘Species’] := 0;
tbSpeciesDH[‘Species_lkp’] := 'All species';
tbSpeciesDH[‘Hcurve_P1’] := glP1_;
tbSpeciesDH[‘Hcurve_P2’] := glP2_;
tbSpeciesDH[‘Height_Syx’] := Syx_;
tbSpeciesDH[‘Height_Rcoef’] := Rcoef_;
tbSpeciesDH[‘Height_Count’] := Count_;
tbSpeciesDH.Post;
finally
tbTrees.Free;
end;
//species models
tbSpecies.First;
while not tbSpecies.EOF do begin
tbTrees :=
Project.GetQueryResult(
format( 'SELECT CAST(DBH_mm AS FLOAT)/10 AS DBH_cm, Height_m '
+'FROM Trees '
+'WHERE Species=%d AND Height_m IS NOT NULL',
[tbSpecies.ValueAsInteger[‘Species’]]));
tbAllTrees :=
Project.GetQueryResult(format( 'SELECT IDPlots,ID,X_m,Y_m,'
+'Edit_Date,Edit_User,'
+'CAST(DBH_mm AS FLOAT)/10 AS DBH_cm, '
+'Height_m,CalculatedHeight_m '
+'FROM Trees '
+'WHERE Species=%d',
[tbSpecies.ValueAsInteger[‘Species’]]));
try
StepProgressBar;
Log(format('%s n=%d',
[ tbSpecies.ValueAsString[‘Species_lkp’],
tbTrees.RecordCount]));
ParameterizeRegressionModel( tbTrees,
'DBH_cm',
'Height_m',
'DBH, cm',
'Height, m',
format('Species: %s',
[tbSpecies[‘Species_lkp’]]),
'HCURVE',
Options_,
P1_,P2_,P3_,Rcoef_,Syx_,Count_);
tbSpeciesDH.Append;
tbSpeciesDH[‘Species’] := tbSpecies[‘Species’];
tbSpeciesDH[‘Species_lkp’] := tbSpecies[‘Species_lkp’];
tbSpeciesDH[‘Hcurve_P1’] := P1_;
tbSpeciesDH[‘Hcurve_P2’] := P2_;
tbSpeciesDH[‘Height_Syx’] := Syx_;
tbSpeciesDH[‘Height_Rcoef’] := Rcoef_;
tbSpeciesDH[‘Height_Count’] := Count_;
tbSpeciesDH.Post;
//calculate missing heights using local or global model
if VarIsNull(P1_) or (Count_<4) then begin
Log(#9'(global model)');
P1_:=glP1_;
P2_:=glP2_;
end;
tbAllTrees.First;
while not tbAllTrees.EOF do begin
tbAllTrees.Edit;
tbAllTrees[‘CalculatedHeight_m’] :=
Round(CalculateModelValue('HCURVE',P1_,P2_,P3_,tbAllTrees[‘DBH_cm’]),2);
tbAllTrees[‘Edit_Date’] := Now;
tbAllTrees[‘Edit_User’] := Project.UserLoginName;
tbAllTrees.Post;
tbAllTrees.Next;
end;
finally
tbTrees.Free;
tbAllTrees.Free;
end;
tbSpecies.Next;
end;
//save model parameters to Excel
tbSpeciesDH.SaveToExcel( ProjectDir+'MISC\DiamHeightCurves',
'Tree heights',
true,
true);
ResetProgressBar;
Log('');
Log('Diameter-heightcurves calculated');
CloseLogWithDelay(3500);
finally
tbSpecies.Free;
tbSpeciesDH.Free;
end;
Trees.Refresh;
end.
The script and the example is working from Field-Map X6.0.7444 or newer!
Download scripting example 005 (Field-Map Project)