GolfmlClass

From Lazarus wiki
Revision as of 08:08, 27 May 2014 by BigChimp (talk | contribs) (some categories. I'm sure DoDi knows some more ;))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

tgolfmlclass


  • A Lazarus/Free Pascal class to accept data via properties and write a well-formed golfml XML golf information exchange file.
  • It will also read a well-formed golfml XML golf information exchange file and present the data via properties.
  • You can have as many Courses and Tee positions as you like (they are stored in internal dynamic arrays) , but only one Golf Club. Holes can be 1 up to 18.
  • ugolfmlclass.pas is available for download from here
  • An example application Golfml Coursewriter is available from here
  • To learn more about golfml visit http://code.google.com/p/golfml/

Declaration

Uses: ugolfmlclass
Var: GolfmlClass:TGolfMLClass;

Methods

  • function *InitOK:* boolean
 * Returns TRUE = Success, FALSE = Fatal Error
  • Procedure *Reset* (use before re-assigning a new club and courses)

Both methods initialise all variables in the class and prepare it for use. The Function InitOK only returns TRUE if all is well.

FORM CREATE EVENT EXAMPLE:

GolfmlClass:=TGolfMLClass.Create; 
If NOT GolfmlClass.InitOK then Halt;
  • function MakeGolfmlFile:Boolean;
 * Returns TRUE=Success.  Overwrites any file with the same name (set in CourseXMLPath property)
  • function GetCourseInfoFromFile:boolean
 * Returns TRUE=Success

Reading

  • GolfmlClass.GetCourseInfoFromFile is called *before* any properties are read and after CourseXMLPath has been set.

Writing

  • GolfmlClass.!MakeGolfmlFile should only be called after all the data has been set using the properties (see below)

Properties Read/Write

// Club-wide Properties
property ClubAmeneties[iIndex:Integer]: string // 0..
property ClubComments[iIndex:Integer]: string // 0..
// Both are dynamic properties that grow as assigned.  They should be assigned in order for reliable results.
// The type and description are separated by a comma
// GolfmlClass.ClubAmeneties[0]:='amenity type,amenity description';
// GolfmlClass.ClubAmeneties[1]:='amenity type,amenity description';


property CourseXMLPath: string // Note: THIS NOT CHECKED FOR VALIDITY by tgolfmlclass.
property ClubName: string
property ClubCountry: string
property ClubCountryCode: string
property ClubMunicipality: string
property ClubRegion: string
property ClubStreet: string
property ClubPostCode: string
property ClubWebsite: string
property ClubPhone: string


// Course-wide Properties
// Change courses by changing the CourseIndex property (0-based)
property CourseIndex:Cardinal  //(zero-based)
Property CourseName:String
Property CoursePar:Cardinal // Total Par value of the course
Property CourseNumberOfHoles:Cardinal //(1-based, usually 9 or 18)


// Tee Position-wide Properties
// Change Tee sets by changing the TeeColourIndex property (0-based)
// Normally, TeeColourIndex is normally from Gold (0) to Red (5)
//  but it can be any scheme you like as long as the TeeColour and
// TeeGender agree.
Property TeeColourIndex:Cardinal  //(zero-based)
property TeeTitle: string // Can be anything: 'Competition', 'Regular', 'Ladies'
property TeeColour: string // i.e. 'gold', 'black', 'white', 'yellow', 'blue', 'red'
property TeeGender: string // 'gentlemen' or 'ladies'
Property CourseRating:Single
Property SlopeRating:Cardinal



// Hole Properties
// Change Hole by changing the HoleIndex property (0-17)
property HoleIndex:Cardinal //(zero-based)
Property Par:Cardinal
Property StrokeIndex:Cardinal
Property Metric:Boolean // Affects Distance conversion. Metric=TRUE means distances in meters
Property TeeDistanceMetres:Cardinal
Property TeeDistanceYards:Cardinal
// Note Tee Distances are automatically converted yards->meters and meters->yards.
// Only specify yards OR meters when setting Tee Distances

// Stylesheet writing properties
Property IncludeScoreCardStylesheetReference:Boolean
Property IncludePlayerScoreCardStylesheetReference:Boolean
Property ScoreCardPlayerName:String
Property ScoreCardPlayerGender:String
Property ScoreCardPlayerDateOfBirth:String
Property ScoreCardPlayerHandicap:Single

=== Properties Read Only ===

Property Version:String readonly;
Property InTeeDistance:Cardinal; // Calculated value for each course.Metric determines metres or yards
Property OutTeeDistance:Cardinal // Calculated value for each course. Metric determines metres or yards
Property TotalTeeDistance:Cardinal // Calculated value for each course. Metric determines metres or yards
Property CourseTotalPar:Cardinal // Calculated value for each course.
Property BogeyRating:Single // Calculated value for each tee position.
property MaxCourseIndex:Cardinal // Highest value for CourseIndex
Property MaxTeeColourIndex:Cardinal
Property ClubMaxAmenitiesIndex:Cardinal
Property ClubMaxCommentsIndex:Cardinal
  • MaxIndex-type properties help when setting up a loop to read the indexed property values e.g.
With GolfmlClass do
  Begin
    For iCount:=0 to MaxCourseIndex do
     begin
        CourseIndex:=iCount; // Set the course number
        MyStringList.Add(CourseName); // Read data for this course
    end;
  End;

SIMPLE WRITING EXAMPLE: To set the Par of Hole 3 to the value 5 on the first course at Tee-position 1:

GolfmlClass.CourseIndex:=0;
GolfmlClass.TeeIndex:=0;
GolfmlClass.HoleIndex:=2;
GolfmlClass.Par:=5;

SIMPLE READING EXAMPLE: To get the Par of Hole 3 on the first course at Tee-position 1:

GolfmlClass.CourseIndex:=0;
GolfmlClass.TeeIndex:=0;
GolfmlClass.HoleIndex:=2;
cParVariable:=GolfmlClass.Par;

How to populate the data before calling MakeGolfmlFile

Normally you would set up 3 nested loops, and assign values to properties within the loops according to their scope.

MULTIPLE WRITING EXAMPLE:

GolfmlClass.Reset;
...Set Club-wide properties...
For CourseLoop:=0 to ... DO
  GolfmlClass.CourseIndex:=CourseLoop; // Write data to this course
  ...assign Course-wide properties...
  For TeeLoop:=0 to .. DO
    GolfmlClass.TeeColourIndex:=TeeLoop; // Write data to this Tee Position in this course
    ...assign Tee Position-wide properties...
    For HoleLoop:=0 to 17 (or 9) DO
        GolfmlClass.HoleIndex:=HoleLoop; // Write data to this hole in this Tee Position in this course
        ...assign Hole properties....
    end; // next hole
  end; // next tee position
end; // next course
GolfmlClass.CourseXMLPath:='C:\courses\mycourse.xml';
GolfmlClass.MakeGolfmlFile;

How to retrieve the data after calling GetCourseInfoFromFile

MULTIPLE READING EXAMPLE

GolfmlClass.Reset;
GolfmlClass.CourseXMLPath:='C:\courses\mycourse.xml';
GolfmlClass.GetCourseInfoFromFile;

//Retrieve the Club properties first.
sName:=GolfmlClass.Clubname;
...etc
//Now get all the Club Amenities via a loop.

Remember the amenity type and description are separated by a comma

Here's a function to separate them

procedure SplitAmenety(var fAmenityType,fAmenetyValue:String;Const aString:String);
// Changes fAmenityType, fAmenetyValue
// Uses C_AMENETYDELIMITERCHAR
Var
   i:Integer;
begin
     if Length(aString)=0 then exit;
     i:=Pos(C_AMENETYDELIMITERCHAR,aString);
     If i > 1 then
     Begin
          fAmenityType:=LeftStr(aString,i-1);
          fAmenetyValue:=RightStr(aString,Length(aString)-i);
     end;
end;

Var sAmenityType, sAmenityValue:String;
For iLoop:=0 to GolfmlClass.ClubMaxAmenitiesIndex do
  begin
       // Initialise strings to pass by value to procedure
       sAmenityType:=;
       sAmenityValue:=;    
SplitAmenety(sAmenityType,sAmenityValue,GolfmlClass.ClubAmeneties[iLoop]);
       MyAmenityTypeList.Add(sAmenityType);
       MyAmenityValueList.Add(sAmenityValue);
  End;

... fetch the ClubComments in the same way...

For iLoop:=0 to GolfmlClass.ClubMaxCommentsIndex do
  begin 
       MyStringList.Add(GolfmlClass.ClubComments[iLoop]);
  End;

Retrieve the data for each hole in each tee set in each course via a loop

For CourseLoop:=0 to GolfmlClass.MaxCourseIndex DO
  GolfmlClass.CourseIndex:=CourseLoop; // Read data from this course
  ...get Course-wide properties...
  .. get Hole pars and strokeindexes (via a holeindex loop)
  For TeeLoop:=0 to GolfmlClass.MaxTeeColourIndex DO
    GolfmlClass.TeeColourIndex:=TeeLoop; // Read data from this Tee Position in this course
    ...get Tee Position-wide properties for this course
    .... get Course and Slope ratings.  Get the Tee colours, titles and genders...
    For HoleLoop:=GolfmlClass.CourseNumberOfHoles DO
        GolfmlClass.HoleIndex:=HoleLoop; // Read data from this hole in this Tee Position in this course
        GolfmlClass.Metric:=TRUE; //=FALSE would retrieve yards
        ...Get Hole distances in metres
    end; // next hole
  end; // next tee position
end; // next course

Summary

Each property has a scope within a Club, Course, Tee-position or Hole.

..for instance:

  • Distances are for a course, tee-position and hole
  • StrokeIndexes are for a course and hole only.
  • CourseRating is for a course and tee-position only

GolfmlClass tries to make this as simple as possible for reading and writing by having 3 "master" index properties for Course, TeePosition and Hole. (There is only ever one Club) In this way, you always know the scope of the property that you are trying to read or write.