# Saturday, August 30, 2008

Javascript compression is something I had on my list for the next major release of RADE.  RADE is not quite ready for this step yet, so I thought I would give it a shot on Mapguide Enterprise and see what kind of results it would yield.  For a small site or an internal site this will probably not yield significant benefits.  However if you run a large public site javascript compression could squeeze out some more performance as well as save you on bandwidth costs.  Yahoo has a good article on .

I did some brief looking around and word on the internets is that the is one of the better compressors out there.  The YUI compressor is an open source java applet.   This *should* work with Mapguide Open, heck this might even be done already in MGOS - but I am only using Enterprise so I cannot confirm, deny, or test this.  

Some of the key things the compressor will do:

  1. remove all comments
  2. remove all white space and line breaks
  3. rename all local variables and parameters to single characters

The YUI compressor should not alter variable values or your logic in any way.

To use the YUI compressor you will need to .  Note that if you have the Oracle client installed, you probably have Java already  Once you have Java, you can download a copy of the (I'm going to start referring to it as the YC now...).  If you don't feel like downloading Java and the YC - I've attached the processed files at the bottom of this post.

Lets first look at the javascript shipped with Mapguide Enterprise.  If you browse to your web server extension viewer files (the default location is C:\Program Files\Autodesk\MapGuideEnterprise2009\WebServerExtensions\www\viewerfiles I believe) you will see ten javascript files.  If you choose to process these files on your own please back them up first.  Don't blame me if you don't backup your files and something goes wrong =).

Before YC:

Mapgude Enterprise Javascript before YUI Compression

Using the YC is simple:

   1: c:\oracle\product\10.2.0\client_1\jdk\bin\java.exe -jar f:\utils\YUICompress\yuicompressor-2.3.6\build\yuicompressor-2.3.6.jar -o comp\browserdetect.js browserdetect.js

 

Update the paths to Java and the YC as per your environment.  Using the handy dir /B *.js > go.bat I created a batch file of all the javascript files in the viewerfiles folder.  Be sure to run this from a dos window in the viewerfiles folder, or update the paths.  You will also need to create the comp folder in viewerfiles.   Quick cut and pasting created the following batch file:

   1: c:\oracle\product\10.2.0\client_1\jdk\bin\java.exe -jar f:\utils\YUICompress\yuicompressor-2.3.6\build\yuicompressor-2.3.6.jar -o comp\browserdetect.js browserdetect.js
   2: c:\oracle\product\10.2.0\client_1\jdk\bin\java.exe -jar f:\utils\YUICompress\yuicompressor-2.3.6\build\yuicompressor-2.3.6.jar -o comp\contextmenu.js contextmenu.js
   3: c:\oracle\product\10.2.0\client_1\jdk\bin\java.exe -jar f:\utils\YUICompress\yuicompressor-2.3.6\build\yuicompressor-2.3.6.jar -o comp\digitize.js digitize.js
   4: c:\oracle\product\10.2.0\client_1\jdk\bin\java.exe -jar f:\utils\YUICompress\yuicompressor-2.3.6\build\yuicompressor-2.3.6.jar -o comp\hashtable.js hashtable.js
   5: c:\oracle\product\10.2.0\client_1\jdk\bin\java.exe -jar f:\utils\YUICompress\yuicompressor-2.3.6\build\yuicompressor-2.3.6.jar -o comp\initdwfctrl.js initdwfctrl.js
   6: c:\oracle\product\10.2.0\client_1\jdk\bin\java.exe -jar f:\utils\YUICompress\yuicompressor-2.3.6\build\yuicompressor-2.3.6.jar -o comp\legend.js legend.js
   7: c:\oracle\product\10.2.0\client_1\jdk\bin\java.exe -jar f:\utils\YUICompress\yuicompressor-2.3.6\build\yuicompressor-2.3.6.jar -o comp\numfmt.js numfmt.js
   8: c:\oracle\product\10.2.0\client_1\jdk\bin\java.exe -jar f:\utils\YUICompress\yuicompressor-2.3.6\build\yuicompressor-2.3.6.jar -o comp\pngfix_map.js pngfix_map.js
   9: c:\oracle\product\10.2.0\client_1\jdk\bin\java.exe -jar f:\utils\YUICompress\yuicompressor-2.3.6\build\yuicompressor-2.3.6.jar -o comp\sarissa.js sarissa.js
  10: c:\oracle\product\10.2.0\client_1\jdk\bin\java.exe -jar f:\utils\YUICompress\yuicompressor-2.3.6\build\yuicompressor-2.3.6.jar -o comp\wz_jsgraphics.js wz_jsgraphics.js

 

(*Sorry about the overlap.  I'm working on a new layout and am addressing that in there)

Running that output all of the compressed of the files down somewhat, to pretty significantly.

Mapgude Enterprise Javascript After YUI Compression

A quick comparison of one of the function calls:

   1: function MenuData(menuName, arrowHeight, scrollInc, scrollDelay, minSize, iconScrollUp, iconScrollUpDisabled, iconScrollDown, iconScrollDownDisabled, owner, withIFrame, bkColor)
   2: function MenuData(F,H,I,K,E,G,D,J,A,C,B,L)

 

As you can see - the savings can be significant.

I'm not using the yet so I did not process those files, but I did check some of the JS in there and each script file had a huge header comment.  It looks like Fusion could also benefit from some compression action.  Please note, I've been running my web tier using this script for a day or two.  I've not run any serious testing on this code - so try this at your own risk.  You did make that backup I suggested, right?  That said, I have not personally experienced any problems yet.  Also, should you compress your viewerfiles and have problems be sure to try your backups.  Especially before calling your dealer or Autodesk for help. (sorry product support and ADN guys.  Please don't hate me =] ).

if you would rather not run the YC yourself.

Enjoy!

Friday, August 29, 2008 11:18:36 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Friday, August 15, 2008

has an article stating that the next version of will support multiple displays.  I'm very excited about this enhancement.  Long Long ago, we went to dual head Matrox G200 cards and dual displays for all developers at Kanotech.  This was fantastic. Particularly since 95% of my time was spent doing AutoCAD development.  Whether it was Visual Lisp, VB, or C++ - debugging something in AutoCAD screamed for multiple monitors. The AutoCAD window would start up and switching between the IDE to step through code, and doing what needed to be done in the AutoCAD UI was a huge pain.

More recently, I was running quad 19" monitors, and Visual Studio was maximized (manually) across the two center monitors.  This was a bit of a pain - but left a lot of room for running other apps as well as debugging.  Now - I've got a Samsung 305T 30" monitor for primary, and a 24" and one remaining 19" (need to upgrade this one of these days so everything looks consistent =]).  Visual Studio is maximized on the 30" and I debug on the left or right monitor.

More details on the Multi-Display enhancement can be found - sadly it doesn't have much detail other than "Windows within Visual Studio should be docked by default and allow the user to undock any window and move it to another display on the system".  I really hope they knock this one out of the park though.

Technorati Tags:
Friday, August 15, 2008 9:41:54 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Tuesday, August 05, 2008

It's just about that time.  is December 2nd to 5th at in .  Signup begins on August 15th!  Before you register, try contacting your Autodesk rep, or Autodesk reseller and ask if they have any AU discount codes available.  If you register, and get a discount code after the face you can call up the helpful events staff, and they will apply the credit after the face.  If you are planning on attending, I strongly encourage you to book as close to the 15th as possible.  Rooms at the Venetian fill up quickly, and its a huge benefit to be staying in the hotel where the conference is located.  "Across the street" in Las Vegas units of measurement is a twenty minute walk =).

This will be my third AU, and I'm looking forward to it.  I was a bit concerned the first time I attended an AU about the technical level of the courses.  I was very pleasantly surprised to find that I was able to fill my week with courses targeting GIS developers, and that the course content was pretty good.  I really enjoy the classes put on by the Autodesk developers and technical staff. 

This year again the is putting on a full schedule of developer courses.  Hurray!  Autodesk Developer Network members can also sign up for the extra ADN Dev Day on December 1st wherein you get an NDA sneak peek at the up and coming 2010 releases.  The extra day is free, you only need to cover the cost of the additional night's stay.  Room rates are pretty decent for extra nights.  I believe my extra nights last year were around 160 a night.

Autodesk has released a complete list of the and additional information can be found on the .  

If you're planning on attending, mayhaps we could get some of the GIS nerds together for some drinks.  Drop me a note if this interest you.

Technorati Tags:
Tuesday, August 05, 2008 1:15:58 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Sunday, August 03, 2008

My friend and colleague recently wrote an article on the (sometimes known as @MAppDR, ATMapp or ATT_MApp).   A strange twist of events also resulted in me working very briefly with the most "recent" build of the product.  It had been many years since I really saw the application running - so I had a bit of a fresh eye.  This made me a little bit nostalgic, and also quite proud.  We had really made some amazing software when you got right down to it.  Unfortunately, in "internet years" it has sadly become a dinosaur.

Long ago (it seems like a lifetime) I worked for a company called Kanotech.  One of my first real development projects of scale was on the .  @MApp was a powerful extension built for AT&T/Comcast cable.  My first task was to head to Seattle and learn how field technicians would walk the existing RF Plant (fancy word for cabling and RF equipment) and map the existing assets, on paper.  The first task was devise a way to run @MApp on one of the early rugged .  I walked the streets of the greater Seattle area with some of the field technicians and got my first introduction into the world of cable TV networks.  At the end of this trip I had a collection of notes and enough information to design and implement the pen based version of @MApp.  This was the beginning of my life with @MApp.

With the bigger picture in mind, there were many underlying goals for @MAppDR, one of the key needs was standards enforcement (and creation -  Evan created the first solid standard which, though very much evolved is still in use today).  Like many organizations back in the day (and likely even today) the mapping data being generated was garbage.  Each division, each consultant, sometimes each drafter had their own set of "Standards".  As Evan put it, the mapping data was "Only good for printing" - and even that was a stretch in some of the sample data we saw.  Our top priority was to create a set of tools which facilitated drafting standards compliant drawings - as well as a method to test each drawing to ensure the drawing was truly compliant.

Under the hood, @MAppDR was all database driven.  Layers, cable types and properties, even symbols and block attributes could be configured in the database.  Generic lisp calls were defined to allow simple wrapper functions to be created to add new entities to the application.  The application had been created using an extensive amount of , VB6, , Python, and SQL Server/Access databases.  Let me tell you, I still have nightmares about parentheses =).@MApp DR drafting tools

The drafting tools, in retrospect were good.  Damn good.  Obvious elements were there, select a cable, or equipment type using standard AutoCAD toolbar buttons.  @MAppDR went a step further.  It would create/set the layer, set the desired object snaps, draft the cable.  Network connected equipment would snap to the cable, rotate, trim and physically connect itself to the model.  In some circumstances, inserting a block/cable of a certain type also required an accompanying block.  If required, the user would be prompted to insert these as well.  In some cases - these blocks were placed automatically.  Using @MAppDR - a user could draft very clean RF drawings without having to really know  AutoCAD.  Every piece of possible equipment was available from a comprehensive set of toolbars - and only one click away. 

On insertion of blocks, the user was presented with a form powered by the attribute information stored in the databases.  Some attributes were required, some were populated programmatically based on nearby objects or other conditions, and some were selected from lookups or manually entered by the user. 

@MAppDR had a really cool connectivity process.  This process would perform physical connectivity on the network, following rules defined for equipment inputs and outputs.  In addition to this, rules were also defined to dictate what equipment could connect to other equipment.  This connectivity, in my opinion was one of the most powerful components of @MAppDR.  Connectivity information was stored on the entities.  When a trace was done, we could follow the network and do all kinds of great reporting.  I recall one situation where we knew that in situations where a specific combination of equipment was setup - it would cause service problems.  Within a few hours, I had a batch process created that would process hundreds of drawings and spit out a report of nodes, and locations where this combination existed.  The problems in the field were fixed even before customer complaints came in. 

One of the key requirements for @MAppDR was a quality assurance process.  We defined several "levels" of QA.  Each level of QA required a password to execute.  The first two levels of QA were for contractors doing mapping redraft, or drafting.  These levels would let the consultants know that the required data had been entered and would "stamp" the drawing.  The drawings were then submitted, and Comcast staff would run their password protected version of the QA routines - which would verify that indeed the contractor had done the required work.  If not, the drawing was rejected and the contractor had to fix it.  I can say with a great deal of certainty that Comcast, using @MAppDR is one of the few organizations with near perfect data.  And the things they do with that data are incredible.@MAppRF Drafting Enhancements

The final version of @MApp, @MappRF could have dominated the cable industry.  Sadly, it was never completed.  This release added RF design to the drafting.  A library of equipment was created, as well as design parameters which were sub-selection of the equipment that let the RF designer know what equipment was available to be used.  All of the equipment's operating parameters were captured.  As the user drafted equipment, the actual equipment model would be selected on the attributes.  This allowed us to increase the efficiency of populating attributes during the drafting phase all the while making the stored data even more accurate and complete.   

One of the coolest bits of @MAppRF was what came to be known as the TRID.  The TRID was a  multi-threaded C++ control was created that contained a tree-grid hybrid.  This form could be docked within AutoCAD or floating on a separate monitor.  As the user drafted, the RF signal and power calculations were performed in real-time, without interfering with the drafting process.  I recall being told, this project would be simple.  RF design is just table math.  And it is, but, mix in a multi-threaded C++ form running per entity calculations on a potentially infinite number of @MAppRF Design Diaglog - the TRIDfrequencies both going forward, and backwards - oh and sprinkle in a little bit of power draw calculations.  Then tell me its simple.  =)

If I could do it over again.  Wow, what a difference the current technology would make.  By far the single largest flaw @MApp has is its dependence on drawing based storage.  Given the timeline, we didn't have a choice.  was available, but immature.  Going with Oracle at that time would have likely been more grief than it was worth.   Seamless map access would be a must.  Given the times we used a special piece of ObjectARX code called the SPE.  This gave us spatial analysis abilities that rival even Oracle Spatial.  One of the major downfalls here is that it required AutoCAD to run.  Therefore - most of the calculations had to occur within AutoCAD itself.  This became a problem as other applications could benefit from these operations - but couldn't take advantage of them without also being AutoCAD based. 

Leveraging a multi-tiered architecture, a lot of the common functions could be moved to a more like architecture.  Now, though the TRID could still be a multi-threaded form in AutoCAD - the calculations could be done on the server side - thereby making the AutoCAD portion a presentation layer - instead of a business logic layer.  Now the RF design calculations could be done in any user interface - instead of having to opening a drawing in AutoCAD. 

And that my dear reader, concludes my epic tale on @MApp.  Even this large novel like piece only scratched the surface of this project.  It was my life for many years.  I slept under my desk a number of times - but it was a great project.  It was fun to think about it again and put together something to share with you. =)

Technorati Tags: ,,
Sunday, August 03, 2008 12:51:26 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Wednesday, July 30, 2008

Everyone knows there is a , right?  Well ok, maybe you didn't - but there is.  What that limit is depends on the browser.  There is a lot of conflicting information out there on the magical .  An RFC defines it, but no one really seems to pay attention to those anyhow.  (Are you listening Microsoft, of course you are! =]).  Anyhow, for IE, the query string length is usually around 2000 characters.

However, in most cases you're better off using a form and posting your data up to the server side that way, as the limitations on data are so large you will likely not need to worry about them.  Sometimes, query strings can also show your users just a little too much information - though I'm by no means a proponent of "security through obscurity" hiding a little bit more from your users will keep the curious ones a little more in check =).

When working with / we need to grab some potentially massive XML strings from the MgMap object and pass these along to the server side for processing.  Take the selection XML from the MgMap object, even a single entity selection can use a significant portion of the characters available in the query string.  On top of that, passing this data via query string requires that the data be URL encoded, using even more of our precious query string characters.

Depending on the design of your application it may not always be feasible to define a hard coded form, or even a form defined server side using ASP.NET.  In some cases (you guessed it - my case) you may want to use javascript and do all the work on the client side to define a form and pass the data long that way.

Well you're in luck, I found a pretty nice solution (WELL, at least I'm liking it  =]).   I'm kicking myself for not realizing this long ago, but oh well.  So the following javascript function demonstrates how to build, add, populate, and submit a form on the fly using some information from the MgMap object.

   1: function postData()   
   2: {   3: //get the map   
   3: mapObj = GetMap();   
   4:  
   5: //define the new form   
   6: var newForm = document.createElement("form");   
   7: //set the method to POST - the opposite of query strings..   
   8: newForm.method="POST";  
   9:  //add the new form to the current document  
  10:  document.body.appendChild(newForm);  
  11:  
  12:  //lets get some data and add it to the form  
  13:  AddFormElement(newForm, "MapName", oMap.GetMapName());  
  14:  AddFormElement(newForm, "SID", oMap.GetSessionId());  
  15:  //be sure you escape the selection XML - or you will get an error on post about a   
  16:  //"potentially dangerous form value".  Remember on the server side to Server.UrlDecode() it  
  17:  AddFormElement(newForm, "sel", escape(oMap.GetSelectionXML()));  
  18:  
  19:  //lets create our new window  
  20:  var szTarget = "targetWin"  
  21:  newForm.target = szTarget;  
  22:  //set the name/path of the ASPX file you want to process your form with  
  23:  newForm.action = "/url_to_open/file.aspx"  
  24:  
  25:  //open a new window to submit the form to.  Its a good idea to have a blank.htm so you don't get a file not found error  
  26:  var oWin = window.open("blank.htm",szTarget,'menubar=yes, resizable=yes,scrollbars=yes, status=no,toolbar=no,width=300, height=300');  
  27:  
  28:  //give the window focus.  Users like this  
  29:  oWin.focus();  
  30:  
  31:  //submit the form - it will now open in the new window  
  32:  newForm.submit();  
  33:  //remove the form from the document, we're done with it  
  34:  document.body.removeChild(newForm);  
  35:  }  
  36:  
  37:  function AddFormElement(form, elementName, elementVal)  
  38:  {  
  39:      var newElement = document.createElement("<input name='" + elementName + "' type='hidden'/>");  
  40:      newElement.value = elementVal;  
  41:      form.appendChild(newElement);  
  42:      return form;  
  43:  }

 

On the server side, you can now access this data from ASP.NET using Request.Form, for example Request.Form("MapName") would give you the map name.  Don't forget when retrieving the selection XML to run that through Server.UrlDecode, or HttpUtility.UrlDecode.

As usual, any comments, bugs, or rotten fruit - send em my way.  Enjoy!

  Technorati Profile
Wednesday, July 30, 2008 3:22:27 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback