ThinkGeo.com    |     Documentation    |     Premium Support

Client & Server State

I have a map setup with a google background and a couple shapefile layers, each in their own LayerOverlay. Currently I am using the built-in OverlaySwitcher to toggle layers on the client side. As soon as I hit a Map1_Click event, the OverlaySwitcher reverts back to its original state, and all the overlays are turned on, on the map. So I am basically losing the client map state when server side events get fired.


I noticed a couple posts suggesting creating a custom Overlay Switcher. Is there any documentation on how to interact between the server and the client? In the MapSuite 2.0 model, there was AjaxEvent() to talk to the server, and AjaxReturnArgs to talk to the client. What is the suggested way of passing data back and forth in the new model?


I am in the process of trying to convert an existing 2.x application over to MapSuite 3.0. In our existing application, we do a lot of the work on the client side, only sending requests to the server to update the server state and interact with shapefiles.



Rob, 
  
 Thanks for your post! 
  
 We didn’t synchronize the OverlaySwitcher to server side in the current edition (3.0.131), we will add it in the coming version which will be released around 22th this month though, sorry for the inconvenience now. 
  
 In Map Suite 2.0, we used callback to interact between server and client while in 3.0 we use postback. When you change the map status using javascript, it won’t be synchronized automatically on the Server side so client will be back to the previous status after a postback. That’s why we recommend using the server side API in a 3.0 edition as we have the automatic synchronization, also by putting the map to an update panel we can avoid flicking easily with clean and easy to read codes. 
  
 Let us know if you have any queries. 
  
 Ben 


Glad to hear about the new version that fixes this! 
  
 But I am concerned about moving from Ajax callbacks to full postbacks. This seems like a step backwards. Won’t this be sending a lot of data back and forth with each user interaction, rather than just the minimal data for the server to grind the spatial query and sync the state? 
  
 With the introduction of Ajax functionality in 2.0, we reworked our (huge) application to really take advantage of the lightweight communication between server and client. We have an initial pageload that sets everything up, then the rest is handled in javascript at the client, with Ajax callbacks for hitting methods. 
  
 How can we take advantage of rich client code for moving around GUI controls and options, when as soon as the user clicks something on the map, all state is lost? Help! 
  


Rob,


You are right that Callback provides more power and we can make it really efficient by minimize the sync data. One thing is that people need to write javascript code in that mode. We use postback and synchronize Server and Client side so users can only program on server side without any knowledge of JavaScript. We think that will be convenient for most users.
 
But whatever, you can still implement Callback on your page easily. Please have a look at the link below for how to make Callback on one page.
 
msdn.microsoft.com/en-us/library/ms178208.aspx.
 
If you still have problem, could you provide us a specific requirements and we can do a little callback sample for you.
 
PS: Here is the whitepaper of our Client API, in case you want to have a look.
gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/20/aft/4902/afv/topic/Default.aspx
 
Thanks,
 
Ben.

I can implement Callback on my end, but I’d still need to be able to fire off Click() and TrackShapeFinish() events without losing state. 
  
 Would I be able to somehow intercept the Clicked event and TrackShapeFinished event at the client side before it does a postback?

Rob, 
  
 That’s a good suggestion and we will enhance it in the upcoming version (around 22nd this month).  We will have each server event with a property for client event, just like asp button, it has a Click event and also it has an OnClientClick property. If you are using both of them, the client one will trigger before the server event does. 
  
 In current version (3.0.131) instead, we do the postback directly without raising the client event, as we never have the requirements for that. It’s definitely better to add it and thanks for the insights! 
  
 Thanks, 
  
 Ben 


That will be a great addition. It opens up a lot of opportunities to customize and optimize things.  
  
 Thanks for listening!

Thank you, Rob! 
  
 More good suggestions are appreciated :)

Is there any way to access the CustomOverlays of the map through a static method? I’m assuming that this is stored somewhere in Session. 
  
 I’d like to be able to shoot off PageMethods (which have to be static, and therefore can’t access the Map1 member variable) and query layers that are already loaded in memory somewhere, rather than load up a new copy on each request. 
  
 Can you give us some info on when shapefiles are actually loaded, opened, closed? After the initial page load, what is the state of the shapefile? Is it just referenced? Or is the file actually open and ready for querying? What is the life cycle on a full postback? 
  
 Thanks, 
 Rob 


In addition to the above questions…  
  
 Is there a way to force an Overlay reload from client side, without a postback? I’d like to be able reload the HighlightOverlay without redrawing the entire map.

Rob,


      We don’t provide APIs to refresh highlight overlays at client side, but you can get it with the following client script, and write the fresh logic yourself. One thing to be aware is that we can’t synchronize your custom client side changes to server side.


  

        function GetHighlightOverlay() {
            var highlightOverlay = null;
            var overlays = Map1.GetOpenLayersMap().layers;
            for (var i = 0; i < overlays.length; i++) {
                if (overlays[i].name == 'HighlightOverlay') {
                    highlightOverlay = overlays[i];
                    break;
                }
            }
 
            return highlightOverlay;
        }

  For your previous post, sorry for no response on my end these days as we are now have too many stuff to do and that question needs to sit down and think it over, I just cannot provide a good reply for now.  We will give you a response about that letter.


Thanks,


Ben



Ben, 
  
 I understand how I can get a handle on the client side HighlightOverlay, but how would I reference a new Overlay from the server? I can remove the client side HighlightOverlay, but I’m not sure how I would add an Overlay that exists on the server. Especially since I would like to be able to change which shape is highlighted, which needs to be done on the server, and rendered as tiles. 
  
 Sorry for all the client side interaction, but that is really what our customers have grown to expect in our existing application. 
  
 Maybe I could take another route here. Is it possible to directly setup a WMS server using MapSuite Web? Something that could be consumed by OpenLayers? 
  
 Thanks, 
 Rob

Rob, 
  
 I am sorry I didn’t get you quite well. Can you let me know more about your scenario or provide a concrete example as that will better for us to understand? 
  
 On client side, you can remove or add features by javascript, the required info for a new feature including WKT, ColumnValues and Id can be get using callback. So that will not be difficult to highlight or unhighlight a shape on client. But as we don’t synchronize the client and server for highlight overlay, the status on server side will be constant no matter whatever changes on HighlightOverlay on client, if you want to edit shapes, we recommend you to use EditOverlay, we made states synchronization there. 
  
 If you want to select a highlighted feature and add it to a server overlay to render, we have a Click event on the HighlightOverlay, you can find the clicked feature by the following code and add it into any layers on server side: 
 
     Feature highlightFeature = e.ClickedFeature;
 
 You know Web Edition uses OpenLayers as its client base, in fact internally, WebEdition builds a web service which is consumed by OpenLayers. So I think if a WMS Service can solve your problem, we can also solve it with Web Edition. 
  
 Thanks, 
  
 Ben 


Ben, 
  
 What I am trying to do is allow a user to click on a shapefile feature, and using OnClientClick, fire off a WebMethod that will return some data from the DBF, as well as highlight the feature they selected.  
  
 I have everything working except the highlighting. I know I could return the WKT from the server and draw it client side, but we have some (polygon) features with hundreds of thousands of points. Needless to say, we can’t have all that processing on the client side.  
  
 So what I’m looking for is a way to setup an InMemoryFeatureLayer that can highlight specific shapes without a postback. You say that under the hood, Web Edition is setting up a web service to be consumed by OpenLayers. So how would I edit the InMemoryFeatureLayer from a static web method? 
  
 Thanks, 
 Rob

Rob, 


We cannot use static web method to interact with the fields on the page, but we can use callback instead. Here is the solution for you using callback.
 
Thanks
 
Ben.

407-Post5077.zip (95.8 KB)

Is there anything I need to reference to make the sample work? I set a breakpoint in both GetCallbackResult() and RaiseCallbackEvent() and neither get fired.

Rob, 
  
 You don’t need anything special to make it work. Are you using VS 2005 or VS 2008? If using VS2005 you need to install .NET framework 3.5.  Also, can you make sure the “Disable script debugging” option in your IE is not checked, just in case some javascript exception is eaten so we cannot see? 
  
 It’s very strange that sample doesn’t work on your machine. If problem still exists, can you let me know more about your environment, like the browser, the system, the VS edition? 
  
 Thanks, 
  
 Ben 


I’m using VS 2008, and have tried both IE and Firefox. No client side errors thrown in either. Using Firebug, I can see that the POST is receiving a “500 Internal Service Error”, but I can’t see any further details. I tried adding a clientErrorCallback function, but that never gets fired either. Any ideas? 
  
 A side question: Internally, how are InMemoryFeatureLayers stored? ViewState? Session?

Rob,  
  
 I guess there are two possible reasons for your issue. First one, you are not using the latest version 3.1.16. Please check the version by checking the static property Map.Version.  Secondly, maybe there are some problems with your system, can you try writing a callback without our map control and see whether that works? 
  
 BTW, InMemoryFeatureLayers is stored in the Session. 
  
 Thanks, 
  
 Ben 
   


That was the problem, I was on 3.1.0.  
  
 I think this will do the trick! Can you think of any tricks to minimize the amount of ViewState data? 
  
 Thanks!