TGLOBE |
Author
Graham Knight
Web Page
Version
2.00 beta
Date
September 1997
Copyright (c) 1997 Graham Knight. All rights reserved.
TGlobe is a Delphi component, compatible with Delphi 1, 2 and 3.
TGlobe displays a three-dimensional globe or mercator projection of the world and allows you to interact in realtime with the countries and objects displayed.
The globe can be rotated and zoomed to display a close-up of any region of the Earth accurate to one nautical mile or one minute of a degree.
This component will definitely benefit from a fast Pentium machine and a fast Video card. It was built on a P166 with 32M of Ram.
This is a shareware component, the source is available on registration. See the end of this document for registration details.
Any bugs, requests for clarification, comments or suggestions welcome.
Please check the Web site http://www3.mistral.co.uk/helmstone/tglobe for the latest version of the component and demo program.
Contents |
Version Control |
- 2.00beta
- Complete re-build to make the internals of TGlobe properly object orientated. Now much easier to add new types of display objects to the globe.
- Added many new functions to facilitate interaction with the globe.
- 1.01
- Finally fixed the 16 bit version
- 1.00
- Introduced Overlays
- Improved performance
- 0.94
- Added MaxTextHeight property to restrict the displayed text height
- Added the ObjectByTitle method to find an object using its title.
- Sorted out the Delphi 3 package, now the delphi 3 version is called Globe3.dcu.
- I have removed the Globe.DPL package as it is not really necessary for D3.
- Some optimisations in the painting routines.
- 0.93
- 16 bit version withdrawn due to compatability problems, if there is enough interest in the 16 bit version I will look at it again.
- Modified Demo program to show realtime updating.
- Fixed Delphi 3 package.
- Add LineLLToLL method to draw lines on the surface of the Globe.
- Added LLtoDeviceXY method to convert Long/Lat coords to XY coords.
- Changed the Parameters to DeviceXYtoLL for consistancy.
- Opened up the OnPaint event.
- Added ScaleFactor property for scaling of objects.
- Fixed Clipping of Objects.
- 0.92
- Allocates working array from heap not static data.
- Included compiled version for Delphi 3.0.
- Added Projection property.
- Added OnZoomed event.
- Added GlobeColor property.
- 0.91
- Cleaned up the globe data file, remove a number of duplicates.
- Moved text to Layer 4 in datafile.
- Fixed Scrollbar Thumb positioning.
- Added LocateObject() method.
- Fixed bug with rendering of countries.
- 0.90
- First public release.
Important Information |
The TGLOBE component must be installed before compiling and running the Demo application. If you do not install the component you will receive errors when you try to compile and run the Demo application.
Globe Component Installation |
Copy these files to the installation to directory of your choice then install the components into your IDE before attempting to compile and run the Demo program.
The rest of the files are required to build and run the Demo program. The GLOBE.DAT file should be placed in the same directory as the Demo program so that is can be loaded on startup.
Installing the TGLOBE component in the Delphi 2 IDE:
To install under the Delphi 3 IDE:
Globe Definitions |
For TGLOBE the following are defined:
EarthRadius = 3437.7;In minutes of a degree or nautical miles
ONE_DEGREE = 60;One degree in minutes of a degree.
DEGREES_360 = (360 * ONE_DEGREE);360 degrees in minutes of a degree
DEGREES_180 = (180 * ONE_DEGREE);180 degrees in minutes of a degree
DEGREES_90 = (90 * ONE_DEGREE);90 degrees in minutes of a degree
MAXPOINTS = 10000;Maximum number of points in an object
MAXOVERLAYS = 10;Maximum number of overlays on the globe
MAXLAYERS = 255;Maximum number of layers on the globe
TPointArray = array [0..MAXPOINTS] of TPoint; PTPointArray = ^TPointArray;Defines an array of TPoint objects, required by some of the Class.Define() routines
TPoint3D = record X,Y,Z : SmallInt; end;Definition of a 3 dimensional point. Longitude, Latitude coordinate pairs are converted to 3D points before being project onto the screen.
EGlobeException = class(Exception);exception raised by the Globe object
Longitude and Latitude are defined as minutes of a degree, this allows reasonable accuracy i.e. a point on the globe can be specified to an accuracy of one nautical mile and all points on the globe can fit within a 16 bit integer value.
Longitude can range between -180 degrees to +180 degrees therefore the range of values for Longitude is from -10800 to +10800 in minutes.
Latitude can range between -90 degrees to +90 degrees therefore the range of values for Latitude is from -5400 to +5400 in minutes.
Globe Utility Functions |
function Point3D( X, Y, Z : Integer ) : TPoint3D;
Creates a TPoint3D from the supplied parameters.
function MinVal( lLeft, lRight : LongInt ) : Longint;
Returns the smaller of the supplied parameters.
function MaxVal( lLeft, lRight : LongInt ) : Longint;
Returns the larger of the supplied parameters.
function AngleToRadians( iAngle : integer ) : double;
Converts an angle in minutes to radians.
function RadiansToAngle( rad : double ) : integer;
Converts an angle in radians to minutes.
Globe object hierachy |
The TGlobe component is actually a manager component for a collection of container objects. The globe component holds a number of overlays ( MAXOVERLAYS ) each overlay contains a collection of globe objects and their associated attributes. Each overlay is independant of any other overlay, but the TGlobe component can bring all of the overlays together. For example the method GLOBE.ObjectAtXY( X, Y ); will search each overlay in turn looking for an object at the specified location.
* TGlobePersistant = class( TObject )
* TGlobeAttribute = class( TGlobePersistant )
TGlobePen = class( TGlobeAttribute )
TGlobeBrush = class( TGlobeAttribute )
TGlobeFont = class( TGlobeAttribute )
* TGlobeObject = class( TGlobePersistant )
TGlobeText = class( TGlobeObject )
TGlobePointText = class( TGlobeText )
TGlobePolyLine = class( TGlobeObject )
TGlobePolyGon = class( TGlobePolyLine )
* TGlobeOverlay = class( TObject )
TGlobe = class( TCustomControl )
Objects marked with an * are internal to the operation of TGlobe and should never be instantiated by the user.
The attribute objects, TGlobePen, TGlobeBrush and TGlobeFont should not be instantiated by the user, these should always be created using the Class.Define() method. This method will create a new instance of the object if necesary otherwise it will return an existing object if it exactly matches the supplied parameters.
TGlobePersistant = class( TObject ) |
This is the root class for all objects and their associated attributes that can be saved to or loaded from a globe data file.
This is an abstract class and should never be instantiated. All classes derived from TGlobePersistant must implement the CreateObject, SaveToStream and LoadFromStream methods.
Actually there should be very little reason to directly derive any object from TGlobePersistant, all objects should be derived from TGlobeAttribute or TGlobeObject. Objects derived from TGlobeAttribute or TGlobeObject should implement the SaveToStream and LoadFromStream methods if they need to be stored into the data file.
constructor CreateObject( Overlay : TGlobeOverlay ); virtual; abstract;
procedure SaveToStream( AStream : TStream ); virtual; abstract;
procedure LoadFromStream( AStream : TStream ); virtual; abstract;
TGlobeAttribute = class( TGlobePersistant ) |
This is the root class for all attributes associated with each globe object. All attributes can be stored in the globe data file.
This is an abstract class and should never be instantiated. All attributes used to draw objects are derived from this class.
constructor CreateObject( Overlay : TGlobeOverlay ); override;
This is called when a new attribute is created, it will associate the attribute with its overlay.
procedure RenderAttribute( State : TGlobeObjectState ); virtual; abstract;
This is called when the attribute is about to be used. The attribute should then set the GlobeCanvas property to the desired values. e.g. TGlobePen will set :-
GlobeCanvas.Pen.Color := Colour; GlobeCanvas.Pen.Style := Style;property Index : integer;
Returns the attributes position in the overlays attribute list associated with the attribute.
TGlobePen = class( TGlobeAttribute ) |
The pen attribute defines the colour and style of lines used to draw the globe objects.
Colour : TColor;
Style : TPenSTyle;
Class function Define( Overlay : TGlobeOverlay; Colour : TColor; Style : TPenStyle ) : TGlobePen;
The Class method Define() should be used to create new pens for use with the overlay. This method searches the overlay for an existing pen that has the same properties as the supplied parameters. If an existing definition is found then it is returned, otherwise a new TGlobePen is created and added to the overlay attribute list.
procedure SaveToStream( AStream : TStream ); override;
procedure LoadFromStream( AStream : TStream ); override;
procedure RenderAttribute( State : TGlobeObjectState ); override;
When called TGlobePen will set the Colour and style of the GlobeCanvas pen.
TGlobeBrush = class( TGlobeAttribute ) |
The brush attribute defines the colour and style used to fill the globe objects when drawn.
Colour : TColor;
Style : TBrushStyle;
Class function Define( Overlay : TGlobeOverlay; Colour : TColor; Style : TBrushStyle ) : TGlobeBrush;
The Class method Define() should be used to create new brushes for use with the overlay. This method searches the overlay for an existing brush that has the same properties as the supplied parameters. If an existing definition is found then it is returned, otherwise a new TGlobeBrush is created and added to the overlay attribute list.
procedure SaveToStream( AStream : TStream ); override;
procedure LoadFromStream( AStream : TStream ); override;
procedure RenderAttribute( State : TGlobeObjectState ); override;
TGlobeFont = class( TGlobeAttribute ) |
The font attribute defines the font, face, size, style and angle used to display the globe object text.
Colour : TColor;
iSize, iAngle : SmallInt;
The angle is specified in tenths of a degree therefore it can be in the range 0 - 3600
Styles : Byte;
sFace : TGlobeTitle;
Class function Define( Overlay : TGlobeOverlay; const Face : string; Colour : TColor; Size, Angle : integer; Styles : TFontStyles ) : TGlobeFont;
The Class method Define() should be used to create new fonts for use with the overlay. This method searches the overlay for an existing font that has the same properties as the supplied parameters. If an existing definition is found then it is returned, otherwise a new TGlobefont is created and added to the overlay attribute list.
procedure SaveToStream( AStream : TStream ); override;
procedure LoadFromStream( AStream : TStream ); override;
procedure RenderAttribute( State : TGlobeObjectState ); override;
TGlobeObject = class( TGlobePersistant ) |
This is the root object for all globe objects that can be drawn on the globe.
property BoundsRect : TRect;
This is the bounding rectangle surrounding the object, this is specified in latitude and longitude coordinates.
property Index : integer;
Readonly property returns the index of the object in the overlays object list.
property Layer : Byte;
The layer on which the object sits within the overlay. The layer controls the order that objects are displayed with objects at layer 0 being displayed first. The Layer can be set to a value fro 0 to 255.
property Origin : TPoint;
This is the initial location for the object, by modifying this value objects can be moved across the globe.
property Overlay : TGlobeOverlay;
Readonly property returns the parent overlay of the object
property OverlayIndex : integer;
Readonly property returns the index of the overlay in the globes overlay list
property State : TGlobeObjectState;
This holds the current state of the object TGlobeObjectState is defined as one of the following values :-
osReset
When set to this it causes the CalcProjectionData method to be called so that any optimisations of the objects associated data can be made.
osRedraw
When the object is modified in some way e.g. its origin is moved then this causes the object to be re-drawn.
osHidden
The object is on the otherside of the globe or outside of the viewing are so does not need to be drawn.
osVisible
The object can be seen and therfore needs to be drawn.
osSelected
The object is the selected object and should be drawn with different attributes.
property Title : TGlobeTitle;
The title associated with the object. TGlobeTitle is defined as string[32].
procedure CalcProjectionData; virtual;
Called when the object is created and whenever the globe is zoomed, this can be used to pre-calculate any data that does not change as the globe is rotated. This is done to improve performace when rendering the object to the screen.
constructor Create( Overlay : TGlobeOverlay; const sTitle : string; iLayer : integer; iLong, iLat : Longint );
Must be called by all derived classes. This initialises the object and set the default data required by all TGlobeObjects.
constructor CreateObject( Overlay : TGlobeOverlay ); override;
Called internally by the Create method. This is used to attach the object to the overlays object list.
procedure Delete;
Method used to delete an object from an overlay, the object is destroyed.
function IsVisible : Boolean; virtual;
This function decides whether the object is on the visible side of the globe and whether it should be painted on the screen. The object can use the TGlobe.GlobeClipRect property to decide what region of the globe is visible.
function LLInObject( iLong, iLat : Longint ) : Boolean; virtual;
Returns True if the specified Longitude and Latitude lie within the boundRect of the object.
procedure LoadFromStream( AStream : TStream ); override;
Called to load all of the objects properties from a data file.
procedure LoadPointsFromStream( AStream : TStream; Origin : TPoint; aPointsLL : PTPointLLArray; iCount : integer );
Utility function to load a list of points from the data file into an array.
procedure SavePointsToStream( AStream : TStream; aPointsLL : PTPointLLArray; iCount : integer );
Utility function to save an array of points to the data file.
procedure Render; virtual;
Called when the object needs to be painted onto the globe.
procedure SaveToStream( AStream : TStream ); override;
Called to Save all of the objects properties to a data file.
TGlobeText = class( TGlobeObject ) |
The text object defines the location and text to display on the globe. The maximum size of the text is limited by the Font.Size property associated with the objce. The minimum size of the text is controled by the TGlobe.MinTextSize property. If the scaled size of the text falls below the minimum size the text will not be displayed.
constructor Create( Overlay : TGlobeOverlay; const sTitle : string; iLayer : integer; iLong, iLat : Longint );
procedure Render; override;
procedure SaveToStream( AStream : TStream ); override;
procedure LoadFromStream( AStream : TStream ); override;
property ObjectFont : TGlobeFont;
TGlobePointText = class( TGlobeText ) |
Has all of the same methods and properties as the TGlobeText object except it displays a circle at the origin location for the object. As for the TGlobeTextObject the text will not be displayed if the scaled size of the text is less than the TGlobe.MinTextSize, but a single pixel will always be displayed to locate the position of the text. The diameter of the circle that is displayed will be the same as the Font.Size property associated with the object.
procedure Render; override;
TGlobePolyLine = class( TGlobeObject ) |
Draws a multipoint line e.g. a river.
constructor Create( Overlay : TGlobeOverlay; const sTitle : string; iLayer : integer; const PointArray : PTPointArray; iCount : integer );
procedure Render; override;
property PointLLArray : PTPointLLArray;
property CountLL : Word;
procedure SaveToStream( AStream : TStream ); override;
procedure LoadFromStream( AStream : TStream ); override;
function LLInObject( iLong, iLat : LongInt ) : Boolean; override;
property ObjectPen : TGlobePen;
TGlobePolyGon = class( TGlobePolyLine ) |
Draws a filled area e.g. a country or state. This object is derived from the TGlobePolyline object and inherits all of its properties and methods.
procedure Render; override;
procedure SaveToStream( AStream : TStream ); override;
procedure LoadFromStream( AStream : TStream ); override;
constructor Create( Overlay : TGlobeOverlay; const sTitle : string; iLayer : integer; const PointArray : PTPointArray; iCount : integer );
property ObjectBrush : TGlobeBrush;
TGlobeOverlay = class( TObject ) |
Objects displayed on the globe can be divided into a series of overlays. Each overlay can hold a single data file, therefore the displayed globe can show multiple files of data at once. Overlays are displayed in order, with overlay 0 being displayed first.
property Enabled : Boolean;
If set to false then the objects inside the overlay will be displayed but will not be searched by the Globe component when the ObjectAtLL() and ObjectAtXY() methods are called. This allows an overlay to be used as a background overlay which cannot be selected.
property Filename : string;
The name of the file associated with the overlay. If this is set to a valid data file name then the file will be loaded into the overlay and displayed.
property Globe : TGlobe;
The parent TGlobe object that owns this overlay.
property Index : integer;
readonly index of the overlay in the range of 0 to MAXOVERLAYS
property LayerEnabled[Index : integer] : Boolean;
Array of flags used to control the display of individual layers within the overlay.
property Objects[Index : LongInt] : TGlobeObject;
The array of objects held in the overlay.
property ObjectCount : LongInt;
The number of objects associated with this overlay.
procedure Clear;
Deletes all data associated with the overlay.
function ObjectAtLL( iLong, iLat : LongInt ) : TGlobeObject;
Returns the object found at the supplied Longitude and Latitude. If no object in the overlay exists at this location then nil is returned.
function ObjectByTitle( const sTitle : string; ObjStart : TGlobeObject ) : TGlobeObject;
Finds an object in the object list which has a matching Title. the ObjStart parameter specifies where in the list the search will start from. If the ObjStart parameter is nil then the search will start from the beginning of the list, if an object is supplied then the search will start from the next object in the list. If no object is found then nil is returned. The returned object can be passed to LocateObject to rotate the globe. This will search all enabled Overlays for an object with the supplied title.
procedure LoadFromFile( const sFileName : string );
Loads a Globe data file into the overlay.
procedure SaveToFile( const sFileName : string );
Saves the data associated with the overlay to a file. If the file already exists then it will be overwritten.
TGlobe = class( TCustomControl ) |
This is the main component class, it combines all of the overlays together and provides the main user interface routines.
Propertiesproperty Bitmap : TBitMap;
Readonly property. This is the bitmap used by the component to draw all of the globe objects onto befor blitting it to the controls window. This can be used to capture an image of the component for use in an external application.
property Canvas;
This is the normal canvas associated with the controls window.
property GlobeCanvas : TCanvas;
This canvas encapsulates the drawing surface used by the component. Drawing operations onto this canvas actually go to the internally held bitmap which is then blitted onto the window.
property Overlays[Index : integer] : TGlobeOverlay;
You can load from 0 to MAXOVERLAYS Globe datafiles, these will be displayed one over the other with overlay 0 being displayed first. Each overlay is independent of any other overlay.
property ScaleFactor : double;
This property is the value used to scale all objects on the globe. 1/ScaleFactor is the number of logical lat/long points that fit inside a single device pixel. An object that is say 100 logical points long can be scaled by multiplying by the ScaleFactor, the result gives the proportional length of the object relative to the globe.
property SelectedObject : TGlobeObject;
Points to the currently selected object or nil if no object is selected. The Selected object is set by the User to any object on the Globe. When the Globe is subsequently painted the selected object is highlighted in red.
property ViewRect : TRect;
This defines the size of the view of the globe that is displayed.
This rectangle is specified in nautical miles. The rectangle is used to zoom into or out of the Globe. To display the whole of the Globe set this rectangle to :
Globe.ViewRect := Rect( 0,0,0,0 );property Brush : TBrush;
This is the brush that will by default be associated with any objects when they are created.
property Color;
This is the colour of the surface of the globe, this will be the colour of the sea.
property DrawGrid : TDrawGrid;
This can be set to either dgNone, dgBehind or dgInFront this will allow the grid to be switched off, or displayed behind or infront of the country objects.
Property Font;
This is the font that will by default be associated with any objects when they are created.
property GlobeFile : string;
This is the path and filename of a TGLOBE database file. The file will be loaded into Overlay 0.
property LongitudeStep : integer;
property LatitudeStep : integer;
These properties control the spacing of the globe's grid lines, the values are in degrees and set relative to the equator and the Greenwich meridian. Setting the longitude step to 15 will display a grid line for every hour difference from GMT. If either property is set to zero then the grid will not be displayed.
property MinTextHeight : integer;
This controls the minimum size of text. If the scaled text is small than this value then it is not displayed. If the value is set to 0 then the text will always be displayed.
property MouseZoomButton : TMouseZoomButton;
This can be set to mzbLeft, mzbRight, mzbMiddle or mzbNone. By setting this to one of the mouse buttons an automatic zoom facility is enabled. If it is set to mzbRight then by pressing and holding the right mouse button a window can be drawn on the globe, when the mouse button is released the globe will expand to display the selected area of the globe.
property Pen : TPen;
This is the pen that will by default be associated with any objects when they are created.
property Projection : TGlobeProjection;
This can be set to gpSpherical or gpMercator. If set to gpSpherical then a 3D Globe is displayed that can be zoomed or rotated. If gpMercator is set then the World is displayed as a 2 dimensional map, the X and Y Rotation properties have no effect when gpMercator is set.
property ScrollBars : TScrollStyle;
This property controls the display of the horizontal or vertical scroll bars for the TGLOBE window.
property XRotation : integer;
property YRotation : integer;
These set the amount that the globe is rotated about the X and Y axes. The axes are orientated in the standard way with the Y axes going from the bottom to the top and the X-axes going from then left to right of the screen. The value of rotation is set in degrees.
property XRotationInMins : integer;
property YRotationInMins : integer;
These set the amount that the globe is rotated about the X and Y axes. The axes are orientated in the standard way with the Y axes going from the bottom to the top and the X-axes going from then left to right of the screen. The value of rotation is set in minutes of a degree.
procedure Clear;
Clears the Globe database of all data and objects. All Overlays are cleared.
function DecimalToLL( DecimalLong, DecimalLat : double ) : TPoint;
This method converts from the decimal Longitude, Latitude values to a Longitude, Latitude point that is used in the Globe datafile, e.g.
The decimal Longitude and Latitude of London England is :
Long = 0.0 degrees Lat = 51.51 degreesThis will be converted to the point ( 0, 3091 ).
function DeviceXYToLL( iX, iY : integer; var ptLL : TPoint ) : Boolean;
Converts screen X, Y coordinates to a Longitude, Latitude coordinate pair. Returns true if the X,Y coordinates lie over the globe and therfore the returned point contains valid data.
procedure LLAsDecimal( iLong, iLat : Longint; var Long, Lat : double );
Converts the Longitude and Latitude coordinates to their decimal representation.
function LLAsString( iLong, iLat : Longint ) : string;
Converts the Longitude, Latitude coordinates to a string representation.
function LLToDeviceXY( iLong, iLat : LongInt; var ptXY : TPoint ) : Boolean;
Converts the iLongitude / iLatitude coords to a device XY coordinate. The boolean return if True indicates that the point is visible, if False then the point lies on the far side of the globe.
function LLToPoint3D( iLong, iLat : LongInt ) : TPoint3D;
procedure ObjectLocate( Obj : TGlobeObject );
Adjusts the Xrotation and Yrotation of the globe to bring the supplied object into the viewing area.
function ObjectAtXY( iX, iY : integer ) : TGlobeObject;
Converts the screen X, Y coordinates to Globe coordinates and returns the object found at that location, or nil if none found. The X, Y coordinates of the Mouse events can be passed directly into this method to retrieve the object located under the mouse cursor.
function ObjectAtLL( iLong, iLat : LongInt ) : TGlobeObject;
Returns the object located at the coordinates supplied, if no object found then nil is returned. This will search all enabled Overlays for an object at the location.
procedure PanViewRect( iX, iY : integer );
Scrolls the current view of the globe to the left, right, up or down by iX and iY nautical miles.
function Point3DToDeviceXY( pt3D : TPoint3D; var pt : TPoint ) : Boolean;
Converts a 3D point to its X,Y coordinate for the screen. The return value is true if the 3D point appears on the visible side of the globe.
function Point3DToLL( p3D : TPoint3D ) : TPoint;
Converts a 3D point to a Longitude, Latitude coordinate pair.
procedure RegisterGlobeClass( AClass : TGlobePersistantClass );
If you derive a new class from TGlobeObject or TGlobeAttribute and you want the object to be stored in the data file then it needs to be registered with the TGlobe component. Only registered objects can be loaded from or saved to the data file.
procedure RenderAttributes( State : TGlobeObjectState; const Attrs : array of TGlobeAttribute );
This will set the GlobeCanvas attributes to the array of passed GlobeAttribute objects
procedure RenderPolygon( const Points : array of TPoint );
Draws a filled polygon using the passed array of points to define the Longitude and Latitude vertices of the polygon. The polygon will be drawn using the current pen and brush associated with the GlobeCanvas. The polygon is projected onto the surface of the globe.
procedure RenderPolyLine( const Points : array of TPoint );
Draws a polyline using the passed array of points to define the Longitude and Latitude vertices of the polyLine The polyline will be drawn using the current pen associated with the GlobeCanvas. The polyline is projected onto the surface of the globe.
procedure RenderTextOut( iLong, iLat : LongInt; const sText : ShortString );
Draws the text at the Longitude and Latitude supplied. The text will be drawn using the current font associated with the GlobeCanvas. The text is projected onto the surface of the globe.
procedure RenderLine( ptFromLL, ptToLL : TPoint; iSteps : integer );
Draws a projected line between the supplied points using the number of steps supplied. A large number of steps will display a smooth line but will take more time to draw.
function ScaleDegreesToDevice( Value : Longint ) : Longint;
Scales a value in degrees to the number of pixels it would represent on the screen.
function ScaleMinutesToDevice( Value : Longint ) : Longint;
Scales a value in minutes of a degree to the number of pixels it would represent on the screen.
property OnPaint : TNotifyEvent;
This event occours after the globe objects have been painted to the GlobeCanvas and its image has been blitted to the Window. This is a good time to draw to the window canvas directly.
property OnRender : TNotifyEvent;
This event occours after the globe objects have been painted to the GlobeCanvas but before the GlobeCanvas has been blitted to the window. This is a good time to write any extra information to the canvas e.g. Titles etc.
property OnSelected : TNotifyEvent;
This event occours whenever an object is selected by setting the Globe.SelectedObject property.
property OnZoomed : TNotifyEvent;
This event occours whenever the Globe is zoomed in or out.
Creating New Globe Objects |
Here is an example of creating a simple globe object. This object displays a scaled triangle at the origin location for the object, this could be used to plot an object moving about the globe e.g. a ship or plane. The displayed triangle is not projected onto the surface of the globe. To plot the object directly onto the surface of the globe the Globe.RenderPolygon() method should be used.
This object can be saved with the data file. The object needs to be registered with the Globe component using the Globe.RegisterGlobeClass() method, this should be done in the FormCreate method before any loading or saving of globe data files has occoured.
If the object does not need to be saved to a data file then it is not necessary to implement the .SaveToStream and .LoadFromStream methods. It is also important that the Globe.RegisterGlobeClass() method is not called so that the Globe object does not try to save or load this class.
The CalcProjectionData method is implemented so that the object can be selected using the mouse. If the object is for display purposes only then this method is not required.
TGlobeTriangle = class(TGlobeObject)
public FPen : TGlobePen; FBrush : TGlobeBrush; FFont : TGlobeFont; constructor Create( Overlay : TGlobeOverlay; const sTitle : string; iLayer : integer; iLong, iLat : integer ); procedure Render; override; procedure CalcProjectionData; override; procedure LoadFromStream( AStream : TStream ); override; procedure SaveToStream( AStream : TStream ); override; end; constructor TGlobeTriangle.Create( Overlay : TGlobeOverlay; const sTitle : string; iLayer : integer; iLong, iLat : integer ); begin inherited Create( Overlay, sTitle, iLayer, iLong, iLat ); with Overlay.Globe do begin FPen := TGlobePen.Define( Overlay, Pen.Color, Pen.Style ); FBrush := TGlobeBrush.Define( Overlay, Brush.Color, Brush.Style ); FFont := TGlobeFont.Define( Overlay, 'Arial', Font.Color, Font.Size, 0, Font.Style ); end; end; procedure TGlobeTriangle.Calcprojectiondata; begin with Origin do BoundsRect := Rect( X - 30, Y - 30, X + 30, Y + 30 ); end; procedure TGlobeTriangle.Render; var iTmp : integer; pt : TPoint; begin with Overlay.Globe do begin RenderAttributes( State, [ FPen, FBrush, FFont ] ); LLToDeviceXY( Origin.X, Origin.Y, pt ); with pt do begin { Scale the size to the globe } iTmp := ScaleMinutesToDevice( 30 ) + 1; GlobeCanvas.Polygon( [ Point( X , Y + iTmp ), Point( X - iTmp, Y - iTmp ), Point( X + iTmp, Y - iTmp ) ] ); SetBkMode( GlobeCanvas.Handle, TRANSPARENT ); GlobeCanvas.TextOut( X - iTmp, Y + iTmp, Title ); SetBkMode( GlobeCanvas.Handle, OPAQUE ); end; end; end;
procedure TGlobeTriangle.LoadFromStream( AStream : TStream ); {-------------------------------} function ReadSmallInt : SmallInt; begin AStream.Read( Result, SizeOf( SmallInt )); end; begin inherited LoadFromStream( AStream ); FPen := TGlobePen( Overlay.Attributes[ReadSmallInt] ); FBrush := TGlobeBrush( Overlay.Attributes[ReadSmallInt] ); FFont := TGlobeFont( Overlay.Attributes[ReadSmallInt] ); end; procedure TGlobeTriangle.SaveToStream( AStream : TStream ); {-----------------------------------------} procedure WriteSmallInt( iVal : SmallInt ); begin AStream.Write( iVal, SizeOf( SmallInt )); end; begin inherited SaveToStream( AStream ); { only save the references to the attributes } WriteSmallInt( FPen.Index ); WriteSmallInt( FBrush.Index ); WriteSmallInt( FFont.Index ); end;
Globe Data File format |
The data file consists of a version identifier and then a list of object classes and the instance data for each class. The attribute classes always come before the object classes because the object classes need to reference the instances of the attribute classes. Each class is responsible for saving and loading any data that is associated with the class instance.
The TGlobePolyline and TGlobePolygon classes store their point data in a compressed form. The points are stored as differences between coordinate pairs to reduce the data file size. ( see below )
The format for globe data file is as follows :-
Size of entry in data file |
Definition of entry |
|
|
Word |
Globe file version |
SmallInt |
Count of objects to follow |
Pascal String |
Name of object class |
|
|
|
|
|
|
TGlobePen |
|
SizeOf( TColor ) |
Pen colour |
SizeOf(TPenStyle) |
Pen style |
|
|
TGlobeBrush |
|
SizeOf( TColor ) |
Brush colour |
SizeOf(TBrushStyle) |
Brush style |
|
|
TGlobeFont |
|
SizeOf( TColor ) |
Font face colour |
SmallInt |
Font size |
SmallInt |
Font angle |
Byte |
Font styles |
Pascal String |
Font face name |
|
|
TGlobeText & TGlobePointText |
|
Byte |
Layer |
Pascal String |
Title |
SmallInt |
Origin Longitude |
SmallInt |
Origin Latitude |
SmallInt |
Font Attribute index number |
|
|
TGlobePolyline |
|
Byte |
Layer |
Pascal String |
Title |
SmallInt |
Origin Longitude |
SmallInt |
Origin Latitude |
SmallInt |
Count of Points in object |
|
|
SmallInt |
Pen Attribute index number |
|
|
TGlobePolygon |
|
|
|
SmallInt |
Brush Attribute index number |
Point List data storage
The point data is stored in a compressed format.
The points are saved as coordinate diferences, the coordinate pairs are actually the difference from the previous coordinate to the new coordinate. This means that each point cannot be more that +127 or -127 minutes different from the prior point.
If the difference between coordinates is greater that +127 or -127 from the prior coordinate then a marker coordinate of 0,0 is output and the following coordinate is output as a full absolute coordinate as SmallInts.
e.g.
Initially the object origin is used as the starting point for the point list.
Origin = 100, 100 Point 1 = 110, 110 Point 2 = 120, 110 Point 3 = 400, 110 Point 4 = 300, 100The output data generated from this will be as follows :- (note the origin coordintes will already have been output )
Char 10, 10 Char 10, 0 Char 0, 0 SmallInt 400, 110 Char -100, -10