From 0fd67f19a8f8ea87d76e512ac5f84d1c252ab824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Sat, 2 Mar 2019 14:55:04 +0100 Subject: [PATCH 1/2] Improve docs related to EWKB and SRID --- geoalchemy2/elements.py | 39 ++++++++++++++++++++------------------- geoalchemy2/types.py | 5 +++++ 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/geoalchemy2/elements.py b/geoalchemy2/elements.py index fb147fbc..d159bc12 100644 --- a/geoalchemy2/elements.py +++ b/geoalchemy2/elements.py @@ -130,32 +130,33 @@ class WKBElement(_SpatialElement): type. In most cases you won't need to create ``WKBElement`` instances yourself. + If ``extended`` is ``True`` and ``srid`` is ``-1`` at construction time + then the SRID will be read from the EWKB data. + Note: you can create ``WKBElement`` objects from Shapely geometries using the :func:`geoalchemy2.shape.from_shape` function. - - Extended WKB automatically parse unknown SRID. - Warning: unicode data are assumed to be hexadecimal value. - - WKB struct { - byte byteOrder; - uint32 wkbType; - uint32 SRID; - struct geometry; - } - - byteOrder enum { - WKB_XDR = 0, // Most Significant Byte First - WKB_NDR = 1, // Least Significant Byte First - } - """ geom_from = 'ST_GeomFromWKB' geom_from_extended_version = 'ST_GeomFromEWKB' def __init__(self, data, srid=-1, extended=False): - if extended and srid == -1: # unpack srid from WKB struct - if isinstance(data, str_): # unicode data assumed to be hex val + if extended and srid == -1: + # read srid from the EWKB + # + # WKB struct { + # byte byteOrder; + # uint32 wkbType; + # uint32 SRID; + # struct geometry; + # } + # byteOrder enum { + # WKB_XDR = 0, // Most Significant Byte First + # WKB_NDR = 1, // Least Significant Byte First + # } + if isinstance(data, str_): + # SpatiaLite case + # assume that the string is an hex value header = binascii.unhexlify(data[:18]) else: header = data[:9] @@ -163,7 +164,6 @@ def __init__(self, data, srid=-1, extended=False): header = bytearray(header) byte_order, srid = header[0], header[5:] srid = struct.unpack('I', srid)[0] - _SpatialElement.__init__(self, data, srid, extended) @property @@ -172,6 +172,7 @@ def desc(self): This element's description string. """ if isinstance(self.data, str_): + # SpatiaLite case return self.data desc = binascii.hexlify(self.data) if PY3: diff --git a/geoalchemy2/types.py b/geoalchemy2/types.py index ad1257e6..2e01c80a 100644 --- a/geoalchemy2/types.py +++ b/geoalchemy2/types.py @@ -195,6 +195,11 @@ class Geometry(_GISType): See :class:`geoalchemy2.types._GISType` for the list of arguments that can be passed to the constructor. + If ``srid`` is set then the ``WKBElement` objects resulting from queries will + have that SRID, and, when constructing the ``WKBElement`` objects, the SRID + won't be read from the data returned by the database. If ``srid`` is not set + (meaning it's ``-1``) then the SRID set in ``WKBElement` objects will be read + from the data returned by the database. """ name = 'geometry' From ffa7430d52f3a6d8b373a46846d9d4e93a7715b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Sat, 2 Mar 2019 15:46:11 +0100 Subject: [PATCH 2/2] Remove non-breaking spaces --- RELEASE.rst | 2 +- doc/spatialite_tutorial.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASE.rst b/RELEASE.rst index 393e6909..3c6405fc 100644 --- a/RELEASE.rst +++ b/RELEASE.rst @@ -4,7 +4,7 @@ Release This file provides the steps for releasing a new version of GeoAlchemy 2. Add a new section to CHANGES.txt, change the version number in ``setup.py`` and -``docs/conf.py``, then create a PR with that. Proceed when the PR is merged. +``docs/conf.py``, then create a PR with that. Proceed when the PR is merged. Make sure Travis is all green: https://travis-ci.org/geoalchemy/geoalchemy2. diff --git a/doc/spatialite_tutorial.rst b/doc/spatialite_tutorial.rst index 9960316d..8d994039 100644 --- a/doc/spatialite_tutorial.rst +++ b/doc/spatialite_tutorial.rst @@ -10,7 +10,7 @@ the :ref:`orm_tutorial`, which you may want to read first. Connect to the DB ----------------- -Just like when using PostGIS connecting to a SpatiaLite database requires an ``Engine``. This is how +Just like when using PostGIS connecting to a SpatiaLite database requires an ``Engine``. This is how you create one for SpatiaLite:: >>> from sqlalchemy import create_engine @@ -100,7 +100,7 @@ There's nothing specific to SpatiaLite here. Create a Session ---------------- -When using the SQLAlchemy ORM the ORM interacts with the database through a ``Session``. +When using the SQLAlchemy ORM the ORM interacts with the database through a ``Session``. >>> from sqlalchemy.orm import sessionmaker >>> Session = sessionmaker(bind=engine)