Wednesday, November 16, 2011

Want to know when Google is adding your area to Street Level View?

Google doesn't tell many people when they are driving around in their cars, photographing an area for Street Level View (I understand Google notifies Women's Shelters and other organizations that are sensitive about exterior photographs of their buildings).  There are several obvious reasons for not being too public about their mapping intentions, of course.  Most importantly, I imagine, is that Google wants to keep their data from being "tampered" with by people who would make some special display specifically for the mapping vehicle (e.g. a "Hi Mom!" banner).

I, however, really want to know anyway.  I live on a small island that relies heavily on tourism.  Our island has many artists and artisans who work out of studios on their own properties.  I would like to have these artists have displays of their work on the ends of their driveways when Google conducts a street level view on our island (our island hasn't been covered yet, but I think it may be covered in the future).  I think it would be good for the locals, and for the tourists who look at our island online.

As I said, google doesn't broadcast where they intend to cover next; but they DO broadcast where they are currently.  Google has a special site that you can visit to see the current location of their vehicles, categorized by country:

http://maps.google.com/help/maps/streetview/learn/where-is-street-view.html

As I said, the chart on this page shows the current location and only seems to list the city or general area they are currently mapping.  However, I think it's a start and below I'll show you how you can use this data to get an alert when Google starts mapping a new area in your country.

The method I'll describe here is a very simple one.  The country data on the page above is populated through an XML feed.  I decided to import the data into a Google Docs spreadsheet, and make the spreadsheet notify me via email if the cell that contains the data for my country changes.  The steps I took are as follows:

  1. Create a spreadsheet in Google Docs
  2. In the first cell on the default worksheet (A1) insert the following function:
    =ImportFeed("http://spreadsheets.google.com/feeds/list/0AjZ9lY-SjtYacnNVdGhsckJrM3k5X1hFd3BIWlhWcFE/oda/public/basic")
  3. Select Tools > Notification Rules and add a new rule
  4. Click the checkbox next to "Any of these cells are changed: ".  In the cell range box, put the name of the cell that contains the data for your country (for my country, Canada, the cell was C7)
  5. Click the checkbox next to "Email - Right Away" under "Notify Me With..."
  6. Save your spreadsheet and exit!  
The spreadsheet doesn't poll the source every second, but you should get a notification shortly after the data changes (certainly within the hour).  Again, this isn't exactly "notice", but hopefully it will give you some warning.

If there is a lot of activity in your country (and you're getting too many notifications) you can use the FIND function to locate your area/city name within your country data and then base your notification on the result.

Tuesday, July 19, 2011

Accessballot

I've completed the initial version of a English US EAC compliant paper ballot generating API. It takes XML candidate/issue data and uses it to generate a PDF of a ballot that is 100% compliant with the US EAC ballot design standards.


The application is Opensource and you can find it on Google Code at the following address:
http://code.google.com/p/accessballot/

You can also use the hosted version on the Accessvote.com (which is free of charge). The following is a sample ballot generated using the free API:
http://accessvote.com/api/us_eac/?s=http://accessvote.com/sample_ballots/us_eac-sample.xml.

If you would like more information on how to use it/integrate it into your own applications, you can view the project wiki at the following location:
http://code.google.com/p/accessballot/w/list.

Wednesday, January 26, 2011

Making DIVs, using the CSS "Float Left" property, all have uniform heights; automatically adjusting to match the tallest DIV in the row

Update: I modified the code so it would work with the onresize() event


Would you believe that was the best title I could come up with? Honestly, if you can think of a better one shoot me a line - I want to hear from you.

Okay, I'm a big fan of Fluid Design. I love to design websites/webapps that flow into the space available, from giant screened desktops to mobile phones, and always look like they were designed with exactly that screen size in mind.

One thing that CSS-P brought to web design that didn't exist back when we were using invisible nested tables to do webpage layout is the ability to have rows with a dynamic number of "columns". So, for instance, if you are showing rows of thumbnails, you can have more thumbnails on a row if the browser window is wide, and fewer if the window is narrower.

The method for doing this is to cause items to "Float Left". Usually this means putting your content (say a thumbnail and label) into a DIV; and giving the DIV the CSS property of:

div.column
{
   float:left;
}

If the above were added to a page's stylesheet, the DIVs with the class "column" assigned to them would stack to the right of the item before it on the page, and if there are more than one item, each will stack to the right of the previous DIV until there is no more room on that line, and then the next will appear below that row, starting a new one.

If the DIVs do not share the same height, each row will have their tops all lined up, but will have bottoms extend downwards as much as they need to to accommodate the content they contain. And the next row, which also has all the tops lined up, will appear just below the bottom of the DIV, from the previous row, that was "tallest". Like this:

(So above the second row begins below the "tallest" item in the first row, which is c)


This isn't bad, but many designers would rather have some uniformity to the DIV sizes and have, say, the container backgrounds and borders fill in the spaces below a, b, and d.  We can do that, of course, by giving each container a specified height, instead of letting the content drive the height, but then we would have to make all the containers as tall as they are likely ever to get which isn't prefect either. 

Ideally, I think, it would be best to have all of the DIVs in a row be all be the same height, but only be as tall as is actually needed to accommodate the tallest DIV in the row.  Like this:

(in the above example, the DIVs in the first row are as tall as the tallest DIV in the row, which is c, and all the DIVs in the second row are as tall as f, which is the tallest DIV in that row)

Well, with a bit of jQuery you can have your DIVs all adjust their heights so they are uniform across the entire row. You will have to add jQuery to your page (see How jQuery Works) and add the following Javascript to your page:
var currentTallest = 0;
var currentRowStart = 0;
var rowDivs = new Array();

function setConformingHeight(el, newHeight) {
 // set the height to something new, but remember the original height in case things change
 el.data("originalHeight", (el.data("originalHeight") == undefined) ? (el.height()) : (el.data("originalHeight")));
 el.height(newHeight);
}

function getOriginalHeight(el) {
 // if the height has changed, send the originalHeight
 return (el.data("originalHeight") == undefined) ? (el.height()) : (el.data("originalHeight"));
}

function columnConform() {

 // find the tallest DIV in the row, and set the heights of all of the DIVs to match it.
 $('div.column').each(function(index) {

  if(currentRowStart != $(this).position().top) {

   // we just came to a new row.  Set all the heights on the completed row
   for(currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) setConformingHeight(rowDivs[currentDiv], currentTallest);

   // set the variables for the new row
   rowDivs.length = 0; // empty the array
   currentRowStart = $(this).position().top;
   currentTallest = getOriginalHeight($(this));
   rowDivs.push($(this));

  } else {

   // another div on the current row.  Add it to the list and check if it's taller
   rowDivs.push($(this));
   currentTallest = (currentTallest < getOriginalHeight($(this))) ? (getOriginalHeight($(this))) : (currentTallest);

  }
  // do the last row
  for(currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) setConformingHeight(rowDivs[currentDiv], currentTallest);

 });

}


$(window).resize(function() {
 columnConform();
});

$(document).ready(function() {
 columnConform();
});
(the above code assumes you have assigned the CSS class called "column" to each of the DIVs that are "Floating Left")

If you can read Javascript/jQuery, you will find the code comments will sufficiently explain how it works; but in a nutshell: The script goes through each DIV, determining which are on the same row by comparing the X value of the top of each container.  It keeps track of which is the tallest, and then sets the height for each DIV in the row based on that value.