Skip to content

Helper methods for working with SpatiaLite #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
simonw opened this issue Jan 31, 2020 · 8 comments
Closed

Helper methods for working with SpatiaLite #79

simonw opened this issue Jan 31, 2020 · 8 comments
Labels
enhancement New feature or request spatialite

Comments

@simonw
Copy link
Owner

simonw commented Jan 31, 2020

As demonstrated by this piece of documentation, using SpatiaLite with sqlite-utils requires a fair bit of boilerplate:

# Open a database and load the SpatiaLite extension:
import sqlite3
conn = sqlite3.connect("places.db")
conn.enable_load_extension(True)
conn.load_extension("/usr/local/lib/mod_spatialite.dylib")
# Use sqlite-utils to create a places table:
db = sqlite_utils.Database(conn)
places = db["places"].create({"id": int, "name": str,})
# Add a SpatiaLite 'geometry' column:
db.conn.execute("select InitSpatialMetadata(1)")
db.conn.execute(
"SELECT AddGeometryColumn('places', 'geometry', 4326, 'MULTIPOLYGON', 2);"
)
# Fetch some GeoJSON from Who's On First:
geojson = requests.get(
"https://data.whosonfirst.org/404/227/475/404227475.geojson"
).json()
# Convert to "Well Known Text" format using shapely
wkt = shape(geojson["geometry"]).wkt
# Insert the record, converting the WKT to a SpatiaLite geometry:
db["places"].insert(
{"name": "Wales", "geometry": wkt},
conversions={"geometry": "GeomFromText(?, 4326)"},
)

@eyeseast
Copy link
Contributor

Came here to add this. I might pick it up.

Would also add a utility to create (and update and delete?) a spatial index. It's not much code but I have to look it up every time.

@eyeseast
Copy link
Contributor

Some proposals I'd add to sqlite-utils:

Some version of this, from geojson-to-sqlite:

def init_spatialite(db, lib):
    db.conn.enable_load_extension(True)
    db.conn.load_extension(lib)
    # Initialize SpatiaLite if not yet initialized
    if "spatial_ref_sys" in db.table_names():
        return
    db.conn.execute("select InitSpatialMetadata(1)")

Also a function for creating a spatial index:

db.conn.execute("select CreateSpatialIndex(?, ?)", [table, "geometry"])

I don't know the nuances of updating a spatial index, or checking if one already exists. This could be a CLI method like:

sqlite-utils spatial-index spatial.db table-name column-name

@eyeseast
Copy link
Contributor

Other thing: If there get to be enough utils, I think it's worth moving all the spatialite stuff into its own file (gis.py or something) just so it's easier to find later.

@eyeseast
Copy link
Contributor

One more thing I'm going to add: A method to add a geometry column, which I'll need to do to create a spatial index on a table.

@eyeseast
Copy link
Contributor

@simonw I have a PR here #385 that adds Spatialite helpers on the Python side. Please let me know how it looks.

@eyeseast
Copy link
Contributor

eyeseast commented Feb 3, 2022

Taking part of the conversation from #385 here.

Would sqlite-utils add-geometry-column ... be a good CLI enhancement. for example?

Yes. And also sqlite-utils create-spatial-index would be great to have. My plan would be to add those once the Python API is settled.

@simonw simonw closed this as completed in ee11274 Feb 4, 2022
simonw added a commit that referenced this issue Feb 4, 2022
simonw added a commit that referenced this issue Feb 4, 2022
simonw added a commit that referenced this issue Feb 4, 2022
Should help tests pass for #395 and #79
simonw added a commit that referenced this issue Feb 4, 2022
simonw added a commit that referenced this issue Feb 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request spatialite
Projects
None yet
Development

No branches or pull requests

2 participants