Monday, July 16, 2012

Detect changes between 2 polygon layers in gvSIG

gvSIG can be used to identify the spatial changes between two polygon vector layers. This can be done by using the Geoprocessing tools' Analysis Overlay difference function. An illustration of this is described below using the scenario of identifying the new vegetation growth and the loss of vegetation cover between a period of time.

Identify new vegetation growth

  1. Start gvSIG OADE. Open a map view. Load and display two polygon layers e.g. vegetation2001.shp and vegetation2011.shp.

  2. Select View | Geoprocessing tools.

    The Geoprocessing tools dialog appears.
  3. Expand the nodes Geoprocessing tools | Analysis | Overlay. Select Difference. Click Open Tool.

    The Analysis tools dialog box appears.
  4. In the Input layer field, choose vegetation2011.
  5. In the Overlay layer field, choose vegetation2001.
  6. In the Output layer field, type in the output file name, e.g. C:\temp\new_growth.shp.
  7. Click OK.

    The polygons representing the new vegetation growth is created.
Identify the loss in vegetation cover
  1. If the Geoprocessing tools dialog is not opened, then select View | Geoprocessing tools.

    The Geoprocessing tools dialog is displayed.
  2. Expand the nodes Geoprocessing tools | Analysis | Overlay. Select Difference.
  3. Click Open tool.

    The Analysis tools dialog box appears.
  4. In the Input layer field, choose vegetation2001.
  5. In the Overlay layer field, choose vegetation2011.
  6. In the Output layer field, type in the output file name e.g. C:\temp\loss_of_vegetation.shp.
  7. Click OK.

    The polygons representing the loss in vegetation cover are created.

Monday, July 9, 2012

Create geo-referenced heat maps Google Mapplet

Comma-separated-values (CSV) of statistical data in the format latitude, longitude, and magnitude can be imported and visualized as heat maps in Google Maps using this custom mapplet. An example screenshot is shown below.



While the heat maps feature is already possible using the Google Docs FusionTable object, the heat maps created from this Mapplet is done using the HTML5 canvas object via the Javascript heatmap.js library. On  top of that, the Mapplet provides the option to export out the heat map image file along with supporting geo-referenced information in the form of world and projection files.

To run the Mapplet, click this link http://dominoc925-pages.appspot.com/mapplets/vheatmap.html.

The Mapplet's sidebar contains a few button commands that should be obvious - Import, Export, Fit and Clear.


Clicking the Import button brings up the Import Points dialog. 

Copy and paste your comma-separated-values data into the text box. The data must be comma delimited and in  the following order: latitude, longitude, and magnitude. Alternatively, click Use random samples to let the Mapplet randomly create CSV data for demonstration purposes. 

Then click Start Import to create the heat map. 

Click  the Export button to export the heat map and supporting files. This will bring up the Export Heatmap dialog box. 

To save out the heat map image, right click on the image preview and choose Save image as

Next, click on the World file text box and press +C to copy the contents to the clipboard. Then paste inside a text editor and save the world file with the same file name but with the prefix *.pgw. 

Similarly, click on the Projection text box and press +C. Then paste in a text editor and save the contents into a projection file with the same file name prefix but with the extension *.prj. 


Once the image, world file and projection have been exported, the heat map can be displayed and overlaid with other geo-spatial data in any GIS software e.g. Global Mapper as shown below. 


Monday, July 2, 2012

Use gvSIG to create Voronoi or Thiessen polygons

A GIS software such as gvSIG can help marketers to create polygons representing regional areas of coverage for their companies' branch offices if none are available. All that is required are the points representing the offices and perhaps a polygon representing the overall area of coverage e.g. the State boundary.

The basic steps to create the regional areas are simply the following:

  1. Generate Voronoi or Thiessen polygons from the points
  2. Mask away the extra parts of the Voronoi polygons from the area of coverage polygon

For a detailed explanation of Voronoi or Thiessen polygons, visit the Wikipedia site http://en.wikipedia.org/wiki/Voronoi_diagram.

The example below illustrates how to generate the Voronoi polygons of cities in the state of Montana.

  1. Start gvSIG OADE. Load and display the cities and the state boundary polygon in a map view.


  2. Select View | Geoprocessing tools.

    The Geoprocessing tools dialog box appears.

  3. Expand the Geoprocessing tools | Analysis | Computational geometry nodes. Double click Voronoi/Delaunay.

    The Analysis tools dialog box appears.

  4. In the Input layer field, choose the points layer e.g. cities_in_montana.shp.
  5. Toggle on Voronoi(Thiessen) polygons.
  6. In the Output layer field, click Choose. In the Save dialog, type in the output layer name e.g. c:\temp\voronoi.shp. Click Save. Click OK.

    The polygons are generated.
     
  7. If the Geoprocessing tools dialog box is closed, select View | Geoprocessing tools.


  8. Expand the Geoprocessing tools | Analysis | Overlay nodes. Double click on Intersection.

    The Analysis tools dialog box appears.

  9. In the Input layer field, choose the newly created Voronoi polygons layer e.g. voronoi.shp.
  10. In the Overlay layer field, choose the overall area of coverage polygon layer e.g. montana.shp.
  11. In the Output layer field, click Choose. In the Save dialog box, type in the output layer name e.g. c:\temp\cities_coverage_pol.shp. Click Save.
  12. Click Ok.

    The final regional area polygons are created and nicely masked.

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.