Friday, May 30, 2008
2008 ESRI Dev Summit Code Entry
Wednesday, May 28, 2008
The 2008 ESRI Dev Summit
Friday, May 23, 2008
ESRI Holistic Lab: Flex API Day 3
Built In Tasks
Having gotten the QueryTask to work on day two I decided to take a gander at the other built in tasks on my last day in the labs. The other two currently available are the Locate and Find tasks. They work similarly to the QueryTask, using the built-in support of the REST API to do their work. Neither of these tasks is currently bug free however so I was unable to satisfactorily test them.
Debugging
This leads me to the next thing I would like to go over, debugging your flex code. Here, especially when using native REST API calls, you can take serious advantage of the Services Explorer. This is typically located at http://serverName/ArcGIS/rest/services and from here you can view any of the MapServices setup for that server. You can also see what capabilities exist both for the service and each individual layer and even test them. The explorer also has links directly to the REST API documentation which can be invaluable.
The other priceless tool for debugging is an extension to Firefox called Firebug. Firebug allows you to see requests being made over your browser. You can then see the request, header, parameters, and the response. By right clicking on a request you can copy it and then paste it into your browser’s address bar and see the result in your browser. I was able to figure out several issues I had with the QueryTask by doing this and then manipulating the variables directly within my request. I wouldn’t recommend working with the Flex API without using Firebug or something similar.
Building an Extensible Framework
The original Flex API from ArcWebServices was built on a variation of OSGi www.osgi.org/ which is a dynamic module system originally created for Java. Using such a framework allows for seamless adding and removing of modules from an application without having to take it down. You can simply drop a new module into your framework on a server while the application is running and it will be discovered and its functionality made available.
Eclipse (the base application for Flex Builder) is built on top of the OSGi Spec. The basic idea is that each module you create must implement the IBundle and IBundleActivator interface. When a new module is discovered your application then casts it to an IBundleActivator, passing it a context (IBundleContext) and retrieves all of the services (IService) from the module. Now any other part of the application can find and use the services provided by this new module. There are several freely available OSGi frameworks. Knoplerfish ( http://www.knopflerfish.org/ ) and Felix ( http://felix.apache.org/ ) are two fairly uncomplicated and well known ones.
Transmitting Data
We also spent some time on the different ways to transmit data using Flex. There are three basic ways beyond Web Services which are available: Remote Objects, messaging, and data services. Adobe provides a free Blaze DS service which allows you to do the first two. If you want to do the third though, you’ll need to shell out $25,000 for the privilege. Each of these transmission types buy you something. Using remote objects allows you to transmit actual objects as binary over the wire, speeding things up considerably over the use of web services. Messaging allows clients to subscribe to a destination point on a server and then receive any messages that come from there. Data Services allows for things like ‘active rows’ where you are given and can manipulate a row from a database table that will automatically manipulate the row on the server and let other users of that row that it has changed. There are a lot of powerful uses I can think of for this last method which is probably why it is so expensive.
ESRI Holistic Lab: Flex API Day 2
We also sat together as a group for a couple of hours in the morning and afternoon and talked about basic Flex programming dos and don’ts. Many of the following ideas come from the Cairngorm flex framework http://labs.adobe.com/wiki/index.php/Cairngorm
Code-behind
We started out by going over the basic GUI coding paradigm of code-behind and how it works in the Flex world. The best way to do this is to create your own Actionscript class, MyApp for instance, which has Application as a super class. You then create your base application mxml and have it subclass your MyApp Actionscript class. At this point you can put all of the code you need to run your application within its own actionscript class and keep it completely separated from the mxml gui tags. In order to access your gui items from your MyApp class you must declare a public variable within your class with the same name and type as the items within the mxml. So if you have a
The names that you give your objects now become very important because you will be coding the logic in a separate file from where the GUI is created. If you name your objects and event handlers poorly you will have trouble keeping up with what functions and items do what. Therefore it is good to not only give your objects meaningful names but to also follow a standard when naming your event handlers. Using the convention of objected_eventNameHandler() is the standard way of naming your event handlers and does a good job of concisely informing you on what it is (an event handler), what type of event it handles and for what object it does the handling.
Making use of Singletons
Cairngorm recommends creating a bindable singleton class which holds on to all of your application level information and allows any class to manipulate that class level data and always be sure that it is the correct version of the data. Making the class bindable also allows other classes to bind to these application level variables and be automatically updated when those values change. The Flex API team called this class the Model. We used a singleton class in our original Network Express prototype which definitely made life much easier but the one we were shown had a couple of advantages over the one we used previously. Chief among these was the ability to make sure that only one instance of the Model is ever created, and the ability to be certain there is only ever one instance of any given application level object.
The Flex Object Lifecycle
All objects which are created in the Flex world go through the same cycle when they are created. There are several events and functions which fire off that can be overloaded to allow you as the programmer to perform specific functions even before the CreationComplete event has fired.
·
- New (Label) – the first step is the object instantiation is started.
- PreInitialize – an event dispatched before any actual initialization takes place.
- Setter – calls all Set functions
- Initialize – another event dispatched to alert of actual initialization
- CommitProperty – a function. Overriding this function will allow you to make changes to the object atomically, preventing flashes and other artifacts from occurring as properties are set.
- CreateChildren – function which starts the Lifecycle on all children objects. This is another function which can be overridden.
- Measure – Sets all of the width, height, etc.
- UpdateDisplayList – function that adds the new object to the display list atomically.
- CreationComplete – the final event which signals that the object is complete. This is called only once.
Simply knowing about this lifecycle opens a lot of possibilities, especially with the functions which can be overridden.
Tips:
1. Make sure to listen to the Load event on map objects as the CreationComplete event will fire well before any layers have actually been loaded. Trying to manipulate the map before the Load event will only cause you heartache, and errors. Each individual map layer will also fire a Load event.
2. Always call super on all overloaded functions. Failing to do so will keep the normal behavior from occurring.
For more information on the Flex lifecycle check out this document: http://livedocs.adobe.com/flex/2/docs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000492.html
Events
Let’s say you have an application with a VBox that contains a button. The display tree would look like: Application --> VBox --> Button. If you were too hook into the click event on this button then I’m sure you can guess that your function will be informed when the button is clicked. What you might not know however is that Every item in the display list starting at the top will receive a click event as well. This means that if you were to hook the click event on the VBox or the Application you would catch an event each time the button was clicked as well. So how does your function know if the event it catches was meant for it? The event object has target and currentTarget properties. The target property contains the id of the actual target of the event and the currentTarget property contains the id of the item in the display list currently receiving the event.
Events also have a phase. There are two event phases: capture and bubble. The capture phase occurs as the event is making its way down the display list looking for the target. If you need to cancel an event for some reason you would want to handle it during the capture phase. The bubble phase occurs on the way back up to the top of the display list. When a handler is added it will fire by default on the bubble phase. There is also a bubbles property on an event which is set to true by default.
Delegates and Unit Testing
During the afternoon of day 2 we sat down together and did a quick example application using Delegates which we then performed unit testing upon. Delegates take the idea of code-behind a step further. Once you have your mxml application and the code for it separated, you then perform all of the actual logic of your program via Commands. These commands are called by events in your code-behind which then in turn call their own Delegate classes which perform all of the actual work. The Commands are then in charge of making changes to application level data within your Model. Delegate classes are completely independent of the rest of your program, not caring how they are used as long as they receive their input in the correct form. The Delegates for your application can even be removed to separate swc libraries without causing any issues. This allows teams to break up tasks fairly easily and logically. One person can be in charge of creating the GUI for the application, another in charge of the code-behind application and commands, and yet another person or group can be in charge of creating the Delegates to actually perform the logic of the application.
Unit testing can be performed on Delegate classes very easily because they have well defined inputs and outputs. As long as a Delegate receives input in the correct format it doesn’t matter where it comes from. The unit testing framework we used was Flex Unit http://code.google.com/p/as3flexunitlib/ which is a free download and a very slick addition to your Flex environment which I highly recommend and plan to use myself.
Tips:
When your mxml application is compiled by the flex compiler it goes through several steps. First it is parsed into MXMLC and then it is translated into an actual actionscript (as3) file before being compiled into a swf. Now I know what you’re thinking, wouldn’t it be nice to see how flex natively converts all of those mxml tags into neat concise code? Well it turns out that you can. There is a compiler setting which allows you to tell the compiler to leave all of those as3 files behind instead of deleting them once it is finished, allowing you to learn all types of tips and tricks by seeing how the compiler creates all of that code.
Wednesday, May 21, 2008
Holistic Lab: Flex API Day 1
This is obviously the first beta, and a closed beta at that, of the new Flex API so you expect a few rough edges. One of those is error handling. There are a few places where I would expect no error to be thrown but they are anyway, if a layer’s url property is set to an empty string then the next pan/zoom will throw an error, and a few places where you would like an error to be thrown to let you know something is wrong and it isn’t. The main place I can think of is when a tiling service fails you have no way of knowing this which caused some of the people here issues. I have no doubt these will be fixed going forward.
Authentication
There is no support currently for secured services. If you want to use one you must first add it to an mxd and then expose it as an unsecured map service in Arc Server. I did this with an IMS weather service and it worked just fine. This is something that will be added but hasn’t crept to the top of the development team’s list yet.
Slow/Dead Services
There are issues with services which are either slow to respond or have died. When a zoom occurs and a service doesn’t respond correctly the area on the screen which is coming from that service will behave weirdly, growing or shrinking out of proportion with the rest of the map. This caused a small set of data in Montgomery to eventually cover the entire South East US for me when I tested it by stopping the map service completely. In the case of extremely slow services this will eventually correct itself but it may take several minutes. This is something the team was working on fixing as the day progressed and may even now be dealt with.
Layering Services
Layering multiple services is now much smoother than it was with the old api. When you drop services on top of one another they now automatically leave the area not covered by their features transparent. This means that if I put a map service with gas mains on top of a service showing street data I can automatically see all of the data. This is a nice improvement from the past when you had to set transparency colors etc. to get this effect.
No More IMouseHandler!!
The IMouseHandler interface is gone with the wind. This made me sad mainly because we have created a number of mouse handlers to do various tasks for us. After talking it over with the development team however it seems there will be a new paradigm called Toolkits which will allow the same type of behavior along with (hopefully) even more flexibility...no pun intended.
TOC Control
One of the first tests I did was to recreate the table of contents control I had made with the old api. This is now much more straight forward. LayerInfo objects now come along with your layer when it is received from the rest api. This means you can immediately cycle through all of the layers, drop them in a VBox as checkboxes, and correctly check/uncheck them based upon the default visibility property. I was very pleased with the TOC control in both performance and ease of coding. The only issue that I saw was when switching the URL of my background layer there would be a flicker as the background turned momentarily white. I didn’t even notice it at first but when the Product Lead was watching me show the TOC control he commented on it. I’m not sure if this will get fixed to not redraw the background layer until the new source comes through but that would be a nice little adjustment.
Tips:
Use
Whenever you change the underlying map document for a map service be ready to also clear the REST cache. You can find the REST manager by going to http://servername/ArcGIS/rest/admin where the only option is currently to clear the cache or setup a schedule for it to be cleared. If you don’t do this and the api has already been used to get information on that map service then you will get some strange inconsistencies.
Monday, May 19, 2008
Traveling to the ESRI Holistic Lab
Let me start by saying this is the very first time I have ever attempted to fly American Airlines. I've flown many times with multiple airlines all over the states and over seas and nothing like this has ever happened before.
My 9:05 flight got delayed until 11 am and then canceled all together because of an apparent issue with one of the engines. Don't get me wrong, I'm glad they caught it, flying with a faulty engine is not my idea of a good time. From that point onward however things were just handled badly.
To begin with they lined all 300+ passengers up at the gate and had two people begin to reroute everyone. If those numbers don't seem bad enough already it took an average of ten minutes per passenger, and I was at the very back of the line. After about thirty five minutes someone from the airline came up and told us "if you will go to gate sixteen they have five people there that can help you". So the back thirty or so of us started the long walk to gate sixteen.
When we arrived fifteen minutes later to see the two people there staring off into space I was not pleased. We told one of the ladies what was going on and what we had been told and she told us we had to go out past security and go speak with the ticketing agents. Okay, not convenient but still faster than waiting in that other line. We all get outside and line up. There are five agents there but only three of them are willing to help us as the other two apparently had better things to do staring out into space.
After a few minutes I get my turn, I tell the lady what the issue is and she begins to help me. She tells me I can't go to my actual destination but I can go to an airport thirty miles away. That stinks but at least I can still make my destination. She puts me standby on the 11:45 flight and gets me a 'confirmed' ticket on the 3:15 flight which had my seat assignment and everything.
Now I went back through security, and rushed to the 11:45 gate to see if I have a chance, it was 11:05 when I got my ticket. When I make it to the gate they tell me that the boarding door was closed and so no new passengers may enter. That was a bummer but at least I had my ticket for the 3:15 flight. I bought some lunch, bought and read an entire magazine, and waited.
My 3:15 flight was delayed...of course. At 3:30 boarding began. Once they finally called my group I got in line and handed the attendant my boarding pass. He swiped it as I have seen many times before but this time something new happened: the scanner flashed red and beeped. I was pulled aside and asked to sit down while the other gate attendant tried to figure out the problem. Well it turns out the problem was that they had canceled my ticket! According to American Airlines I had left on the 1:45 flight to my original destination! The very flight I had been told was fully booked when I went out and talked to the ticket agent earlier in the day! So not only had my luggage gone with that flight but they had canceled my ticked for this flight, and they couldn't get me on it because it was full!!
After telling me he was sorry the gate agent booked me on a 10:15pm flight, still not to Ontario (my original destination) but to the 'close by' airport. He also can't actually issue me a ticket for it because according to their computers I already flew out of the airport. So I have to go back out to a ticketing agent again. Have I mentioned yet that I love American Airlines? So I go back out and go to get my ticket.
When I get there I let the lady at the counter know everything that has happened and what my current situation is regarding the fact that I'm actually still in the airport despite what the computer says. She managed to actually get me a confirmed ticket on a 4:55pm flight to the 'close by' airport, but it was already 4:05 at this point so I had to hurry. She also wasn't able to get me a seat assignment but assured me that they would give me one when I arrived. I ran to security, got threw there and then ran to the terminal train.
I managed to arrive at the gate as the last of the passengers were boarding and told the gate agent what the ticketing agent had said and handed her my ticket. She was not impressed. She told me that yes I was confirmed but I would have to wait until all of the other passengers were on before they could try to find me a seat. So I waited for fifteen minutes while they waited to see if anyone else would show up for the flight. Finally they actually printed me a boarding card and reluctantly allowed me to get on the plane. I hate American Airlines.
The flight went off without a hitch, as far as I know since I slept the entire time. After I got to the 'close by' airport I was told that it was a forty five minute drive when 'traffic is good'. I hopped on the super shuttle and a quick two hours later I was at the Ontario airport!
The only good thing I can say about the whole experience is that the airport actually managed to get my luggage to the hotel faster than me. The scariest part of the whole thing is that I still have the return trip to deal with. I won't even go into my issues with the rental car company here but it wasn't much better and was exactly what I needed to go along with all of my American Airlines fun.
Coming soon: The Flex API Holistic testing day 1 recap.