Friday, February 4, 2011

Resume

Alex Egg
San Diego, Ca

eggie5@gmail.com

Work Experience

Qualcomm (Tapioca Mobile), Software Engineer, June 2010 -- Current

Developing Tapioca's applications and systems to deliver video content to mobile devices.

  • Application and feature development in ruby
    • Send MMS and SMS messages though aggregator
    • Various features (mostly ruby work/some nodejs)
  • Expanding infrastructure - build out DB replication segmented giant web app into smaller pieces
  • Part-time during school

2 year break in Korea

Tapioca Mobile, Software Engineer, May 2007 -- May 2008

Developing Tapioca's applications and systems to deliver video content to mobile devices.

  • Developed system to send and receive millions of SMS/MMS messages
  • Developed system to transcode thousands of videos to work on any mobile handset
  • Test Driven Development - small agile team - Ruby on Rails
  • Integration with multiple detached systems via REST API
  • See: www.msnack.com    www.tapiocamobile.com

AComm Inc., Software Engineer (Contract), Jan 2007 -- May 2007

Defense industry start up. Helped with hardware/software integration - USB development (C#, C)

Cubic Defense Inc., Software Engineering Intern, Summer 2006 – Jan 2007

8/2006-1/2007, Software Engineer, Hardware/Software Integration

  • Ported USB 2.0 Xilinx FPGA interface software (see Signum Concepts) to the Pocket PC platform.
  • Enabling soldiers to run the software in the field with a small/light instead of full laptop or at a desktop station. (C#, .Net Compact Framework)
  • Developed 3D real time emulator of physical helicopter hardware – takes X, Y, Z input from via
  • USB 2.0 interface. (DirectX & C#)
  • Reused above USB 2.0 class library to interface weather station hardware. (C#)

Helped developed custom solutions enabling engineers to interface hardware via custom UIs
within Windows. This streamlined and enabled real time configuration of hardware which was previously done via tools not designed directly for that purpose. Helped bridge the gap between Cubic manufactured hardware and the computer/software world.


Qualcomm Inc., Software Engineering Intern, Summer 2005 – Summer 2006

4/2006-8/2006, Lead Software Engineer, User Interface Development

  • Envisioned and chartered user interface client for console-based internal testing software
  • Led a small team of intern engineers through technical design and implementation of client(Java).
  • Served as one of the first engineers on the project, from initial design through launching the beta and eventually division-wide release.
  • Boosted use of testing by 40% internally, due to ease of use (this is just my own estimate). Users were no longer scared away by console window, which old version of software was based.

6/2005 – 9/2005, Software Engineer, Internal Testing Framework: Enchantments

  • Lead the enhancement effort of internal testing/build framework and successfully made numerous code releases. Enhancements included the addition of HTTP and HTML testing ability which automated testing of the Qualcomm BREW content system. Required knowledge of HTTP protocol along with HTML and cross browser rendering intricacies. Code required to be cross-platform compatible, i.e. Windows and Linux support. (Java, Ant)
  • Provided support for internal company-wide users and groups, while brainstorming w/ teams for new product enhancements.
  • Lead group-wide effort in rewriting software to support the full range of Unicode encodings.
  • Member of the testing and automation team, which among other things developed and maintained the division’s internal software build process. Specifically, responsible for addition of new features to the internal build system’s xUnit automated testing framework. Also responsible for providing support to various internal users and groups, while spearheaded an effort to make group-wide software Unicode aware and friendly.

Wireless Personal Multimedia Communications Symposia (Volunteer), Lead Web

Developer/Designer, Fall 2005 – Present

  • Lead Developer/Designer responsible for annual wireless conference’s website from design to implementation, including development of custom automated paper submission/revision system. (C#/ASP.NET, Javascript)
  • Worked closely and meet weekly with conference committee and sponsors: Nokia, Qualcomm, Wiley Publishing, NiCT and YRP.
  • Received over 100 hits/day (during conference duration) and over 600,000 this year alone.
  • Large call for papers response: Over 400 papers submitted (all managed by said paper system)
  • http://www.wpmc2006.org
  • Donated source code to WPMC 2007, India

Nokia (formally Tourmaline Networks), Software Engineering Intern, Summer 2004

7/2004-9/2005, Software Engineer, Business Metrics Application


  • From design to implementation lead the development of an in house user metrics application used to display sales information from a rich user interface.
  • Sales data – from “raw XML” monthly-generated database files – was parsed/processed and displayed graphically in easy to digest charts and tables. (C#/ASP.NET) Helped company realize strengths/weaknesses in their current model. For example, users were not purchasing full application after trying demo, i.e. full version was too expensive.

5/2004-7/2004, Software Engineer, Automated Testing Solution (C#, BREW SDK)

  • Responsible for the development of automated testing solution of mobile phone BREW applications. Tests cases executed though rich user interface automatically, effectively eliminating human testing and keeping interaction to a minimum.
  • Developed custom interface code to emulate button presses on handsets to use with above testing software via USB or Serial. Note: This was before the release of the BITL SDK from Qualcomm (C#, Perl, C++)
  • Exposed various previously undiscovered product bugs. Example: Discovered bug in email software where user entered non-ASCII characters in the message body would cause handset to power cycle.

Tourmaline Networks (before Nokia’s acquisition) was a private ISV developing email suites for the Qualcomm Brew Platform. Tourmaline Networks was in need of a comprehensive testing solution to ensure the quality and features of released products. Tests had to be run nightly and provide easy customization for non-technical employees. Their needs were achieved through the development of an easy-to-use user interface to the testing system and one-on-one collaboration with the other developers on my team.

Signum Concepts Inc., Software Engineering Consultant, Present

  • Design and implementation of Xilinx Vertex 2 Pro FPGA to USB 2.0 interface on a software radio implementation. Including development of rich user interface for real time radio configuration via USB. (C#)

Education

  • Undergraduate (Sophomore) of Computer Engineering, San Diego State University
  • William E. Jr. Leonhard Endowment Engineering Scholarship

Skills

  • Speak Korean proficiently
  • Proficient in: Ruby, Javascript, C#, Java, VB.NET, C, ASP.NET, Databases
  • Proficient in: .Net Framework/Compact Framework, Windows API, BREW SDK
  • Experience in: User Interface Development, Windows Development, Web Development
  • Experience in software to hardware interfacing in Windows, USB software implementation
  • Experience in Agile/XP software engineering methodologies

Conferences

  • Organizing committee member, Wireless Personal Multimedia Symposium, 2006 – La Jolla, Ca.
  • Attendee, Qualcomm BREW Conference 2006 – San Diego, Ca.

Monday, February 26, 2007

AJAX Safe HTML Forms

Whenever you create a form on a HTML page it's easy to make it AJAX safe. All you have to do is call your ajax form submission code in the forms onsubmit event and specify the standard postback address in case the ajax fails or the user doesn't have javascript support. Use this template:

<form action="servercode.aspx" onsubmit="return ajax submit()">
...
.
.
.

function ajax_submit()
{
// if ajax submission successfull
return false;

//else if ajax submssion failed
return true;
}

So if the ajax postback to the server was successful post back to the action URL will not take place. Hence, if you pass false to onsubmit, the form will not postback. However if you return true to onsubmit the form will do a traditional post back.

In conclusion, since we only return false if the ajax action was successful the program degrades gracefully to a traditional post back. That is an ajax safe html form!

Saturday, February 10, 2007

Creating Custom Controls for Google Maps

With the release of the Google Maps API, usage of the fantastic framework Google has laid is now possible. Fueled by the easy to use, highly abstracted and well documented API, customized versions of Google Maps are running all over the Internet. With the API it is possible to create custom effects, tools, data, etc. for your map -- basically, the possibilities are endless because you have access to the whole world of the Javascript language. This article will show how to create a custom control for google maps, which will allow a user to click and drag a rectangle over a selected area on the map which will then be centered on and magnified.

What is a Google Maps Control?

While there is no specific definition of a maps API control per se, however basically a control is this: some tool ("control") that is displayed in the google maps window and provides some custom functionally that doesn't come with the maps API. Technically, a control is anything that implements the GControl Interface. The maps API already comes with a hand full of helpful controls:
  • GLargeMapControl - a large pan/zoom control used on Google Maps. Appears in the top left corner of the map.
  • GSmallMapControl - a smaller pan/zoom control used on Google Maps. Appears in the top left corner of the map.
  • GSmallZoomControl - a small zoom control (no panning controls) used in the small map blowup windows used to display driving directions steps on Google Maps.
  • GScaleControl - a map scale
  • GMapTypeControl - buttons that let the user toggle between map types (such as Map and Satellite)
  • GOverviewMapControl New! - a collapsible overview map in the corner of the screen
If you've ever used the maps API you should be familiar with at least one of these controls. They are already implemented and included in the maps API, however now, we are going to make our own custom control, that allows the user to click a point on the map and drag a rectangle over and area to another point. This area will then be centered upon and magnified to the appropriate level.

The Hello World of GMaps Controls

As I alluded to above, the most minimal amount of code you have to write to create a true gmaps control is implement the GControl interface.

// base definition and inheritance
function MyCustomControl()
{
}

//Default constructor for GControl
MyCustomControl.prototype = new GControl(false,false);

// Default location for the control
MyCustomControl.prototype.getDefaultPosition = function() {
return new GControlPosition(G_ANCHOR_TOP_LEFT,new GSize(700,8));
};

GControlSelector.prototype.initialize = function(gmapref)
{

var container=gmapref.getContainer();

var c = document.createElement("div");
c.innerHTML="This is a custom control";

container.appendChild(c);

return c;
}


The first function MyCustomControl()is the name of the class and the control, this is your base class for the control. The next block of code simply initializes an instance of the GControl() interface using it's default constructor, so now we must implement all it's required interfaces.

The required members of the GControl interface are:
  • printable() > bool -- Returns to the map if the control should be printable.
  • selectable() > bool -- Returns to the map if the control contains selectable text.
  • initialize(map) > Node -- Will be called by the map so the control can initialize itself.
  • getDefaultPosition() > GControlPosition -- Returns to the map the position in the map view at which the control appears by default. This will be overridden by the second argument to GMap2.addControl().
We already have 2 of these implimented by means of our call to the GControl contstructor which has this signature: GControl(printable?, selectable?). Since we passed false to both the parameters we only need to impliment initialize(map) and getDefaultPosition().

initialize(map) - The purpose of the initialize method is to build the control, i.e. load it's code for use. For, all we are doing in initialize is build the UI, which is a simple div element with some text inside. Once we build the UI we add it the map and return it.
getDefaultPosition() - The purpose of the getDefaultPosition() method is so the maps API knows where to place the control if the user doesn't specify a custom location.

Almost there. Once we have designed our custom control we have one step left, we must add it to the map using the method Gmap2.addControl().

Adding the control to the map

Now we have to add our control to the map, this is the last step of creating your custom control.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example</title>
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=abcdefg"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[

function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.addControl(new MyCustomControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
}
}

//]]>
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>

The above is a stock google maps page. The above highlighted text is all we need to do to use
our new google maps custom control.






Friday, February 9, 2007

The Medium is the Message; The Future of the User Interfaces

Critical comparison of traditional user interface development and web-based user interface development showing how web-based user interfaces are the future

Abstract
HTML is the most perfect medium available today to build user interfaces for software; compiled programming languages are not and are already being matched in complexity and easy of use by their web based (HTML/CSS/Javascript) rivals. Progress in web based UIs is being fueled by the Renaissance of the XMLHTTP Javascript object, or in more commonly, "AJAX". With a web-based front end interface and C#/ASP.net back end connected via asynchronous AJAX calls over broadband Internet connections, the web based user experience is virtually as seamless as their desktop based rivals.

Designing a UI with C#/Java
The process of creating UI elements in a C# applicaiton is reletlivy simple in itself, but the larger context you'll see how it is inheretnly not suited for this task. Also, I will not go deeply into the symantics of C#. Below is a barebones .net 3.0 windows app written in C#:

using System;
using System.Windows.Forms;

namespace alexegg.com
{
class UI : Form
{
static void Main()
{
Application.Run(new UI());
}
}
}



None of the above code actually defines/configures any element of the UI. All it does is tell the C# language, which is not natively designed to build UIs, that we want this class to have a Windows UI. Lets modify the above skeleton C# windows from to look like the below HTML login screen:



I'll save the HTML for this example for later, now let's look at the C# code required to recreate this simple HTML interface:


using System;
using System.Windows.Forms;

namespace alexegg.com
{
class UI : Form
{
private System.Windows.Forms.TextBox textBoxPassword;
private System.Windows.Forms.Button buttonSubmit;
private System.Windows.Forms.PictureBox pictureBoxLogo;
private System.Windows.Forms.Panel panelDialog;
private System.Windows.Forms.CheckBox checkBoxRemember_me;
private System.Windows.Forms.Label labelPassword;
private System.Windows.Forms.Panel panelDialogBorder;

public UI()
{
this.textBoxPassword = new System.Windows.Forms.TextBox();
this.buttonSubmit = new System.Windows.Forms.Button();
this.pictureBoxLogo = new System.Windows.Forms.PictureBox();
this.panelDialog = new System.Windows.Forms.Panel();
this.labelPassword = new System.Windows.Forms.Label();
this.checkBoxRemember_me = new System.Windows.Forms.CheckBox();
this.panelDialogBorder = new System.Windows.Forms.Panel();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxLogo)).BeginInit();
this.panelDialog.SuspendLayout();
this.SuspendLayout();


//
// textBoxPassword
//
this.textBoxPassword.Font = new System.Drawing.Font("Verdana", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxPassword.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(102)))), ((int)(((byte)(102)))), ((int)(((byte)(102)))));
this.textBoxPassword.Location = new System.Drawing.Point(125, 31);
this.textBoxPassword.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.textBoxPassword.Name = "textBoxPassword";
this.textBoxPassword.Size = new System.Drawing.Size(150, 27);
this.textBoxPassword.TabIndex = 0;
this.textBoxPassword.UseSystemPasswordChar = true;
//
// buttonSubmit
//
this.buttonSubmit.Font = new System.Drawing.Font("Verdana", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.buttonSubmit.Location = new System.Drawing.Point(125, 107);
this.buttonSubmit.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.buttonSubmit.Name = "buttonSubmit";
this.buttonSubmit.Size = new System.Drawing.Size(66, 29);
this.buttonSubmit.TabIndex = 1;
this.buttonSubmit.Text = "Sign in";
this.buttonSubmit.UseVisualStyleBackColor = true;
//
// pictureBoxLogo
//
this.pictureBoxLogo.Image = System.Drawing.Image.FromFile("resources\tcs_logo.png");
this.pictureBoxLogo.Location = new System.Drawing.Point(258, 49);
this.pictureBoxLogo.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.pictureBoxLogo.Name = "pictureBoxLogo";
this.pictureBoxLogo.Size = new System.Drawing.Size(106, 107);
this.pictureBoxLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.pictureBoxLogo.TabIndex = 2;
this.pictureBoxLogo.TabStop = false;
//
// panelDialog
//
this.panelDialog.BackColor = System.Drawing.Color.White;
this.panelDialog.Controls.Add(this.checkBoxRemember_me);
this.panelDialog.Controls.Add(this.labelPassword);
this.panelDialog.Controls.Add(this.textBoxPassword);
this.panelDialog.Controls.Add(this.buttonSubmit);
this.panelDialog.Location = new System.Drawing.Point(72, 192);
this.panelDialog.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.panelDialog.Name = "panelDialog";
this.panelDialog.Size = new System.Drawing.Size(475, 162);
this.panelDialog.TabIndex = 3;
//
// labelPassword
//
this.labelPassword.AutoSize = true;
this.labelPassword.Font = new System.Drawing.Font("Verdana", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelPassword.Location = new System.Drawing.Point(25, 35);
this.labelPassword.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.labelPassword.Name = "labelPassword";
this.labelPassword.Size = new System.Drawing.Size(92, 18);
this.labelPassword.TabIndex = 2;
this.labelPassword.Text = "Password:";
//
// checkBoxRemember_me
//
this.checkBoxRemember_me.AutoSize = true;
this.checkBoxRemember_me.Font = new System.Drawing.Font("Verdana", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.checkBoxRemember_me.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(102)))), ((int)(((byte)(102)))), ((int)(((byte)(102)))));
this.checkBoxRemember_me.Location = new System.Drawing.Point(125, 77);
this.checkBoxRemember_me.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.checkBoxRemember_me.Name = "checkBoxRemember_me";
this.checkBoxRemember_me.Size = new System.Drawing.Size(235, 20);
this.checkBoxRemember_me.TabIndex = 3;
this.checkBoxRemember_me.Text = "Remember me on this computer";
this.checkBoxRemember_me.UseVisualStyleBackColor = true;
//
// panelDialogBorder
//
this.panelDialogBorder.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
this.panelDialogBorder.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
this.panelDialogBorder.Location = new System.Drawing.Point(60, 180);
this.panelDialogBorder.Name = "panelDialogBorder";
this.panelDialogBorder.Size = new System.Drawing.Size(500, 186);
this.panelDialogBorder.TabIndex = 4;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(229)))), ((int)(((byte)(229)))), ((int)(((byte)(229)))));
this.ClientSize = new System.Drawing.Size(622, 415);
this.Controls.Add(this.pictureBoxLogo);
this.Controls.Add(this.panelDialog);
this.Controls.Add(this.panelDialogBorder);
this.Font = new System.Drawing.Font("Verdana", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.Name = "Form1";
this.Text = "Login Form";
((System.ComponentModel.ISupportInitialize)(this.pictureBoxLogo)).EndInit();
this.panelDialog.ResumeLayout(false);
this.panelDialog.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}

static void Main()
{
Application.EnableVisualStyles();
Application.Run(new UI());
}
}
}

Below is the respective HTML + CSS for the exact same UI


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Login Form</title>
<style>
#login_container
{
width:100%;
height:700px;
position:absolute;
background-color:#E5E5E5;
z-index:99;
color:#333333;
font-family:"Lucida Grande",verdana,arial,helvetica,sans-serif;
margin:0pt auto;
padding:0pt;
text-align:center;
}
.login div.cont {
margin:60px auto 20px;
min-width:inherit;
width:500px;
}
div#LogoBox {

}
div#LogoBox img {

}
.login div#Dialog {
background:#FFFFFF none repeat scroll 0%;
border:10px solid #CCCCCC;
padding:15px 20px 10px;
text-align:left;
}
form {
margin:0pt;
padding:0pt;
}
.login dl {
margin:10px 0pt 0pt;
}
.login dt {
float:left;
font-size:14px;
line-height:24px;
width:80px;
}
.login dd {
color:#666666;
font-size:11px;
line-height:24px;
margin:0pt 0pt 5px 80px;
}
.login input#password {
margin-right:5px;
width:150px;
}
.login dd span {
color:#CCCCCC;
}
.login input {
font-size:14px;
}
#Flash.bad {
background:#CC0000 url(images/alertbad_icon.gif) no-repeat scroll left center;
border-color:#CC9999;
color:#FFFFFF;
}
.login #Flash {
font-size:12px;
margin-top:12px;
}
#Flash {
border:1px solid #CCCCCC;
font-size:14px;
margin:0pt 7px 12px auto;
padding:5px 5px 5px 30px;
text-align:left;
}
</style>
</head>
<body>
<div class="login" id="login_container">
<div class="cont">
<div id="LogoBox">
<img alt="Time Critical Solutions" src="resources/tcs_logo.png" /></div>
<div id="Dialog">
<form method="post" action=" ">
<dl>
<dt>Password:</dt>
<dd>
<input type="password" id="password" name="password" />
</dd>
<dd>
<input type="checkbox" name="remember_me" />
Remember me on this computer</dd>
<dd>
<input type="submit" value="Sign in" /></dd>
</dl>
</form>
</div>
</div>
</div>
</body>
</html>


Why is the Java community so far behind the C# community in terms of UI Development (An example of why c based language UI development is inherently wrong)
Designing user interfaces with technologies (HTML/CSS/Javascript) designed for information layout make infinitely more sense then designing interfaces with technologies designed for procedural tasks (compiled programming languages). Even with Microsoft Visual Studio Form Designer, one of the most advanced software interface building applications available today, design and development of UIs is awkward and clunky and almost impossible with the automated code emitted from the form builder. This truth is evident when you take a look at the state of UIs in the Java community. SWING/AWT and a few other tools kits available to the Java community are ill suited and largely inferior to Microsoftnulls solution, which is reflected in the lack of UI progression in the java community. This is a direct reflection of how awkward it is to create compelling user interfaces with c based languages. C# and Java are very similar in syntax and functionally, they can be considered cousins, however then why does the .net/C# community have such more advanced and numerous developed UIs? It's not cause one is more suited to develop UIs or that C# has a larger commuinity using it or that C# is older, but that the .net community has the Visual Studio form designer, a powerful tool to create UIs.

A window on a computer is not good for presenting information with a compelling design. With a pixel based layout, you spend more time writing code to get your content int he right place or to display at all, rather then concentrate on the content and if it looks compelling.

Creating rich UIs with c based languages, is simply too hard. For example, if I wanted to show a little emphasis to an element on my web page, I could just make a quick call to the Highlight method in the Prototype library. However, to do this in a programming environment, I'd have to find some class library with that functionally that works with my language/environment or else I'd have to code that from scratch. In the end you decide it's not even worth it for a little UI garnish.

Explore XAML UIs in .net 3.0

test from google docs

Thursday, February 8, 2007

Using Google Maps without API Key, Guide

When you use the Google maps API, you have to get a site key. To get a site key you need to register your website, however, what if you don't even have a website yet and you developing your site locally? If you enter 'http://localhost' into the API key registration form, it will give you a key but don't let this fool you, the maps won't load!

This is an easy problem to alleviate, with a simple one line javascript edit. Let's take a look at the Google Maps hello world example:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example</title>
<script src="http://maps.google.com/maps?file=api&amp;v=2&key=abcdefg"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[

function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
}
}

//]]>
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>

Notice the red line in the above source. This downloads a javascript file from google that acts like a configuration file for your map. Included in it is the code that checks your API key. All we have to do is remove the line that checks and were in action. So, since we need to run the js config file directly, we need to save it to our computer, just enter the line in red into your browser. This is the config file that the script element in your html page points to.

var G_INCOMPAT = false;
function GScript(src) {
document.write('<' + 'script src="' + src + '"' + ' type="text/javascript"><' + '/script>');
}
function GBrowserIsCompatible() {
if (G_INCOMPAT) return false;
if (!window.RegExp) return false;
var AGENTS = ["opera", "msie", "safari", "firefox", "netscape", "mozilla"];
var agent = navigator.userAgent.toLowerCase();
for (var i = 0; i < agentstr =" AGENTS[i];" versionexpr =" new" version =" 0;" version =" parseFloat(RegExp.$1);" agentstr ="=">= 7;
if (agentStr == "safari") return version >= 125;
if (agentStr == "msie") return (version >= 5.5 &&amp;amp;amp;amp;amp; agent.indexOf("powerpc") == - 1);
if (agentStr == "netscape") return version > 7;
if (agentStr == "firefox") return version >= 0.8;
}
}
return !!document.getElementById;
}
function GVerify() {
}
function GLoad() {
if (!GValidateKey("")) {
G_INCOMPAT = true;
alert("The Google Maps API key used on this web site was registered for a different web site. You can generate a new key for this web site at http://www.google.com/apis/maps/.");
return;
}
GLoadApi(["http://mt0.google.com/mt?n=404&v=w2.37&amp;amp;amp;amp;amp;", "http://mt1.google.com/mt?n=404&v=w2.37&", "http://mt2.google.com/mt?n=404&v=w2.37&", "http://mt3.google.com/mt?n=404&v=w2.37&"], ["http://kh0.google.com/kh?n=404&v=14&", "http://kh1.google.com/kh?n=404&v=14&", "http://kh2.google.com/kh?n=404&v=14&", "http://kh3.google.com/kh?n=404&v=14&"], ["http://mt0.google.com/mt?n=404&v=apt.36&", "http://mt1.google.com/mt?n=404&v=apt.36&", "http://mt2.google.com/mt?n=404&v=apt.36&", "http://mt3.google.com/mt?n=404&v=apt.36&"], "", "", "", false);
if (window.GJsLoaderInit) {
GJsLoaderInit("http://maps.google.com/mapfiles/maps2.72.api.js");
}
}
function GUnload() {
if (window.GUnloadApi) {
GUnloadApi();
}
}
var _mFlags = {
}
;
var _mHost = "http://maps.google.com";
var _mUri = "/maps";
var _mDomain = "google.com";
var _mStaticPath = "http://www.google.com/intl/en_us/mapfiles/";
var _mTermsUrl = "http://www.google.com/intl/en_us/help/terms_local.html";
var _mTerms = "Terms of Use";
var _mMapMode = "Map";
var _mMapModeShort = "Map";
var _mMapError = "We are sorry, but we don\'t have maps at this zoom level for this region.

Try zooming out for a broader look.

";
var _mSatelliteMode = "Satellite";
var _mSatelliteModeShort = "Sat";
var _mSatelliteError = "We are sorry, but we don\'t have imagery at this zoom level for this region.

Try zooming out for a broader look.

";
var _mHybridMode = "Hybrid";
var _mHybridModeShort = "Hyb";
var _mSatelliteToken = "fzwq2rajrYBh2hw6LvGp_HbYvCkqeQX6J9W0Jg";
var _mZoomIn = "Zoom In";
var _mZoomOut = "Zoom Out";
var _mZoomSet = "Click to set zoom level";
var _mZoomDrag = "Drag to zoom";
var _mPanWest = "Pan left";
var _mPanEast = "Pan right";
var _mPanNorth = "Pan up";
var _mPanSouth = "Pan down";
var _mLastResult = "Return to the last result";
var _mMapCopy = "Map data ©2007 ";
var _mSatelliteCopy = "Imagery ©2007 ";
var _mGoogleCopy = "©2007 Google";
var _mKilometers = "km";
var _mMiles = "mi";
var _mMeters = "m";
var _mFeet = "ft";
var _mPreferMetric = false;
var _mPanelWidth = 20;
var _mTabBasics = "Address";
var _mTabDetails = "Details";
var _mDecimalPoint = '.';
var _mThousandsSeparator = ',';
var _mUsePrintLink = 'To see all the details that are visible on the screen,use the "Print" link next to the map.';
var _mPrintSorry = '';
var _mMapPrintUrl = 'http://www.google.com/mapprint';
var _mPrint = 'Print';
var _mOverview = 'Overview';
var _mStart = 'Start';
var _mEnd = 'End';
var _mStep = 'Step %1$s';
var _mStop = 'Destination %1$s';
var _mHideAllMaps = 'Hide Maps';
var _mShowAllMaps = 'Show All Maps';
var _mUnHideMaps = 'Show Maps';
var _mShowLargeMap = 'Show original map view.';
var _mmControlTitle = null;
var _mAutocompleteFrom = 'from';
var _mAutocompleteTo = 'to';
var _mAutocompleteNearRe = '^(?:(?:.*?)\s+)(?:(?:in|near|around|close to):?\s+)(.+)$';
var _mSvgEnabled = true;
var _mSvgForced = false;
var _mStreetMapAlt = 'Show street map';
var _mSatelliteMapAlt = 'Show satellite imagery';
var _mHybridMapAlt = 'Show imagery with street names';
var _mSeeOnGoogleMaps = "Click to see this area on Google Maps";
var _mLogInfoWinExp = true;
var _mLogPanZoomClks = false;
var _mLogWizard = true;
var _mTransitV2 = false;
function GLoadMapsScript() {
if (GBrowserIsCompatible()) {
GScript("http://maps.google.com/mapfiles/maps2.72.api.js");
}
}
GLoadMapsScript();



So to block the site key from being checked just remove the first whole if statement from the GLoad() function. Now the only step left is to point your script tag in your html file to point to this new config file instead of Google's. For example, I saved my script file as 'gmaps_config.js' to the same directory as my html page. So, I changed the script tag to this:

<script src="gmaps_config.js" type="text/javascript"></script>

Now the key check never takes place, and I can do development with Google maps without copying my site to a webserver everything I want to test it!


Update: 2/9/07

Geocoding by use of the GClientGeocoder class in the Google Maps API will not work if you are not using an API key. When you call any members of the GClientGeocoder class your API key as defined in your script block is attached to the http request sent to Google:

http://maps.google.com/maps/geo?q=San%20Diego%2C%20Ca&output=json&callback=__geoStore.__cg01171075463312&key=

Notice how the last parameter, 'key' is blank, well it appears that google validates this on the server side and since we don't have one defined the geocoder returns a 610 error which maps back to, GGeoStatusCode.G_GEO_BAD_KEY or " The given key is either invalid or does not match the domain for which it was given."

Well, I know what I'll be working on for the next few days!