Monday, July 6, 2009

ArcGIS Server Sample Flex Viewer: TwitterFeedWidget



I have been thinking about how Twitter could be used to enhance the capabilities/user experience of a web mapping system and came op with some decent stories. The first would be providing users with access to a feed dedicated to the application which contains information about it including updates, news, changes, downtimes, etc. The second would be users who wish to perform searches of Twitter content that may be related to the map and eventually, overlaying geolocated Tweets onto the map. These (and the fact that I just wanted to poke around the Twitter API) gave me enough of an excuse to start messing with the Twitter API. I ended up with a simple little widget that allows users to search for tweets within a specified geographic location, in this case, a circle. Nothing earth shattering but still maybe somewhat useful. Before giving you some of the nuts and bolts of this, I want to be sure and reference the materials I used:

Some Details on how it works.
It is really pretty simple. The user is able to draw a circle on the map and any tweets that originated from within that location based on the Twitter user's location property are returned as an ATOM Feed. The processes uses the Twitter API geocode parameter where a lat, long and radius of a circle are needed. The widget obtains the lat, long, and radius values from the circle tool. I added a coordinate transformation function to the Circle Tool component to convert the distance units (radius of the circle) to miles from decimal degrees. I used the Great Circle Distance Formula. The ATOM feed is parsed using the Flex XMLSyndication package and is validated using the Flex CoreLib Utility Package (see links above).

Proxy Server
As with any application making cross-domain asynchronous data requests, a proxy server is needed to "fool" the browser security settings. Flex has a nice framework for bypassing this. If the feed host contains a crossdomain.xml file that allows cross-domain access, you are good to go. However, Twitter locks this down (Twitter crossdomain.xml). I have included a proxy server implemented in Java within the package. It is NOT PRODUCTION quality but will get you started. There are other implementations that are easier out there. Have a look at the resources I sited for some other examples.

Known Issues and Limitations
Simply put, there are several limitations with this that make it, lets say, less than production quality. I hope to rectify these soon. These include:
  • I haven't tested the feed results very well. The widget catches feeds that are empty which is good but the way I did this is kind of sloppy. I won't go into it here but if you have questions, I can elaborate.
  • The coordinate transformation for the distance units (radius conversion from DD to miles) I am using is very rough but good enough for this use.
  • It doesn't play very nicely with the map action and map navigation state of the Sample Flex Viewer (SFV). Given that the draw circle component wasn't designed for use with the SFV, it isn't integrated very well with the event driven model the SFV uses. Not to say it isn't a nice component because it is. Using it in the Sample Flex Viewer is just a bit of a stretch. There are alot of issues with this but from a use perspective, users have to keep clicking on the draw circle tool after each use and then state defaults back to the default map navigation (pan). Another problem is if the user trys to change the map action or map navigation state (by selecting another component that does so), during the middle of component use, bad things happen. One of the reasons for this is that I didn't want to make changes to the core by adding custom events, etc. However, I am hopeful that I can improve this without making changes to the core and will look into it.
  • Improvement can be made to the tweet results listing (links to profile, user timeline, etc...).
  • Alot of other testing needs to occur as well. Just running out of time right now.

Wednesday, July 1, 2009

Keeping Your Grass Green (with little water)

This is an odd post and intended for all of you who follow this and aren't geogeeks (sorry nerds but this might interest you as well). This advise is for people with Kentucky Bluegrass lawns (Colorado). So many people have asked me how I keep my grass so healthy and claim I water like crazy. In fact, I am a huge conservationist and try to minimize waste. I promise I have only watered 3 times this year (as of July 1st, 2009). Here is a pic.

Granted, it was a wet Spring for us but I am certain these techniques still apply. Here is the secret:

  • First, assuming you have a lawn with a good foundation and good drainage (nice organics) and it is established, you need to fertilize. This is critical. I use all organic fertilizers. Once a month (more like 1 1/2 months), I apply:
    ---2 parts Richlawn Turffood Pro
    ---1 part Revive granules (kind of expensive but critical)

    I mix these up and apply with a standard spreader. I will leave the amounts to you based or your square footage. It is also critical that you apply the Fall season version of Richlawn in October.
  • Secondly, please mulch. Most modern mowers can mulch. If you don't have one, get one. Bagging grass is a tragedy. You are filling landfills with unneeded waste and the mulch actually helps the sod maintain hydration and ensures that it requires less fertilizer given that you are replenishing the nutrients. One issue is that you will have to mow more often (maybe twice a week if the grass is growing crazy). You can't mulch if your grass is too long.
  • Finally, you must integrate organic material into the subsurface before you lay sod. This is hard to do if you already have a mature landscape but worth mentioning. This means rototilling at least 4 inches of nice organic material into the crappy clay (Typical in Colorado).
That is about it. A couple of items worth mentioning: First, you will have to do this for a couple of years before your lawn responds, don't expect it to respond overnight. You need to train it. Secondly, don't water too much. Kentucky Bluegrass is very drought tolerant if you let it be. If you water too much, it will use the water. Stress it a bit.

Thursday, June 18, 2009

Webmap of US Oil and Gas Production

The USGS Energy Resources Program recently upgraded the US Oil and Gas Production map service for use in their new web mapping platform called Envision which is based on the ArcGIS Server Sample Flex Viewer. The ERP is actively updating the system to deliver all legacy map services and has recently upgraded the US Oil and Gas Production map (By Laura R.N. Biewick USGS DDS 69-q)

Friday, June 12, 2009

Interesting MTB Routes (South Denver)

I have been a recreational MTB cyclist for a long time. Some of my buds are crazy in the cycling world (http://twitter.com/skinnerchris) but I never could get into it at that level. Not knocking it because guys like @skinnerchris can ride freakishly. Its just not in my DNA.

Anyhow, check out a couple of these routes. These are by no means my favorites but represent those that are not mentioned online much. My favorites have been ridden like mad and have been documented well.

Route 1: In Highlands Ranch. Brand new trails. Not much climbing. Not many people. Smooth, non-technical, leisurely (Hope this crappy GM works. Should show actual trail).

View hr route 1 in a larger map


Route 2: Private property (residents only). Great range. Technical, climbing, private. Got to have an "in" to use these particular trails. Heavy Security by local rangers.



View Ranch Loop in a larger map

Monday, June 1, 2009

ArcGIS Server Sample Flex Viewer: Adding ArcIMS Image Map Service Support

Adding ArcIMS image map service support to the Sample Flex Viewer (SFV) is rather simple and handy for those of you who might have loads of legacy services that might not make the AGS migration any time soon. It is simply a matter of extending the ConfigManager class and MapManager class. You will then need to make a slight modification to any ArcIMS elements in the config.xml file.



Extend the ConfigManager class by adding the following:



//map

var configMap:Array = [];

var mapserviceList:XMLList = configXML..mapservice;

for (i = 0; i < mapserviceList.length(); i++)

{



var msLabel:String = mapserviceList[i].@label;

var msType:String = mapserviceList[i].@type;

var msVisible:Boolean = true;

if (mapserviceList[i].@visible == "false")

msVisible = false;

var msAlpha:Number = 1;

if (!isNaN(mapserviceList[i].@alpha))

msAlpha = Number(mapserviceList[i].@alpha);


//retrieve newly added arcims service host attribute from map service entry

var msHost:String = mapserviceList[i].@host;

var msURL:String = mapserviceList[i];


var mapservice:Object =

{



label: msLabel,

type: msType,

visible: msVisible,

alpha: msAlpha,

url: msURL,



//add newly added host attribute to mapservice object for ArcIMS Map Services

host: msHost



}


configMap.push(mapservice);



}


Continue by extending the MapManager class as follows:


for (i = 0; i < configData.configMap.length; i++)

{



var label:String = configData.configMap[i].label;

var type:String = configData.configMap[i].type;

var url:String = configData.configMap[i].url;

var visible:Boolean = configData.configMap[i].visible;

var alpha:Number = Number(configData.configMap[i].alpha);



//new variable for collecting host attribute for arcims services

var host:String = configData.configMap[i].host;



switch (type.toLowerCase())

{



case "tiled":

{



var tiledlayer:ArcGISTiledMapServiceLayer = new ArcGISTiledMapServiceLayer(url);

tiledlayer.id = label;

tiledlayer.visible = visible;

tiledlayer.alpha = alpha;

map.addLayer(tiledlayer);

break;



}

case "dynamic":

{



var dynlayer:ArcGISDynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer(url);

dynlayer.id = label;

dynlayer.visible = visible;

dynlayer.alpha = alpha;

map.addLayer(dynlayer);

break;



}

case "arcims":

{



var arcimslayer:ArcIMSMapServiceLayer = new ArcIMSMapServiceLayer(host,url)

arcimslayer.id = label;

arcimslayer.visible = visible;

arcimslayer.alpha = alpha;

arcimslayer.imageFormat = "jpg"

map.addLayer(arcimslayer);

break;



}



}

}

The entry for the config.xml file would then be something like this:

<mapservice label="2008 Province 31 Assessment" type="arcims" visible="false" alpha="0.7" host="http://certmapper.cr.usgs.gov">prov31_2000</mapservice>

where the value of the element is the map service name. One thing to keep in mind with this is that some of the FLEX api features are not supported for ArcIMS image map services including the identify task. There is also some info on this in the ESRI user forums that may also be helpful.



Wednesday, May 13, 2009

AIR/Flex vs. Silverlight Debate

Now that the ArcGIS Server development platform has finally come of age, many are asking: which platform do I use? There are a number a criteria that enter into this equation and I think others have done a good job of defining these so I will not be discussing them here. The intent of this post is simply to provide you with some of the resources I have found that evaluate at least the 2 RIA platforms ESRI is now providing: Flex and Silverlight. There is alot of chatter/bashing going on and it is often hard to sift through some of the biases so the following are the most resent/unbiased postings I could find. For what its worth, I think they are both great and good for one another. The harder they compete, the better off we all are. Heck, I hope we even start discussing JavaFX in the near future.

The Battle for the RIA Throne: Flex vs. Silverlight
Flash vs. Silverlight: What Suits Your Needs Best?
Video: Air/Flex Silverlight Debate: MS and Adobe evangelists go head to head.