MapInfo Pro

 View Only
  • 1.  Designer legend with multiple themes in Layouts issue

    Posted 05-09-2019 06:29
    I'm currently working on a 64bit version of our existing 32bit mapbasic application. One aspect i'm having trouble with is with the print layouts. At the moment we provide a set of print templates that includes an empty frame where we were inserting a theme legend. This could include legends for multiple themes displayed on the map but we were able to neatly add this into a single designated frame positioned wherever the user had set the legend frame within the template.

    My understanding is that its not now possible to add a theme legend window into a frame in a layout for MI v17. is that definitely  the case?

    As far as I can tell it looks like I should now create a Designer Legend window. The problem I'm having with this is that if there are multiple themes I am unable to insert the legends for these into the single designated frame. It appears to be much more difficult to control the positioning of multiple legends than it was in the past.

    For example the code below I create a new designer legend from a map window that has 4 separate layers that include themes. 

    Create Designer Legend from window 3015 frame from layer 1 frame from layer 3 frame from layer 35 frame from layer 36 into ID 16

    The result of this is that only the legend for layer 36 appears within my designated frame with the others appearing to the right of the layout. 

    If I use the below code this triggers an error because it seems that you can only use the 'into ID' if the frame is empty:

    Create Designer Legend from window 3015 frame from layer 1 into ID 16 frame from layer 3 into ID 16 frame from layer 35 into ID 16 frame from layer 36 into ID 16

    I see that each legend within a Designer Legend window has its own frame but is there not a way of inserting the entire  Designer Legend window (incorporating all associated legend frames) into a single frame/window or globally controlling the position?

    When you have a Designer Legend window open with a map window these all appear neatly inside the Legend Designer window. On a layout the legend frames  appear to be more independent. The image below hopefully shows visually what I am trying to achieve:

    Multple legends into a window on a layout


    ------------------------------
    Andy Bendall
    System Developer
    Buchanan Computing Ltd
    London
    ------------------------------


  • 2.  RE: Designer legend with multiple themes in Layouts issue

    Posted 05-13-2019 21:08
    Hi Andy,

    I apologize for such a delay in responding to your post, but I've been out of the office on vacation.

    You are right that each legend has its own frame, so to insert legends into empty frames in a layout template you need to append the "Into ID x" clause for each Frame from Layer clause:
                ... Frame From Layer 1 into ID 16 Frame From Layer 3 Into ID 16, ... etc.

    If you know how many legends you want to add for a map, you could add the correct number of empty frames positioned where you want them, then use Create Designer Legend to insert each legend. Or you could just use the Create Designer Legend statement to programmatically place each legend you want to add without having to insert into empty frames.  This is done by adding the "Custom"  keyword before you add any Frame From Layer clauses. Then each Frame From Layer clause needs to include a Position clause.

    This is certainly different than the 32 bit layout.  In the 32 bit layout you could insert the entire contents of a window into one frame, but the frame would clip the contents if they were too long. However, if your legend window had exactly the legends you wanted, it was a simpler way to include them at one location in a template.  We have discussed alternatives but it would be great to hear back if you have any input as to how you'd want it to work.  

    Thanks,
    Michele

    ------------------------------
    Michele Buselli
    PITNEY BOWES SOFTWARE, INC
    ------------------------------



  • 3.  RE: Designer legend with multiple themes in Layouts issue

    Posted 05-14-2019 08:06
    Hi Michele

    Thanks for your reply.

    If I use the command below where ID 16 is an empty frame in a layout window the result isn't an error (as I mentioned previously) but only the legend from layer 4 appears in the frame. The legend for layer 2 does not appear anywhere in the layout.

                           Create Designer Legend from window 3017 frame from layer 2 into ID 16 frame from layer 4 into ID 16

    So it doesn't look its possible to insert multiple legends into a single frame which I think is what you have alluded to.

    The changes introduced in the 64bit version for legend frames do have their advantages especially if there is only a single theme in the layout but it would be nice to still have the flexibility to insert an entire designer legend comprising multiple legends into one frame.  This to me still seems a neater solution where multiple theme legends are involved.

     I can see now that we may need to provision a set of templates that have multiple empty frames to handle instances where there are multiple theme legends in order to ensure the legends are positioned as optimally as they can be without requiring the user to have to constantly move them around.

    Kind regards

    Andy

    ------------------------------
    Andy Bendall
    Senior System Developer
    Buchanan Computing Ltd
    London
    ------------------------------



  • 4.  RE: Designer legend with multiple themes in Layouts issue

    Posted 05-14-2019 18:38
    Hi Andy,
    I'm sorry - that was my copy/paste error. I should have written something like this:
      ... Frame From Layer 1 into ID 16 Frame From Layer 3 Into ID 17, ... etc.

    so you are correct - it is not possible to insert multiple legends into a single frame. Sorry for the confusion. I think the right idea is having a set of templates to handle different scenarios for legends. Please let me know if you need any more help with using the layout and legend MapBasic to create your solution.

    -Michele

    ------------------------------
    Michele Buselli
    PITNEY BOWES SOFTWARE, INC
    ------------------------------



  • 5.  RE: Designer legend with multiple themes in Layouts issue

    Posted 05-21-2019 07:11
    Hi Michele

    I have now written some code that will use an empty frame on a template to insert a legend and in the case of multiple legends it will add further frames positioned below or above the original frame depending on where the empty frame is positioned in the template i.e. top right, top left, bottom right or bottom left. This is working fairly well except I am having troubles as a result of the width of the frame being automatically adjusted once a theme layer is inserted. This can result in something like below where a legend frame overlaps outside the map window. Here I am stacking legends on top of the original empty frame which is the lower of the legends. As you can see the middle legend width overlaps outside the map frame:

    thumbnail image

    In order to account for this i've added further code that interrogates the frame width after the legend has been inserted into the frame in order to work out the new width from which I can adjust the position. However I am finding that when issuing a LayoutItemInfo on the frame width the width returned is not the new width but the width of the original empty frame.

    Example code below is within a loop through all the displayed layers that checks for thematic layers and insert legends if any are found. The first legend has already been added at this stage:

        sFrameName = "LEGEND"+t
        Run Command "Create Frame ("+ newlegframeminx + "," + newlegframeminy + ") (" + newlegframemaxx + "," + newlegframemaxy +")      Pen(1,2,0)  Brush(2,16777215,16777215) Name " + chr$(34) + sFrameName + chr$(34)
        legFrameID = GetLayoutFrameID(sFrameName)
        Add Designer Frame Window wndLegend frame from layer ilayer into ID legFrameID  
        newlegframew = LayoutItemInfo(layout_id, legFrameID ,LAYOUT_ITEM_INFO_WIDTH)
        if newlegframew  <> origframew then        ''adjust position                       
                           alter designer frame ….
        end if

    I've also tried the LegendFrameInfo command to return the FRAME_INFO_WIDTH property instead of LayoutItemInfo but this returns the same:
          newlegframew = LegendFrameInfo(wndLegend,i,FRAME_INFO_WIDTH)

    I have noticed however that if i add a note after the Add Designer Frame Window command then the new width is returned. i.e.

        sFrameName = "LEGEND"+t
        Run Command "Create Frame ("+ newlegframeminx + "," + newlegframeminy + ") (" + newlegframemaxx + "," + newlegframemaxy +")      Pen(1,2,0)  Brush(2,16777215,16777215) Name " + chr$(34) + sFrameName + chr$(34)
        legFrameID = GetLayoutFrameID(sFrameName)
        Add Designer Frame Window wndLegend frame from layer ilayer into ID legFrameID  
        note "frame added"
        newlegframew = LayoutItemInfo(layout_id, legFrameID, LAYOUT_ITEM_INFO_WIDTH)


    With the note added my code works as i want it and the end result is as below:

    thumbnail image


    I have also noticed that once another legend has been added (via the Add Designer Frame command) i can then return the new width of the previously added legend. This does allow me to reposition the legends except the last one that is added.

    I have also tried to issue the set designer legend window wndLegend refresh command in place of the note but this didn't work.

    Any assistance with this would be much appreciated! 

    Regards

    Andy






    ------------------------------
    Andy Bendall
    Senior System Developer
    Buchanan Computing Ltd
    London
    ------------------------------



  • 6.  RE: Designer legend with multiple themes in Layouts issue

    Posted 05-28-2019 13:15
    Hi Andy,
    The legends, and most of the content (exception is map) in the Layout is drawn using WPF. You've run into one thing we dislike about WPF; retained mode rendering. It has its advantages and disadvantages. The disadvantage is that immediately after controls are created they may not yet be measured and arranged, especially if they are complex. So querying them immediately after creation doesn't always give the final rendered size. This is why adding a note, or doing some other processing before getting rendered size fixes the problem for you.  Have you tried adding all legends first, then going back to the beginning (first legend added) before you start querying for size so you can re-position?


    ------------------------------
    Michele Buselli
    PITNEY BOWES SOFTWARE, INC
    ------------------------------



  • 7.  RE: Designer legend with multiple themes in Layouts issue

    Posted 05-29-2019 06:44
    Hi Michele

    Thanks again for your reply.

    To answer your question yes I have tried creating a separate loop that goes through each legend frame in order to reposition where necessary however the width returned for the last legend added is still the original empty frame width. 

    I thought about adding an extra 'dummy' legend in order for me to get the width of the last proper legend added and then delete this. But to do that I'd need to create a another theme as you cant add the same theme layer to multiple legend frames so not really viable I don't think.

    I even tied adding a  scalebar to the layout after the legends had been added but still couldn't get the new width of the last legend.

    Seems like i'll either have to pop a note up after the last legend has been added which will then allow me to reposition afterwards or live with it in the knowledge the user may need to manually adjust the layout before printing. 

    Regards

    Andy

    ------------------------------
    Andy Bendall
    Senior System Developer
    Buchanan Computing Ltd
    London
    ------------------------------



  • 8.  RE: Designer legend with multiple themes in Layouts issue

    Posted 05-29-2019 10:04
    You could try adding a Sleep statement instead of a pop-up note.

    ------------------------------
    Michele Buselli
    PITNEY BOWES SOFTWARE, INC
    ------------------------------