Adding a custom Google Map on a web page

Google mapOn last January I started playing around with the Google Maps API that is especially intended to instigate the coding skills of the developers around the world. At that time I created a simple page to host a map that showed the directions from a start city to a destination city. Then I did other test in which I used Microsoft Visual C# 2008 Express to retrieve and parse the XML data generated by a Google Map search query. I was curious about how I could send a search to Google Map webservice and as a result get back the structured data to be consumed by some application. I just wanted to explore and see how it worked. At that time I set plans to blog about the Google Map functionally and so today I'm doing just that.

As the title states, I'm going to list here the steps necessary to add a Google Map on a web page and I will comment about the drawbacks I had to overcome to get it functioning the way I wanted.

The map I'll show has different markers. When one of these markers is clicked an info windows is opened to display some useful information. For a real example look at the map I place here on this blog. It's on the sidebar. As you can see the map starts in a hybrid fashion, that is, it shows normal and satellite views. The zoom level is adjusted based on the bounds of the existing markers. I'll detail what is necessary to do to get a map just like the one you see on this blog so that you can make your own.

The programming language used to construct the map is basically JavaScript. It's a good idea to check the Google Maps API documentation in order to get acquainted with the object types used when coding the map. For more information regarding a specific map object, refer to the documentation.

The steps I followed to get a functional map were:

  1. Obtain a Google Maps API key at the Sign Up for the Google Maps API form
    The Google Maps API lets you embed Google Maps in your own web pages. A single Maps API key is valid for a single "directory" or domain. At the end of the sign up form just enter your domain name and you'll be given a key. Without this key your maps won't function.
  2. Implement the map code

The following is the code I used to build the map:

<!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" xmlns:v="urn:schemas-microsoft-com:vml">
    <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
      <title>Leniel Macaferi's blog - Places I cite on this blog - Google Maps JavaScript API Example: Asynchronous Data Retrieval</title>
      <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YourKey" type="text/javascript"></script>

      <script type="text/javascript">
      function initialize()
      {
        if(GBrowserIsCompatible())
        {
          <!-- Create a base icon for all of our markers that specifies the shadow, icon dimensions, etc. -->
          var baseIcon = new GIcon();
          baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
          baseIcon.iconSize = new GSize(20, 34);
          baseIcon.shadowSize = new GSize(37, 34);
          baseIcon.iconAnchor = new GPoint(9, 34);
          baseIcon.infoWindowAnchor = new GPoint(9, 2);
          baseIcon.infoShadowAnchor = new GPoint(18, 25);

          <!-- Creates a marker whose info window displays the letter corresponding to the given index. -->
          function createMarker(point, index, tooltip, html)
          {
            <!-- Create a lettered icon for this point using our icon class -->
            var letter = String.fromCharCode("A".charCodeAt(0) + index);
            var letteredIcon = new GIcon(baseIcon);
            letteredIcon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";

            <!-- Set up our GMarkerOptions object -->
            markerOptions = { icon:letteredIcon, title:tooltip};

            var marker = new GMarker(point, markerOptions);

            GEvent.addListener(marker, "click", function()
            {
              marker.openInfoWindowHtml(html);
            });

            return marker;
          }

          <!-- Creating the map and setting its essential properties -->
          var map = new GMap2(document.getElementById("map_canvas"));
          map.setCenter(new GLatLng(0,0),0);
          map.setMapType(G_HYBRID_MAP);
          map.addControl(new GLargeMapControl());
          map.addControl(new GMapTypeControl());

          var bounds = new GLatLngBounds();

          <!-- Download the data in data.xml and load it on the map. The format we expect is:
               <markers>
                 <marker lat="37.441" lng="-122.141" tooltip="Tooltip" html="HTML Code" />
                 <marker lat="37.322" lng="-121.213" tooltip="Tooltip" html="HTML Code" />
               </markers> -->
         GDownloadUrl("googlemap.xml", function(data)
         {
           var xml = GXml.parse(data);

           var markers = xml.documentElement.getElementsByTagName("marker");

           for(var i = 0; i < markers.length; i++)
           {
             var latlng = new GLatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));

             var tooltip = markers[i].getAttribute("tooltip");

             var html = markers[i].getAttribute("html");

             map.addOverlay(createMarker(latlng, i, tooltip, html));

             bounds.extend(latlng);
           }

           map.setZoom(map.getBoundsZoomLevel(bounds));

           map.setCenter(bounds.getCenter());
         });
       }
     }

     </script>
  </head>

  <body onload="initialize()" onunload="GUnload()" style="width:265px; height:300px; margin:0px; padding:0px;">
<div id="map_canvas" style="float:left; width:265px; height:300px; margin:0px; padding:0px;"></div>
</body>
</html>
Let's see the first java script tag right beneath the title tag
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YourKey" type="text/javascript"></script>
Note the YourKey value. Substitute this value with you own Google Maps API key. The JavaScript function initialize() is called when the page hosting the map is loaded. Look at the body tag:
<body onload="initialize()" ...
The initialize function firstly checks if the client browser is compatible with Google Maps with the GBrowserIsCompatible function:
if(GBrowserIsCompatible())
{
  ...
}
If this is the case, it's possible to go ahead and start the map construction. I won't comment the code I reuse. I'll just pass by it and brief explain what it does. Expect me explaining the other parts for sure. See the following lines:
<!-- Create a base icon for all of our markers that specifies the shadow, icon dimensions, etc. -->
var baseIcon = new GIcon();
baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
baseIcon.iconSize = new GSize(20, 34);
baseIcon.shadowSize = new GSize(37, 34);
baseIcon.iconAnchor = new GPoint(9, 34);
baseIcon.infoWindowAnchor = new GPoint(9, 2);
baseIcon.infoShadowAnchor = new GPoint(18, 25);
The above lines of code are defining a standard icon that'll be used to construct the markers on map.

The function createMarker does a really beautiful work. See it bellow:

<!-- Creates a marker whose info window displays the letter corresponding
to the given index. -->
function createMarker(point, index, tooltip, html)
{
  <!-- Create a lettered icon for this point using our icon class -->
  var letter = String.fromCharCode("A".charCodeAt(0) + index);
var letteredIcon = new GIcon(baseIcon);
letteredIcon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";

  <!-- Set up our GMarkerOptions object -->
  markerOptions = { icon:letteredIcon, title:tooltip};

  var marker = new GMarker(point, markerOptions);

  GEvent.addListener(marker, "click", function()
  {
    marker.openInfoWindowHtml(html);
  });

  return marker;
}
What does it do? I receives a point, more specifically a GPoint, and index, a tooltip, and a html code. It then creates a GIcon using Google's letter images for each marker, based on its index. The markerOptions variable has a type of GMarkerOptions and stores the attributes that has do with the icon properties as for example the title that receives the tooltip parameter value. For each maker it's set up an event handler for the click event. When the marker is clicked its openInfoWindowHtml method is called with the html content passed as a parameter. The createMarker function then returns the new created marker that will be added to the map overlay.

What follows is the instantiation of the map:

var map = new GMap2(document.getElementById("map_canvas"));
A new object of type GMap2 is created. This object is instantiated in order to create a map. This is the central class in the API. Everything else is auxiliary. The object constructor accepts as argument an HTML container, which is typically a DIV element. In this case the id of the DIV element I use is map_canvas. If you look at the div tag that is inside the body tag you'll see the map_canvas id applied to the div.
<div id="map_canvas" ...
Next we center the map with zero values. I'll explain later why I do so. Then the map type is set:
map.setCenter(new GLatLng(0,0),0);
map.setMapType(G_HYBRID_MAP);
The function setMapType can accept the following list of values:
  • G_NORMAL_MAP- the default view
  • G_SATELLITE_MAP - showing Google Earth satellite images
  • G_HYBRID_MAP - showing a mixture of normal and satellite views
  • G_DEFAULT_MAP_TYPES - an array of these three types, useful for iterative processing
The next line of code uses a GSmallMapControl object to add to the map a control with buttons to pan in four directions, and zoom in and zoom out, and a zoom slider:
map.addControl(new GSmallMapControl());
The last line of code to mount the basic map framework uses a GMapTypeControl object to add a standard map type control for selecting and switching between supported map types via buttons:
map.addControl(new GMapTypeControl());
This line of code has to do with the zoom that will be applied to the map. A variable called bound is declared and its type is GLatLngBounds. It will be used afterwards to set the zoom level of the map. This variable represents a rectangle in geographical coordinates, including one that crosses the 180 degrees meridian:
var bounds = new GLatLngBounds();
After constructing the framework it's time to populate the map with the desired data. That's the exciting part. Let's get to it.

As the green commentary lines state there's a predefined data format to structure the bits relative to the markers (GMarker class) that will be shown on the map. In this post I'm using a XML file called googlemap.xml to store the markers' data. The data is composed of lat (latitude), lng (longitute), tooltip (title of the marker) and html (any text). What is really cool is that you can format the text inside the html value using HTML and CSS. The text will be displayed inside the marker's info window. Altough I don't use formating in my XML file you're being infored that this is possible. Bellow is the content of the file:

<markers>
<!-- Don't use copy and paste on this XML file, use "View Source" or "Save As"
What the browser displays is *interpreted* XML, not XML source. -->
  <marker lat="-22.522778" lng="-44.103889" tooltip="Hello World!" html='Hello World!"/>
  <marker lat="-23.209862" lng="-45.876168" tooltip="Jesus Message" html="I'm the way, the truth and the life. John 14:6" />
</markers>
To consume this data we must make a call to the GDownloadUrl function. This function provides a convenient way to asynchronously retrieve a resource identified by a URL. Notice that, since the XmlHttpRequest object is used to execute the request, it is subject to the same-origin restriction of cross-site scripting, i.e. the URL must refer to the same server as the URL of the current document that executes this code. This is known as the Same Origin Policy. Therefore, it is usually redundant to use an absolute URL for the url argument, and it is better to use an absolute or relative path only.

This explanation is really important. While implementing the map you see on the sidebar of this blog I tried to store the googlemap.xml file on a domain different from the one of this blog, that is, I placed the XML data file on leniel.googlepages.com and was trying to consume its content at lenielmacaferi.blogspot.com. It's not possible because of cross-domain scripting limitations. It's a security issue! So what I did? I thought about other way of implementing it. I created the map host page at leniel.googlepages.com and used an IFrame to show the page on the sidebar of this blog. Simple, isn't it? Doing so, there's no security issue since I'm running the above JavaScript and consuming the XML data on the same domain leniel.googlepages.com. An inconvenience if I can call it this way is that I had to get another Google Maps API key to use on the other domain. It's not a inconvenience at all! :)

That said, let's move on.

The GDownloadUrl function has the following signature:

GDownloadUrl(url, onload, postBody?, postContentType?)
As you can see I'm using just two of the parameters above when I call the function in the code:
GDownloadUrl("googlemap.xml", function(data)
{
  ...
});
It then retrieves the resource from the given URL and calls the onload function, in this case function with the text of the document as first argument.

Now what must be done is the parsing operation. We need to read each line of the markers' XML file and extract its individual components such as lat, lng, html and tooltip. To that end we declare a variable named xml that will store the GXml parsed content. Note the use of the parse static method that consumes the data we got from the googlemap.xml:

var xml = GXml.parse(data);
After parsing it's now created a variable named markers that will store the individual nodes (markers) of the XML file:
var markers = xml.documentElement.getElementsByTagName("marker");
As you can see the getElementByTagName function gets the marker elements from the XML file. Each marker has this form:
<marker lat="-23.209862" lng="-45.876168" tooltip="Jesus Message" html="I'm the way, the truth and the life. John 14:6" />
In the next step an iteration takes place over the collection of markers with a for loop:
for(var i = 0; i < markers.length; i++)
{
  ...
}
The next instruction instantiates a new object of type GLatLng so that we can get the lat and lng values of each marker and store the same in the latlng variable:
var latlng = new GLatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));
It's time to retrieve the html code and tooltip values that will be shown on each mark. To that end are the following to lines:
var html = markers[i].getAttribute("html");

var tooltip = markers[i].getAttribute("tooltip");
A GMarker marks a position on the map. It implements the GOverlay interface and thus is added to the map using the GMap2.addOverlay() method. Each marker is created using its respective lat and lng values along with other relevant data you want as is the case of the following line of code. This is without doubt the trickiest part of the code :). I mean, after we call the createMarker function defined and explained above:
map.addOverlay(createMarker(latlng, i, tooltip, html));
For the purpose of setting a nice zoom on the map I use the bounds variable:
bounds.extend(latlng);
This variable is extended in conformity with the largest latitude and longitude. The above line is the last one pertaining to the loop and now we're almost done. We have two more lines of code to go through to finalize the map construction:
map.setZoom(map.getBoundsZoomLevel(bounds));
map.setCenter(bounds.getCenter());
The first line sets the zoom using the bounds variable and the second one center the focus on the map using the getCenter method from the bounds variable. That's it. The map is ready!

You can see this map running at this URL: http://leniel.googlepages.com/googlemap.html

Final notes
Pay close attention to the written code. If you change a letter in the name of a variable for example, your code won't function and you'll probably not see the map.

If loading the information from XML as is the case of this post, replace '<' and '>' characters with &lt; and &gt;. For example: &lt;img src="image.jpg" width=150 height=100&gt;

There are plenty of excellent material about the Google Maps API on the internet and the possibilities are uncountable. Just let your imagination flow and build amazing, astonishing maps that fit your will.

References
The code I present on this post is a mix from a variety of sources and some of them are listed bellow. I just adapted it so that I could get the result I wanted.

The following links are great sources of information. Particularly, take a look at Mike's Little Web Page. He has a bunch of great stuff about Google Maps API.

Mike Little's Web Page
http://www.econym.demon.co.uk/

Google Maps API Tutorial
http://econym.googlepages.com/index.htm

Fitting the map to the data
http://econym.googlepages.com/basic14.htm

Links and Images, etc.
http://econym.googlepages.com/basic6.htm http://econym.googlepages.com/example_map6b.htm

Services - Google Maps API - Google Code http://code.google.com/apis/maps/documentation/services.html

Google Maps JavaScript API Example: Asynchronous Data Retrieval http://code.google.com/apis/maps/documentation/examples/xhr-requests.html

Google Maps JavaScript API Example: Custom Icon http://code.google.com/apis/maps/documentation/examples/icon-custom.html

Programming-Constructing a Batch file

Batch file
In MS-DOS, OS/2, and Windows, a batch file is a text file containing a series of commands intended to be executed by the command interpreter. When a batch file is run, the shell program (usually COMMAND.COM or cmd.exe) reads the file and executes its commands, normally line-by-line. Batch files are useful for running a sequence of executables automatically and are often used by system administrators to automate tedious processes.

For more details, see the Batch file document at Wikipedia.

A sample batch file
In a recent post titled Syntactic Analyzer built with Flex and YACC I used a simple batch file in the compilers construction paper. Why I did that? To avoid boiler plate work while executing the commands necessary to generate the syntactic analyzer executable.

In this post I'll present and comment in more details the content of such batch file.

The following table shows the content of the batch file. I also include the command line number and its respective comment in the table, so that it's easier to visualize what's going on.

# Code Comment
1 @Echo Off Turn off screen messages
2 ::cls A comment. Start with ::
3 :Start Declare the label Start
4 Echo. Print a blank line. See the dot after Echo.
5 Echo Batch file Menu Print the string "Batch file Menu"
6 Echo. Print a blank line
7 Echo 1 - MinGW Print the string "1 - MinGW"
8 Echo. Print a blank line
9 Echo 2 - SinAn Print the string "2 - SinAn"
10 Echo. Print a blank line
11 Echo 3 - Exit Print the string "3 - Exit"
12 Echo. Print a blank line
13 set choice= Declare the choice variable
14 set /p choice=Choice: See note 1.
15 if not '%choice%'=='' set choice=%choice:~0,1% See note 2.
16 if '%choice%'=='1' goto MinGW Go to label MinGW at line 22
17 if '%choice%'=='2' goto SinAn Go to label SinAn at line 25
18 if '%choice%'=='3' goto Exit Go to label Exit at line 37
19 Echo "%choice%" is not valid. Prints error if choice isn't 1, 2 or 3
20 Echo. Print a blank line
21 goto Start Go to label Start at line #3
22 :MinGW Declare the label MinGW
23 path=C:\MinGW\bin;%PATH% Rewrite path with new value. See note 3.
24 goto end Go to label end at line 39
25 :SinAn Declare the label SinAn
26 @Echo On Turn on screen messages
27 path=C:\MinGW\bin;%PATH% Rewrite path with new value
28 cls Clear the screen
29 CD CompCons Navigate to CompCons directory
30 flex -i lexan.lex Execute flex command
31 yacc sinan.yacc Execute yacc command
32 gcc y.tab.c yyerror.c main.c -osinan -lfl Execute gcc command
33 sinan <factorial.txt Execute sinan command. See note 4.
34 cd.. Navigate one directory above
35 @Echo Off Turn off screen messages
36 goto end Go to label end at line 39
37 :Exit Declare the label Exit
38 goto end Go to label end at line 39
39 :end Declare the label end. EOF :)

Notes
There are four notes that I think are worth commenting:

  1. set /p choice=Choice:
    The /p switch tells the command interpreter that the value of the variable choice will be the input entered by the user. The interpreter will display the string "Choice:" before reading the line of input.
    This command has the following format: set /p variable=[promptString]
  2. if not '%choice%'=='' set choice=%choice:~0,1%
    Every time you need to get the content of a variable it's necessary to enclose it with the percent sign %. Note the use of the quotation mark in both sides too. If a command contains two percent signs, the command interpreter will treat any characters between them as an environment variable to be expanded.
    The tilde sign ~ tells the interpreter that I want to slice a string in a variable.
    This command has the following format: %NAME:~s,n where s is the start position (zero-offset) and n is the number of characters. If s is negative, then the offset starts from the right side minus 1 (i.e. -1 refers to the rightmost character). If n is negative, then length -n characters, are extracted.
    If the variable choice isn't empty, get only the first character of the user input.
  3. path=C:\MinGW\bin;%PATH%
    The path variable is already part of the operating system set of variables. In this case I'm just rewriting its value with the desired directory. Note that I also attribute to path the content of other defined variable called PATH.
  4. sinan < factorial.txt
    Having no to do with the batch file explanation and just for the sake of clarification: the less angle bracket symbol < means that I'm redirecting the contents of the file factorial.txt to the executable file sinan. The sinan executable will consume the data stored in the factorial.txt file to do its computations.

To execute a batch file, just open a command prompt and type its name. You can even type the name without the .bat extension.

When a batch file is executed, the command interpreter will automatically execute each line of the batch file automating the whole process, that is, you won't need to type the same series of commands each time you want to execute a single work.

In this sample batch file what I want to accomplish is to run 4 executable files - see lines 30, 31, 32 and 33. By selecting option 2 at line 17, the interpreter goes to line 25 and so I'll have all the 4 executables running with a single command since the SinAn label at line 25 comprises these commands.

You can get the sample batch file at: http://leniel.googlepages.com/SampleBatchFile.bat

English-Portuguese Freelancer Translator

I just created an account at ProZ. ProZ is the translation workplace providing translation service and translation jobs for freelance translators and translation agencies. It's is also home to the world's largest community of professional translators.

Translators and translation resources

Take a look at my Translator profile at ProZ.

If you ever need a translation work be it from English to Portuguese or from Portuguese to English, please, feel free to contact me at

I really like this kind of job, that is, to translate any type of material related to my area of expertise: software, technology and computer related stuff.

I translate ScottGu's blog from English to Portuguese - see Translating ScottGu's Blog to Portuguese post. ScottGu's blog is one of the most accessed Technology blogs in the world.

I'm looking forward to work with you.

Syntactic Analyzer built with Flex and YACC

Compilers construction paper
I and a dear brother in faith of mine called Wellington Magalhães Leite wrote a paper titled: A Syntactic Analyzer built with the CASE tools Flex and YACC

See the paper's abstract below:

The function of a syntactic analyzer in a compiler is to verify the syntactic structure of a program’s source code. It then detects, signalize and handle the syntactic errors found in the source code and at the same time servers as the framework for the front-end (user interface) of the program. So, its construction helps with the familiarization regarding the tasks included in the compiler project.

The language used in this paper does not have left recursion. The language neither presents subprograms, nor indexed variables and its only loop command is while for the sake of simplicity. The syntactic analyzer implemented uses the bottom-up parsing approach.

This paper presents the steps to the construction of a syntactic analyzer, which serves as a base element for a compiler implementation.

Keywords: syntactic analyzer, syntactical analysis, compiler construction, case tools, flex, yacc

CONTENTS
1 INTRODUCTION 7
  1.1 Objective 7
  1.2 Definition 7
      1.2.1 Grammar 7
            1.2.1.1 Grammar productions 8
            1.2.1.2 Lexical specifications 8
            1.2.1.3 Reserved words or keywords 10
            1.2.1.4 Operator types and attributes 11
            1.2.1.5 Separator types 11
2 DEVELOPMENT 13
  2.1 Lexical analysis 13
      2.1.1 Sample source code of a factorial program 13
      2.1.2 Flex 16
  2.2 Syntactical analysis 16
      2.2.1 Sample syntactic tree 16
      2.2.2 YACC 20
3 APPLICATION 21
  3.1 Constructing the file for the lexical analysis (lexan.lex) 21
  3.2 Constructing the file for the syntactic analysis (sinan.yacc) 21
  3.3 Guide to implementation 24
  3.4 Using a batch file to avoid boilerplate work 28
4 CONCLUSION 30
5 REFERENCES 31
6 ADDENDUM 32

See a screenshot of the syntactic analyzer in action:

SyntacticAnalyzerFlexYACCSyntaxError

You can get a PDF copy of the paper and the accompanying syntactical analyzer's files in a ZIP file at:

http://leniel.googlepages.com/SyntacticAnalyzerBuiltWithFlexYACC.pdf http://leniel.googlepages.com/SyntacticAnalyzerBuiltWithFlexYACC.zip

Tonal X Spatial Resolution X File Size

Computer graphics paper
I and a dear brother in faith of mine called Wellington Magalhães Leite wrote a paper titled: Influence of Tonal and Spatial Resolution on the Image File Size

See the original image we used to perform the tests regarding our paper:

The paper is accompanied by a spreadsheet and both are available in English and Portuguese.

See the paper's abstract below (English/Portuguese):

ABSTRACT

It is interesting to notice how the three variables (bits per pixel, number of colors and image file size) discussed in this paper are extremely related.

More and more we express ourselves through the use of images, which consequently need a place to be stored and this has to do with their usage in digital mediums as is the case of the Internet; take the Flickr service as an example. The storage is made in a digital form, that is, in bits.

It is known that: the better the image quality, the bigger will be the number of bits per pixel that are used to compose the image, what makes us capable of visualizing a great number of colors (tonal resolution), for the number of colors is coupled up to the quantity of bits per pixel. If we increase the number of pixels (spatial resolution) of the image, the generated file size will be bigger, in other words, more bits will be consumed to compose the image and depending on this value, the distribution or visualization of the image can be inadequate in certain conditions.

So, we can perceive the necessity of a case by case study, looking for a suitable value to the three variables, what will provide us with an ideal image file for each type of job.

Keywords: computer graphics, tonal resolution, spatial resolution, bits per pixel, number of colors, image file size

CONTENTS
1 INTRODUCTION 6
  1.1 Objective 6
  1.2 Definition 6
  1.3 Tonal resolution 7
  1.4 Spatial resolution 7
2 DEVELOPMENT 8
  2.1 Image edition 8
      2.1.1 Creating the work directory 8
      2.1.2 Obtaining the data “bits” for the experiment 8
      2.1.3 Selecting only the image of interest 8
      2.1.4 Opening the test file with Photoshop 9
      2.1.5 Visualizing the image size properties 10
      2.1.6 Redefining the image size 11
      2.1.7 Saving the modified image 12
      2.1.8 Producing images with different spatial resolution 13
      2.1.9 Altering the tonal resolution 13
      2.1.10 Returning to Windows Paint 14
      2.1.11 Producing images with different tonal resolutions 15
3 APPLICATION 16
  3.1 24, 16, 8, 4 and 1 bit tonal resolutions 16
  3.2 Tonal resolution vs. Spatial resolution vs. Image size 20
4 CONCLUSION 22
5 REFERENCES 23

RESUMO

É interessante notar como as três variáveis (bits por pixel, número de cores e tamanho do arquivo de imagem) discutidos neste trabalho estão intensamente relacionadas.

Cada vez mais nos expressamos através de imagens, as quais necessitam conseqüentemente de um local para serem armazenadas, haja vista a utilização em meio digital. Veja o site Flickr por exemplo. O armazenamento por sua vez é feito de forma digital, ou seja, através de bits.

É sabido que quanto maior for a qualidade da imagem, maior será o número de bits por pixel utilizados na composição da mesma, o que nos possibilita a visualização de um grande número de cores (resolução tonal), pois o número de cores está atrelado à quantidade de bits por pixel. Se aumentamos o número de pixels (resolução espacial) da imagem, maior será o tamanho do arquivo gerado, ou seja, mais bits serão consumidos para armazenar a imagem e dependendo deste valor, a distribuição ou visualização da imagem pode se tornar inadequada em certas condições.

Percebe-se então a necessidade de um estudo caso a caso, em busca de um valor adequado para essas três variáveis, de modo a obter um arquivo de imagem ideal para cada tipo de trabalho.

Palavras-chave: computação gráfica, resoulução tonal, resolução espacial, bits por pixel, número de cores, tamanho do arquivo de imagem

SUMÁRIO
1 INTRODUÇÃO 7
  1.1 Objetivo 7
  1.2 Definição 7
  1.3 Resolução tonal 8
  1.4 Resolução espacial 8
2 DESENVOLVIMENTO 9
  2.1 Edição de imagens 9
      2.1.1 Criando a pasta de trabalho 9
      2.1.2 Obtendo os dados “bits” para o experimento 9
      2.1.3 Selecionando somente a imagem de interesse 9
      2.1.4 Abrindo o arquivo de teste com o Photoshop 10
      2.1.5 Visualizando as propriedades do tamanho da imagem  11
      2.1.6 Redefinindo o tamanho da imagem 12
      2.1.7 Salvando a imagem modificada 13
      2.1.8 Produzindo imagens com diferentes resoluções espaciais 15
      2.1.9 Alterando a resolução tonal 15
      2.1.10 Retornando ao Paint do Windows 15
      2.1.11 Produzindo imagens com diferentes resoluções tonais 16
3 APLICAÇÃO 17
  3.1 Resoluções tonais de 24, 16, 8, 4 e 1 bit 17
  3.2 Resolução tonal vs. Resolução espacial vs. Tamanho do arquivo 21
4 CONCLUSÃO 23
5 BIBLIOGRAFIA 24

See the PivotChart created with the spreadsheet data:

Pivot Chart

You can get a PDF copy of the paper and the accompanying Excel spreadsheet at:

English version
http://leniel.googlepages.com/TonalSpatialResolutionImageFileSize.pdf
http://leniel.googlepages.com/TonalSpatialResolutionImageFileSize.xls

Portuguese version
http://leniel.googlepages.com/ResolucaoTonalEspacialTamanhoArquivo.pdf http://leniel.googlepages.com/ResolucaoTonalEspacialTamanhoArquivo.xls

Governmental and Private Scholarships in Brazil

This post aims to discuss a recent experience I had. It's is directly related to the problem of governmental and private scholarships in Brazil.

Flag of Brazil

I recently had to stop working in a highly exciting project called GradeBR - Rede Galileu. I just couldn't afford it. I can explain it better.

I wrote a post in which I discuss about the job I had gotten at the Computational Transport Phenomena Laboratory located at the Aeronautics Technological Institute (ITA). I was really motivated. What I had thought for my future was happening. I had gotten a great job opportunity at one of the most prestigious academic institutions here in Brazil. I’ve been planning to go to ITA since college. I had already talked about a master’s degree project and was even flying to meet with Rede Galileu’s work group. I had the first opportunity to travel in an aircraft. Believe it or not, it’s not so usual here in Brazil. Everything was perfect. I was just missing the company of my parents of course.

I started on the job on February 11th, and for almost two months (till April 4th) I didn't receive the scholarship that had been promised. As a matter of fact, I’ve been invited by the laboratory’s lead to go to ITA as I described in this post. There is an old saying that is as follow: if Leniel will not go to the mountain, the mountain must come to Leniel. I think it translates well what happened to me.

The reasons for the scholarship not being granted: pure bureaucracy, corruption and disregard to the development of the Brazilian nation.

I know there are lots of sheets of paper that must be read before the final signature granting the scholarship, but in this case, it wasn't the sheets of paper. The fact is that this scholarship was not from the government but from a private company called Petrobras that is one of the major global oil & gas market players. The scholarship agreement between a private company and a federal institution is established and managed through a Research Foundation that has as its motto: foster the development of projects related to research and development (R&D).

I won’t detail what specifically happened but the reasons I wrote above serve as a start point to think about why my scholarship didn’t take place.

My case is related to a private scholarship. I know people that don’t even have the possibility of getting a scholarship granted by the government. Why that? You may ask. My answer is: actually there is almost no condition of fostering research and development in this country. Because? You may ask. My answer: things were worse, today they are getting better but we still don’t have a serious investment plan to prepare human resources and to finance research and development projects. The rules are so complex that even a PhD professor doesn’t know how to ask a scholarship for his students. There are so many embarrassments. When there’s a scholarship the value paid is incompatible with real life. They only pay you for project related material and trips. They don’t think about the expenses related to relocation, about your daily necessities. They think you’re a research and development slave. In addition, you can’t work on other projects, that is, you must be a full-time researcher receiving a part-time scholarship. Do you get it? The work you do isn’t valued as it should be.

A nation can only grow and give fruits if and only if it has a really well prepared workforce. To have such really well prepared workforce it's necessary to invest in education. Education includes all sorts of knowledge fields, not only research and development, though in this specific post I treat about it.

I particularly like the Wikipedia's definition for Education: "Education means 'to draw out', facilitating realization of self-potential and latent talents of an individual", that is, without education, great part of people can't realize their potential, their talent and consequently the nation doesn't leverage as everyone expects.

It's not surprising that this country "Brazil" has a history marked by corruption and poor education or would it be a history marked by poor education and corruption? I think the former is worst given that is poor education that leads to corruption and all sorts of maliciousness. That's why Brazil is still a underdeveloped country. People grow governed by bad politicians that even don't know how to speak their mother tongue. Again this is a case of poor education. Education was so neglected that the ones that should represent the country don't know how to speak correctly. Can you understand that? It's all a matter of education. Your brain without proper instructions (education) can't do much. It's just like a computer hardware without software. I could develop more into this subject but I won't. I think this is sufficient to pass the message.

Getting back to the main topic: I had to relocate to a different city called São José dos Campos that is 140 miles far away from my parent's home in Volta Redonda. To stay there I had (my parents had) to pay for my lodging, lunch, etc. There's no free lunch at all! Without the scholarship that was previously promised I couldn't continue on the job. So what should I do? I just had to get back home and unfortunately abandon that great project. Was that easy? Surely no.

The people governing this country think that you are a robot researcher without emotions and aspirations.

What rest to comment about it? Oh, that there isn't incentive from the government to give scholarships to the ones that really want to continue their academic studies be it through a Master's degree or even a Doctor's degree. You see, I only could finish my graduation in Computer Engineering because my parents did work hard and set aside some money for my study. That's not easy here in Brazil. The major part of families can't afford a particular college. What is the result? More people without the proper education, more people with latent talents not realizing their potential. This causes sometimes more corruption, that is, without the proper means for achieving what people really want they take another easier paths to get there.

While this story doesn't change, we'll continue to have frustrated plans. Brazil won't change its status quo up to the time that every single person has conditions to study, to acquire the so called culture what will definitely permit that their aspirations be realized.

I'd like to write better words here, but if I did I would be more one liar. For some (the richest ones) everything in Brazil is going fine. The stock market is breaking records and that's just what matter. For others (as is my case) there's no free lunch!

Translating ScottGu's Blog to Portuguese

Joe Stagner from Microsoft wrote a post in which he calls people to volunteer for translating Scott Guthrie's Blog posts originally written in English to Portuguese. I immediately contacted Joe emphasizing that I would like to help. Since then I've translated three posts and I really expect to translate many more.

You can access the new blog created especially for the Portuguese community at http://weblogs.asp.net/scottguportuguese

Other great news for the Brazilian community is that the Developer Division, more precisely the Community Localization Team from Microsoft has released the Brazilian Localization of Visual Studio 2008 and .NET FX 3.5. More details can be found on this post at Somasegar's WebLog.

Again, I volunteered to participate in these community localization projects assisting with translating into my native language: Portuguese.

I think it's a good idea to participate in such projects. You can learn a lot more. As Joe stated in the title of his post "Do you translate ScottGu's blog in your head?"; my answer is YES, I do. I always do that. Besides, it's worth it to help others that still don't know the English language.