-
-
Notifications
You must be signed in to change notification settings - Fork 116
Add new spatialite helper methods #385
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
Conversation
@simonw Not sure if you've seen this, but any chance you can run the tests? |
Sorry had missed this - tests should run now. |
Codecov Report
@@ Coverage Diff @@
## main #385 +/- ##
==========================================
- Coverage 96.52% 95.91% -0.62%
==========================================
Files 6 6
Lines 2389 2421 +32
==========================================
+ Hits 2306 2322 +16
- Misses 83 99 +16
Continue to review full report at Codecov.
|
Fixed my spelling. That's a useful thing. |
OK, this change makes a bunch of sense to me - and also raises some interesting questions about future additions to I see you've already talked about that in #79 - moving this conversation there! |
To avoid needing to bump the major version number to 4 to indicate a backwards incompatible change, we should keep a |
What do you think about adding these as methods on the # This is with an optional argument, which if omitted runs find_spatialite() for you:
db.init_spatialite()
# Instead of:
init_spatialite(db, find_spatialite()) Likewise, the # Instead of this:
add_geometry_column(db["locations"], "POINT", "geometry")
create_spatial_index(db["locations"], "geometry")
# Could have this:
db["locations"].add_geometry_column("POINT")
db["locations"].create_spatial_index("geometry") On the one hand, this is much more consistent with the existing But on the other hand... this is mixing SpatiaLite functionality directly into the core classes. Is that a good idea, seeing as SpatiaLite is both an optional extension (which can be tricky to install) AND something that has a very different release cadence and quality-of-documentation from SQLite itself? There's a third option: the SpatiaLite could exist on subclasses of from sqlite_utils.gis import SpatiaLiteDatabase
db = SpatiaLiteDatabase("geo.db")
db.init_spatialite()
db["locations"].add_geometry_column("POINT")
db["locations"].create_spatial_index("geometry") On the one hand, this would keep the SpatiaLite-specific stuff out of the core Database/Table classes. But it feels a bit untidy to me, especially since it raises the spectre of someone who was already subclassing Database for some reason now needing to instead subclass So I don't have a strong opinion formed on this question yet! |
I'm not sure I like add_geometry_column(db["locations"], "POINT")
create_spatial_index(db["locations"], "geometry") I had to go and look at the code to figure out if |
sqlite_utils/gis.py
Outdated
|
||
def add_geometry_column( | ||
table: Table, | ||
geometry_type: str, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to figure out the list of valid geometry type values, which is surprisingly hard!
I eventually found a list on http://www.gaia-gis.it/gaia-sins/spatialite-sql-5.0.1.html by searching for AddGeometryColumn
- that documentation says that valid values are:
POINT
,POINTZ
,POINTM
,POINTZM
LINESTRING
,LINESTRINGZ
,LINESTRINGM
,LINESTRINGZM
POLYGON
,POLYGONZ
,POLYGONM
,POLYGONZM
MULTIPOINT
,MULTIPOINTZ
,MULTIPOINTM
,MULTIPOINTZM
MULTILINESTRING
,MULTILINESTRINGZ
,MULTILINESTRINGM
,MULTILINESTRINGZM
MULTIPOLYGON
,MULTIPOLYGONZ
,MULTIPOLYGONM
,MULTIPOLYGONZM
GEOMETRYCOLLECTION
,GEOMETRYCOLLECTIONZ
,GEOMETRYCOLLECTIONZM
,GEOMETRYCOLLECTIONZM
GEOMETRY
,GEOMETRYZ
,GEOMETRYM
,GEOMETRYZM
I was going to suggest maybe providing constants for these and requiring that the argument was one of those constants... but with that many options I'm not sure that would be better than sticking with strings, and letting SpatiaLite itself raise an exception on an invalid value!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if GEOMETRY
would be a reasonable default value for add_geometry_column(geometry_type=)
? I believe that's a column which can hold any type of geometry value - then we could allow users who want to be more restrictive to use geometry_type="POINT"
or similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I had to dig for that, too. And those types are case-insensitive, as far as I can tell. I'm happy to provide constants, but if you pass in "point"
as your geometry type, Spatialite won't complain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine to take out the default column name. Using geometry
was my effort to standardize on GeoJSON, but I've seen plenty of examples that don't. Then you could have a similar signature, something like this:
add_geometry_column(db["locations"], "geometry", "POINT")
create_spatial_index(db["locations"], "geometry")
I thought about adding these as methods on I do sort of like having all the Spatialite stuff in its own module, just because it's built around an extension you might not have or want, but I don't know if that's a good reason to have a different API. You could have |
This is fixed now. I had to take out the type annotations for |
Yeah that's too clever. You know what? I'm pretty confident we are both massively over-thinking this. We should put the methods on |
Works for me. I was just looking at how the FTS extensions work and they're just methods, too. So this can be consistent with that. |
OK, I moved all the GIS helpers into I think this is better. |
This looks fantastic, thanks for all of the work you put into this! |
Shipped this as |
Awesome. Thanks for your help getting it in. Will now look at adding CLI versions of this. It's going to be super helpful on a bunch of my projects. |
Refs #79
This PR adds three new Spatialite-related methods to Database and Table:
Database.init_spatialite
loads the Spatialite extension and initializes itTable.add_geometry_column
adds a geometry columnTable.create_spatial_index
creates a spatial indexHas tests and documentation. Feedback very welcome.