User Tools

Site Tools


guides:migration

Migrating to DK11

Documentation | Migration

DK11 is highly compatible with the previous DK code, though it is internally heavily redesigned. A few things that were modernized, however, require some code changes when upgrading an application to the DK11 from an earlier version.

Be sure to also read: Known issues.

Control Properties

Some obsolete control properties were abandoned. As a result, opening forms can cause a warning message, like “Error reading GIS.XYZ: Property XYZ does not exist”. To resolve this, just touch your form to change something on it, even just for a while, to remove the obsolete property. For example, change a bit the size of the form to force the modification flag and then save.

Enums

Previously enums were like this: gisFieldTypeString. Now enums are unified to a naming scheme that looks like this: TGIS_FieldType.String. Delphi users can bring back old names by compiling the app with GIS_DK10VCL_COMPATIBILITY define.

Inheritance

The most important change is TGIS_ViewerWnd is no longer inherited from TGIS_Viewer, and is now implemented just as IGIS_Viewer interface. Thanks to this, TGIS_Viewer is just a pure object which is used internally by TGIS_ViewerWnd, which can be directly inherited from a proper control.

Mouse/Tap handling

On gesture-enabled devices (Windows with Touch Screen, Android, iOS), we interpret mouse gestures automatically only if GIS.Mode = TGIS_ViewerMode.Select.

However, using standard MouseDown, MouseMove, and MouseUp events is not reliable in such situation because these events can also be fired upon interpreting gestures. Therefore, the following new events were implemented in DK11:

  • TapSimpleEvent
    For simple tap-release
  • TapDoubleEvent
    For double tap
  • TapLongEvent
    For tapping and holding for a bit longer

These events are available also on non-gesture devices (like plain Windows) and are recommended for general use in application code, instead of handling MouseDown / MouseUp events.

Accessing Canvas object

Canvas objects that could be accessed via TGIS_ViewerWnd.Canvas no longer exist. Generally, such a way of accessing the canvas worked only on GDI32 and GDIPlus. With the DK11 we introduced rendering also using a GPU card (see Plugable Renderers). In such an environment, a “canvas” like an object exists only upon drawing. Furthermore, we introduced a number of methods that support device-independent drawing. Therefore, instead of using:

  GIS.Canvas.Pen.Width := 1 ;

a paint event based access is required (which is provided in active _renderer context):

  _renderer.CanvasPen.Width := 1 ;
  _renderer.CanvasDrawRectangle( rect );

Please take a look at CustomPaint sample.

Event const modifier

Event handlers are now without const modifier. See DK.Delphi: More compatible events parameters

Event names

Event names were unified. All events introduced by the Developer Kernel 11 now have names like PaintShapeEvent instead of OnPaintShape.

Due to event name changes, when porting projects from DK10, events attached in design mode become detached and must be attached again.

Paint events

For information on how to replace DK10 OnBeforePaint, OnAfterPaint and OnPaint, take a look at our new Redefined Paint Events Model.

Map invalidation

Map invalidation model has been simplified:

  • TGIS_Shape.Invalidate
    Is now parameter-less and self-aware of how deep invalidation should be (is it a topmost tracking layer or not).
  • TGIS_Viewer.InvalidateWholeMap
    Issues a deep (full) map redraw.
  • TGIS_Viewer.InvalidateTopmost
    Issues a redrawing only of the topmost (tracking) layers
  • TGIS_Viewer.InvalidateSelection
    Redraws only the selection state of the selected shapes.

Use of the old TGIS_Viewer.InvalidateExtent is still possible, but methods are marked as deprecated.

Using TGIS_ViewerWnd.Update or TGIS_ViewerWnd.Refresh orTGIS_ViewerWnd.Invalidate does not invalidate the map.

For TGIS_ViewerBmp avoid using .Draw. Use InvalidateWholeMap instead. See Known Issues

Map updates

Map updates upon zooming or dragging are animated and delayed to allow for further map operations before starting the map update process. This behavior is controlled using the viewer properties:

* TGIS_ViewerWnd.UseAnimations - Use True if animation upon zooming is allowed
* TGIS_ViewerWnd.ProgressiveUpdate - If > 0, map will be updated upon time-consuming updates
* TGIS_Viewer.DelayedUpdate - If > 0, map will be updated after a while, allowing for next operations before full redraw

If you want map updates to behave like in the DK10 (no delay, no animations), set these properties to 0 (or False).

Shape selection

Selecting a shape using the IsSelected property no longer requires calling MakeEditable on the shape. Also, the selection is invalidated and drawn automatically on the map. Therefore, to avoid delays upon multi-selection, the viewer should be locked before the operation and unlocked after the operation is finished to invalidate the selection.

Exporting to image

The TGIS_ViewerWnd.ExportToImage and ExportToGrid methods have been deprecated. The DK11 introduced a new class TGIS_PixelExportManager (defined in GisPixelExportManager.pas) as a mechanism for exporting the content of TGIS_ViewerWnd. TGIS_PixelExportManager can output the image to any write-supported pixel layer format or to a generic TGIS_LayerPixel.

Also, now all the write-supported descendants of the TGIS_LayerPixel class are implemented with the ImportLayer/ExportLayer methods, which allow conversion of images between layer formats, exporting a portion of an image to another layer, and reprojection of an image to another coordinate system.

Printing

The TGIS_ViewerWnd.Print method has been deprecated. Now all the printing is handled with the TGIS_PrintManager class.

Generating a simple printout:

// GIS is TGIS_ViewerWnd
pm := TGIS_PrintManager.Create ;
try
  pm.Title := 'Title' ;
  pm.Print( GIS ) ;
finally
  FreeObject( pm ) ;
end ;

Previewing a custom printout utilizing a printing template:

tp := TGIS_TemplatePrint.Create ;
tp.TemplatePath := 'sample.tpl' ;
tp.GIS_Viewer[ 1 ] := GIS ;
tp.GIS_ViewerExtent[ 1 ] := GIS.VisibleExtent ;
 
pm := TGIS_PrintManager.Create ;
try
  pm.Template := tp ;
  GIS_ControlPrintPreviewSimple1.Preview( pm ) ;
finally
  FreeObject( pm ) ;
end ;

Handling the PrintPage event:

pm := TGIS_PrintManager.Create ;
try
  pm.PrintPageEvent := PrintPage ;
  pm.Print( GIS ) ;
finally
  FreeObject( pm ) ;
end ;
 
procedure PrintPage(     _sender       : TObject  ;
                         _printmanager : TGIS_PrintManager ;
                     var _lastpage     : Boolean ) ;
begin
  ...
end ;

PrintDC

PrintDC is not supported anymore. A PrintBmp method should be considered as a replacement. However, 1-to-1 copy of the screen is required then TGIS_ViewerWnd.GetCacheBitmap can be used as well.

Java specific

Please be aware of these changes if porting existing DK code to Java:

  1. Java has no records concept. All records from other platforms (like TGIS_Point), in Java are represented as objects and require constructors like ptg = new TGIS_Point() before accessing properties.
  2. Also, copying records does not work in Java - assigning ptg2 = ptg1 does not copy values but only makes a copy of the object reference. To copy value you have to use method MakeCopy() as presented below:
    ptg2 = ptg1.MakeCopy();
  3. In addition, when coding in Java, you must use getters and setters to get and set properties.
  4. Java method parameters cannot be passed by var. We will prepare more overrides to fight this problem. Meanwhile, a solution is to use VarParameter
    double dist = 0;
    int part = 0;
    TGIS_Point proj = null;
     
    VarParameter<Double> vpdist = new VarParameter<Double>(dist);
    VarParameter<Integer> vppart = new VarParameter<Integer>(part);
    VarParameter<TGIS_Point> vpproj = new VarParameter<TGIS_Point>(proj);
     
    TGIS_Shape shp = lv.LocateEx( TGIS_Utils.GisPoint( 12, 13 ), 0.0001, 0, vpdist, vppart, vpproj );
    if (shp != null) {
      dist = vpdist.Value ;
      part = vppart.Value ;
      proj = vpproj.Value ;
    }
  5. In Java, we do not have an equivalent of Application.ProcessMessages or Application.DoEvents, so we need to start another thread and then make use of SwingUtilities.invokeAndWait. You may ask why the new thread? Because this method cannot be used in the dispatcher thread. So, as an example, in VCL we use code like this:
      for i:=0 to 90 do
      begin
        shp.SetPosition( TGIS_Utils.GisPoint( i * 2, i ), nil, 0 ) ;
        Sleep( 10 ) ;
        Application.ProcessMessages ;
      end ; 

    and in Java it looks like this

    new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int i = 0 ; i < 90 ; i++){
                        final int x = i;
                        try {
                            SwingUtilities.invokeAndWait(new Runnable() {
                                @Override
                                public void run() {
                                    shp.SetPosition(TGIS_Utils.GisPoint(x * 2, x), null, 0);
                                    try {
                                        Thread.sleep(10);
                                    } catch (InterruptedException ex) {
                                        Logger.getLogger(InMemoryUI.class.getName()).log(Level.SEVERE, null, ex);
                                    }                        
                                }
                            });
                        } catch (InterruptedException ex) {
                            Logger.getLogger(InMemoryUI.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (InvocationTargetException ex) {
                            Logger.getLogger(InMemoryUI.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }).start();        

    As you can see, to achieve the same effect in Java as in Delphi, we need to write a bit more complicated code.

Delphi / C++Builder Specific

Be aware of these changes if porting an existing VCL application to DK11 VCL or FMX:

  1. All control platform specific units have namespace scope added like “VCL.GisViewerWnd.pas”. In a Delphi project property, there is a way to add default unit scopes - so we recommend altering the code. C++Builder developers also must alter the code of their applications. See: RAD Studio Help
  2. Existing GisDefs were split into:
    1. GisTypes
      Common constants and types like TGIS_Point. To be frequently used by client code, i.e., including it is almost a requirement.
    2. GisFunctions
      Common methods like GisLongitudeToStr(). This definition can be useful, but including it is not required.
    3. GisClasses
      Some common classes and containers. Generally, to be used only within DK11 code, but some methods can require it. For example, TGIS_Bytes are used in some methods as a platform-independent byte array.
    4. GisInternals
      Generally to be used only within DK11 code.
    5. GisUtils
      Common methods like GisPoint() wrapped into TGIS_Utils class methods. To be frequently used by client code, i.e., including it is almost a requirement.
    6. GisRtl
      Platform dependent code for some basic functions which can be missed in some environments. By platform, we understand Delphi, Java, .NET, etc.
      Generally used only in DK11 source code and is not required in a client code. FreeObject() is defined in this unit.
    7. GisTypesUI
      Common abstract types like TGIS_Color, TGIS_Bitmap, TGIS_Pen, and TGIS_Brush used for cross platform compatibility.
    8. In most cases just adding GisTypes and GisUtils will be enough.
  3. GisLayers
    Base class for all layers - TGIS_Layer. TGIS_Layer substitutes TGIS_LayerAbstract.
  4. GisAllLayers
    Contains all layers which can be used in the DK11, as listed here.
  5. GisAllEnterpriseLayers
    Contains all enterprise layers which can be used in the DK11, as listed here.
  6. GisAllBasicLayers
    Contains all basic layers which can be used in the DK11, as listed here

FMX specific

  1. Be aware of FMX specific rendering logic (bug/feature?):
    1. If controls touch each other, then painting one control will issue painting of the other control(s) because FMX rendering logic adds at least one pixel around the control size to determine the drawing area.
    2. Suppose you have an example like this:
      1. TToolbar with Align=TAlignLayout.alClient
      2. TButton inside TToolbar with Align=TAlignLayout.alLeft
      3. TGIS_ViewerWnd with Align=TAlignLayout.alClient
    3. In such a situation, moving the mouse over TButton will cause the map to repaint because the controls are sticking !!!
    4. A workaround is to set for TGIS_ViewerWnd.Margin=(1,1,1,1)

FMX Mobile specific

  1. Remember that the object live cycle in Delphi for iOS and Android is ARC (Automatic Referencing Counting) and the existing VCL life cycle should be retested upon porting.
  2. SQLite installed by default on iOS and Android is a limited version without spatial indexes. We prepared a spatial compilation that should be included in your project. If you plan to use it:
    1. On Android:
      Add to deployment and set Remote Path to “library\lib\armeabi-v7a\”.
    2. On IOS:
      Just place in a folder with your .dpr file the file named libttksqlite3.a (from the deployment folder); The library will be linked statically into your application. This is a universal (32/64 bit) library.
  3. FMX Canvas on Mobile uses GPU, which is somehow different from the default Windows FMX canvas. We suggest debugging upon Windows having your main form:
    {$IFDEF MSWINDOWS}
    initialisation
      FMX.Types.GlobalUseDirect2D := True ;
    {$ENDIF}

    If labels are looking too bold, try:

    {$IFDEF MSWINDOWS}
    initialization
      FMX.Types.GlobalUseGDIPlusClearType := False ;
    {$ENDIF}

ActiveX specific

All objects got new naming: “TGIS* instead of “XGIS_”. For example:

Old name New name
XGIS_LayerVector TGIS_LayerVector
IXGIS_LayerVector ITTGIS_LayerVector

The main reason for this change is to make the DK for ActiveX as similar as possible to the other DK editions. The old “XGIS_” naming was forced by technical limitations that no longer exist.

Editor specific

Scripts developed for the Editor 4 must be upgraded for the Editor 5. The process is not complicated, though, some coding is required.

  • For easy upgrading of an existing script, a PowerShell script UpgradeScripts.ps1 is provided. It is a very simple “find-replace” utility that should solve most problems. Be aware of:
    1. make a backup copy of your scripts before executing the upgrade,
    2. perform an upgrade only once.
  • Avoid using with. It does not work properly if an exposed object is interface based.
  • Scripts do not support method overloading. Instead an overload is marked as Locate, Locate_2, Locate_3, etc. In the Editor 4 a default name corresponds to a complete method (with all possible parameters). In the Editor 5, a default name corresponds to the most commonly used method.
  • There is no longer App.SelectedShapes list. Scripts should use TGIS_LayerVector.SelectedList instead.
  • GIS.Items property is read-only.
  • Some lists (like TGIS_Layervector.Fields) are now of a different type. So, if direct casting was used - the code needs to be altered.

Cursor numbers

Standard Cursors

Name Value
Default 0
None -1
Arrow -2
Cross -3
IBeam -4
Size -22
SizeNESW -6
SizeNS -7
SizeNWSE -8
SizeWE -9
UpArrow -10
HourGlass -11
Drag -12
NoDrop -13
HSplit -14
VSplit -15
MultiDrag -16
SQLWait -17
No -18
AppStart -19
Help -20
HandPoint -21
SizeAll -22

DK specific cursors

Name Value Comment
DRAG_CURSOR 15 Cursor for dragging
SELECT_CURSOR 16 Cursor for selecting
ZOOM_CURSOR 18 Cursor for zooming
EDIT_CURSOR 19 Cursor for editing
CUSTOM_CURSOR 20 Cursor for custom operations
WAIT_CURSOR 21 Cursor for lengthy operations
CAMPOS_CURSOR 30 Cursor for TGIS_Viewer3DMode.CameraPosition
CAMROT_CURSOR 31 Cursor for TGIS_Viewer3DMode.CameraRotation
CAMXYZ_CURSOR 32 Cursor for TGIS_Viewer3DMode.CameraXYZ
CAMXY_CURSOR 33 Cursor for TGIS_Viewer3DMode.CameraXY
CAMZOOM_CURSOR 34 Cursor for TGIS_Viewer3DMode.Zoom
SUNPOS_CURSOR 35 Cursor for TGIS_Viewer3DMode.SunPosition
SELECT3D_CURSOR 36 Cursor for TGIS_Viewer3DMode.Select

Unit / Class rename

Class rename:

Old name New name
TGIS_LayerAbstract TGIS_Layer
TGIS_CompoundLayer* TGIS_LayerCompound*
TGIS_SubLayer* TGIS_LayerSublayer*
TGIS_LayerSDERaster* TGIS_LayerSqlSdeRaster*
TGIS_LayerSqlMsSpatialAdo TGIS_LayerSqlMsSpatialAdoNet
TGIS_LayerPixelStoreAbstract2 TGIS_LayerPixelStoreAbstract
TGIS_LayerPixelStoreAdo2 TGIS_LayerPixelStoreAdo
TGIS_LayerPixelStoreAdoNet2 TGIS_LayerPixelStoreAdoNet
TGIS_LayerPixelStoreDbx2 TGIS_LayerPixelStoreDbx
TGIS_LayerPixelStoreLibpq2 TGIS_LayerPixelStoreLibpq
TGIS_LayerPixelStoreSqlite2 TGIS_LayerPixelStoreSqlite

Units renamed (important only for Delphi/C++Builder developers):

Old name New name
GisLayerSDERaster* GisLayerSqlSdeRaster*
GisSubLayer GisLayerSublayer
GisCompoundLayer GisLayerCompound
GisLayerSqlMsSpatialAdo GisLayerSqlMsSpatialAdoNet
GisLayerPixelStore2 GisLayerPixelStore
GisLayerPixelStoreAdo2 GisLayerPixelStoreAdo
GisLayerPixelStoreAdoNet2 GisLayerPixelStoreAdoNet
GisLayerPixelStoreDbx2 GisLayerPixelStoreDbx
GisLayerPixelStoreLibpq2 GisLayerPixelStoreLibpq
GisLayerPixelStoreSqlite2 GisLayerPixelStoreSqlite

Other naming issue

All DPI was renamed to PPI. There is still some mixing in various system libraries (for example DirectX uses DPI naming). But a clear name for naming resolution is Pixels-Per-Inch, so we decided to use this in all the API. For a perfect explanation, see: PPI vs DPI - Explained Properly or DPI and PPI Explained

Discontinued

  • TGIS_ViewerWMF, as well as any WMF output, is discontinued because it was causing more trouble than it should. It was platform dependent, dependent on main screen resolution, and support for anti-aliasing was limited and also platform dependent. Please use TGIS_ViewerBMP, which supports ARGB so drawing on a transparent background is no longer an issue.
  • TGIS_Device and all related TGIS_Viewer methodss, like LockTransparent, LockaCacheLabel, PrepareChache, and PostCache have been removed because are no longer useful, anyway we support ARGB colors and, to some extent, renderers that take the responsibility of TGIS_Device.
  • TGIS_Viewer.CachedPaint is no longer available. Now, the map is always cached. TGIS_Layer.CachedPaint is still meaningful.
  • GDIType is no longer available. Instead, there are renderers that can be switched via the Renderer property.
  • All TGIS_Params field-based parameters (like TGIS_ParamsLine.WidthEx) are discontinued. Full text parameters should be used instead, like TGIS_paramsLine.WidthAsText=“FIELD:MYWIDTHS:1.5 m”, where value means that “1” from an attribute field should be interpreted as 1.5 meters.
  • TGIS_Layer.Addition had used only for creating anaglyph images. It is no longer useful, so discontinued.
  • TGIS_Layer.LabelsOnTop & TGIS_Layer.IncrementalPaint are discontinued.
  • OnAfterVisibleExtentChanged event is discontinued and replaced by VisibleExtentChangeEvent.
2021/09/24 08:38

Page Tools