Archive for February, 2010

Custom Dynamic POIs in Flex 3.5 & MapQuest API

February 23, 2010

Recently, I had a fun problem to work on with our homegrown mapping application.  I wanted to create a POI that would bring multiple images together to create an icon on-the-fly so we didn’t have to make two or three dozen of them.  Normally you just embed a custom image to use as an POI icon.  Well, with all the type of things we might add to an icon it could cause the swf to get very large and the icons to become unmanageable.  You can think of it as if you were going to show a radio station on your map.  Perhaps you want to have a pretty little FM or AM graphic on it depending on the type of station.  Well you would have to make two or three graphics to make sure you get all the combinations traditionally.  Then embed those graphics into the system.  This way we have three seperate graphics and they are smaller in file size so they don’t add as much weight to the application.  In short, think of it Photoshopping with code.

So here comes the How-to. It seems pretty simple now that I am writing it, but it was a little bit of a pain to figure it out. In English what I want to do is bring in the image as a class, turn it into a Bitmap then get the Bitmap-Data out of it. Call Merge on Bitmap data and pass in the proper information and get back some new Bitmap data. We will then turn that into a Bitmap and put is into a Map Icon.

/*We can set this as a class/global variable so the functions know what kind of multiplier we need. This is just a number to know how much the merge should combine the two images*/

private var mult:uint = 0xff; //
private function createPoiBitmap(mainPoi:Bitmap,initials:String,fontSize:Number = 10):Bitmap
{
//this is the main graphic for the POI that I need to get.
var bmdMainPoi:BitmapData = mainPoi.bitmapData;
//this is the bitmap that will house the whole picture.
var holder:BitmapData = new BitmapData(45, 34, true, 0X00000000);
//this is the main POI that got pulled

//this is the rectangle placement and size it will pull from the bitmap

var rectItm:Rectangle = new Rectangle(3, 4, bmdMainPoi.width - 7, bmdMainPoi.height);

var ptItm:Point = new Point(8, 9);//this is the point at which the merged item will be placed.

if(initials.length > 0)

{

//this is initial badge that we need to put on

var bmdBadge:BitmapData = getBadgeWithText(initials,fontSize).bitmapData;

//this is the name badge that was made. //this is the rectangle placement and size it will pull from the bitmap

var rectBadge:Rectangle = new Rectangle(0, 0, bmdBadge.width -1, bmdBadge.height - 1);

var ptBadge:Point = new Point(13, 0);//this is the point at which the merged item will be placed.

//add the new items to the holder image

holder.merge(bmdBadge,rectBadge,ptBadge,mult,mult,mult,mult);

}

holder.merge(bmdMainPoi,rectItm,ptItm,mult,mult,mult,mult); //make the holder image a bitmap and add it to the screen var bm1:Bitmap = new Bitmap(holder); return bm1; }
The following piece of code is actually adding the Text into the image. It is going to load up an object that I am caching so it doesn’t have to build it every time. I took out that if statement so you could see how it works.

private function getBadgeWithText(initials:String,fontSize:Number = 10):Bitmap
{
var object = getMyObject(); //this gets me a custom object so i can get and set bitmaps
var bmdInitbadge:BitmapData = object.getEmptyBadge().bitmapData;
var textitm:BitmapData = new BitmapData(10, 30, true, object.getBackgroundColor());
var txtFrmt:TextFormat = new TextFormat('Arial',fontSize,0xFFFFFF);
var uit:UITextField = new UITextField();
uit.background = true;
uit.backgroundColor = object.getBackgroundColor();
uit.text = object.getInitials();
uit.setTextFormat(txtFrmt);
var textBitmapData:BitmapData = ImageSnapshot.captureBitmapData(uit);
var rectText:Rectangle = new Rectangle(3, 3, 14, 10);
var ptText:Point = new Point(8, 7);//this is the point at which the merged item will be placed.
textitm.merge(textBitmapData,rectText,ptText,mult,mult,mult,mult);
bmdInitbadge.merge(textBitmapData,rectText,ptText,mult,mult,mult,mult);
var bmReturn:Bitmap = new Bitmap(bmdInitbadge);
object.setCompletedBadge(bmReturn);
return object.getCompletedBadge();
}

At this Point another function that called all this can set the Bitmap into the MapIcon

var icn:MapIcon = new MapIcon();
icn.setImage(createPoiBitmap(getMainIcn(),"ME",10));

Cygwin and SVN—friends at last

February 23, 2010

I’m kind of a CLI junky. Ironically, I prefer command line over GUI for its simplicity (that and I haven’t found a pointing device I care to use). In a Windows world, short of setting up an ssh server, this pretty much leaves me with Cygwin or PuTTYcyg (no, cmd.exe doesn’t count for anything).

The problem

When we upgraded to Subversion 1.5 (and now 1.6), I started running into problems with the new interactive conflict management. I prefer not to use it, but occasionally forget to add the --non-interactive flag to my commands.

The Dos emulator handled this just fine, but Cygwin would lock up. With PuTTYcyg, I can ctrl-C to at least get my prompt back. Then I have to svn cleanup. Sometimes this can bork your svn meta data beyond what ‘cleanup’ can fix. There are few things more frustrating than spending good development time on fixing your development environment.

The Solution

It turns out, you can disable interactive-conflicts by default by modifying your Subversion client’s config file. On Windows, this is %APPDATA%\Subversion\config (“$APPDATA/Subversion/config” for PuTTYcyg users).

Because I started with svn 1.1, the commented options in my config were outdated so I did the following to get a fresh one:

rm "$APPDATA/Subversion/config"
svn --version

Any subversion command will (re-)create a default config file.
Finally, I just uncommented the following line:

# interactive-conflicts = no

Now I can run SVN in my CLI of choice with no worries of losing time to repairing my local code check-out.

UPDATE: svn/cygwin now happily interactive

A colleague of mine suggested simply installing svn through the cygwin package management (i.e. re-run cygwin’s setup.exe). After doing so, I can interact with svn through local puttcyg just as I would through normal ssh. (Among other things, I no longer have to worry about my credentials being echoed when svn prompts me for authentication!)