Django

Code

Ticket #9877 (closed: fixed)

Opened 1 year ago

Last modified 1 year ago

More Pythonic mutations of geometry objects

Reported by: Aryeh Leib Taurog <vim@aryehleib.com> Assigned to: jbronn
Milestone: 1.1 Component: GIS
Version: 1.0 Keywords:
Cc: Triage Stage: Accepted
Has patch: 1 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 0

Description

Experimenting with geodjango, I found myself immediately wanting easier, more Pythonic ways to manipulate the data in the GEOS geometry objects:

geometryObj[i:j] = ((33.42,-70.89),(34.819,-67.61))

So I have extended the LineString and LinearRing classes' __getitem__ and __setitem__ methods to allow slicing, added a __delitem__ while I was at it, and threw in most of the non-special, standard list methods as well.

I'd like to do this for the geometry collections next, but I'm posting this here (is there a better place?) to solicit feedback on these mods before I continue.

Questions

1. Is there some really good reason not to do this that I'm missing, or am I just the first one who wanted it enough to sit down and do it?

2. Did I do this correctly? It seems to work. I tested the correctness of the mutations themselves, but haven't extensively tested the GEOS methods on the mutated objects.

3. I've created a situation where

del geometryObj[:]  # now works
geometryObj = LinearString([]) # doesn't work

Is there some reason I shouldn't do that?

4. Does it make sense to implement similar mutation methods for Point objects or Polygon objects?

5. I think it would be nice to make the LinearRing mutations fool-proof. Meaning since the first and last point must be the same, a LinearRing object with n points should really behave like a list of n - 1 coordinates, all the while maintaining the last coordinate as a mirror of the first so that the geometry won't be invalidated by the mutations. Comments?

6. I implemented count() which is redundant with __len__() and, in this case, num_points(). Overkill?

7. Also I'm not sure if index(x) and remove(x) made sense in this context, but I could imagine cases where they might be useful and so I erred on the side of implementing as much of the standard list interface as I thought reasonable. Comments?

8. The sort() and reverse() methods don't seem applicable here. These are the only standard list methods which I did not implement. However, I think that they might apply to the geometry collections. Comments?

Attachments

pythonic_mutation_patch_part_I (17.8 kB) - added by Aryeh Leib Taurog <vim@aryehleib.com> on 12/17/08 16:13:46.
This is a patch to the django 1.0.2 release
pythonic_mutation_patch_part_I.2 (19.3 kB) - added by Aryeh Leib Taurog <vim@aryehleib.com> on 12/18/08 09:49:09.
This is an updated patch to Django 1.0.2 release
pythonic_mutation_patch_part_II (28.5 kB) - added by Aryeh Leib Taurog <vim@aryehleib.com> on 12/31/08 12:12:27.
More complete list-style mutations for Geometry Collections; refactored code

Change History

12/17/08 16:13:46 changed by Aryeh Leib Taurog <vim@aryehleib.com>

  • attachment pythonic_mutation_patch_part_I added.

This is a patch to the django 1.0.2 release

12/18/08 09:49:09 changed by Aryeh Leib Taurog <vim@aryehleib.com>

  • attachment pythonic_mutation_patch_part_I.2 added.

This is an updated patch to Django 1.0.2 release

12/18/08 09:53:10 changed by Aryeh Leib Taurog <vim@aryehleib.com>

  • needs_better_patch changed.
  • needs_tests changed.
  • needs_docs changed.

Regarding question 2 above, I've attached an updated patch with additional tests checking that the following GEOS properties work as expected on the mutated geometries:

num_coords, empty, valid, simple, ring, boundary, convex_hull, extend, area, length

12/31/08 12:08:27 changed by Aryeh Leib Taurog <vim@aryehleib.com>

I've completed a second round of modifications and am attaching a patch which supersedes the previous patches.

I modified the GeometryCollection class with list-like, slice-enabled mutations. I then refactored the code, placing the bulk of the modifications in a ListMixin class, which I added as a superclass to both LineString and GeometryCollection. I'm sure a similar mixin exists already somewhere (the UserList module did not seem to be appropriate) but I didn't know where to look.

I also modified the tests (with a little bending backwards) to exercise both the geometries and the geometry collections. Currently the tests operate on LineString, LinearRing, MultiPoint, and MultiLineString.

I am still relatively new both to Django and to Python, so I'd love some feedback on style, etc.

12/31/08 12:12:27 changed by Aryeh Leib Taurog <vim@aryehleib.com>

  • attachment pythonic_mutation_patch_part_II added.

More complete list-style mutations for Geometry Collections; refactored code

12/31/08 12:16:32 changed by Aryeh Leib Taurog <vim@aryehleib.com>

Note that the pythonic_mutation_patch_part_II attachment is also a patch to the django 1.0.2 release and supersedes the patches I attached earlier.

03/09/09 18:36:56 changed by jbronn

  • milestone set to 1.1.

03/09/09 18:37:14 changed by jbronn

  • owner changed from nobody to jbronn.
  • status changed from new to assigned.
  • stage changed from Unreviewed to Accepted.

03/23/09 19:12:22 changed by jbronn

  • status changed from assigned to closed.
  • resolution set to fixed.

(In [10131]) Refactored the GEOS interface. Improvements include:

* Geometries now allow list-like manipulation, e.g., can add, insert, delete vertexes (or other geometries in collections) like Python lists. Thanks, Aryeh Leib Taurog. * Added support for GEOS prepared geometries via prepared property. Prepared geometries significantly speed up certain operations. * Added support for GEOS cascaded union as MultiPolygon.cascaded_union property. * Added support for GEOS line merge as merged property on LineString, and MultiLineString geometries. Thanks, Paul Smith. * No longer use the deprecated C API for serialization to/from WKB and WKT. Now use the GEOS I/O classes, which are now exposed as WKTReader, WKTWriter, WKBReader, and WKBWriter (which supports 3D and SRID inclusion) * Moved each type of geometry to their own module, eliminating the cluttered geometries.py. * Internally, all C API methods are explicitly called from a module rather than a star import.

Fixed #9557, #9877, #10222


Add/Change #9877 (More Pythonic mutations of geometry objects)




Change Properties
Action