Monday, September 29, 2014

Join 2 lines in QGIS

There is a useful plugin in QGIS - Join Lines, that can be used to join two lines into one; reversing the direction of vertices of one line if necessary. This can be useful if you want to construct polygons later on from the lines. The following example shows a problem that can arise if generating polygons from lines that have opposing directions.

The screenshot below shows the counter-clockwise digitized direction of a line feature.


The other line feature is digitized in a clockwise direction.


If a polygon is constructed using the QGIS Line to Polygon function, the following polygon will be generated.


Using the Join Lines command

  1. If the Join Lines plug-in is not installed, select Plug-ins | Manage and install plug-ins and install the Join Lines plug-in.


  2. In the map view, select two lines.


  3. Select Vector | Join two lines | Join two lines.


  4. Select Layer | Toggle editing.


  5. Click Save.

    The joined line is saved.
If the joined lines are used to generate a polygon, the following area geometry will be constructed.


Monday, September 22, 2014

Example Windows Phone 8 C# code to show AdMob interstitial ad on start up

I did not find examples on the net illustrating how to show an AdMob interstitial advertisement when a Windows Phone 8 app is started. So here is an example I wrote using C#, basing it on an Android example. In a nutshell, the following need to be done:

  1. Create a splash screen XAML file
  2. Edit the splash screen code behind file
  3. Set the splash screen XAML as the start up object
  4. Override the Windows Phone 8 app main page XAML's OnNavigatedTo method to prevent the back key from bringing up the splash screen
Create a splash screen XAML
  1. In Visual Studio, add a New Item to the Windows Phone 8 project. Give it a name e.g. SplashScreen.xaml.


  2. Edit the newly created splash screen XAML file to your liking. In this example, we want to display only a progress bar without any text, as shown in the code below.

<phone:PhoneApplicationPage
x:Class="dominoc925.GPSLocalTime.SplashScreen"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">
 
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
 
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
</StackPanel>
 
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ProgressBar Margin="10" IsIndeterminate="True" />
</Grid>
</Grid>
 
</phone:PhoneApplicationPage>

Edit the splash screen code behind file

  1. In Visual Studio, open the splash screen code behind file e.g. splashscreen.xaml.cs.
  2. Code in the following:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using GoogleAds;
using System.Threading;
 
namespace dominoc925.GPSLocalTime
{
public partial class SplashScreen : PhoneApplicationPage
{
//The time to wait for the ad to load in milliseconds
private static int WAIT_TIME = 5000;
private static string INTERSTITIAL_AD_UNIT_ID = "ca-app-pub-xxxxxxxxxxxxxxxxxx";
#if DEBUG
private static bool ADMOB_FORCE_TESTING = true;
#else
private static bool ADMOB_FORCE_TESTING = false;
#endif
private static Timer _waitTimer;
private static bool _interstitialCanceled = false;
 
private InterstitialAd _interstitialAd;
 
public SplashScreen()
{
InitializeComponent();

_interstitialAd = new InterstitialAd(INTERSTITIAL_AD_UNIT_ID);

//Set up the Ad event listeners
_interstitialAd.ReceivedAd += OnAdReceived;
_interstitialAd.FailedToReceiveAd += OnAdFailedToLoad;
_interstitialAd.DismissingOverlay += OnAdDismissed;
 
AdRequest adRequest = new AdRequest();
adRequest.ForceTesting = ADMOB_FORCE_TESTING;
_interstitialAd.LoadAd(adRequest);
 
TimerCallback callback = new TimerCallback(ProcessTimerEvent);
_waitTimer = new Timer(callback, this, WAIT_TIME, Timeout.Infinite);
}
//Cancel the timer when the waiting time has been reached and show the App's main page.
private void ProcessTimerEvent(object obj)
{
_interstitialCanceled = true;
_waitTimer.Dispose();
 
Dispatcher.BeginInvoke(() =>
{
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
});
}
//Display the App's main page when the user dismisses the ad 
private void OnAdDismissed(object sender, AdEventArgs e)
{
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
//Display the App's main page when the ad fails to load
private void OnAdFailedToLoad(object sender, AdErrorEventArgs e)
{
_waitTimer.Dispose();
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
//Show the ad only when the ad has been received and within the waiting time 
private void OnAdReceived(object sender, AdEventArgs e)
{
if (!_interstitialCanceled)
{
_waitTimer.Dispose();
_interstitialAd.ShowAd();
}
}
}
}
Set the splash screen XAML file as the start up object

  1. In Visual Studio, open up the file WMAppManifest.xml file in the designer.

  2. In the Navigation Page field, type in the name of the splash screen XAML file e.g. SplashScreen.xaml.

Override the main page's OnNavigatedTo method
  1. In Visual Studio, open up the main page's code behind file e.g. MainPage.xaml.cs.

  2. In the code editor, change the OnNavigatedTo method to the following:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (NavigationService.BackStack.Count() == 1)
{
NavigationService.RemoveBackEntry();
}
}

Note: This will remove the splash screen XAML from the back stack i.e. when the user press the back button, the splash screen will not be loaded again.

Now when the Windows app is run, the splash screen will load and may display an interstitial ad as shown below.

Monday, September 15, 2014

Android App for monitoring 911 incident calls in Tampa Bay, Florida


Users can monitor Tampa City's Fire Dept.'s call for services (updated every 10 minutes), the Police Department's calls for service (updated within 30 to 45 minutes), and traffic related calls for service (updated every 15 minutes); and Pinellas County's fire call for services. The incidents can be viewed as a text list or on a map as icons or as a heat map. Examples of incidents include burglary, accident, fire, assault, drugs, death, and many more. Incident details can be viewed by touching an item on the list or a marker on the map display. A function is available to easily filter away unwanted incidents from the list or map by text. The app allows the user to send the incident location to Google Maps and/or Street View for better visualization of the 911 incident environment.

Upon launching the app on a handset, the list of incidents will be downloaded (if not downloaded before) and displayed with associated icons as shown below. Subsequently, the user will have to explicitly tap the Refresh icon and choose a feed to download again. 
The list of incidents can be filtered by using the Filter command, which is activated by selecting the Filter icon on the Action bar or menu item. This will toggle the display of the filter text entry field. As you type in any text, e.g. medical, the incident list is dynamically updated. 
To view all the incidents on a map, just tap the Map option item in the Action Bar menu. The filter (if any) remains in effect until it is cleared. Touching any incident icon will pop up a snippet of information about the incident. Touching the snippet will display the incident details.
Users can visualize the incidents a heat map instead of as marker icons. This can be done by choosing the Heat map option item in the Action Bar menu, as shown below. To display as marker icons again, just choose the Markers option item in the Action Bar menu. 
Long pressing any item in the incident list will pop up a menu, as shown below, where the selected incident can be shared, located on a map, or sent to the Google Maps or Street View apps. 

On a tablet, the app will display a two pane layout - an incident list on the left, and a map view on the right, as shown below. 

As on a handset, the incidents can be displayed as marker icons or as a heat map. 
Long pressing an item on the list will pop up a menu.

To refresh the incident list, tap the Refresh icon and choose a feed to download. 

You can download this app on the Play Store.
Get it on Google Play

Monday, September 8, 2014

C# code snippet to write a Stanford Polygon binary file

The Stanford Polygon file format (PLY) is a standard three-dimensional file format typically used in 3-D software such as Blender, 3D Studio Max and many others. I looked for some C# source code to write 3-D data into a file in binary PLY format but could only find C++ examples. So I came up with my own code snippet which just writes out simple 3-D vertices without additional properties, as shown below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
 
SomeFunction()
{
BinaryWriter writer = new BinaryWriter(new FileStream("myBinaryFile.ply", FileMode.Create), Encoding.ASCII);
//Write the headers for 3 vertices
writer.Write(str2byteArray("ply\n"));
writer.Write(str2byteArray("format binary_little_endian 1.0\n"));
writer.Write(str2byteArray("element vertex 3\n"));
writer.Write(str2byteArray("property float x\n"));
writer.Write(str2byteArray("property float y\n"));
writer.Write(str2byteArray("property float z\n"));
writer.Write(str2byteArray("end_header\n"));

//Write the 1st vertex
writer.Write(float2byteArray((float)1000.0));
writer.Write(float2byteArray((float)1230.3));
writer.Write(float2byteArray((float)2390.1));

//... write the remaining 2 vertices here

//Close the binary writer
writer.Close();
}
private byte[] float2byteArray(float value)
{
return BitConverter.GetBytes(value);
}
private byte[] str2byteArray(string theString)
{
return System.Text.Encoding.ASCII.GetBytes(theString);
}
This example is meant only for little endian machines.

Monday, September 1, 2014

How to build 3D Toolkit's SLAM6D on Ubuntu 64 bit

The open source 3D Toolkit http://slam6d.sourceforge.net/index.html provides tools to process 3D point clouds. The binary executables can be downloaded but unfortunately they may be outdated. The latest and greatest can be downloaded from the source code repository but you must build and compile the code. I could not compile it successfully on Windows but I could do it on the latest Ubuntu 14.04 64 bit operating system.

The following steps show how to build SLAM6D on Ubuntu.

  1. In Ubuntu, open a Terminal window.
  2. If necessary, update Ubuntu and download the g++ compiler and other development essentials. Run the following commands.

    $ sudo apt-get update
    $ sudo apt-get install build-essential

  3. Download the latest SLAM6D source code to a folder e.g. /home/obama/Documents/slam6d-code.

    $ svn checkout http://svn.code.sf.net/p/slam6d/code/trunk slam6d-code
  4. Install the prerequisite Boost libraries.

    $ sudo apt-get install libboost-all-dev libcv-dev freeglut3-dev libxmu-dev libxi-dev
  5. Use an Internet browser to download the latest OpenCV source code for Linux from http://opencv.org/downloads.html. Extract the files into a folder e.g. /home/obama/Documents/opencv-2.4.9/.
  6. In a Terminal window, use cmake to configure OpenCV source code by entering the following commands.

    $ cd opencv-2.4.9
    $ mkdir release
    $ cd release
    $ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..

  7. Now compile and install OpenCV.

    $ make
    $ sudo make install

  8. Compile and build the SLAM6D source code downloaded previously.

    $ cd slam6d-code
    $ make

At this point, the SLAM6D executables would have been built and can be used to process 3D point clouds.