Chicago

Photo by Mihai Iacob for the 2010 National Geographic Photography Contest,

chicago, photography by Mihai Iacob, 2011 National Geographic Photography Contest

I happened to be in the right place at the right time when I took this picture. The place was Nichols Bridgeway leading to The Modern Wing of The Art Institute of Chicago, with beautiful views of downtown Chicago, while the time was sunset. I love the architecture, the vibrant city life and the light, all captured in the same frame.


The last IPv4 blocks

A somewhat historic moment, the last IPv4 blocks were allocated to regional registries last week. We now move to IPv6 or the internet stops growing (well, sorta, putting aside things like virtual hosting, NAT, etc.).

last IPv4 blocks allocated


Web safe fonts

Despite growing @font-face support, it’s still useful to know which fonts are web safe.

This very cool chart was made by Dustin Brewer,

web safe fonts

Tahoma is missing from the table. I think it’s up in the air whether or not it’s web safe. It’s shipped with all versions of Windows since Windows 95 and ships with OS X 10.5 (Leopard) and higher, but on Linux you generally won’t find it – it’s not installed by default and not part of the msttcorefonts package. However, a fallback to the similiar, but wider, Verdana may be acceptable.


Rtf2Html 1.22

New stuff:

  • UI tweaks
  • Removal of block indent (where every line is indented) from pasted RTF text
  • Tweaks for better HTML output (e.g. no more useless span tags containing only whitespace)
  • Accurate preview using XULRunner (via GeckoFX); no longer using the stupid .NET WebBrowser control
  • New logo/icon (I just really hated the old one I made and it was bugging the hell out of me)

Rtf2Html logo

Download here
(requires .NET Framework 2.0 or higher)

Rtf2Html screenshot

The app was designed around the goal of being able to quickly copy and paste snippets of code from Visual Studio (or Netbeans) and turning it into HTML that I could embed in these blog posts; this update stays true to that, and that’s why this app is still so sparse on features, such as conversion of font size or paragraph alignment attributes.

The block indentation removal that now occurs after text is pasted in may be a bit slow. Text in the RichTextBox is selected and altered within the text box itself (it’ll also freeze the UI – if you understand multithreading and WinForms, you know why it’s not simply a matter of spawning off a thread). The alternative is to deal with an RTF parser and edit the RTF input directly, but that’s way more work than I’d care to devote to this app at the moment.


Launching a Mono/.NET exe from Adobe Air

I’m working on some bridging code between Adobe Air and Mono/.NET stuff. The first challenge in the process was figuring out how the launch the .exe from Adobe Air. In Windows you can just launch the .exe file (assuming the .NET Framework is installed), but for other system you need to pass it as an argument to the mono executable. The JavaScript code is shown below.

var proc = new air.NativeProcess();
if
(air.Capabilities.os.toLowerCase().indexOf("win") > -1) {
    
var file = air.File.applicationDirectory;
    file = file.resolvePath(
"air.SocketBridgeServer.exe");
                            
    
var nativeProcessStartupInfo = new air.NativeProcessStartupInfo();
    nativeProcessStartupInfo.executable = file;

    proc.start(nativeProcessStartupInfo);
}
else {
    
var mono = new air.File();
    mono = mono.resolvePath(
"/usr/bin/mono");
                            
    
var exeFile = air.File.applicationDirectory;
    exeFile = exeFile.resolvePath(
"air.SocketBridgeServer.exe");
                            
    
var args = new air.Vector["<String>"];
    args.push(exeFile.nativePath);
                            
    
var nativeProcessStartupInfo = new air.NativeProcessStartupInfo();
    nativeProcessStartupInfo.executable = mono;
    nativeProcessStartupInfo.arguments = args;
    proc.start(nativeProcessStartupInfo);
}

This handles Windows, OS X, and should handle most distros of Linux; the location of the mono executable is the tricky part, Adobe Air doesn’t read the path environment variable, so the exact location of mono must be specified. mono is usually in /usr/bin, but custom distros, installations, etc. could put it elsewhere.


NYC yum yum

NYC yum yum is my web app for the NYC Big Apps 2.0 competition.

NYC yum yum

It’s a very simple app for quickly finding restaurants by cusine + location. For each resturaunt, it shows the restaurant inspection grade, to give you an idea of how clean and safe the food at the establishment is, and also pulls the Yelp star rating to give you and idea of how good the food is.

NYC yum yum front page

NYC yum yum results

Search by cuisine and location (specifically, neighborhood) I felt was really important. Searching by name is, of course, much simpler, but when it comes to finding a new restaurant your likely not to know the name beforehand. Even if you have been to the restaurant before, unless it’s a regular spot for you, you’d likely still has issues remembering the name given the number of places to eat in New York City.

That said, this was far more difficult than I anticipated and I’m sad to say the current implementation is far from ideal. Here’s why:

  • The raw data set from the NYC Data Mine contains no geographic coordinates (latitude, longitude), so to get an accurate location, the address must be geocoded. There are a number of services to do this, but they’re all pretty limited. Google’s Geocoding API was my first choice, but I was wary of the terms of use,

    … the Geocoding API may only be used in conjunction with a Google map; geocoding results without displaying them on a map is prohibited. For complete details on allowed usage, consult the Maps API Terms of Service License Restrictions.

    My second choice was geocoder.us, but it had issues geocoding locations outside of Manhattan. So I put aside the idea of doing a geocode.
  • My next attempt was to do queries by neighborhood. Surely, it would be easy to translate between neighborhoods and zip codes, right?! Nope. All I could find were commercial services (e.g. maponics) that did it, and I wasn’t willing to go down that road.
  • My final attempt and what’s implemented, is grabbing the zip code from the the marker location on the google map. This sorta works. The problem is that the area covered by a zip code doesn’t necessarily match up exactly with a neighborhood’s boundary. So a restaurant that may not be shown in the search if it falls into an adjacent zip code.

My big disappointment is how restrictive and inaccessible all of this geographic data is, and the lack of such data severely compromises the effectiveness of the search.

Another, somewhat major issue with the raw data set is how restaurants are categorized. I’m noticing tons of establishments are simply identified with the cuisine type of “American.” For example, B Cup is a café in the East Village. If I was looking for it, I would search for “Café/Coffee/Tea” not “American.”

NYC yum yum

In fact, I think “American” is way to generic to describe any sort of cuisine.

In any case, NYC yum yum still works pretty well and does hit of the target of being able to find good, clean places to eat at, quick and easily. I’ll likely be working on improvements to it in the near future.

Edit: mixed up geocoding and reverse geocoding


Old school

Came across this while clearing out some old stuff from my bookshelf,

visual basic 3.0 programmer's guide


jQuery toggle button

On most of the mobile platforms you’ve probably seen a toggle, switch-style, button used as a replacement for a checkbox. I took a stab at doing something similar in HTML, CSS and Javascript.

toggle button

You can see the final result here (it’s a pain in the ass to embed it)

Note that while I used jQuery, this is not a jQuery extension. It doesn’t use that much jQuery and I really don’t get the desire to make everything-and-the-kitchen-sink a jQuery plugin.

The button depends upon 2 images, a base, containing the design and both states of the button:

toggle button base

… and a frame (optional if you can get away with using CSS borders):

toggle button frame

(note, the middle is transparent, not white)

The HTML and CSS consists of a:

  • A div, which has the its background-image set to the base and sized to the button’s inner area, roughly half the width (in this case, plus a few pixels as some pixels were shared by both states of the button) of the base and the same height
  • A block-level anchor element within the div, which has its background-image set to the frame and sized to the same area as the frame image. The anchor allows the area to be clickable and we’ll respond to the click event that occurs on this element.
  • An input checkbox which will store the checked/unchecked state of the button.
<div style="margin:0; padding:0; background:url(base.png) -41px 1px no-repeat transparent; width:46px; height:20px;">
<a class="toggle-button" href="#" style="margin:0; padding:0; display:block; background:url(frame.png) 0 0 no-repeat transparent; width:48px; height:20px;">
<input style="display:none;" type="checkbox" />
</a>
</div>

The Javascript code to handle the click event, where the background is shifted left or right when the button’s state is toggled using jQuery’s animate function,

$('.toggle-button').click(function ()
{
if (!$('input', this).is(':checked')) {
$(
this).parent().animate({ "background-position": "0px 1px" }, "slow");
$(
'input', this).attr('checked', true);
}
else {

$(
this).parent().animate({ "background-position": "-41px 1px" }, "slow");
$(
'input', this).attr('checked', false);
}

return false;
});

This all works great, but it’s not-so-great as a reusable component, so I encapsulated the code so that I could easily transform a div, such as the one shown below, into the toggle button.

<div id="my_toggle_button"></div>

Central to this is creating a ToggleButtonFactory, which will make the button by inserting the necessary HTML/CSS code into the DOM and bind the anchor to the click event. There’s also a ToggleButton object created by the factory which will have methods to toggle the button state (.toggle) and get the state of the button (.val).

function ToggleButton(_element, _funcSelectYes, _funcSelectNo)
{
this.jqDomElement = _element;
this.funcSelectYes = _funcSelectYes;
this.funcSelectNo = _funcSelectNo;

this.val = function ()
{
return $(this.jqDomElement).find('input').is(':checked');
}

this.toggle = function (funcSelectYes, funcSelectNo)
{
if (!this.jqDomElement.find('input').is(':checked')) {
this.jqDomElement.animate({ "background-position": "0px 1px" }, "slow");
this.jqDomElement.find('input').attr('checked', true);

if (this.funcSelectYes) {
this.funcSelectYes();
}
}
else {

this.jqDomElement.animate({ "background-position": "-41px 1px" }, "slow");
this.jqDomElement.find('input').attr('checked', false);

if (this.funcSelectNo) {
this.funcSelectNo();
}
}
}
}

var ToggleButtonFactory = {};
ToggleButtonFactory.makeButton =
function (element, initialState, funcSelectYes, funcSelectNo)
{
if ($(element).is('div')) {

var elemId = $(element).attr('id');
var newDivId = '__toggle_button_div_' + Math.ceil((Math.random() * 100000));
$(element).replaceWith(
'<div id="' + newDivId + '" style="margin:0; padding:0; background:url(base.png) -41px 1px no-repeat transparent; width:46px; height:20px;"><a class="toggle-button" href="#" style="margin:0; padding:0; display:block; background:url(frame.png) 0 0 no-repeat transparent; width:48px; height:20px;"><input id="' + elemId + '" name="' + elemId + '" style="display:none;" type="checkbox" /></a></div>');

var newElem = $('#' + newDivId);
var tb = new ToggleButton(newElem, funcSelectYes, funcSelectNo);

newElem.find(
'a').click(function ()
{
tb.toggle();
return false;
});

if (initialState) {
tb.toggle();
}

return tb;
}
}

Note there’s some additional code here to deal with setting the button to an initial state and callbacks for when the button is set to the “Yes” or “No” state.

Now, to transform the my_toggle_button div shown above into a toggle button, the following is done:

var btn = ToggleButtonFactory.makeButton('#my_toggle_button', false, function () { }, function () { });

(the call can be shorter, this shows calling with all arguments and capturing the return value [the ToggleButton object])

For another take on this, see the jQuery LightSwitch plugin.


Paper Half-Life 2

Incredibly impressive,


poly2path

I’m working on a little SVG project using Raphaël. Unfortunately, Illustrator exports polygons in its SVG output which is not supported by Raphaël (only paths are supported). So I wrote an app to convert the SVG polygon string to an SVG path string.

Download Here

the conversion…

poly2path conversion

Note that you only input the points data from the polygon (from the points attribute), not the entire polygon element. The result is the path string for the d attribute of the path element.

The conversion is very simple and based upon the fact that a polygon is a path starting with an absolute moveto, linetos to each of the points, and a closepath (this bug report [yes, a bug report!] was pretty helpful).

I actually wanted to render the output, but I was disappointed to discover that Adobe Air doesn’t currently support SVG.

The main reason for not including it was runtime size concerns (adding it would have increased the runtime size by 15 to 20 percent). Initially, the main pain-points regarding AIR were the size of the runtime, integration with the operating system and native APIs, support for the <canvas> tag and new CSS properties, and JavaScript performance. These priorities, coupled with a trend toward reduced interest in SVG graphics, led to SVG support not being included in the current version of Adobe AIR.