Monday, June 25, 2012

Google Mapplet for creating persistent point markers

This Google Mapplet can be used to create persistent markers on Google Maps that will still be there when you close and reopen the web page. The markers will remain until they are explicitly deleted. The mapplet makes use of the IndexDB feature of the HTML5 specifications to persist the markers in the browser. This means that only modern Internet browsers such as Chrome, Firefox, and the upcoming Internet Explorer 10 will be able persist the markers. The mapplet can function in older browsers such as Internet Explorer 8 or 9 but the markers will not be retained on the next visit to the page.

To run this mapplet, click on the link http://dominoc925-pages.appspot.com/mapplets/plpoint.html.

Choice of markers
You can choose the type of marker to be pinned on to the map e.g. green, orange etc. Once placed, the markers can be dragged to another location, deleted, and labelled.

Export Points
The markers can be exported out as KML or comma-separated-values (CSV) format. This can be done by clicking the Export button in the side bar.

The Export Points dialog box is shown below.


Export Points example

  1. In the Output format drop down  box, choose the output format, e.g. KML.

    The Coordinate system type drop down box is enabled for CSV and disabled for KML.
  2. If necessary, in the Coordinate system type field, make a choice e.g. Projected.

    The Projection drop down box is enabled.
  3. If necessary, in the Projection field, choose a suitable destination projection for the output e.g. UTM 48N.
  4. If necessary, in the Geodetic datum field, choose a suitable destination datum e.g. WGS84.
  5. Click Start Export.

    The markers are exported to the destination format. The results are displayed in the Results box.


  6. Click the Results text. Press CTRL+C.
  7. In Notepad, press CTRL+V.

    The results are pasted into Notepad.


  8. Close and save the results into a *.csv file.


 An example of the results of a KML output displayed in Google Earth is shown below.


Monday, June 18, 2012

Stop the click event from propagating from the Google Maps marker InfoWindow

I was writing Google Maps Javascript code to delete a marker already placed on the map by clicking a 'delete' link on the marker's InfoWindow. However, a new marker kept getting placed at the location of the delete link. The problem is illustrated in the before and after screenshots below.

After reading up, I figured out that the click event on the InfoWindow link was being propagated down to the map's onclick event listener. To prevent this from happening, the click event must be stopped from being propagated down.

The following code snippet illustrates how to stop the propagation.
//Create a new marker on this map
var mkr = new google.maps.Marker({
    icon: icon,
    shadow: shadow,
    position: point, 
    id: id, 
    desc: desc,
    title: desc,
    map: this.map
});

//Now create the infowindow object that will be attached to the marker
var contentString;
//Create a div element with an ID to contain the info window contents
contentString = '<div id="infoDiv" >';
contentString += "<textarea rows='3' cols='25' onclick='this.select();'>";
contentString += desc;
contentString += "</textarea>" + "<br />";
contentString += "<a href='#' onclick='onMkrInfoDeleteClick()'>Delete</a>|";
contentString += "<a href='#' onclick='onMkrInfoOkClick()'>Ok</a>";
contentString += '</div>';
var infoWnd = new google.maps.InfoWindow({content: contentString});
google.maps.event.addListener(mkr,'click',
    function(evt){
        infoWnd.open(this.map,mkr);
    }
);
//call this function when the InfoWindow's Delete link is clicked    
function onMkrInfoDeleteClick(){
    //get the pointer to the InfoWindow div element
    var div = document.getElementById('infoDiv');
    if (div)
        //cancel the click event so that it doesn't propagate to the map object below the InfoWindow
        google.maps.event.addDomListener(div, 'click', 
            function (evt){
                evt.cancelBubble = true;
                if (evt.stopPropagation)
                    evt.stopPropagation();
            }        
        );
    // Erase the clicked marker 
    mkr.setMap(null);
};

Monday, June 11, 2012

Use HTML5 IndexedDB cursors to update existing records

The HTML5 IndexedDB is still in the working draft stage and not fully implemented in major Internet browsers yet. Nevertheless, I tried to use its asynchronous API to develop a Google Maps application. It took me a little while to figure out how to update an existing record in the IndexedDB database store. This can be done by opening a read-write cursor to the record to be updated. Then call the cursor update method to replace it with the new record.

An example Javascript code snippet is shown below.


try {
var objDb;    //the database to update
var store = 'myStore';    //the database store to update
var key = 88;    //the key of the existing record to update
var newRec = 'hello world';    //the new record


var objStore = null;
var objTrans = null;
var objCursor = null;
var objKeyRange = null;
 
//...etc...open the database....etc...


//open a read-write transaction
objTrans = objDb.transaction(store,_IDBTransaction.READ_WRITE);


//get the store
objStore = objTrans.objectStore(store);


//create a range from the key
objKeyRange = _IDBKeyRange.only(key);


//open a cursor of only the record to update
objCursor = objStore.openCursor(objKeyRange);


objCursor.onsuccess = function(evt){

  var cursor = evt.target.result;

  //do the update
  var objRequest = cursor.update(newRec);

  objRequest.onsuccess = function(ev){
    console.log('Success in updating record 88');
    };
  objRequest.onerror = function(ev){
    console.log('Error in updating record 88');
    };
  };
  objCursor.onerror = function(evt){
    console.log('Error in retrieving record 88');
  };
}
catch (e){
  console.log('Exception:'+e.message);
}

Monday, June 4, 2012

Create a camera calibration chess board pattern PDF file

For calibrating a camera to calculate its intrinsic parameters e.g. focal length, principal point and distortion, some camera calibration toolboxes make use of images of chessboard patterns taken with the camera. One such toolbox is this open-source software from this site http://graphics.cs.msu.ru/en. To create this calibration chess board pattern, there are a variety of methods that can be employed to generate it.


In this post, I shall use the free and open-source vector illustration software Inkscape to create an A4 sized 8x3cm by 6x3cm tiles calibration pattern. Inkscape can be downloaded from this site http://inkscape.org.

  1. Start Inkscape.

  2. Select File | Document Properties.

    The Document Properties dialog box appears.
  3. In the Page Size list box, select A4. In the Default Units field, choose cm. Close the Document Properties dialog box.
  4. In the toolbox, click the Create rectangles and squares icon.
  5. Click and drag out a rectangle on the page.

  6. In the Change W and H fields, type in 3.
  7. In the toolbox, click the Select and transform objects icon.

  8. Select Edit | Copy.
  9. Select Edit | Paste. Repeat to paste the square two more times.

  10. Change the fill color of two squares to black. Change the fill color of two squares to white.

  11. Click the Select and transform objects icon and select all squares.
  12. Select Object | Rows and Columns.

    The Rows and Columns pane appears.
  13. Ensure the Rows and Columns are set to 2. Ensure the Set spacing is 0. Click Arrange.

    The squares are rearranged.
  14. Ensure all the squares are selected. Select Object | Group.

    All the squares are grouped as a single object.
  15. Select Edit | Copy.
  16. Select Edit | Paste. Repeat 10 more times to place a total of 48 (3x4x4) tiles.
  17. Press CTRL-A.

    All the tiles are selected.
  18. Select Object | Rows and Columns if the Rows and Columns pane is not displayed.

    The Rows and Columns pane is displayed.
  19. In the Rows field, type in 4. In the Columns field, type in 3. Click Arrange.

    The calibration chess board pattern is complete.
  20. Select File | Save As.

    The Select file to save to dialog box appears.
  21. In the Save as type field, choose Portable Document Format (*.pdf). Browse and type in a file name e.g. calib.pdf. Click Save.

    The file is saved.

Monday, May 28, 2012

Google Mapplet for showing local coordinates

This Google Mapplet was written to show the local projected coordinates for any clicked point on Google Maps. Run it from this website http://dominoc925-pages.appspot.com/mapplets/cs_readout.html.


The mapplet currently supports only the following projection types: Cassini-Soldner, Mercator, Oblique Mercator and Transverse Mercator. The datum transformation between the WGS84 datum used by Google Maps and the local projection datum is done using the Standard Molodensky transformation. The transformation parameters of the datums and ellipsoid parameters are taken from this University of Colorado site http://www.colorado.edu/geography/gcraft/notes/datum/edlist.html.

Define and save projection parameters
There are probably hundreds of projection parameter sets in use in the world - too many to keep track. A facility has been built in using some HTML5 features to allow projection parameters to be changed, saved and named, and reuse in the current browser.


  1. In the Side bar on the right, click the Projection link.
  2. In the Projection combo box, select any default projection parameter set e.g. British National Grid.
  3. Change any parameters e.g. Longitude of origin.
  4. Click Save projection as.

    A text entry field appears.
  5. Type in a meaningful name e.g. MyProjection. Click Ok.

    The projection parameters are saved and named as MyProjection.

    Simply select the saved projection to use it for the coordinate readout. 

Monday, May 21, 2012

Adjust brightness and contrast of intensity images using Imagemagick

Sometimes the intensity images generated from LiDAR las files are too dark or too bright. An example of a dark intensity image is shown below.

It is useful to be able to apply some post-processing brightness and contrast adjustments to the images. Photoshop can be used to interactively adjust the brightness and contrast but I like to use the free Imagemagick open source software to process images in batch. Imagemagick has a convert utility which can perform brightness and contrast adjustments on images from the command line.

To make an intensity image brighter, type in the following at the command line prompt with the brightness-contrast option.
c:\> convert -brightness-contrast 50x20 input.tif out_lighter.tif

where the 50 tells the utility to increase the brightness by +50 and 20 is to increase the contrast by 20.



To make an intensity image darker, type in the following at the command line prompt with negative brightness and/or contrast values.
c:\> convert -brightness-contrast -30x10 input.tif out_darker.tif

where -30 is to darken by 30 and +10 is to increase the contrast by 10.

More information about the convert utility is available on this link.

Monday, May 14, 2012

Re-align a raster image to the corners in Gimp

The free and open source software Gimp is an Adobe Photoshop like software that can be used to edit or adjust raster images. If you use the Gimp software for editing raster images for contrast, brightness, color balance, etc. then it just might be possible to make a mistake and shift the entire raster image layer so that it is no longer align to the canvas corners. The screenshot below shows a shaded relief raster image that has been mistakenly shifted - the bottom right is no longer aligned to the corner.

In order to shift the raster layer back precisely, the Gimp ruler guide lines can be used as described below.

  1. In the Gimp Toolbox, click the Zoom tool and zoom closer to the corner.


  2. On the top horizontal ruler bar, press down the left mouse button and drag out a horizontal guide line until it snaps to the bottom of the canvas.


  3. On  the left vertical ruler bar, press down the left mouse button and drag out a vertical guide line until it snaps to the right of the canvas.
  4. In the Toolbox, click the Move tool. Press down the left mouse button on the raster image and drag the image so that the bottom right corner snaps  to the horizontal and vertical guide lines.

    The raster image is snapped to the canvas corner.


    The raster image is now correctly aligned again.