Monday, April 29, 2013

How I build Boost for 64 bit Windows

I decided to build liblas binaries for 64 bit Windows since I could not easily find the 64-bit binaries. One of the prerequisites include boost. However, I had some difficulty getting 64-bit Boost binaries and header files, and the official Boost 64 bit installer seems to have x86 libraries included somehow causing me linking errors while building liblas. So I decided to compile Boost for x64 myself for liblas. The following steps are what I did to get Boost to compile.

  1. Download the latest Boost source code from Sourceforge http://sourceforge.net/projects/boost/files/boost/. Extract the files to a folder e.g. C:\Work\src\boost_1_52_0\.
     
  2. On the Windows desktop, select Start | All Programs | Microsoft Visual Studio 2010 | Visual Studio Tools | Visual Studio x64 Win64 Command Prompt.

    The Visual Studio x64 Win64 Command Prompt appears.
  3. In the Command Prompt, change directory to the extracted Boost source code folder e.g.

    C:\> cd \Work\src\boost_1_52_0
  4. In the Command Prompt, run the bootstrap.bat.

    C:\> bootstrap.bat

    Bootstrapping is done.
  5. In the Command Prompt, run b2.exe.

    C:\> b2 --toolset=msvc-10.0 architecture=x86 address-model=64 stage

    The Boost C++ libraries are built.

Monday, April 22, 2013

Create a rounded border around a layout of an Android Activity

A rounded border can be easily created around a layout in an Android Activity. An example of how it looks like is shown in the screenshot below.


To define a rounded border drawable using the Android Development Toolkit, in Eclipse, the following steps can be done:

Create a new Android drawable XML file
  1. In the Package Explorer pane of Eclipse, right click on the drawable folder.

    A pop up menu appears.

  2. Choose New | Android XML File.

    The New Android XML File dialog box appears.


  3. In the File field, type in the name of the drawable XML file e.g. myborder.xml.
  4. In the Root Element list, choose shape. Click Finish.

    The file is created and the following code is displayed in Eclipse. 

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

 
</shape>

Edit the drawable Android XML file
  1. In the Eclipse code editor, type in the following to define the rounded border shape.



    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"> 
    <stroke 
    android:width="1dip" 
    android:color="@android:color/darker_gray" /> 
    <solid 
    android:color="@android:color/background_dark" /> 
    <padding 
    android:left="7dip" 
    android:top="7dip" 
    android:right="7dip" 
    android:bottom="7dip" /> 
    <corners 
    android:radius="6dip" /> 
    </shape>


  2. Save the code.

Using the drawable Android XML file in a layout

When editing the layout XML of an Activity, the newly created rounded border drawable can be referenced and used. For example, in the LinearLayout element, the android:background attribute can be set to the myborder drawable created previously, as shown in the code snippet below.



<LinearLayout 
android:orientation="vertical"
android:background="@drawable/border_rounded_corner"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="GPS Week"
/>
<RelativeLayout 
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content"
android:layout_width="wrap_content">

<kankan.wheel.widget.WheelView
android:id="@+id/digit4GpsWeek"
android:padding="0dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"            
/>
<kankan.wheel.widget.WheelView
android:id="@+id/digit3GpsWeek"
android:padding="0dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/digit4GpsWeek"
/>
<kankan.wheel.widget.WheelView
android:id="@+id/digit2GpsWeek"
android:padding="0dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/digit3GpsWeek"
/>
<kankan.wheel.widget.WheelView 
android:id="@+id/digit1GpsWeek"
android:padding="0dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/digit2GpsWeek"
/>
</RelativeLayout>
<!-- etc -->
</LinearLayout>

The corresponding resultant Activity may look like the screenshot below.

Monday, April 15, 2013

Using the NetTopologySuite to read and write Shapefiles in C#

I was looking for a .NET library to use to read and write Shapefiles without using unmanaged dynamic link libraries. I found quite a few that could read but not write Shapefiles. In the end, I found the NetTopologySuite at http://code.google.com/p/nettopologysuite/ to suit my requirements the best.

The following code snippet show how to use the library's ShapefileDataReader to read a Shapefile. In the example, all the database records and the Shape geometries are read into a features collection.


using GisSharpBlog.NetTopologySuite.Features;
using GisSharpBlog.NetTopologySuite.Geometries;
using GisSharpBlog.NetTopologySuite.IO;
using GeoAPI.Geometries;

...etc....

GeometryFactory factory = new GeometryFactory();
ShapefileDataReader shapeFileDataReader = new ShapefileDataReader(shpFilename, factory);
 
//Display the shapefile type
ShapefileHeader shpHeader = shapeFileDataReader.ShapeHeader;
Console.WriteLine(string.Format("Shape type: {0}", shpHeader.ShapeType));
 
//Display the min and max bounds of the shapefile
IEnvelope bounds = shpHeader.Bounds;
Console.WriteLine(string.Format("Min bounds: ({0},{1})", bounds.MinX, bounds.MinY));
Console.WriteLine(string.Format("Max bounds: ({0},{1})", bounds.MaxX, bounds.MaxY));
 
//Display summary information about the Dbase file
DbaseFileHeader header = shapeFileDataReader.DbaseHeader;
Console.WriteLine("Dbase info");
Console.WriteLine(string.Format("{0} Columns, {1} Records", header.Fields.Length, header.NumRecords));
for (int i = 0; i < header.NumFields; i++)
{
DbaseFieldDescriptor fldDescriptor = header.Fields[i];
Console.WriteLine(string.Format("   {0} {1}", fldDescriptor.Name, fldDescriptor.DbaseType));
}
 
//Reset the pointer to the start of the shapefile, just in case
//shapeFileDataReader.Reset();
 
//Read through all records of the shapefile (geometry and attributes) into a feature collection 
ArrayList features = new ArrayList();
while (shapeFileDataReader.Read())
{
Feature feature = new Feature();
AttributesTable attributesTable = new AttributesTable();
string[] keys = new string[header.NumFields];
IGeometry geometry = (Geometry)shapeFileDataReader.Geometry;
for (int i = 0; i < header.NumFields; i++)
{
DbaseFieldDescriptor fldDescriptor = header.Fields[i];
keys[i] = fldDescriptor.Name;
attributesTable.AddAttribute(fldDescriptor.Name, shapeFileDataReader.GetValue(i));
}
feature.Geometry = geometry;
feature.Attributes = attributesTable;
features.Add(feature);
}
//Close and free up any resources
shapeFileDataReader.Close();
shapeFileDataReader.Dispose();

It is important to free up any resources used by calling the Close and Dispose methods, especially if you want to apply any file based operations e.g. deleting or renaming onto the Shapefile.

The following screenshot shows an example output from the code snippet.


The ShapefileDataWriter class can be used to create a Shapefile. It seems that the class can only create new Shapefiles and there are no methods append to an existing Shapefile. The following code snippet shows how to write features with geometry and attributes into a Shapefile.



//Create a new shapefile from features
GeometryFactory outGeomFactory = new GeometryFactory();
//The constructor will append a ".shp" extension to the input filename so the 1st argument should not have an extension at all
string outShpFilenameNoExt = Path.Combine(Path.GetDirectoryName(outShpFilename), Path.GetFileNameWithoutExtension(outShpFilename));
ShapefileDataWriter writer = new ShapefileDataWriter(outShpFilenameNoExt, outGeomFactory);
DbaseFileHeader outDbaseHeader = ShapefileDataWriter.GetHeader((Feature)features[0], features.Count);
writer.Header = outDbaseHeader;
writer.Write(features); 

Monday, April 8, 2013

Add text label as attribute to polygon in Global Mapper

It is useful to be able to copy the text label from points (so called area centroids) to the enclosing area polygons as attributes. This can be done using Global Mapper's Add Attributes to Selected Areas from Points command. If the text labels are not already point attributes, then there is a simple workaround that can be performed to convert them into point attributes. The following example illustrates the workaround by simply exporting out the points as a Shapefile and using the exported Shapefile for the source point attributes.

  1. In Global Mapper, create, load and display the area polygons and points with labels.


  2. Select File | Export Vector Format.

    The Select Export Format dialog box appears.

  3. Choose Shapefile. Click OK.

    The Shapefile Export Options appear.

  4. Toggle on Export Points. Specify the destination point Shapefile name and location, e.g. C:\Temp\centroid.shp.


  5. Click OK.

    The point Shapefile is created.
  6. Unload the original point layer.


  7. Drag and drop the exported point Shapefile, e.g. centroid.shp, onto the Global Mapper's map view.
  8. Press ALT+P. Click on one of the points.

    The Feature Information dialog box appears.

    Note: the text label is an attribute
    .
  9. Press ALT+D. Click and drag to select all the area polygons and points.


  10. Press right click on the mouse.

    A popup menu appears.


  11. Choose Attribute Functions | Add Attributes to Selected Areas from Points.

    A prompt appears.

  12. Click Yes.

    A message appears.

  13. Click OK.

    The text label is added to the area polygons as attributes.

Monday, April 1, 2013

Build libLAS for Windows 64 bit with GDAL and GeoTIFF support


In order to build 64 bit Windows binaries of liblas, the header files and 64 bit binaries for Boost must be accessible by Microsoft Visual Studio. The CMake utility from http://www.cmake.org needs to be used to configure and generate the Microsoft Visual Studio project files for liblas. The following illustrates how I build the liblas 64 bit binaries with GDAL and GeoTIFF support. Note that the 64-bit executables may not run successfully even though the compilation is successful depending on how the source code was written.
  1. Download the latest liblas source code from http://www.liblas.org/download.html. Extract the files to a folder e.g. E:\Work\src\liblas-1.7.0\.
  2. On the Windows Desktop, select Start | All Programs | CMake 2.8 | CMake (cmake-gui).

    The CMake application appears.
  3. In the Where is the source code field, click Browse Source.

    The Browse for Folder dialog box appears.
  4. Select the folder where the liblas archive was extracted, e.g. E:\Work\src\libLAS-1.7.0\. Click OK.
  5. In the Where to build the binaries field, click Browse Build.

    The Browse for Folder dialog box appears.
  6. Select or create the folder where the Microsoft Visual Studio solution project files will be created e.g. E:\Work\src\libLAS-1.7.0\bin\. Click OK.

  7. Click Configure.

    A prompt appears.
  8. In the combo box, choose a generator for this project e.g. Visual Studio 10 Win64. Click Finish.

    A Error message appears.
  9. Close the message.

  10. In the list box, select Boost_INCLUDE_DIR. Then click the browse [...] button.

    The Browse For Folder dialog box appears.
  11. Choose the root folder containing Boost e.g. E:\Work\src\boost_1_52_0\. Click OK.

    Note: the boost folder containing the header include files should be underneath the root folder.
  12. Click Configure again.

    The configuration files are created.
  13. Toggle on WITH_GDAL and WITH_GEOTIFF. Click Configure.

    An error message appears.
  14. Close the message. Select GDAL_INCLUDE_DIR. Click the browse [...] button.

    The Browse for Folder dialog box appears.
  15. Select the folder containing the GDAL header include files e.g. E:\Work\src\gdal-1.9.2\gcore\. Click OK.
  16. Select GDAL_LIBRARY. Click the browse [...] button.

    The Select File for GDAL_LIBRARY dialog box appears.
  17. Select the GDAL library e.g. E:\Work\src\gdal-1.9.2\gdal_i.lib. Click Open.
  18. Click GEOTIFF_INCLUDE_DIR. Click the browse [...] button.

    The Browse for Folder dialog box appears.
  19. Select the folder containing the libGeotiff header files e.g. E:\Work\src\libgeotiff-1.4.0\. Click OK.
  20. Select GEOTIFF_LIBRARY. Click the browse [...] button.

    The Select File for GEOTIFF_LIBRARY dialog box appears.
  21. Choose the GEOTIFF library file e.g. E:\Work\src\libgeotiff-1.4.0\geotiff_i.lib. Click Open.
  22. Click Generate.

    An error message appears.
  23. Close the message. Click TIFF_INCLUDE_DIR. Click the browse [...] button.

    The Browse for Folder dialog box appears.
  24. Select the folder containing the TIFF header files e.g. E:\Work\src\tiff-4.0.3\libtiff\. Click OK.
  25. Click TIFF_LIBRARY. Click the browse [...] button.

    The Select File for TIFF_LIBRARY dialog box appears.
  26. Select the TIFF library file e.g. E:\Work\src\tiff-4.0.3\libtiff\libtiff_i.lib. Click Open.
  27. Click Generate.

    The Microsoft Visual Studio project files are generated the specified destination build folder.
  28. Close CMake.
  29. Run Microsoft Visual Studio 2010. Open up the libLAS.sln file.
  30. Press F7 to build all the projects.

    Note: it might be necessary to add in the paths to the include files if the compiler cannot locate them in the build process.

    The 64 bit liblas binaries are generated.