ThinkGeo.com    |     Documentation    |     Premium Support

Layer visibility on client in server-side processing?

Hi,


This may be a no-brainer, but I haven't been able to find the answer myself, so here goes.


I'm trying to generate a pdf of my map using the PDF extension. This I got up and running fast using the blog entry examples.


My map consists of several custom overlays, all included with LayerOverlay. Thus all layers are server-side rendered, and have layers.


My problem is, how to determine which layers are visible in the client and which are not. I don't want to render invisible layer to the pdf.


As it is now, all layers are rendered in the pdf, even the layers (base layers and not base layers) that the client has turned off.


Please help me out. Cheers.


 



Hi Lars, 
  
 Have you tried to use a HiddenField in your application? I think you could write the invisible layers information to the HiddenField in the client side, and then in the server side parse the HiddenField information to see which layers have been turned off when you generate the PDF document. 
  
 Hope this helps and any more questions please let us know. 
  
 Thanks, 
  
 Sun 


Hi Sun 
  
 I was kinda hoping for a solution before attempting a work-around :-) 
  
 Does your answer imply, that Map Suite doesn’t have some built-in mechanism for this sort of information retrieval ? 
  
 Cheers

Lars I.


Maybe there are some misunderstanding between LayerOverlay and Layer. One LayerOverlay can consist of more than one Layer and is corresponding to a layer in client side.


It is simple to determine the visibility of dynamic overlays (non-base layer in client side) by “isVisible” property, but little complex for base overlays. It needs to be implemented by “BaseOverlayChanged” Event of the Map, and here are some sample code:




protected void Map1_BaseOverlayChanged(object sender, BaseOverlayChangedEventArgs e)
{
     string currentBaseOverlayId = e.CurrentBaseOverlayId;
     // Current baseoverlay is the one that wiil be shown
     Overlay visibleBaseOverlay = Map1.CustomOverlays[currentBaseOverlayId];

      // Todo: some custom implementations
}



Any question please let me know, Thanks!


Johnny

 



Thanks Johnny,



An additional Q: Is it possible to build a similar feedback for ordinary layers, i.e. non-base layers ?



The provided sample code works, and yet doesn't. It seems to loose the visibleBaseOverlay somehow:




Partial Public Class _Default
    Inherits System.Web.UI.Page

    Private visibleBaseOverlay As Overlay

    Protected Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button2.Click
        Dim pdfDoc As New PdfDocument()
        Dim pdfPage As PdfPage = pdfDoc.AddPage()

        Dim pdfGeoCanvas As New PdfGeoCanvas()

        Dim LabelsInLayer As New System.Collections.ObjectModel.Collection(Of SimpleCandidate)

        For Each ovl As Overlay In Map1.CustomOverlays
            If ovl.IsVisible And ovl.Equals(visibleBaseOverlay) Then 'THIS ERRS, visibleBaseOverlay is nothing
                If ovl.ToString().Split(".").Last() = "LayerOverlay" Then
                    Dim layovl As LayerOverlay = ovl
                    For Each lyr As Layer In layovl.Layers
                        If lyr.IsVisible Then
                            pdfGeoCanvas.BeginDrawing(pdfPage, ExtentHelper.GetDrawingExtent(Map1.CurrentExtent, CDbl(pdfPage.Width.Point), CDbl(pdfPage.Height.Point)), Map1.MapUnit)
                            lyr.Open()
                            lyr.Draw(pdfGeoCanvas, LabelsInLayer)
                            lyr.Close()
                            pdfGeoCanvas.EndDrawing()
                        End If
                    Next
                End If
            End If
        Next
    End Sub

    Protected Sub Map1_BaseOverlayChanged(ByVal sender As Object, ByVal e As ThinkGeo.MapSuite.WebEdition.BaseOverlayChangedEventArgs) Handles Map1.BaseOverlayChanged
        Dim currentBaseOverlayId As String = e.CurrentBaseOverlayId
        visibleBaseOverlay = Map1.CustomOverlays(currentBaseOverlayId)
    End Sub
End Class



Cheers.



Lars I.



Everytime you do a postback, we will synchronize between client side and server side. That is to say, if you set a no-base layer to invisible, and on the server side you will get it. So your code maybe likes this:




//Draw base overlay
            if (visibleBaseOverlay != null) {
                foreach (Layer layer in visibleBaseOverlay.Layers) {
                    RectangleShape printExtent = ExtentHelper.GetDrawingExtent(Map1.CurrentExtent, (float)Map1.WidthInPixels, (float)Map1.HeightInPixels);
                    pdfGeoCanvas.BeginDrawing(page, printExtent, GeographyUnit.DecimalDegree);
                    layer.Open();
                    layer.Draw(pdfGeoCanvas, labelsInLayers);
                    layer.Close();
                    pdfGeoCanvas.EndDrawing();
                }
            }
           
            //Draw no-base overlay
            foreach (LayerOverlay overlay in Map1.CustomOverlays) {
                if (overlay.IsVisible && !overlay.IsBaseOverlay) {
                    foreach (Layer layer in overlay.Layers) {
                        RectangleShape printExtent = ExtentHelper.GetDrawingExtent(Map1.CurrentExtent, (float)Map1.WidthInPixels, (float)Map1.HeightInPixels);
                        pdfGeoCanvas.BeginDrawing(page, printExtent, GeographyUnit.DecimalDegree);
                        layer.Open();
                        layer.Draw(pdfGeoCanvas, labelsInLayers);
                        layer.Close();
                        pdfGeoCanvas.EndDrawing();
                    }
                }
            }



Also, you could get base overlay in the “BaseOverlayChanged” event handler of the Map, the code likes below:


        protected void Map1_BaseOverlayChanged(object sender, BaseOverlayChangedEventArgs e) {
            visibleBaseOverlay = (LayerOverlay)Map1.CustomOverlays[e.CurrentBaseOverlayId];
        }





Another thing is that you need to set visibleBaseOverlay as static filed or add it to ViewState, otherwise visibleBaseOverlay will be null when you postback next time.



Any more question please let me know.



Thanks,

Johnny

Hi Johnny,


Thanks, but I implemented a hiddenfield work-around, since I didn't want to use the BaseOverlayChanged handler after all.


I instead utilized a client-side script in my Asp.Net button's onClientClick event to compile a list of visible layers before the postback occurred.


Cheers.


 



Lars I, 
  
 You are so welcome. Please feel free to let us know if you have more queries. 
  
 Thanks, 
  
 Johnny