User Tools

Site Tools


guides:migration

Migrating to DK11

Documentation | Migration

DK11 is highly compatible with existing code, though it is internally heavily redesigned. However, we decided to modernize a few things which will require some code changes.

Be sure to also read: Known issues.

Control Properties

Some obsolete control properties have been abandoned. As a result opening form can cause a warning message like “Error reading GIS.XYZ: Property XYZ does not exist”. To resolve this just touch your form (change something on your form even for a while, for example, change a bit size of the form) to force modification flag and then save - an obsolete property will be removed.

Enums

Previously enums were like this: gisFieldTypeString, now we unified it to a naming scheme and it 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 that TGIS_ViewerWnd is no longer inherited from TGIS_Viewer anymore but is just implemented as IGIS_Viewer interface. Thanks to this, TGIS_Viewer is just a pure object which is used internally by TGIS_ViewerWnd, which can be inherited from a proper control directly.

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, 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:

  • 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 a code instead of handling MouseDown / MouseUp events

Accessing Canvas object

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

  GIS.Canvas.Pen.Width := 1 ;

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

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

Please, take a look at CustomPaint sample.

Event const modifier

Event handler 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 now have names like PaintShapeEvent instead of OnPaintShape.

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

Paint events

For information on how to replace DK11 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 will be self aware 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
    will issue a redrawing only of the topmost (tracking) layers
  • TGIS_Viewer.InvalidateSelection
    Will redraw only selection state of selected shaped

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

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

Map updates

Map updates upon zooming or dragging are animated and delayed to allow 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 are allowed
* TGIS_ViewerWnd.ProgressiveUpdate - If > 0, map will be updated on a time consuming updates
* TGIS_Viewer.DelayedUpdate - If > 0, map will be updated after a while allowing next operations before full redraw

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

Shape selection

Selecting a shape using the IsSelected property doesn't require calling MakeEditable on the shape anymore. Also 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 it's finished to invalidate the selection.

Exporting to image

The TGIS_ViewerWnd.ExportToImage and ExportToGrid methods have been deprecated. A new class TGIS_PixelExportManager (defined in GisPixelExportManager.pas) is introduced 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 implement the ImportLayer/ExportLayer methods which allow conversion of images between layer formats, exporting a portion of an image to other layer and reprojection of image to another coordinate system.

Printing

The TGIS_ViewerWnd.Print method has been deprecated. Now all the printing is to be 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 ;

Java specific

Please be aware on those changes if porting an existing DK code to Java:

  1. Java has no records concept. Therefore all records on platforms other than Java (like TGIS_Point) 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 it you have to use method MakeCopy() as presented below:
    ptg2 = ptg1.MakeCopy();
  3. In addition, while coding in Java you have to use getters and setters to set and get properties.
  4. Java methods parameters cannot be passed by var. We will prepare more overrides to fight with 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 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();        

    So as you can see to achive 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 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 a default unit scopes - but we recommend to alter code. C++Builder developers must alter code of their applications. See: RAD Studio Help
  2. Existing GisDefs were split into:
    1. GisTypes
      Common constant and types like TGIS_Point. To be frequently used by a client code and including it is almost a requirement.
    2. GisFunctions
      Common methods like GisLongitudeToStr(). This definition can be useful, but is not required to include it.
    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 a client code and including it is almost a requirement.
    6. GisRtl
      Platform dependent code for some basic function which can be missed on 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, TGIS_Brush used for cross platform compatibility.
    8. In most cases just adding GisTypes and GisUtils will be enough.
  3. GisLayers
    Base of class for all layers - TGIS_Layer. TGIS_Layer substitutes TGIS_LayerAbstract.
  4. GisAllLayers
    Contains all layers which can be used in our DK11, they are listed here.
  5. GisAllEnterpriseLayers
    Contains all enterprise layers which can be used in our DK11, they are listed here.
  6. GisAllBasicLayers
    Contains all basic layers which can be used in our DK11, they are listed here

FMX specific

  1. Be aware about FMX specific rendering logic (bug/feature?):
    1. If controls touch each other, then painting one control will issue painting of another control 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 situation, moving a mouse over TButton will cause map repaints because 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 are ARC (Automatic Referencing Counting) and the existing VCL life cycle should be retested upon porting.
  2. SQLIte installed by default on iOS and Android are a limited version w/o spatial indexes. We prepared a spatial compilation which 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 a file named libttksqlite3.a (from the deployment folder); 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 for default Windows FMX canvas. We suggest debugging upon Windows having your main form:
    {$IFDEF MSWINDOWS}
    initialization
      FMX.Types.GlobalUseDirect2D := True ;
    {$ENDIF}

    If labels are looking bold please try to:

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

ActiveX specific

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

Old name New name
XGIS_LayerVector TGIS_LayerVector
IXGIS_LayerVector ITTGIS_LayerVector

The main reasons for this change are making DK for ActiveX as similar to other editions as possible. Old “XGIS_” naming was forced by the technical limitation which does not last.

Editor specific

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

  • For easy upgrading existing script a PowerShell script UpgradeScripts.ps1 is provided. It is a very simple “find replace” utility which should solve the majority of problems. Be aware of:
    1. make a backup of your scripts before running executing the upgrade,
    2. perform an upgrade only once.
  • Avoid using with. It does not work properly if exposed object is interface based.
  • Scripts do not support method overloading. Instead an overload are marked as Locate, Locate_2, Locate_3, etc. In Editor 4 a default name corresponds to a method complete method (with all possible parameters). In Editor 5 it corresponds to a 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 different type. So if direct casting were used - 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 operation
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

Unit rename (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). However, a clear name for naming resolution is no Pixels-Per-Inch and we decided to use it on all our 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. It causes more trouble than it should. It is platform dependent, dependent on main screen resolution, support for anti-aliasing is limited and is also platform dependent. Please use TGIS_ViewerBMP, which supports ARGB so drawing on transparent background is no longer an issue.
  • TGIS_Device & all related TGIS_Viewer methods 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. Map is always cached. TGIS_Layer.CachedPaint is still meaningful.
  • GDIType is no longer available. Instead there are renderers that can be switched via Renderer property.
  • All TGIS_Params field based parameters (like TGIS_ParamsLine.WidthEx) are discontinued. A 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 meter.
  • TGIS_Layer.Addition has the use only for creation of anaglyph images. It is not usefull anymore.
  • TGIS_Layer.LabelsOnTop & TGIS_Layer.IncrementalPaint are discontinued.
  • OnAfterVisibleExtentChanged event is discontinued and replaced by VisibleExtentChangeEvent.
2019/04/19 09:37