mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-28 04:44:26 +02:00
Add documentation for gis functions
This commit is contained in:
parent
653350a551
commit
5581756831
2 changed files with 124 additions and 26 deletions
|
|
@ -291,9 +291,9 @@ This method also accepts ``offset=`` and ``limit=`` arguments, for specifying an
|
||||||
Counting rows
|
Counting rows
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
To count the number of rows that would be returned by a where filter, use ``.count_where(where, where_args)``:
|
To count the number of rows that would be returned by a where filter, use ``.count_where(where, where_args)`` :
|
||||||
|
|
||||||
>>> db["dogs"].count_where("age > ?", [1]):
|
>>> db["dogs"].count_where("age > ?", [1])
|
||||||
2
|
2
|
||||||
|
|
||||||
.. _python_api_pks_and_rows_where:
|
.. _python_api_pks_and_rows_where:
|
||||||
|
|
@ -1246,7 +1246,7 @@ To change the primary key for a table, use ``pk=``. This can be passed a single
|
||||||
Changing not null status
|
Changing not null status
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
You can change the ``NOT NULL`` status of columns by using ``not_null=``. You can pass this a set of columns to make those columns ``NOT NULL``:
|
You can change the ``NOT NULL`` status of columns by using ``not_null=``. You can pass this a set of columns to make those columns ``NOT NULL`` :
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
|
@ -2340,26 +2340,6 @@ For example:
|
||||||
# [thumbnail] BLOB
|
# [thumbnail] BLOB
|
||||||
# )
|
# )
|
||||||
|
|
||||||
.. _find_spatialite:
|
|
||||||
|
|
||||||
Finding SpatiaLite
|
|
||||||
==================
|
|
||||||
|
|
||||||
The ``find_spatialite()`` function searches for the `SpatiaLite <https://www.gaia-gis.it/fossil/libspatialite/index>`__ SQLite extension in some common places. It returns a string path to the location, or ``None`` if SpatiaLite was not found.
|
|
||||||
|
|
||||||
You can use it in code like this:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from sqlite_utils import Database
|
|
||||||
from sqlite_utils.gis import find_spatialite
|
|
||||||
|
|
||||||
db = Database("mydb.db")
|
|
||||||
spatialite = find_spatialite()
|
|
||||||
if spatialite:
|
|
||||||
db.conn.enable_load_extension(True)
|
|
||||||
db.conn.load_extension(spatialite)
|
|
||||||
|
|
||||||
.. _python_api_register_function:
|
.. _python_api_register_function:
|
||||||
|
|
||||||
Registering custom SQL functions
|
Registering custom SQL functions
|
||||||
|
|
@ -2440,3 +2420,40 @@ If that option isn't relevant to your use-case you can to quote a string for use
|
||||||
"'hello'"
|
"'hello'"
|
||||||
>>> db.quote("hello'this'has'quotes")
|
>>> db.quote("hello'this'has'quotes")
|
||||||
"'hello''this''has''quotes'"
|
"'hello''this''has''quotes'"
|
||||||
|
|
||||||
|
Spatialite helpers
|
||||||
|
==================
|
||||||
|
|
||||||
|
`SpatiaLite <https://www.gaia-gis.it/fossil/libspatialite/index>`__ is a geographic extension to SQLite (similar to PostgreSQL + PostGIS). Using requires finding, loading and initializing the extension, adding geometry columns to existing tables and optionally creating spatial indexes. The utilities here help streamline that setup.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _init_spatialite:
|
||||||
|
|
||||||
|
Initialize Spatialite
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
.. autofunction:: sqlite_utils.gis.init_spatialite
|
||||||
|
|
||||||
|
|
||||||
|
.. _find_spatialite:
|
||||||
|
|
||||||
|
Finding Spatialite
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
.. autofunction:: sqlite_utils.gis.find_spatialite
|
||||||
|
|
||||||
|
|
||||||
|
.. _add_geometry_column:
|
||||||
|
|
||||||
|
Adding geometry columns
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
.. autofunction:: sqlite_utils.gis.add_geometry_column
|
||||||
|
|
||||||
|
.. _create_spatial_index:
|
||||||
|
|
||||||
|
Creating a spatial index
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
.. autofunction:: sqlite_utils.gis.create_spatial_index
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,22 @@ SPATIALITE_PATHS = (
|
||||||
|
|
||||||
|
|
||||||
def find_spatialite() -> str:
|
def find_spatialite() -> str:
|
||||||
|
"""
|
||||||
|
The ``find_spatialite()`` function searches for the `SpatiaLite <https://www.gaia-gis.it/fossil/libspatialite/index>`__ SQLite extension in some common places. It returns a string path to the location, or ``None`` if SpatiaLite was not found.
|
||||||
|
|
||||||
|
You can use it in code like this:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from sqlite_utils import Database
|
||||||
|
from sqlite_utils.gis import find_spatialite
|
||||||
|
|
||||||
|
db = Database("mydb.db")
|
||||||
|
spatialite = find_spatialite()
|
||||||
|
if spatialite:
|
||||||
|
db.conn.enable_load_extension(True)
|
||||||
|
db.conn.load_extension(spatialite)
|
||||||
|
"""
|
||||||
for path in SPATIALITE_PATHS:
|
for path in SPATIALITE_PATHS:
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
return path
|
return path
|
||||||
|
|
@ -15,7 +31,31 @@ def find_spatialite() -> str:
|
||||||
|
|
||||||
|
|
||||||
def init_spatialite(db: Database, path: str) -> None:
|
def init_spatialite(db: Database, path: str) -> None:
|
||||||
"Load spatialite extension for a database"
|
"""
|
||||||
|
The ``init_spatialite`` function will load and initalize the Spatialite extension.
|
||||||
|
The ``path`` argument should be an absolute path to the compiled extension, which
|
||||||
|
can be found using ``find_spatialite``.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from sqlite_utils.gis import find_spatialite, init_spatialite
|
||||||
|
|
||||||
|
db = Database("mydb.db")
|
||||||
|
init_spatialite(db, find_spatialite())
|
||||||
|
|
||||||
|
If you've installed Spatialite somewhere unexpected (for testing an alternate version, for example)
|
||||||
|
you can pass in an absolute path:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from sqlite_utils.gis import init_spatialite
|
||||||
|
|
||||||
|
db = Database("mydb.db")
|
||||||
|
init_spatialite(db, "./local/mod_spatialite.dylib")
|
||||||
|
|
||||||
|
"""
|
||||||
db.conn.enable_load_extension(True)
|
db.conn.enable_load_extension(True)
|
||||||
db.conn.load_extension(path)
|
db.conn.load_extension(path)
|
||||||
# Initialize SpatiaLite if not yet initialized
|
# Initialize SpatiaLite if not yet initialized
|
||||||
|
|
@ -32,7 +72,27 @@ def add_geometry_column(
|
||||||
coord_dimension: str = "XY",
|
coord_dimension: str = "XY",
|
||||||
not_null: bool = False,
|
not_null: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
"Add a geometry column to a table"
|
"""
|
||||||
|
In Spatialite, a geometry column can only be added to an existing table.
|
||||||
|
To do so, use ``add_geometry_column``, passing in a :ref:`table <reference_db_table>`
|
||||||
|
and geometry type.
|
||||||
|
|
||||||
|
By default, this will add a nullable column called ``geometry`` using
|
||||||
|
`SRID 4326 <https://spatialreference.org/ref/epsg/wgs-84/>`__. These can be customized using
|
||||||
|
the ``column_name`` and ``srid`` arguments.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from sqlite_utils.gis import find_spatialite, init_spatialite, add_geometry_column
|
||||||
|
|
||||||
|
db = Database("mydb.db")
|
||||||
|
init_spatialite(db, find_spatialite())
|
||||||
|
|
||||||
|
# the table must exist before adding a geometry column
|
||||||
|
db["locations"].create({"name": str})
|
||||||
|
add_geometry_column(db["locations"], "POINT")
|
||||||
|
|
||||||
|
"""
|
||||||
table.db.execute(
|
table.db.execute(
|
||||||
"SELECT AddGeometryColumn(?, ?, ?, ?, ?, ?);",
|
"SELECT AddGeometryColumn(?, ?, ?, ?, ?, ?);",
|
||||||
[table.name, column_name, srid, geometry_type, coord_dimension, int(not_null)],
|
[table.name, column_name, srid, geometry_type, coord_dimension, int(not_null)],
|
||||||
|
|
@ -40,5 +100,26 @@ def add_geometry_column(
|
||||||
|
|
||||||
|
|
||||||
def create_spatial_index(table: Table, column_name: str = "geometry") -> None:
|
def create_spatial_index(table: Table, column_name: str = "geometry") -> None:
|
||||||
"Create a spatial index for a table and column"
|
"""
|
||||||
|
A spatial index allows for significantly faster bounding box queries.
|
||||||
|
To create on, use ``create_spatial_index`` with a :ref:`table <reference_db_table>`
|
||||||
|
and the name of an existing geometry column.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from sqlite_utils.gis import add_geometry_column, create_spatial_index
|
||||||
|
|
||||||
|
# assuming Spatialite is loaded, create the table, add the column
|
||||||
|
db["locations"].create({"name": str})
|
||||||
|
add_geometry_column(db["locations"], "POINT", "geometry")
|
||||||
|
|
||||||
|
# now we can index it
|
||||||
|
create_spatial_index(db["locations"], "geometry")
|
||||||
|
|
||||||
|
# the spatial index is a virtual table, which we can inspect
|
||||||
|
print(db["idx_locations_geometry"].schema)
|
||||||
|
# outputs:
|
||||||
|
# CREATE VIRTUAL TABLE "idx_locations_geometry" USING rtree(pkid, xmin, xmax, ymin, ymax)
|
||||||
|
|
||||||
|
"""
|
||||||
table.db.execute("select CreateSpatialIndex(?, ?)", [table.name, column_name])
|
table.db.execute("select CreateSpatialIndex(?, ?)", [table.name, column_name])
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue