Monday, October 24, 2016

Tip to speed up the Android Studio project build compilation process

Android Studio builds Android projects with the default Gradle property settings. If you find the build process taking a long time and your computer has adequate memory, it is possible to tweak the settings to allocate more memory to the build process to reduce the compilation time.

In Android Studio, open up the top level gradle.properties file to change the settings, as shown below.


In the editor, locate the commented line with the string "org.gradle.jvmargs", and make a copy of it directly underneath; then remove the # character to un-comment it.

An example of an edited gradle.properties file is shown below.

# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

Now, the build process should complete faster.

Monday, October 17, 2016

Example efficient two pass Spatialite query to find if a point is inside a polygon

A spatial query can be expensive to run in terms of CPU processing power. In order to improve the query performance, typically, a first pass query is done to reduce the candidates first before running a second pass query to do actual spatial query. The following is an example using SpatiaLite to perform a two pass spatial query to find whether a point is contained within a polygon.
Point 1 is totally outside of any polygons; Point 2 is outside but within a bounding rectangle of a polygon; Point 3 is totally inside a polygon.
The two pass SpatiaLite query has the following syntax.
Note: the first approximate query uses the MBRCONTAINS function and the second finer query uses the ST_CONTAINS function.
SELECT ST_CONTAINS(polygonGeometry, geomfromtext('POINT(116.4688 -31.5502)', 4326))
FROM(
SELECT
polygonGeometry,
MBRCONTAINS(polygonGeometry, geomfromtext('POINT(116.4688 -31.5502)', 4326)) AS inMBR
FROM
(
SELECT geometry AS polygonGeometry FROM MyPolygon
)
WHERE inMBR = 1
)



Case 1: Totally outside 
For Point 1 (Totally outside), the query returns no rows since the point is outside of any bounding rectangles, as shown in the screenshot below.


Case 2: Outside of any polygons but within a bounding rectangle
For Point2, the query returns a result of 0 value, since the point is inside a bounding rectangle but outside of any polygon.

Case 3: Totally inside a polygon
For Point 3, the query returns a result of 1 since the point is inside a bounding rectangle and also inside a polygon.


Monday, October 10, 2016

Simple C# example for creating and using a Spatialite database

A Spatialite database is just a SQLite database loaded with Spatialite module extensions including tables, triggers, functions etc. It is therefore possible to access a Spatialite database using the SQLite .Net Wrapper from https://system.data.sqlite.org and with the Spatialite module extension library mod_spatialite-x.x.x from http://www.gaia-gis.it/gaia-sins/, otherwise the spatial functions will not be available to your C# code.

While the Spatialite database can be created using the SQLite wrapper and the Spatialite module extension, the newly created database lacks all the Spatialite tables, triggers etc. necessary for proper functioning of the Spatialite database. I would need to run some initialization SQL to create all the required Spatialite tables, triggers, etc. So instead, I found it more convenient to create a template Spatialite database with the Spatialite executable beforehand. Then in the C# program, just simple copy the template to create a new Spatialite database.

 The following is an example C# code snippet illustrating creating a new Spatialite database from a pre-prepared template and making a SQL query reading some Spatialite geometry fields from the database.

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System.Data.SQLite;

//...etc...

string pathTemplate = @"\path\to\spatiaLiteTemplate.db";
string destDbFilename = @"\path\to\dest.db";

// Copy the template Spatialite file to the destination Spatialite file
File.Copy(pathTemplate, destDbFilename);

// Create Spatialite SQL Connection
string connectString = "Data Source=" + destDbFilename + ";Version=3;";
SQLiteConnection connection = new SQLiteConnection(connectString);

// Open the database and load in the Spatialite extension
connection.Open();
connection.LoadExtension("mod_spatialite");

// ...etc ...

// Make some Spatialite function calls
string sql = "SELECT ST_MINX(geometry), ST_MINY(geometry), ST_MAXX(geometry), ST_MAXY(geometry) FROM somefeature ";

using (SQLiteCommand command = new SQLiteCommand(sql, connection))
{
 using (SQLiteDataReader reader = command.ExecuteReader())
 {
  while (reader.Read())
  {
   double minX = reader.GetDouble(0);
   double minY = reader.GetDouble(1);
   double maxX = reader.GetDouble(2);
   double maxY = reader.GetDouble(3);
  }
 }
}

// Close and clean up the database connection
connection.Close();
connection.Dispose();
 
//...etc... 


Monday, October 3, 2016

Replaying network packets captured in a PCAP file

Some devices broadcast GPS positions over the network and saved into a PCAP file. Incidentally, PCAP stands for Packet CAPture. I got hold of some PCAP files and tried to use the Linux tcpreplay command to playback the captured network packets over the network.

The tcpreplay command input arguments require to specify the network interface and it conveniently advertises an option --listnics to list all the network interfaces on your machine. An example usage is displayed in  the screenshot below.

$ sudo tcpreplay --listnics


However, using any of the listed interfaces will result in an error when attempting to playback a pcap file, as shown below.

$ sudo tcpreplay --intf1 bluetooth0 *.pcap



After some research, I found the ip command with the link option that lists the network interfaces correctly.

$ ip link



Now plugging in the correct interface name into the tcpreplay command, my network packets are successfully replayed and broadcasted.

$ sudo tcpreplay --intf1 enp0s25 *.pcap