Working with Spatialite

Working with Spatialite

Here is an example of how you can work with a SQLite Database in ArchGDAL.jl, and follows the tutorial in http://www.gaia-gis.it/gaia-sins/spatialite-tutorial-2.3.1.html.

We will work with the following database:

import ArchGDAL
const AG = ArchGDAL

filepath = download("https://github.com/yeesian/ArchGDALDatasets/raw/e0b15dca5ad493c5ebe8111688c5d14b031b7305/spatialite/test-2.3.sqlite", "test.sqlite")

Here's a quick summary of test.sqlite:

AG.registerdrivers() do
    AG.read(filepath) do dataset
        print(dataset)
    end
end

We will display the results of running query on the dataset using the following function:

function inspect(query, filename=filepath)
    AG.registerdrivers() do
        AG.read(filename) do dataset
            AG.executesql(dataset, query) do results
                print(results)
            end
        end
    end
end
inspect (generic function with 2 methods)

Constructing SQL Queries

A Simple LIMIT Query

Here's a first query:

inspect("SELECT * FROM towns LIMIT 5")

A few points to understand:

A Simple ORDER BY Query

Now try this second SQL query:

inspect("select name AS Town, peoples as Population from towns ORDER BY name LIMIT 5")

Some remarks:

The WHERE and ORDER BY clauses

A more complex SQL query:

inspect("""select name, peoples from towns
           WHERE peoples > 350000 order by peoples DESC""")

Some remarks:

Using SQL functions

inspect("""
select COUNT(*) as '# Towns',
    MIN(peoples) as Smaller,
    MAX(peoples) as Bigger,
    SUM(peoples) as 'Total peoples',
    SUM(peoples) / COUNT(*) as 'mean peoples for town'
from towns
""")

Constructing Expressions

inspect("select (10 - 11) * 2 as Number, ABS((10 - 11) * 2) as AbsoluteValue")

The HEX() function

inspect("""
select name, peoples, HEX(Geometry)
from Towns where peoples > 350000 order by peoples DESC
""")
Note

SQLite in its own hasn't the slightest idea of what GEOMETRY is, and cannot do any other operation on it. To really use GEOMETRY values, it's time use the SpatiaLite extension.

Spatialite Features

Well-Known Text

inspect("""
SELECT name, peoples, AsText(Geometry)
from Towns where peoples > 350000 order by peoples DESC
""")

Working with Coordinates

inspect("""
SELECT name, X(Geometry), Y(Geometry) FROM Towns
WHERE peoples > 350000 
ORDER BY peoples DESC
""")
inspect("SELECT HEX(GeomFromText('POINT(10 20)'))")

Format Conversions

you can use the following GEOMETRY format conversion functions:

inspect("SELECT HEX(AsBinary(GeomFromText('POINT(10 20)')))")
inspect("SELECT AsText(GeomFromWKB(X'010100000000000000000024400000000000003440'))")

GEOMETRY Classes

LINESTRING

inspect("SELECT PK_UID, AsText(Geometry) FROM HighWays WHERE PK_UID = 10")
inspect("""
SELECT PK_UID, NumPoints(Geometry), GLength(Geometry),
       Dimension(Geometry), GeometryType(Geometry)
FROM HighWays ORDER BY NumPoints(Geometry) DESC LIMIT 5
""")
inspect("""
SELECT PK_UID, NumPoints(Geometry),
       AsText(StartPoint(Geometry)), AsText(EndPoint(Geometry)),
       X(PointN(Geometry, 2)), Y(PointN(Geometry, 2))
FROM HighWays ORDER BY NumPoints(Geometry) DESC LIMIT 5
""")

POLYGON

inspect("SELECT name, AsText(Geometry) FROM Regions WHERE PK_UID = 52")
inspect("""
SELECT PK_UID, Area(Geometry), AsText(Centroid(Geometry)),
       Dimension(Geometry), GeometryType(Geometry)
FROM Regions ORDER BY Area(Geometry) DESC LIMIT 5
""")
inspect("""
SELECT PK_UID, NumInteriorRings(Geometry),
       NumPoints(ExteriorRing(Geometry)), NumPoints(InteriorRingN(Geometry, 1))
FROM regions ORDER BY NumInteriorRings(Geometry) DESC LIMIT 5
""")
inspect("""
SELECT AsText(InteriorRingN(Geometry, 1)),
       AsText(PointN(InteriorRingN(Geometry, 1), 4)),
       X(PointN(InteriorRingN(Geometry, 1), 5)),
       Y(PointN(InteriorRingN(Geometry, 1), 5))
FROM Regions WHERE PK_UID = 55
""")
inspect("""
SELECT Name, AsText(Envelope(Geometry)) FROM Regions LIMIT 5
""")

Complex Geometry Classes

POINT, LINESTRING and POLYGON are the elementary classes for GEOMETRY. But GEOMETRY supports the following complex classes as well:

We'll not explain in detail this kind of collections, because it will be simply too boring and dispersive. Generally speaking, they extend in the expected way to their corresponding elementary classes, e.g.