MapInfo Pro

 View Only
  • 1.  Using Python can we assign symbology to a dataset?

    Posted 06-15-2020 00:37
    Edited by George Corea 06-15-2020 06:41
    In MI 2019.2 I am looking at using some of the example scripts to create menu items and add multiple groups of tables with preset symbology, themes, legends and hotlinks.

    1. 'Ribbon.py', 'choose table.py' and 'open tool windows.py' makes it simple to add a ribbon button and have the open table dialog but I don't see the python code to directly add a .tab file.
    2. How do I assign custom symbology, themes, legends and hotlinks to it in python?
     - I noticed 'MapInfoTableInfo.py' and 'LayerProperties.py' allows users to see the assigned symbology (layer style) in a tab but is there a way to assign this in python?

    I know it will bring in the default themes/hotlinks from the metadata of the .tab file but Ideally rather than having to code each color etc would it be possible to get the theme to use from another file where the theme and hotlinks can be saved. This is when we need to have different symbology than the default. In QGIS it's a QLR/QML file that can be loaded to overwrite the default symbology in python quite simply

    In Mapbasic it would be

    Open Table "G:\GIS_Tables\S_Mains_ExclAbandoned" As S_Mains_ExclAbandoned Interactive
    Add Map Auto Layer S_Mains_ExclAbandoned

    shade S_Mains_ExclAbandoned with Type values

    "Gravity Main" Line (25,2,16711680) ,
    "Recycled Water" Line (3,3,10502399) ,
    "Rising Main" Line (4,3,16711680)

    Set Map
    Layer prev
    Display Value
    Global Pen (1,2,0) Brush (2,16777215,16777215) Symbol (35,0,12) Line (1,2,0) Font ("Arial",0,9,0)
    Selectable Off
    Zoom (0, 12) Units "km"
    Layer S_Mains_ExclAbandoned
    Display Graphic
    Global Pen (1,2,0) Brush (1,16777215,16777215) Symbol (35,16776960,12,"MapInfo Symbols",16,0) Line (1,2,0) Font ("Arial",0,9,0)

    Activate
    Using "https://edrms/docs/~D"+As_con_InfoXpert_ID Alias "InfoXpert primary link: " On Labels Objects Relative Path Off,
    Using "https://edrms/docs/~D"+CWCF_hyperlink Alias "Additional Details docs: " On Labels Objects Relative Path Off,
    Using "http://council/tickets/v2#open_tickets/"+Spiceworks_ID Alias "Spiceworks: "+Spiceworks_ID On Labels Objects Relative Path Off

    Label Line Arrow Position Above Auto Retry On Font ("Arial",261,7,16711680) Pen (1,2,0)
    With Diameter+"Ø "+Material+" "+Install_Year
    Parallel On Auto On Overlap Off Duplicates On Offset 2
    Visibility Zoom (0, 1) Units "km"

    set legend
    layer Prev
    display on
    shades off
    symbols off
    lines on
    count off
    title "Sewer Mains" Font ("Arial",1,8,0)
    subtitle auto Font ("Arial",1,8,0)
    'ascending on
    ranges Font ("Arial",0,8,0)
    auto display off,
    auto display on


    3. Is there a routine for error capturing?

    Thanks for your advice.

    ------------------------------
    George Corea
    Mangoesmapping
    ------------------------------


  • 2.  RE: Using Python can we assign symbology to a dataset?

    Employee
    Posted 06-16-2020 03:26
    Hi George

    The Python implementation in MapInfo Pro builds on top of our .NET APIs. Unfortunately, these APIs do not cover the full breadth of MapBasic yet. This means that you'll have to use a combination of Python and MapBasic to do what you want to.

    Here's a very simple example that uses Python to loop over a number of predefined columns, create a thematic for each of these and save the resulting map to an image:

    import os

    print("Starting now")

    sTab = 'time_series_covid19_deaths_US'

    themeColumns = [
    _3_9_20',
    '_3_8_20',
    '_3_7_20',
    '_3_6_20',
    '_3_5_20',
    '_3_4_20',
    '_3_3_20',
    '_3_2_20',
    '_3_1_20'
    ]

    for col in themeColumns:
       do('shade window FrontWindow() 1 with {} ignore 0 graduated 0.0:0 10000:24 Symbol (35,12583104,36,"MapInfo Symbols",0,0) Symbol (35,255,36,"MapInfo Symbols",0,0) vary size by "LOG"'.format(col))
       fileName = r'D:\3. Demo\2. Maps\2020\Covid19\04-14 Data April 14\Time Series\US {}.PNG'.format(col)
       print(fileName)
       do('Save Window FrontWindow() As "{}" Type "PNG" Resolution 300'.format(fileName))

       do('Remove Map Window FrontWindow() Layer 1')

    print('Finished')

    We have adjusted the standard print() method in Python to print to the Message window.
    The do method lets you pass a MapBasic command to MapInfo Pro and have it executed. Similarly, you can use the Eval() method to pass a Mapbasic function and get the response from this function.

    In my example, I'm using Python to handle the looping but passing the MapBasic statements to MapInfo Pro using the do method.

    So the answer to your two first questions is to use the do method. You can also use the OpenTable method on the Catalog object to open a table into the current MapInfo Pro session.

    Python has it's own error handling that you of course can use when writing Python add-ins for MapInfo Pro. Here's a very basic example:
    try:
      print(x)
    except:
      print("An exception occurred")

    ------------------------------
    Peter Horsbøll Møller
    Distinguished Engineer
    Pitney Bowes Software & Data
    ------------------------------



  • 3.  RE: Using Python can we assign symbology to a dataset?

    Posted 06-17-2020 06:35
    Edited by George Corea 06-18-2020 02:54
    Thanks for the details Peter.

    When you say 'You can also use the OpenTable method on the Catalog object to open a table into the current MapInfo Pro session' - how do you do this? i.e add a tab file to the current workspace in python? does it mean just do (Open Table "c:\somefile.tab" as somefile)?

    In the new Mapbasic/Python is there a way to load a thm file -there is this old thread about it but no answer.? this would make it easier than having to code each change of a default theme.

    Looking at the examples I am trying to work out how to do the following but am not having much luck.

    r_item_call="Infrastructure_Data" #Name of Button Call, r_ is for Ribbon actions
    r_item_name="Infrastructure Data" #Friendly name of button on main ribbon
    r_button_name="Water #same as operations in the ribbon_customization.py
    r_subroup_name="Not Abandoned" #same as "Table" and "CallBack" in the ribbon_customization.py
    r_subgroup_action="Open\nClose" #same as 'MB Handler\nNo Parameter'in the ribbon_customization.py


    1. Add a ribbon item - this is easy
    tabgroup=pro.Ribbon.Tabs.Add(r_item_call,r_item_name)

    2.Name of item in Button on ribbon (i.e r_button_name above)
    #based on ribbon_customization.py key commands
    #tabGroup1 = self._newTab.Groups.Add("demoGalleryGroup","Demo Gallery")
    #gallery = tabGroup1.Controls.Add("Gallery","Operations", ControlType.GalleryControl)

    so for gallery do we need to have 'demo' and 'Group' before and after it? but then refer to it as gallery (case insensitive)?

    3. Add subgroups to button (ie r_r_subroup_nameabove)
    #galleryGroup1 = gallery.Groups.Add("Table")
    Once 2 is sorted this should work

    4. Add Items to subgroup and make them load a table on click (same as r_subgroup_actionabove)
    customHandlerWP = galleryGroup1.Controls.Add("customHandlerWP","MB Handler\nNo Parameter", ControlType.GalleryItem)
    Not sure how to load a table and same issue as 2.

    The quick graphic below relates to the numbers above...


    Thanks for your advice...

    ------------------------------
    George Corea
    Mangoesmapping


  • 4.  RE: Using Python can we assign symbology to a dataset?

    Employee
    Posted 06-24-2020 07:16
      |   view attached
    Hi George,

    From your post I think you want to create a Addin for MapInfo Pro in Python. For this you can take a look at the attached ribbon customization sample.

    Basically Ribbon has a Tab and inside the Tab we have multiple Ribbon Groups.
    Example:
    newTab = pro.Ribbon.Tabs.Add("myTab", "New Tab") # this will add a new Tab into ribbon with caption "New Tab"  and internal control name as "myTab"

    # We will add ribbon group to this new tab.
    grp = newTab.Groups.Add("grpName","New Group") # this will add a new Ribbon Group into tab with caption "New Group" and internal control name "grpName".

    Similarly this pattern follows for buttons, gallery in a Ribbon Group.
    You can take a look into Extensibility reference for more information on ribbon API. 


    ------------------------------
    Anshul Goel
    Knowledge Community Shared Account
    Shelton CT
    ------------------------------

    Attachment(s)

    zip
    ribbon_customization.zip   46 KB 1 version


  • 5.  RE: Using Python can we assign symbology to a dataset?

    Posted 06-24-2020 23:18
    Thanks Anshul,

    I had looked at this example and it was in the example code I posted. I don't want to create a full add in and would prefer to work only in python. Here's an updated code that shows where I am having issues.

    ### Description: Creates a new Ribbon, Group, Button and list types in Python and trigger open/close of tab file
    #run application "D:\Projects\MGM\MI_Custom_Python_Interface\scripts\AddMenuItem.py" #Run in mapbasic window to execute the py code below

    import sys
    import os
    from os.path import join, dirname

    sys.path.append(join(r'C:\Users\George\AppData\Local\MapInfo\MapInfo\Professional\1900\Tools\PythonQuickStart\PythonAddins'))
    print (sys.path)

    import clr
    from System import Int32, Array
    from mi_common_util import CommonUtil
    from mi_addin_util import AddinUtil
    #from ribbon_customization_ole_handler import OleHandler
    from MapInfo.Types import IMapInfoPro, ControlType, PaperUnits, DimensionedValue, NotificationObject, NotificationType
    from System import Uri, UriKind

    pro.Ribbon.Tabs.Clear() #clear existing python buttons

    # Some standard variables to allow functions to be created for each action for easier use.

    #r_ is for Ribbon actions
    r_item_name="Infrastructure_Data" #Name of button on main ribbon (no spaces allowed)
    r_button_name="Water" #same as operations in the ribbon_customization.py
    r_subroup_name="Not Abandoned" #same as "Table" and "CallBack" in the ribbon_customization.py
    r_subgroup_action="Open\nClose" #same as 'MB Handler\nNo Parameter'in the ribbon_customization.py

    tab = pro.Ribbon.Tabs.Add(r_item_name)
    group = tab.Groups.Add(r_button_name, r_button_name)
    button = group.Controls.Add("ButtonOpenTable", r_subroup_name, ControlType.Button)
    button.IsLarge = True
    button.CommandId = 102 #this is for the open table tool but I want to open a table so 'do (open table "d:\sometable.tab" as sometable)'
    button.LargeIcon = Uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Mapping/infoTool_32x32.png", UriKind.RelativeOrAbsolute)
    #group = tab.Groups.Add('pytab', 'Custom')

    r_subroup_name="Abandoned"
    button = group.Controls.Add("ButtonOpenTable", r_subroup_name, ControlType.Button)
    button.IsLarge = True
    button.CommandId = 102 #this is for the open table tool but I want to open a table so 'do (open table "d:\sometable.tab" as sometable)'
    button.LargeIcon = Uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Mapping/infoTool_32x32.png", UriKind.RelativeOrAbsolute)

    #Create a seperator
    seperatorB = group.Controls.Add("Separator","Seperator",ControlType.RibbonSeparator)

    #Create a list of text items in another group
    r_button_name="Sewer" #same as operations in the ribbon_customization.py
    group2 = tab.Groups.Add(r_button_name, r_button_name)
    splitB = group2.Controls.Add("DropDown", "List1", ControlType.SplitButton) #how do we add additional list items?
    #do ('open table "c:\somefile.tab" as somfile') # open a table when clicked

    #Create a seperator
    seperatorB = group.Controls.Add("Separator","Seperator",ControlType.RibbonSeparator)

    #Create filters
    r_item_call="Planning" #Name of Button Call, r_ is for Ribbon actions
    r_item_name="Planning" #Friendly name of button on main ribbon
    r_button_name="Flood" #same as operations in the ribbon_customization.py
    tab2 = pro.Ribbon.Tabs.Add(r_item_call)
    group2 = t