jps services
  • Home Page
  • GIS Training Courses
    • QGIS Training Courses
    • ArcGIS Training Courses
    • MapInfo Pro Training Courses >
      • MapBasic Training Course
  • About
  • Blog

Using MapBasic code to create a Layout Designer window

12/7/2017

0 Comments

 

Legacy Layout v Layout Designer code

MapInfo Pro provides some information in MapBasic Help concerning legacy code for creating layout windows. However, some features within the legacy layout, available in earlier versions of MapInfo, are no longer supported. For instance, earlier versions of MapInfo had a graph function. Graphs are no longer supported so any code to include graphs in a layout is now redundant and needs to be removed. If the code is left in, at best you will end up with a blank space in the layout, or MapInfo may try to fill the space with a map window frame.

Another issue concerning coding is thematic and cartographic legend layer support for legacy code. If you look up cartographic legend in MapBasic Help you will find code which was developed for the legacy layout format. Below is a section from the Create Cartographic Legend section.

Picture
The first section of this code which should create a Cartographic Legend window creates errors when run in MapInfo Pro.   The second section of code should create a frame for a Thematic Legend window.   However the recommendation to create a frame for a Thematic Legend window, by changing the title to the following does not work as it contains errors:-

S_title="Theme Legend of " + WindowInfo (I_map_id, WW_INFO_NAME)

 By using a note statement you can ascertain the legend name using the first section of the code snippet as shown in the screen below.
Picture
After this point an error screen appeared and the legend is not created.

Picture
The code snippet for creating a thematic legend doesn’t work as anticipated either.

If we take another look at this line of code:-

S_title="Theme Legend of " + WindowInfo (I_map_id, WW_INFO_NAME)
The first thing to note is S_title which should actually be s_title. The word processor which created this section of the help file has automatically changed this variable from s_title to S_title as it was at the beginning of sentence. The same problem occurs with I_map_id. This should be i_map_id if it is to be consistent with the earlier code sample.

The next  thing to note is that WW_INFO_NAME must be a typing error. This should read WIN_INFO_NAME.

Even so when these corrections are made the code still doesn’t get beyond a note statement. As shown in the next image.
Picture
This time after the note statement has been dismissed, no error occurs and the layout completes but without creating a legend element.
Picture
So it would appear that even using the legacy Layout statement with various legacy code provided in MapBasic help, the latest versions of MapInfo Pro do not appear to be able to create cartographic or thematic legends in the layout window with this legacy code.

The Help section spells out the demise of the classic layout window and any related code as the following graphic from Help shows. The relevant statement has been highlighted.
Picture
So looking at what is and is not appearing in the layout we should note the following;-
  • Maps can be brought into a layout, the classic layout Title clause now appears to be optional.
  • Browsers, text and eclipse statements all work without an issue with legacy code.
This leaves the question of cartographic and thematic legend windows where the legacy code no longer appears to be working.

Layout Designer window

At this stage it is useful to note the main difference between the legacy and designer layouts. The new Layout Designer has some powerful features. For instance a major benefit is that you can adjust elements within a layout map frame without having to return to the map window. For all the benefits of the new layout designer please check out the Help section in MapInfo Pro. The MapBasic Help provides information on how to use the new Layout Designer window.

Here is a screen shot from MapBasic Help which also includes some useful code:-
Picture
Picture
This section is useful because it also includes some code which shows how to create a cartographic legend window.

However, this code produces a legend window in the map section rather than in a layout window. We need to modify this code so that it can be used directly in the layout window.

Creating MapBasic code for a Layout Designer window

Here is some sample code to create a map and browser window which are then incorporated into a layout designer window. The layout also includes cartographic legends for each of the map layers.

Include "C:\Program Files (x86)\MapInfo\MapBasic\mapbasic.def"
Declare Sub Main
Sub Main
Dim nMapWinid As Integer
Dim nLayoutWinid As Integer
Dim nBrowseWinid As Integer
Dim sString As String

' Open three tables
Open Table "C:\MapInfo Trial Data\USA\States.tab" As states
Open Table "C:\MapInfo Trial Data\USA\City_125.tab" As cities
Open Table "C:\MapInfo Trial Data\USA\Us_hiway.tab" As hiway

' Create map layers for these tables
Map From cities, hiway, states
Set Map Zoom 6370

' Save the current map window's ID
nMapWinid = Frontwindow()

' Create a browser window for columns State_Name and Pop_1990
Browse State_Name, Pop_1990 from STATES

' Save the current browser window's ID
nBrowseWinid = FrontWindow()

' Create a new layout designer window
Layout Designer Width 4 Height 6

' Save the layout window's ID
nLayoutWinid = FrontWindow()

Set CoordSys Layout Units "in"

' Add the map window to the layout window.
Create Frame Into Window nLayoutWinid
     (0.235,1) (6,6)
     From Window nMapWinid

' The following code is modified from the help section
' This code creates the cartographic legend for the three map layers

Create Designer Legend
     Position (0,0) Units "in"
     Width 0 Units "in" Height 0 Units "in"
     Custom

Default Frame Title "# Legend" Font ("Calibri",1,12,16711680)
Default Frame Subtitle "#" Font ("Arial",2,10,255)
Default Frame Style "%" Font ("Lucida Calligraphy",0,8,16732240)
Default Frame Line Width 36 Units "pt"
Default Frame Region Width 32 Units "pt"
Default Frame Region Height 14 Units "pt"
Default Frame Auto Font Size ON

' Note that we here we can use the map layer names

Frame From Layer states
     Using column object
     label default
     Position (4.7,1.14) Units "in"
    Title "United States"
    Subtitle "State Boundaries"

Frame From Layer cities
     Using column object
     label default
     Position (4.7,1.85) Units "in"
     Title "125 US Cities"
     Subtitle "US Cities"

Frame From Layer hiway
     Using column object
     label default
     Position (4.7,2.5) Units "in"
     Title "US Highways"
     Subtitle "Main Highways"

' Add the browser window to the layout window

Create Frame Into Window nLayoutWinid
    (5.985, 0.985) (7.9, 10.9)
     From Window nBrowseWinid

' Add a title to the layout

Create Text Into Window nLayoutWinid
     "1990 Population Study"
     ' (2.5 Across.5 Down) (8 Across .9 Down)
     (2.5,.5) (8,.9)
     Font MakeFont ("Arial", 1, 24, BLACK, WHITE)

' Add company name and today's date to the layout.

Create Ellipse Into Window nLayoutWinid
     (2.1, 6.75) (4.6, 7.55)
     Pen (3,2, BLUE)

Create Text Into Window nLayoutWinid
     "JPS Services"
     (2.1, 7.03) (4.6, 7.3)
     Font MakeFont("Arial", 0, 16, BLUE, WHITE)
     Justify Center

sString = Str$(CurDate())

Create Text Into Window nLayoutWinid
     sString
     (3,8.6) (4, 8.9)
     Font MakeFont("Arial", 0, 8, BLACK, WHITE)
     Justify Left

End Sub
If you run this code you will produce the following layout page.

Picture
Here is a close up of the cartographic legend:-
Picture
Creating a cartographic legend is not too difficult as we can easily ascertain the layer names. The problem arises when you also need to include a thematic map with a thematic legend in your layout.

The following code should be sufficient to create a thematic legend:-
Frame From Layer (thematic layer name)
      Position (3.7,1.16) Units "in"
      Title "US by 1990 Population"
      Priority 10
However, unlike the map frames, as the thematic layer name is created automatically we need to find some way of ascertaining it.

When run from the map window the following code reveals the names and types of all of the open layers.
include "mapbasic.def"
Declare sub main
Sub Main
          dim i,j as integer
          j = frontwindow()
              for i = 1 to mapperinfo(j,MAPPER_INFO_LAYERS)
                    print "No: " + i +
                    ", Name: " + layerinfo (j,i,LAYER_INFO_NAME) +
                    ", Type: " + layerinfo (j,i,LAYER_INFO_TYPE)
               next
end sub

The output in the message window is shown in the next graphic:
Picture
The thematic layer is called Ranges by Pop_1990 (as shown in the Explorer section). In the message section the thematic layer is shown as states(1). Type 3 confirms that this is the thematic layer. So is this layer called Ranges by Pop_1990 or states(1)?  If you put either name into the code shown below you will get an error.
Frame From Layer (thematic layer name)
        Position (3.7,1.16) Units "in"
        Title "US by 1990 Population"
         Priority 10
However if we assign a variable to hold the thematic name as in the following code we can create a thematic legend:-
j = nMapWinid
for i = 1 to mapperinfo(j,MAPPER_INFO_LAYERS)
            if layerinfo(j,i,LAYER_INFO_TYPE) = 3 Then
            sThematicLayer = layerinfo(j,i,LAYER_INFO_NAME)
            End If
     next

This code snippet uses mapperinfo() and iterates through the layers looking to see if any are of type 3, thematic layer type. If there is a thematic layer then sThematicLayer is assigned the thematic layer name. Please note the above code only works when the appropriate variables have been declared within the program.

The following code creates a map, browser and thematic layer. Then a layout is created with a thematic legend included.
Include "C:\Program Files (x86)\MapInfo\MapBasic\mapbasic.def"
Declare Sub Main

Sub Main

Dim nMapWinid , i, j As Integer
Dim nLayoutWinid As Integer
Dim nBrowseWinid As Integer
Dim sString, sThematicLayer As String

' Open three tables

Open Table "C:\MapInfo Trial Data\USA\States.tab" As states
Open Table "C:\MapInfo Trial Data\USA\City_125.tab" As cities
Open Table "C:\MapInfo Trial Data\USA\Us_hiway.tab" As hiway

' Create map layers for these tables

Map From cities, hiway, states
Set Map Zoom 6370

' Create a thematic map of the States layer

Shade states With Pop_1990

        Ranges 400000: 1500000,
                    1500000: 3500000,
                    3500000: 5500000,
                    5500000: 29800000

nMapWinid = Frontwindow()

' This code obtains the thematic layer name

j = nMapWinid

for i = 1 to mapperinfo(j,MAPPER_INFO_LAYERS)
            if layerinfo(j,i,LAYER_INFO_TYPE) = 3 Then
            sThematicLayer = layerinfo(j,i,LAYER_INFO_NAME)
            End If
      next

' Create a browser window for columns State_Name and Pop_1990

Browse State_Name, Pop_1990 from STATES

nBrowseWinid = FrontWindow()

' Create a new layout window

Layout Designer Width 4 Height 6

nLayoutWinid = FrontWindow()

Set CoordSys Layout Units "in"

'  Add the map window to the layout window.

Create Frame Into Window nLayoutWinid
     (0.235,1) (6,6)
     From Window nMapWinid

' The following code is modified from MapBasic Help section

Create Designer Legend
     Position (0,0) Units "in"
     Width 0 Units "in" Height 0 Units "in"
     Custom

Default Frame Title "# Legend" Font ("Calibri",1,12,16711680)
Default Frame Subtitle "#" Font ("Arial",2,10,255)
Default Frame Style "%" Font ("Lucida Calligraphy",0,8,16732240)
Default Frame Line Width 36 Units "pt"
Default Frame Region Width 32 Units "pt"
Default Frame Region Height 14 Units "pt"
Default Frame Auto Font Size ON

' Note that here we need to use
' the thematic layer name from
' code provided earlier in the program

Frame From Layer sThematicLayer
     Position (3.7,1.16) Units "in"
     Title "US by 1990 Population"
     Priority 10

' Add the browser window to the layout window

Create Frame Into Window nLayoutWinid
     (5.985, 0.985) (7.9, 10.9)
     From Window nBrowseWinid

' Add a title to the layout

Create Text Into Window nLayoutWinid
     "1990 Population Study"
    ' (2.5 Across .5 Down) (8 Across .9 Down
     (2.5, .5) (8, .9)
     Font MakeFont ("Arial", 1, 24, BLACK, WHITE)

' Add company name and today's date to the layout.

Create Ellipse Into Window nLayoutWinid
     (2.1, 6.75) (4.6, 7.55)
     Pen (3,2, BLUE)

Create Text Into Window nLayoutWinid

     "JPS Services"
     (2.1, 7.03) (4.6, 7.3)
     Font MakeFont("Arial", 0, 16, BLUE, WHITE)
     Justify Center

sString = Str$(CurDate())

Create Text Into Window nLayoutWinid
     sString
     (3,8.6) (4, 8.9)
     Font MakeFont("Arial", 0, 8, BLACK, WHITE)
     Justify Left

End Sub
This code creates the following layout page.
Picture
The following graphic shows a close up of the thematic legend.

Picture
In conclusion using MapBasic to create layout pages or to modify existing legacy code requires some understanding of the recent  significant developments in the capability of MapInfo Pro.

When looking at the Help section in MapBasic be aware that some of the sections are referring to legacy code although this is not always explicitly stated.

Moving forward any layout code should be developed using the Layout Designer rather the classic Layout code to ensure that all elements of your layout are displayed correctly.
0 Comments

Your comment will be posted after it is approved.


Leave a Reply.

    Author

    Joe Short BSc has been involved with various mapping solutions for over twenty years.  If you are considering implementing a GIS  or have ArcGIS Pro, MapInfo Pro or QGIS training requirements, jps services would be happy to be of assistance to your organisation. 

    Archives

    April 2020
    March 2020
    October 2019
    September 2019
    August 2019
    July 2019
    March 2019
    November 2018
    October 2018
    August 2018
    July 2018
    November 2017
    October 2017
    September 2017
    July 2017
    February 2017
    January 2017
    December 2016
    November 2016
    October 2016
    May 2016
    February 2016
    September 2015
    August 2015
    April 2015
    February 2015
    November 2014
    October 2014
    July 2014
    June 2014
    May 2014
    March 2014
    February 2014
    December 2013
    November 2013
    October 2013
    September 2013
    August 2013
    June 2013
    May 2013
    April 2013
    February 2013
    December 2012
    October 2012
    September 2012
    August 2012
    July 2012

    Categories

    All
    Arc Gis
    Arcview
    Autodesk
    Cad
    Gis Training
    Local Government
    Mapbasic
    Mapinfo
    Quantum Gis
    Relational Databases
    Saga Gis

    RSS Feed