12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183 |
- ========
- GDAL API
- ========
- .. module:: django.contrib.gis.gdal
- :synopsis: GeoDjango's high-level interface to the GDAL library.
- `GDAL`__ stands for **Geospatial Data Abstraction Library**,
- and is a veritable "Swiss army knife" of GIS data functionality. A subset
- of GDAL is the `OGR`__ Simple Features Library, which specializes
- in reading and writing vector geographic data in a variety of standard
- formats.
- GeoDjango provides a high-level Python interface for some of the
- capabilities of OGR, including the reading and coordinate transformation
- of vector spatial data and minimal support for GDAL's features with respect
- to raster (image) data.
- .. note::
- Although the module is named ``gdal``, GeoDjango only supports some of the
- capabilities of OGR and GDAL's raster features at this time.
- __ https://gdal.org/
- __ https://gdal.org/user/vector_data_model.html
- Overview
- ========
- .. _gdal_sample_data:
- Sample Data
- -----------
- The GDAL/OGR tools described here are designed to help you read in
- your geospatial data, in order for most of them to be useful you have
- to have some data to work with. If you're starting out and don't yet
- have any data of your own to use, GeoDjango tests contain a number of
- data sets that you can use for testing. You can download them here:
- .. code-block:: shell
- $ wget https://raw.githubusercontent.com/django/django/main/tests/gis_tests/data/cities/cities.{shp,prj,shx,dbf}
- $ wget https://raw.githubusercontent.com/django/django/main/tests/gis_tests/data/rasters/raster.tif
- Vector Data Source Objects
- ==========================
- ``DataSource``
- --------------
- :class:`DataSource` is a wrapper for the OGR data source object that
- supports reading data from a variety of OGR-supported geospatial file
- formats and data sources using a consistent interface. Each
- data source is represented by a :class:`DataSource` object which contains
- one or more layers of data. Each layer, represented by a :class:`Layer`
- object, contains some number of geographic features (:class:`Feature`),
- information about the type of features contained in that layer (e.g.
- points, polygons, etc.), as well as the names and types of any
- additional fields (:class:`Field`) of data that may be associated with
- each feature in that layer.
- .. class:: DataSource(ds_input, encoding='utf-8')
- The constructor for ``DataSource`` only requires one parameter: the path of
- the file you want to read. However, OGR also supports a variety of more
- complex data sources, including databases, that may be accessed by passing
- a special name string instead of a path. For more information, see the
- `OGR Vector Formats`__ documentation. The :attr:`name` property of a
- ``DataSource`` instance gives the OGR name of the underlying data source
- that it is using.
- The optional ``encoding`` parameter allows you to specify a non-standard
- encoding of the strings in the source. This is typically useful when you
- obtain ``DjangoUnicodeDecodeError`` exceptions while reading field values.
- Once you've created your ``DataSource``, you can find out how many layers
- of data it contains by accessing the :attr:`layer_count` property, or
- (equivalently) by using the ``len()`` function. For information on
- accessing the layers of data themselves, see the next section:
- .. code-block:: pycon
- >>> from django.contrib.gis.gdal import DataSource
- >>> ds = DataSource("/path/to/your/cities.shp")
- >>> ds.name
- '/path/to/your/cities.shp'
- >>> ds.layer_count # This file only contains one layer
- 1
- .. attribute:: layer_count
- Returns the number of layers in the data source.
- .. attribute:: name
- Returns the name of the data source.
- __ https://gdal.org/drivers/vector/
- ``Layer``
- ---------
- .. class:: Layer
- ``Layer`` is a wrapper for a layer of data in a ``DataSource`` object. You
- never create a ``Layer`` object directly. Instead, you retrieve them from
- a :class:`DataSource` object, which is essentially a standard Python
- container of ``Layer`` objects. For example, you can access a specific
- layer by its index (e.g. ``ds[0]`` to access the first layer), or you can
- iterate over all the layers in the container in a ``for`` loop. The
- ``Layer`` itself acts as a container for geometric features.
- Typically, all the features in a given layer have the same geometry type.
- The :attr:`geom_type` property of a layer is an :class:`OGRGeomType` that
- identifies the feature type. We can use it to print out some basic
- information about each layer in a :class:`DataSource`:
- .. code-block:: pycon
- >>> for layer in ds:
- ... print('Layer "%s": %i %ss' % (layer.name, len(layer), layer.geom_type.name))
- ...
- Layer "cities": 3 Points
- The example output is from the cities data source, loaded above, which
- evidently contains one layer, called ``"cities"``, which contains three
- point features. For simplicity, the examples below assume that you've
- stored that layer in the variable ``layer``:
- .. code-block:: pycon
- >>> layer = ds[0]
- .. attribute:: name
- Returns the name of this layer in the data source.
- .. code-block:: pycon
- >>> layer.name
- 'cities'
- .. attribute:: num_feat
- Returns the number of features in the layer. Same as ``len(layer)``:
- .. code-block:: pycon
- >>> layer.num_feat
- 3
- .. attribute:: geom_type
- Returns the geometry type of the layer, as an :class:`OGRGeomType` object:
- .. code-block:: pycon
- >>> layer.geom_type.name
- 'Point'
- .. attribute:: num_fields
- Returns the number of fields in the layer, i.e the number of fields of
- data associated with each feature in the layer:
- .. code-block:: pycon
- >>> layer.num_fields
- 4
- .. attribute:: fields
- Returns a list of the names of each of the fields in this layer:
- .. code-block:: pycon
- >>> layer.fields
- ['Name', 'Population', 'Density', 'Created']
- .. attribute field_types
- Returns a list of the data types of each of the fields in this layer. These
- are subclasses of ``Field``, discussed below:
- .. code-block:: pycon
- >>> [ft.__name__ for ft in layer.field_types]
- ['OFTString', 'OFTReal', 'OFTReal', 'OFTDate']
- .. attribute:: field_widths
- Returns a list of the maximum field widths for each of the fields in this
- layer:
- .. code-block:: pycon
- >>> layer.field_widths
- [80, 11, 24, 10]
- .. attribute:: field_precisions
- Returns a list of the numeric precisions for each of the fields in this
- layer. This is meaningless (and set to zero) for non-numeric fields:
- .. code-block:: pycon
- >>> layer.field_precisions
- [0, 0, 15, 0]
- .. attribute:: extent
- Returns the spatial extent of this layer, as an :class:`Envelope` object:
- .. code-block:: pycon
- >>> layer.extent.tuple
- (-104.609252, 29.763374, -95.23506, 38.971823)
- .. attribute:: srs
- Property that returns the :class:`SpatialReference` associated with this
- layer:
- .. code-block:: pycon
- >>> print(layer.srs)
- GEOGCS["GCS_WGS_1984",
- DATUM["WGS_1984",
- SPHEROID["WGS_1984",6378137,298.257223563]],
- PRIMEM["Greenwich",0],
- UNIT["Degree",0.017453292519943295]]
- If the :class:`Layer` has no spatial reference information associated
- with it, ``None`` is returned.
- .. attribute:: spatial_filter
- Property that may be used to retrieve or set a spatial filter for this
- layer. A spatial filter can only be set with an :class:`OGRGeometry`
- instance, a 4-tuple extent, or ``None``. When set with something other than
- ``None``, only features that intersect the filter will be returned when
- iterating over the layer:
- .. code-block:: pycon
- >>> print(layer.spatial_filter)
- None
- >>> print(len(layer))
- 3
- >>> [feat.get("Name") for feat in layer]
- ['Pueblo', 'Lawrence', 'Houston']
- >>> ks_extent = (-102.051, 36.99, -94.59, 40.00) # Extent for state of Kansas
- >>> layer.spatial_filter = ks_extent
- >>> len(layer)
- 1
- >>> [feat.get("Name") for feat in layer]
- ['Lawrence']
- >>> layer.spatial_filter = None
- >>> len(layer)
- 3
- .. method:: get_fields()
- A method that returns a list of the values of a given field for each
- feature in the layer:
- .. code-block:: pycon
- >>> layer.get_fields("Name")
- ['Pueblo', 'Lawrence', 'Houston']
- .. method:: get_geoms(geos=False)
- A method that returns a list containing the geometry of each feature in the
- layer. If the optional argument ``geos`` is set to ``True`` then the
- geometries are converted to :class:`~django.contrib.gis.geos.GEOSGeometry`
- objects. Otherwise, they are returned as :class:`OGRGeometry` objects:
- .. code-block:: pycon
- >>> [pt.tuple for pt in layer.get_geoms()]
- [(-104.609252, 38.255001), (-95.23506, 38.971823), (-95.363151, 29.763374)]
- .. method:: test_capability(capability)
- Returns a boolean indicating whether this layer supports the given
- capability (a string). Examples of valid capability strings include:
- ``'RandomRead'``, ``'SequentialWrite'``, ``'RandomWrite'``,
- ``'FastSpatialFilter'``, ``'FastFeatureCount'``, ``'FastGetExtent'``,
- ``'CreateField'``, ``'Transactions'``, ``'DeleteFeature'``, and
- ``'FastSetNextByIndex'``.
- ``Feature``
- -----------
- .. class:: Feature
- ``Feature`` wraps an OGR feature. You never create a ``Feature`` object
- directly. Instead, you retrieve them from a :class:`Layer` object. Each
- feature consists of a geometry and a set of fields containing additional
- properties. The geometry of a field is accessible via its ``geom`` property,
- which returns an :class:`OGRGeometry` object. A ``Feature`` behaves like a
- standard Python container for its fields, which it returns as :class:`Field`
- objects: you can access a field directly by its index or name, or you can
- iterate over a feature's fields, e.g. in a ``for`` loop.
- .. attribute:: geom
- Returns the geometry for this feature, as an ``OGRGeometry`` object:
- .. code-block:: pycon
- >>> city.geom.tuple
- (-104.609252, 38.255001)
- .. attribute:: get
- A method that returns the value of the given field (specified by name)
- for this feature, **not** a ``Field`` wrapper object:
- .. code-block:: pycon
- >>> city.get("Population")
- 102121
- .. attribute:: geom_type
- Returns the type of geometry for this feature, as an :class:`OGRGeomType`
- object. This will be the same for all features in a given layer and is
- equivalent to the :attr:`Layer.geom_type` property of the :class:`Layer`
- object the feature came from.
- .. attribute:: num_fields
- Returns the number of fields of data associated with the feature. This will
- be the same for all features in a given layer and is equivalent to the
- :attr:`Layer.num_fields` property of the :class:`Layer` object the feature
- came from.
- .. attribute:: fields
- Returns a list of the names of the fields of data associated with the
- feature. This will be the same for all features in a given layer and is
- equivalent to the :attr:`Layer.fields` property of the :class:`Layer`
- object the feature came from.
- .. attribute:: fid
- Returns the feature identifier within the layer:
- .. code-block:: pycon
- >>> city.fid
- 0
- .. attribute:: layer_name
- Returns the name of the :class:`Layer` that the feature came from. This
- will be the same for all features in a given layer:
- .. code-block:: pycon
- >>> city.layer_name
- 'cities'
- .. attribute:: index
- A method that returns the index of the given field name. This will be the
- same for all features in a given layer:
- .. code-block:: pycon
- >>> city.index("Population")
- 1
- ``Field``
- ---------
- .. class:: Field
- .. attribute:: name
- Returns the name of this field:
- .. code-block:: pycon
- >>> city["Name"].name
- 'Name'
- .. attribute:: type
- Returns the OGR type of this field, as an integer. The ``FIELD_CLASSES``
- dictionary maps these values onto subclasses of ``Field``:
- .. code-block:: pycon
- >>> city["Density"].type
- 2
- .. attribute:: type_name
- Returns a string with the name of the data type of this field:
- .. code-block:: pycon
- >>> city["Name"].type_name
- 'String'
- .. attribute:: value
- Returns the value of this field. The ``Field`` class itself returns the
- value as a string, but each subclass returns the value in the most
- appropriate form:
- .. code-block:: pycon
- >>> city["Population"].value
- 102121
- .. attribute:: width
- Returns the width of this field:
- .. code-block:: pycon
- >>> city["Name"].width
- 80
- .. attribute:: precision
- Returns the numeric precision of this field. This is meaningless (and set
- to zero) for non-numeric fields:
- .. code-block:: pycon
- >>> city["Density"].precision
- 15
- .. method:: as_double()
- Returns the value of the field as a double (float):
- .. code-block:: pycon
- >>> city["Density"].as_double()
- 874.7
- .. method:: as_int()
- Returns the value of the field as an integer:
- .. code-block:: pycon
- >>> city["Population"].as_int()
- 102121
- .. method:: as_string()
- Returns the value of the field as a string:
- .. code-block:: pycon
- >>> city["Name"].as_string()
- 'Pueblo'
- .. method:: as_datetime()
- Returns the value of the field as a tuple of date and time components:
- .. code-block:: pycon
- >>> city["Created"].as_datetime()
- (c_long(1999), c_long(5), c_long(23), c_long(0), c_long(0), c_long(0), c_long(0))
- ``Driver``
- ----------
- .. class:: Driver(dr_input)
- The ``Driver`` class is used internally to wrap an OGR :class:`DataSource`
- driver.
- .. attribute:: driver_count
- Returns the number of OGR vector drivers currently registered.
- OGR Geometries
- ==============
- ``OGRGeometry``
- ---------------
- :class:`OGRGeometry` objects share similar functionality with
- :class:`~django.contrib.gis.geos.GEOSGeometry` objects and are thin wrappers
- around OGR's internal geometry representation. Thus, they allow for more
- efficient access to data when using :class:`DataSource`. Unlike its GEOS
- counterpart, :class:`OGRGeometry` supports spatial reference systems and
- coordinate transformation:
- .. code-block:: pycon
- >>> from django.contrib.gis.gdal import OGRGeometry
- >>> polygon = OGRGeometry("POLYGON((0 0, 5 0, 5 5, 0 5))")
- .. class:: OGRGeometry(geom_input, srs=None)
- This object is a wrapper for the `OGR Geometry`__ class. These objects are
- instantiated directly from the given ``geom_input`` parameter, which may be
- a string containing WKT, HEX, GeoJSON, a ``buffer`` containing WKB data, or
- an :class:`OGRGeomType` object. These objects are also returned from the
- :class:`Feature.geom` attribute, when reading vector data from
- :class:`Layer` (which is in turn a part of a :class:`DataSource`).
- __ https://gdal.org/api/ogrgeometry_cpp.html#ogrgeometry-class
- .. classmethod:: from_gml(gml_string)
- Constructs an :class:`OGRGeometry` from the given GML string.
- .. classmethod:: from_bbox(bbox)
- Constructs a :class:`Polygon` from the given bounding-box (a 4-tuple).
- .. method:: __len__()
- Returns the number of points in a :class:`LineString`, the number of rings
- in a :class:`Polygon`, or the number of geometries in a
- :class:`GeometryCollection`. Not applicable to other geometry types.
- .. method:: __iter__()
- Iterates over the points in a :class:`LineString`, the rings in a
- :class:`Polygon`, or the geometries in a :class:`GeometryCollection`.
- Not applicable to other geometry types.
- .. method:: __getitem__()
- Returns the point at the specified index for a :class:`LineString`, the
- interior ring at the specified index for a :class:`Polygon`, or the geometry
- at the specified index in a :class:`GeometryCollection`. Not applicable to
- other geometry types.
- .. attribute:: dimension
- Returns the number of coordinated dimensions of the geometry, i.e. 0
- for points, 1 for lines, and so forth:
- .. code-block:: pycon
- >>> polygon.dimension
- 2
- .. attribute:: coord_dim
- Returns the coordinate dimension of this geometry. For example, the value
- would be 2 for two-dimensional geometries.
- .. deprecated:: 5.1
- The ``coord_dim`` setter is deprecated. Use :meth:`.set_3d` instead.
- .. attribute:: is_3d
- .. versionadded:: 5.1
- A boolean indicating if this geometry has Z coordinates.
- .. method:: set_3d(value)
- .. versionadded:: 5.1
- A method that adds or removes the Z coordinate dimension.
- .. code-block:: pycon
- >>> p = OGRGeometry("POINT (1 2 3)")
- >>> p.is_3d
- True
- >>> p.set_3d(False)
- >>> p.wkt
- "POINT (1 2)"
- .. attribute:: is_measured
- .. versionadded:: 5.1
- A boolean indicating if this geometry has M coordinates.
- .. method:: set_measured(value)
- .. versionadded:: 5.1
- A method to add or remove the M coordinate dimension.
- .. code-block:: pycon
- >>> p = OGRGeometry("POINT (1 2)")
- >>> p.is_measured
- False
- >>> p.set_measured(True)
- >>> p.wkt
- "POINT M (1 2 0)"
- .. attribute:: geom_count
- Returns the number of elements in this geometry:
- .. code-block:: pycon
- >>> polygon.geom_count
- 1
- .. attribute:: has_curve
- .. versionadded:: 5.2
- A boolean indicating if this geometry is or contains a curve geometry.
- .. method:: get_linear_geometry
- .. versionadded:: 5.2
- Returns a linear version of the geometry. If no conversion can be made, the
- original geometry is returned.
- .. method:: get_curve_geometry
- .. versionadded:: 5.2
- Returns a curved version of the geometry. If no conversion can be made, the
- original geometry is returned.
- .. attribute:: point_count
- Returns the number of points used to describe this geometry:
- .. code-block:: pycon
- >>> polygon.point_count
- 4
- .. attribute:: num_points
- Alias for :attr:`point_count`.
- .. attribute:: num_coords
- Alias for :attr:`point_count`.
- .. attribute:: geom_type
- Returns the type of this geometry, as an :class:`OGRGeomType` object.
- .. attribute:: geom_name
- Returns the name of the type of this geometry:
- .. code-block:: pycon
- >>> polygon.geom_name
- 'POLYGON'
- .. attribute:: area
- Returns the area of this geometry, or 0 for geometries that do not contain
- an area:
- .. code-block:: pycon
- >>> polygon.area
- 25.0
- .. attribute:: envelope
- Returns the envelope of this geometry, as an :class:`Envelope` object.
- .. attribute:: extent
- Returns the envelope of this geometry as a 4-tuple, instead of as an
- :class:`Envelope` object:
- .. code-block:: pycon
- >>> point.extent
- (0.0, 0.0, 5.0, 5.0)
- .. attribute:: srs
- This property controls the spatial reference for this geometry, or
- ``None`` if no spatial reference system has been assigned to it.
- If assigned, accessing this property returns a :class:`SpatialReference`
- object. It may be set with another :class:`SpatialReference` object,
- or any input that :class:`SpatialReference` accepts. Example:
- .. code-block:: pycon
- >>> city.geom.srs.name
- 'GCS_WGS_1984'
- .. attribute:: srid
- Returns or sets the spatial reference identifier corresponding to
- :class:`SpatialReference` of this geometry. Returns ``None`` if
- there is no spatial reference information associated with this
- geometry, or if an SRID cannot be determined.
- .. attribute:: geos
- Returns a :class:`~django.contrib.gis.geos.GEOSGeometry` object
- corresponding to this geometry.
- .. attribute:: gml
- Returns a string representation of this geometry in GML format:
- .. code-block:: pycon
- >>> OGRGeometry("POINT(1 2)").gml
- '<gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point>'
- .. attribute:: hex
- Returns a string representation of this geometry in HEX WKB format:
- .. code-block:: pycon
- >>> OGRGeometry("POINT(1 2)").hex
- '0101000000000000000000F03F0000000000000040'
- .. attribute:: json
- Returns a string representation of this geometry in JSON format:
- .. code-block:: pycon
- >>> OGRGeometry("POINT(1 2)").json
- '{ "type": "Point", "coordinates": [ 1.000000, 2.000000 ] }'
- .. attribute:: kml
- Returns a string representation of this geometry in KML format.
- .. attribute:: wkb_size
- Returns the size of the WKB buffer needed to hold a WKB representation
- of this geometry:
- .. code-block:: pycon
- >>> OGRGeometry("POINT(1 2)").wkb_size
- 21
- .. attribute:: wkb
- Returns a ``buffer`` containing a WKB representation of this geometry.
- .. attribute:: wkt
- Returns a string representation of this geometry in WKT format.
- .. attribute:: ewkt
- Returns the EWKT representation of this geometry.
- .. method:: clone()
- Returns a new :class:`OGRGeometry` clone of this geometry object.
- .. method:: close_rings()
- If there are any rings within this geometry that have not been closed,
- this routine will do so by adding the starting point to the end:
- .. code-block:: pycon
- >>> triangle = OGRGeometry("LINEARRING (0 0,0 1,1 0)")
- >>> triangle.close_rings()
- >>> triangle.wkt
- 'LINEARRING (0 0,0 1,1 0,0 0)'
- .. method:: transform(coord_trans, clone=False)
- Transforms this geometry to a different spatial reference system. May take
- a :class:`CoordTransform` object, a :class:`SpatialReference` object, or
- any other input accepted by :class:`SpatialReference` (including spatial
- reference WKT and PROJ strings, or an integer SRID).
- By default nothing is returned and the geometry is transformed in-place.
- However, if the ``clone`` keyword is set to ``True`` then a transformed
- clone of this geometry is returned instead.
- .. method:: intersects(other)
- Returns ``True`` if this geometry intersects the other, otherwise returns
- ``False``.
- .. method:: equals(other)
- Returns ``True`` if this geometry is equivalent to the other, otherwise
- returns ``False``.
- .. method:: disjoint(other)
- Returns ``True`` if this geometry is spatially disjoint to (i.e. does
- not intersect) the other, otherwise returns ``False``.
- .. method:: touches(other)
- Returns ``True`` if this geometry touches the other, otherwise returns
- ``False``.
- .. method:: crosses(other)
- Returns ``True`` if this geometry crosses the other, otherwise returns
- ``False``.
- .. method:: within(other)
- Returns ``True`` if this geometry is contained within the other, otherwise
- returns ``False``.
- .. method:: contains(other)
- Returns ``True`` if this geometry contains the other, otherwise returns
- ``False``.
- .. method:: overlaps(other)
- Returns ``True`` if this geometry overlaps the other, otherwise returns
- ``False``.
- .. method:: boundary()
- The boundary of this geometry, as a new :class:`OGRGeometry` object.
- .. attribute:: convex_hull
- The smallest convex polygon that contains this geometry, as a new
- :class:`OGRGeometry` object.
- .. method:: difference()
- Returns the region consisting of the difference of this geometry and
- the other, as a new :class:`OGRGeometry` object.
- .. method:: intersection()
- Returns the region consisting of the intersection of this geometry and
- the other, as a new :class:`OGRGeometry` object.
- .. method:: sym_difference()
- Returns the region consisting of the symmetric difference of this
- geometry and the other, as a new :class:`OGRGeometry` object.
- .. method:: union()
- Returns the region consisting of the union of this geometry and
- the other, as a new :class:`OGRGeometry` object.
- .. attribute:: centroid
- Returns a :class:`Point` representing the centroid of this geometry.
- .. versionchanged:: 5.1
- ``centroid`` was promoted from a :class:`.Polygon` only attribute to
- being available on all geometry types.
- .. attribute:: tuple
- Returns the coordinates of a point geometry as a tuple, the
- coordinates of a line geometry as a tuple of tuples, and so forth:
- .. code-block:: pycon
- >>> OGRGeometry("POINT (1 2)").tuple
- (1.0, 2.0)
- >>> OGRGeometry("LINESTRING (1 2,3 4)").tuple
- ((1.0, 2.0), (3.0, 4.0))
- .. attribute:: coords
- An alias for :attr:`tuple`.
- .. class:: Point
- .. attribute:: x
- Returns the X coordinate of this point:
- .. code-block:: pycon
- >>> OGRGeometry("POINT (1 2)").x
- 1.0
- .. attribute:: y
- Returns the Y coordinate of this point:
- .. code-block:: pycon
- >>> OGRGeometry("POINT (1 2)").y
- 2.0
- .. attribute:: z
- Returns the Z coordinate of this point, or ``None`` if the point does not
- have a Z coordinate:
- .. code-block:: pycon
- >>> OGRGeometry("POINT (1 2 3)").z
- 3.0
- .. attribute:: m
- .. versionadded:: 5.1
- Returns the M coordinate of this point, or ``None`` if the Point does not
- have an M coordinate:
- .. code-block:: pycon
- >>> OGRGeometry("POINT ZM (1 2 3 4)").m
- 4.0
- .. class:: LineString
- .. attribute:: x
- Returns a list of X coordinates in this line:
- .. code-block:: pycon
- >>> OGRGeometry("LINESTRING (1 2,3 4)").x
- [1.0, 3.0]
- .. attribute:: y
- Returns a list of Y coordinates in this line:
- .. code-block:: pycon
- >>> OGRGeometry("LINESTRING (1 2,3 4)").y
- [2.0, 4.0]
- .. attribute:: z
- Returns a list of Z coordinates in this line, or ``None`` if the line does
- not have Z coordinates:
- .. code-block:: pycon
- >>> OGRGeometry("LINESTRING (1 2 3,4 5 6)").z
- [3.0, 6.0]
- .. attribute:: m
- .. versionadded:: 5.1
- Returns a list of M coordinates in this line or ``None`` if the line does
- not have M coordinates:
- .. code-block:: pycon
- >>> OGRGeometry("LINESTRING(0 1 2 10, 1 2 3 11, 2 3 4 12)").m
- [10.0, 11.0, 12.0]
- .. class:: Polygon
- .. attribute:: shell
- Returns the shell or exterior ring of this polygon, as a ``LinearRing``
- geometry.
- .. attribute:: exterior_ring
- An alias for :attr:`shell`.
- .. class:: GeometryCollection
- .. method:: add(geom)
- Adds a geometry to this geometry collection. Not applicable to other
- geometry types.
- ``OGRGeomType``
- ---------------
- .. class:: OGRGeomType(type_input)
- This class allows for the representation of an OGR geometry type
- in any of several ways:
- .. code-block:: pycon
- >>> from django.contrib.gis.gdal import OGRGeomType
- >>> gt1 = OGRGeomType(3) # Using an integer for the type
- >>> gt2 = OGRGeomType("Polygon") # Using a string
- >>> gt3 = OGRGeomType("POLYGON") # It's case-insensitive
- >>> print(gt1 == 3, gt1 == "Polygon") # Equivalence works w/non-OGRGeomType objects
- True True
- .. attribute:: name
- Returns a short-hand string form of the OGR Geometry type:
- .. code-block:: pycon
- >>> gt1.name
- 'Polygon'
- .. attribute:: num
- Returns the number corresponding to the OGR geometry type:
- .. code-block:: pycon
- >>> gt1.num
- 3
- .. attribute:: django
- Returns the Django field type (a subclass of GeometryField) to use for
- storing this OGR type, or ``None`` if there is no appropriate Django type:
- .. code-block:: pycon
- >>> gt1.django
- 'PolygonField'
- ``Envelope``
- ------------
- .. class:: Envelope(*args)
- Represents an OGR Envelope structure that contains the minimum and maximum
- X, Y coordinates for a rectangle bounding box. The naming of the variables
- is compatible with the OGR Envelope C structure.
- .. attribute:: min_x
- The value of the minimum X coordinate.
- .. attribute:: min_y
- The value of the maximum X coordinate.
- .. attribute:: max_x
- The value of the minimum Y coordinate.
- .. attribute:: max_y
- The value of the maximum Y coordinate.
- .. attribute:: ur
- The upper-right coordinate, as a tuple.
- .. attribute:: ll
- The lower-left coordinate, as a tuple.
- .. attribute:: tuple
- A tuple representing the envelope.
- .. attribute:: wkt
- A string representing this envelope as a polygon in WKT format.
- .. method:: expand_to_include(*args)
- Coordinate System Objects
- =========================
- ``SpatialReference``
- --------------------
- .. class:: SpatialReference(srs_input)
- Spatial reference objects are initialized on the given ``srs_input``,
- which may be one of the following:
- * OGC Well Known Text (WKT) (a string)
- * EPSG code (integer or string)
- * PROJ string
- * A shorthand string for well-known standards (``'WGS84'``, ``'WGS72'``,
- ``'NAD27'``, ``'NAD83'``)
- Example:
- .. code-block:: pycon
- >>> wgs84 = SpatialReference("WGS84") # shorthand string
- >>> wgs84 = SpatialReference(4326) # EPSG code
- >>> wgs84 = SpatialReference("EPSG:4326") # EPSG string
- >>> proj = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs "
- >>> wgs84 = SpatialReference(proj) # PROJ string
- >>> wgs84 = SpatialReference(
- ... """GEOGCS["WGS 84",
- ... DATUM["WGS_1984",
- ... SPHEROID["WGS 84",6378137,298.257223563,
- ... AUTHORITY["EPSG","7030"]],
- ... AUTHORITY["EPSG","6326"]],
- ... PRIMEM["Greenwich",0,
- ... AUTHORITY["EPSG","8901"]],
- ... UNIT["degree",0.01745329251994328,
- ... AUTHORITY["EPSG","9122"]],
- ... AUTHORITY["EPSG","4326"]]"""
- ... ) # OGC WKT
- .. method:: __getitem__(target)
- Returns the value of the given string attribute node, ``None`` if the node
- doesn't exist. Can also take a tuple as a parameter, (target, child), where
- child is the index of the attribute in the WKT. For example:
- .. code-block:: pycon
- >>> wkt = 'GEOGCS["WGS 84", DATUM["WGS_1984, ... AUTHORITY["EPSG","4326"]]'
- >>> srs = SpatialReference(wkt) # could also use 'WGS84', or 4326
- >>> print(srs["GEOGCS"])
- WGS 84
- >>> print(srs["DATUM"])
- WGS_1984
- >>> print(srs["AUTHORITY"])
- EPSG
- >>> print(srs["AUTHORITY", 1]) # The authority value
- 4326
- >>> print(srs["TOWGS84", 4]) # the fourth value in this wkt
- 0
- >>> print(srs["UNIT|AUTHORITY"]) # For the units authority, have to use the pipe symbol.
- EPSG
- >>> print(srs["UNIT|AUTHORITY", 1]) # The authority value for the units
- 9122
- .. method:: attr_value(target, index=0)
- The attribute value for the given target node (e.g. ``'PROJCS'``).
- The index keyword specifies an index of the child node to return.
- .. method:: auth_name(target)
- Returns the authority name for the given string target node.
- .. method:: auth_code(target)
- Returns the authority code for the given string target node.
- .. method:: clone()
- Returns a clone of this spatial reference object.
- .. method:: identify_epsg()
- This method inspects the WKT of this ``SpatialReference`` and will add EPSG
- authority nodes where an EPSG identifier is applicable.
- .. method:: from_esri()
- Morphs this SpatialReference from ESRI's format to EPSG
- .. method:: to_esri()
- Morphs this SpatialReference to ESRI's format.
- .. method:: validate()
- Checks to see if the given spatial reference is valid, if not
- an exception will be raised.
- .. method:: import_epsg(epsg)
- Import spatial reference from EPSG code.
- .. method:: import_proj(proj)
- Import spatial reference from PROJ string.
- .. method:: import_user_input(user_input)
- .. method:: import_wkt(wkt)
- Import spatial reference from WKT.
- .. method:: import_xml(xml)
- Import spatial reference from XML.
- .. attribute:: name
- Returns the name of this Spatial Reference.
- .. attribute:: srid
- Returns the SRID of top-level authority, or ``None`` if undefined.
- .. attribute:: linear_name
- Returns the name of the linear units.
- .. attribute:: linear_units
- Returns the value of the linear units.
- .. attribute:: angular_name
- Returns the name of the angular units."
- .. attribute:: angular_units
- Returns the value of the angular units.
- .. attribute:: units
- Returns a 2-tuple of the units value and the units name and will
- automatically determines whether to return the linear or angular units.
- .. attribute:: ellipsoid
- Returns a tuple of the ellipsoid parameters for this spatial reference:
- (semimajor axis, semiminor axis, and inverse flattening).
- .. attribute:: semi_major
- Returns the semi major axis of the ellipsoid for this spatial reference.
- .. attribute:: semi_minor
- Returns the semi minor axis of the ellipsoid for this spatial reference.
- .. attribute:: inverse_flattening
- Returns the inverse flattening of the ellipsoid for this spatial reference.
- .. attribute:: geographic
- Returns ``True`` if this spatial reference is geographic (root node is
- ``GEOGCS``).
- .. attribute:: local
- Returns ``True`` if this spatial reference is local (root node is
- ``LOCAL_CS``).
- .. attribute:: projected
- Returns ``True`` if this spatial reference is a projected coordinate system
- (root node is ``PROJCS``).
- .. attribute:: wkt
- Returns the WKT representation of this spatial reference.
- .. attribute:: pretty_wkt
- Returns the 'pretty' representation of the WKT.
- .. attribute:: proj
- Returns the PROJ representation for this spatial reference.
- .. attribute:: proj4
- Alias for :attr:`SpatialReference.proj`.
- .. attribute:: xml
- Returns the XML representation of this spatial reference.
- ``CoordTransform``
- ------------------
- .. class:: CoordTransform(source, target)
- Represents a coordinate system transform. It is initialized with two
- :class:`SpatialReference`, representing the source and target coordinate
- systems, respectively. These objects should be used when performing the same
- coordinate transformation repeatedly on different geometries:
- .. code-block:: pycon
- >>> ct = CoordTransform(SpatialReference("WGS84"), SpatialReference("NAD83"))
- >>> for feat in layer:
- ... geom = feat.geom # getting clone of feature geometry
- ... geom.transform(ct) # transforming
- ...
- .. _raster-data-source-objects:
- Raster Data Objects
- ===================
- ``GDALRaster``
- ----------------
- :class:`GDALRaster` is a wrapper for the GDAL raster source object that
- supports reading data from a variety of GDAL-supported geospatial file
- formats and data sources using a consistent interface. Each
- data source is represented by a :class:`GDALRaster` object which contains
- one or more layers of data named bands. Each band, represented by a
- :class:`GDALBand` object, contains georeferenced image data. For example, an RGB
- image is represented as three bands: one for red, one for green, and one for
- blue.
- .. note::
- For raster data there is no difference between a raster instance and its
- data source. Unlike for the Geometry objects, :class:`GDALRaster` objects are
- always a data source. Temporary rasters can be instantiated in memory
- using the corresponding driver, but they will be of the same class as file-based
- raster sources.
- .. class:: GDALRaster(ds_input, write=False)
- The constructor for ``GDALRaster`` accepts two parameters. The first
- parameter defines the raster source, and the second parameter defines if a
- raster should be opened in write mode. For newly-created rasters, the second
- parameter is ignored and the new raster is always created in write mode.
- The first parameter can take three forms: a string or
- :class:`~pathlib.Path` representing a file path (filesystem or GDAL virtual
- filesystem), a dictionary with values defining a new raster, or a bytes
- object representing a raster file.
- If the input is a file path, the raster is opened from there. If the input
- is raw data in a dictionary, the parameters ``width``, ``height``, and
- ``srid`` are required. If the input is a bytes object, it will be opened
- using a GDAL virtual filesystem.
- For a detailed description of how to create rasters using dictionary input,
- see :ref:`gdal-raster-ds-input`. For a detailed description of how to
- create rasters in the virtual filesystem, see :ref:`gdal-raster-vsimem`.
- The following example shows how rasters can be created from different input
- sources (using the sample data from the GeoDjango tests; see also the
- :ref:`gdal_sample_data` section).
- .. code-block:: pycon
- >>> from django.contrib.gis.gdal import GDALRaster
- >>> rst = GDALRaster("/path/to/your/raster.tif", write=False)
- >>> rst.name
- '/path/to/your/raster.tif'
- >>> rst.width, rst.height # This file has 163 x 174 pixels
- (163, 174)
- >>> rst = GDALRaster(
- ... { # Creates an in-memory raster
- ... "srid": 4326,
- ... "width": 4,
- ... "height": 4,
- ... "datatype": 1,
- ... "bands": [
- ... {
- ... "data": (2, 3),
- ... "offset": (1, 1),
- ... "size": (2, 2),
- ... "shape": (2, 1),
- ... "nodata_value": 5,
- ... }
- ... ],
- ... }
- ... )
- >>> rst.srs.srid
- 4326
- >>> rst.width, rst.height
- (4, 4)
- >>> rst.bands[0].data()
- array([[5, 5, 5, 5],
- [5, 2, 3, 5],
- [5, 2, 3, 5],
- [5, 5, 5, 5]], dtype=uint8)
- >>> rst_file = open("/path/to/your/raster.tif", "rb")
- >>> rst_bytes = rst_file.read()
- >>> rst = GDALRaster(rst_bytes)
- >>> rst.is_vsi_based
- True
- >>> rst.name # Stored in a random path in the vsimem filesystem.
- '/vsimem/da300bdb-129d-49a8-b336-e410a9428dad'
- .. attribute:: name
- The name of the source which is equivalent to the input file path or the name
- provided upon instantiation.
- .. code-block:: pycon
- >>> GDALRaster({"width": 10, "height": 10, "name": "myraster", "srid": 4326}).name
- 'myraster'
- .. attribute:: driver
- The name of the GDAL driver used to handle the input file. For ``GDALRaster``\s created
- from a file, the driver type is detected automatically. The creation of rasters from
- scratch is an in-memory raster by default (``'MEM'``), but can be
- altered as needed. For instance, use ``GTiff`` for a ``GeoTiff`` file.
- For a list of file types, see also the `GDAL Raster Formats`__ list.
- __ https://gdal.org/drivers/raster/
- An in-memory raster is created through the following example:
- .. code-block:: pycon
- >>> GDALRaster({"width": 10, "height": 10, "srid": 4326}).driver.name
- 'MEM'
- A file based GeoTiff raster is created through the following example:
- .. code-block:: pycon
- >>> import tempfile
- >>> rstfile = tempfile.NamedTemporaryFile(suffix=".tif")
- >>> rst = GDALRaster(
- ... {
- ... "driver": "GTiff",
- ... "name": rstfile.name,
- ... "srid": 4326,
- ... "width": 255,
- ... "height": 255,
- ... "nr_of_bands": 1,
- ... }
- ... )
- >>> rst.name
- '/tmp/tmp7x9H4J.tif' # The exact filename will be different on your computer
- >>> rst.driver.name
- 'GTiff'
- .. attribute:: width
- The width of the source in pixels (X-axis).
- .. code-block:: pycon
- >>> GDALRaster({"width": 10, "height": 20, "srid": 4326}).width
- 10
- .. attribute:: height
- The height of the source in pixels (Y-axis).
- .. code-block:: pycon
- >>> GDALRaster({"width": 10, "height": 20, "srid": 4326}).height
- 20
- .. attribute:: srs
- The spatial reference system of the raster, as a
- :class:`SpatialReference` instance. The SRS can be changed by
- setting it to an other :class:`SpatialReference` or providing any input
- that is accepted by the :class:`SpatialReference` constructor.
- .. code-block:: pycon
- >>> rst = GDALRaster({"width": 10, "height": 20, "srid": 4326})
- >>> rst.srs.srid
- 4326
- >>> rst.srs = 3086
- >>> rst.srs.srid
- 3086
- .. attribute:: srid
- The Spatial Reference System Identifier (SRID) of the raster. This
- property is a shortcut to getting or setting the SRID through the
- :attr:`srs` attribute.
- .. code-block:: pycon
- >>> rst = GDALRaster({"width": 10, "height": 20, "srid": 4326})
- >>> rst.srid
- 4326
- >>> rst.srid = 3086
- >>> rst.srid
- 3086
- >>> rst.srs.srid # This is equivalent
- 3086
- .. attribute:: geotransform
- The affine transformation matrix used to georeference the source, as a
- tuple of six coefficients which map pixel/line coordinates into
- georeferenced space using the following relationship::
- Xgeo = GT(0) + Xpixel * GT(1) + Yline * GT(2)
- Ygeo = GT(3) + Xpixel * GT(4) + Yline * GT(5)
- The same values can be retrieved by accessing the :attr:`origin`
- (indices 0 and 3), :attr:`scale` (indices 1 and 5) and :attr:`skew`
- (indices 2 and 4) properties.
- The default is ``[0.0, 1.0, 0.0, 0.0, 0.0, -1.0]``.
- .. code-block:: pycon
- >>> rst = GDALRaster({"width": 10, "height": 20, "srid": 4326})
- >>> rst.geotransform
- [0.0, 1.0, 0.0, 0.0, 0.0, -1.0]
- .. attribute:: origin
- Coordinates of the top left origin of the raster in the spatial
- reference system of the source, as a point object with ``x`` and ``y``
- members.
- .. code-block:: pycon
- >>> rst = GDALRaster({"width": 10, "height": 20, "srid": 4326})
- >>> rst.origin
- [0.0, 0.0]
- >>> rst.origin.x = 1
- >>> rst.origin
- [1.0, 0.0]
- .. attribute:: scale
- Pixel width and height used for georeferencing the raster, as a point
- object with ``x`` and ``y`` members. See :attr:`geotransform` for more
- information.
- .. code-block:: pycon
- >>> rst = GDALRaster({"width": 10, "height": 20, "srid": 4326})
- >>> rst.scale
- [1.0, -1.0]
- >>> rst.scale.x = 2
- >>> rst.scale
- [2.0, -1.0]
- .. attribute:: skew
- Skew coefficients used to georeference the raster, as a point object
- with ``x`` and ``y`` members. In case of north up images, these
- coefficients are both ``0``.
- .. code-block:: pycon
- >>> rst = GDALRaster({"width": 10, "height": 20, "srid": 4326})
- >>> rst.skew
- [0.0, 0.0]
- >>> rst.skew.x = 3
- >>> rst.skew
- [3.0, 0.0]
- .. attribute:: extent
- Extent (boundary values) of the raster source, as a 4-tuple
- ``(xmin, ymin, xmax, ymax)`` in the spatial reference system of the
- source.
- .. code-block:: pycon
- >>> rst = GDALRaster({"width": 10, "height": 20, "srid": 4326})
- >>> rst.extent
- (0.0, -20.0, 10.0, 0.0)
- >>> rst.origin.x = 100
- >>> rst.extent
- (100.0, -20.0, 110.0, 0.0)
- .. attribute:: bands
- List of all bands of the source, as :class:`GDALBand` instances.
- .. code-block:: pycon
- >>> rst = GDALRaster(
- ... {
- ... "width": 1,
- ... "height": 2,
- ... "srid": 4326,
- ... "bands": [{"data": [0, 1]}, {"data": [2, 3]}],
- ... }
- ... )
- >>> len(rst.bands)
- 2
- >>> rst.bands[1].data()
- array([[ 2., 3.]], dtype=float32)
- .. method:: warp(ds_input, resampling='NearestNeighbour', max_error=0.0)
- Returns a warped version of this raster.
- The warping parameters can be specified through the ``ds_input``
- argument. The use of ``ds_input`` is analogous to the corresponding
- argument of the class constructor. It is a dictionary with the
- characteristics of the target raster. Allowed dictionary key values are
- width, height, SRID, origin, scale, skew, datatype, driver, and name
- (filename).
- By default, the warp functions keeps most parameters equal to the
- values of the original source raster, so only parameters that should be
- changed need to be specified. Note that this includes the driver, so
- for file-based rasters the warp function will create a new raster on
- disk.
- The only parameter that is set differently from the source raster is the
- name. The default value of the raster name is the name of the source
- raster appended with ``'_copy' + source_driver_name``. For file-based
- rasters it is recommended to provide the file path of the target raster.
- The resampling algorithm used for warping can be specified with the
- ``resampling`` argument. The default is ``NearestNeighbor``, and the
- other allowed values are ``Bilinear``, ``Cubic``, ``CubicSpline``,
- ``Lanczos``, ``Average``, and ``Mode``.
- The ``max_error`` argument can be used to specify the maximum error
- measured in input pixels that is allowed in approximating the
- transformation. The default is 0.0 for exact calculations.
- For users familiar with ``GDAL``, this function has a similar
- functionality to the ``gdalwarp`` command-line utility.
- For example, the warp function can be used for aggregating a raster to
- the double of its original pixel scale:
- .. code-block:: pycon
- >>> rst = GDALRaster(
- ... {
- ... "width": 6,
- ... "height": 6,
- ... "srid": 3086,
- ... "origin": [500000, 400000],
- ... "scale": [100, -100],
- ... "bands": [{"data": range(36), "nodata_value": 99}],
- ... }
- ... )
- >>> target = rst.warp({"scale": [200, -200], "width": 3, "height": 3})
- >>> target.bands[0].data()
- array([[ 7., 9., 11.],
- [ 19., 21., 23.],
- [ 31., 33., 35.]], dtype=float32)
- .. method:: transform(srs, driver=None, name=None, resampling='NearestNeighbour', max_error=0.0)
- Transforms this raster to a different spatial reference system
- (``srs``), which may be a :class:`SpatialReference` object, or any
- other input accepted by :class:`SpatialReference` (including spatial
- reference WKT and PROJ strings, or an integer SRID).
- It calculates the bounds and scale of the current raster in the new
- spatial reference system and warps the raster using the
- :attr:`~GDALRaster.warp` function.
- By default, the driver of the source raster is used and the name of the
- raster is the original name appended with
- ``'_copy' + source_driver_name``. A different driver or name can be
- specified with the ``driver`` and ``name`` arguments.
- The default resampling algorithm is ``NearestNeighbour`` but can be
- changed using the ``resampling`` argument. The default maximum allowed
- error for resampling is 0.0 and can be changed using the ``max_error``
- argument. Consult the :attr:`~GDALRaster.warp` documentation for detail
- on those arguments.
- .. code-block:: pycon
- >>> rst = GDALRaster(
- ... {
- ... "width": 6,
- ... "height": 6,
- ... "srid": 3086,
- ... "origin": [500000, 400000],
- ... "scale": [100, -100],
- ... "bands": [{"data": range(36), "nodata_value": 99}],
- ... }
- ... )
- >>> target_srs = SpatialReference(4326)
- >>> target = rst.transform(target_srs)
- >>> target.origin
- [-82.98492744885776, 27.601924753080144]
- .. attribute:: info
- Returns a string with a summary of the raster. This is equivalent to
- the `gdalinfo`__ command line utility.
- __ https://gdal.org/programs/gdalinfo.html
- .. attribute:: metadata
- The metadata of this raster, represented as a nested dictionary. The
- first-level key is the metadata domain. The second-level contains the
- metadata item names and values from each domain.
- To set or update a metadata item, pass the corresponding metadata item
- to the method using the nested structure described above. Only keys
- that are in the specified dictionary are updated; the rest of the
- metadata remains unchanged.
- To remove a metadata item, use ``None`` as the metadata value.
- .. code-block:: pycon
- >>> rst = GDALRaster({"width": 10, "height": 20, "srid": 4326})
- >>> rst.metadata
- {}
- >>> rst.metadata = {"DEFAULT": {"OWNER": "Django", "VERSION": "1.0"}}
- >>> rst.metadata
- {'DEFAULT': {'OWNER': 'Django', 'VERSION': '1.0'}}
- >>> rst.metadata = {"DEFAULT": {"OWNER": None, "VERSION": "2.0"}}
- >>> rst.metadata
- {'DEFAULT': {'VERSION': '2.0'}}
- .. attribute:: vsi_buffer
- A ``bytes`` representation of this raster. Returns ``None`` for rasters
- that are not stored in GDAL's virtual filesystem.
- .. attribute:: is_vsi_based
- A boolean indicating if this raster is stored in GDAL's virtual
- filesystem.
- ``GDALBand``
- ------------
- .. class:: GDALBand
- ``GDALBand`` instances are not created explicitly, but rather obtained
- from a :class:`GDALRaster` object, through its :attr:`~GDALRaster.bands`
- attribute. The GDALBands contain the actual pixel values of the raster.
- .. attribute:: description
- The name or description of the band, if any.
- .. attribute:: width
- The width of the band in pixels (X-axis).
- .. attribute:: height
- The height of the band in pixels (Y-axis).
- .. attribute:: pixel_count
- The total number of pixels in this band. Is equal to ``width * height``.
- .. method:: statistics(refresh=False, approximate=False)
- Compute statistics on the pixel values of this band. The return value
- is a tuple with the following structure:
- ``(minimum, maximum, mean, standard deviation)``.
- If the ``approximate`` argument is set to ``True``, the statistics may
- be computed based on overviews or a subset of image tiles.
- If the ``refresh`` argument is set to ``True``, the statistics will be
- computed from the data directly, and the cache will be updated with the
- result.
- If a persistent cache value is found, that value is returned. For
- raster formats using Persistent Auxiliary Metadata (PAM) services, the
- statistics might be cached in an auxiliary file. In some cases this
- metadata might be out of sync with the pixel values or cause values
- from a previous call to be returned which don't reflect the value of
- the ``approximate`` argument. In such cases, use the ``refresh``
- argument to get updated values and store them in the cache.
- For empty bands (where all pixel values are "no data"), all statistics
- are returned as ``None``.
- The statistics can also be retrieved directly by accessing the
- :attr:`min`, :attr:`max`, :attr:`mean`, and :attr:`std` properties.
- .. attribute:: min
- The minimum pixel value of the band (excluding the "no data" value).
- .. attribute:: max
- The maximum pixel value of the band (excluding the "no data" value).
- .. attribute:: mean
- The mean of all pixel values of the band (excluding the "no data"
- value).
- .. attribute:: std
- The standard deviation of all pixel values of the band (excluding the
- "no data" value).
- .. attribute:: nodata_value
- The "no data" value for a band is generally a special marker value used
- to mark pixels that are not valid data. Such pixels should generally not
- be displayed, nor contribute to analysis operations.
- To delete an existing "no data" value, set this property to ``None``.
- .. method:: datatype(as_string=False)
- The data type contained in the band, as an integer constant between 0
- (Unknown) and 14. If ``as_string`` is ``True``, the data type is
- returned as a string. Check out the "GDAL Pixel Type" column in the
- :ref:`datatype value table <gdal-raster-datatype>` for possible values.
- .. method:: color_interp(as_string=False)
- The color interpretation for the band, as an integer between 0and 16.
- If ``as_string`` is ``True``, the data type is returned as a string
- with the following possible values:
- ``GCI_Undefined``, ``GCI_GrayIndex``, ``GCI_PaletteIndex``,
- ``GCI_RedBand``, ``GCI_GreenBand``, ``GCI_BlueBand``, ``GCI_AlphaBand``,
- ``GCI_HueBand``, ``GCI_SaturationBand``, ``GCI_LightnessBand``,
- ``GCI_CyanBand``, ``GCI_MagentaBand``, ``GCI_YellowBand``,
- ``GCI_BlackBand``, ``GCI_YCbCr_YBand``, ``GCI_YCbCr_CbBand``, and
- ``GCI_YCbCr_CrBand``. ``GCI_YCbCr_CrBand`` also represents ``GCI_Max``
- because both correspond to the integer 16, but only ``GCI_YCbCr_CrBand``
- is returned as a string.
- .. method:: data(data=None, offset=None, size=None, shape=None)
- The accessor to the pixel values of the ``GDALBand``. Returns the complete
- data array if no parameters are provided. A subset of the pixel array can
- be requested by specifying an offset and block size as tuples.
- If NumPy is available, the data is returned as NumPy array. For performance
- reasons, it is highly recommended to use NumPy.
- Data is written to the ``GDALBand`` if the ``data`` parameter is provided.
- The input can be of one of the following types - packed string, buffer, list,
- array, and NumPy array. The number of items in the input should normally
- correspond to the total number of pixels in the band, or to the number
- of pixels for a specific block of pixel values if the ``offset`` and
- ``size`` parameters are provided.
- If the number of items in the input is different from the target pixel
- block, the ``shape`` parameter must be specified. The shape is a tuple
- that specifies the width and height of the input data in pixels. The
- data is then replicated to update the pixel values of the selected
- block. This is useful to fill an entire band with a single value, for
- instance.
- For example:
- .. code-block:: pycon
- >>> rst = GDALRaster(
- ... {"width": 4, "height": 4, "srid": 4326, "datatype": 1, "nr_of_bands": 1}
- ... )
- >>> bnd = rst.bands[0]
- >>> bnd.data(range(16))
- >>> bnd.data()
- array([[ 0, 1, 2, 3],
- [ 4, 5, 6, 7],
- [ 8, 9, 10, 11],
- [12, 13, 14, 15]], dtype=int8)
- >>> bnd.data(offset=(1, 1), size=(2, 2))
- array([[ 5, 6],
- [ 9, 10]], dtype=int8)
- >>> bnd.data(data=[-1, -2, -3, -4], offset=(1, 1), size=(2, 2))
- >>> bnd.data()
- array([[ 0, 1, 2, 3],
- [ 4, -1, -2, 7],
- [ 8, -3, -4, 11],
- [12, 13, 14, 15]], dtype=int8)
- >>> bnd.data(data="\x9d\xa8\xb3\xbe", offset=(1, 1), size=(2, 2))
- >>> bnd.data()
- array([[ 0, 1, 2, 3],
- [ 4, -99, -88, 7],
- [ 8, -77, -66, 11],
- [ 12, 13, 14, 15]], dtype=int8)
- >>> bnd.data([1], shape=(1, 1))
- >>> bnd.data()
- array([[1, 1, 1, 1],
- [1, 1, 1, 1],
- [1, 1, 1, 1],
- [1, 1, 1, 1]], dtype=uint8)
- >>> bnd.data(range(4), shape=(1, 4))
- array([[0, 0, 0, 0],
- [1, 1, 1, 1],
- [2, 2, 2, 2],
- [3, 3, 3, 3]], dtype=uint8)
- .. attribute:: metadata
- The metadata of this band. The functionality is identical to
- :attr:`GDALRaster.metadata`.
- .. _gdal-raster-ds-input:
- Creating rasters from data
- --------------------------
- This section describes how to create rasters from scratch using the
- ``ds_input`` parameter.
- A new raster is created when a ``dict`` is passed to the :class:`GDALRaster`
- constructor. The dictionary contains defining parameters of the new raster,
- such as the origin, size, or spatial reference system. The dictionary can also
- contain pixel data and information about the format of the new raster. The
- resulting raster can therefore be file-based or memory-based, depending on the
- driver specified.
- There's no standard for describing raster data in a dictionary or JSON flavor.
- The definition of the dictionary input to the :class:`GDALRaster` class is
- therefore specific to Django. It's inspired by the `geojson`__ format, but the
- ``geojson`` standard is currently limited to vector formats.
- Examples of using the different keys when creating rasters can be found in the
- documentation of the corresponding attributes and methods of the
- :class:`GDALRaster` and :class:`GDALBand` classes.
- __ https://geojson.org/
- The ``ds_input`` dictionary
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Only a few keys are required in the ``ds_input`` dictionary to create a raster:
- ``width``, ``height``, and ``srid``. All other parameters have default values
- (see the table below). The list of keys that can be passed in the ``ds_input``
- dictionary is closely related but not identical to the :class:`GDALRaster`
- properties. Many of the parameters are mapped directly to those properties;
- the others are described below.
- The following table describes all keys that can be set in the ``ds_input``
- dictionary.
- ================= ======== ==================================================
- Key Default Usage
- ================= ======== ==================================================
- ``srid`` required Mapped to the :attr:`~GDALRaster.srid` attribute
- ``width`` required Mapped to the :attr:`~GDALRaster.width` attribute
- ``height`` required Mapped to the :attr:`~GDALRaster.height` attribute
- ``driver`` ``MEM`` Mapped to the :attr:`~GDALRaster.driver` attribute
- ``name`` ``''`` See below
- ``origin`` ``0`` Mapped to the :attr:`~GDALRaster.origin` attribute
- ``scale`` ``0`` Mapped to the :attr:`~GDALRaster.scale` attribute
- ``skew`` ``0`` Mapped to the :attr:`~GDALRaster.width` attribute
- ``bands`` ``[]`` See below
- ``nr_of_bands`` ``0`` See below
- ``datatype`` ``6`` See below
- ``papsz_options`` ``{}`` See below
- ================= ======== ==================================================
- .. object:: name
- String representing the name of the raster. When creating a file-based
- raster, this parameter must be the file path for the new raster. If the
- name starts with ``/vsimem/``, the raster is created in GDAL's virtual
- filesystem.
- .. _gdal-raster-datatype:
- .. object:: datatype
- Integer representing the data type for all the bands. Defaults to ``6``
- (Float32). All bands of a new raster are required to have the same datatype.
- The value mapping is:
- ===== =============== ===================================
- Value GDAL Pixel Type Description
- ===== =============== ===================================
- 1 GDT_Byte 8 bit unsigned integer
- 2 GDT_UInt16 16 bit unsigned integer
- 3 GDT_Int16 16 bit signed integer
- 4 GDT_UInt32 32 bit unsigned integer
- 5 GDT_Int32 32 bit signed integer
- 6 GDT_Float32 32 bit floating point
- 7 GDT_Float64 64 bit floating point
- 12 GDT_UInt64 64 bit unsigned integer (GDAL 3.5+)
- 13 GDT_Int64 64 bit signed integer (GDAL 3.5+)
- 14 GDT_Int8 8 bit signed integer (GDAL 3.7+)
- ===== =============== ===================================
- .. object:: nr_of_bands
- Integer representing the number of bands of the raster. A raster can be
- created without passing band data upon creation. If the number of bands
- isn't specified, it's automatically calculated from the length of the
- ``bands`` input. The number of bands can't be changed after creation.
- .. object:: bands
- A list of ``band_input`` dictionaries with band input data. The resulting
- band indices are the same as in the list provided. The definition of the
- band input dictionary is given below. If band data isn't provided, the
- raster bands values are instantiated as an array of zeros and the "no
- data" value is set to ``None``.
- .. object:: papsz_options
- A dictionary with raster creation options. The key-value pairs of the
- input dictionary are passed to the driver on creation of the raster.
- The available options are driver-specific and are described in the
- documentation of each driver.
- The values in the dictionary are not case-sensitive and are automatically
- converted to the correct string format upon creation.
- The following example uses some of the options available for the
- `GTiff driver`__. The result is a compressed raster with an internal tiling
- scheme. The internal tiles have a block size of 23 by 23:
- .. code-block:: pycon
- >>> GDALRaster(
- ... {
- ... "driver": "GTiff",
- ... "name": "/path/to/new/file.tif",
- ... "srid": 4326,
- ... "width": 255,
- ... "height": 255,
- ... "nr_of_bands": 1,
- ... "papsz_options": {
- ... "compress": "packbits",
- ... "tiled": "yes",
- ... "blockxsize": 23,
- ... "blockysize": 23,
- ... },
- ... }
- ... )
- __ https://gdal.org/drivers/raster/gtiff.html
- The ``band_input`` dictionary
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The ``bands`` key in the ``ds_input`` dictionary is a list of ``band_input``
- dictionaries. Each ``band_input`` dictionary can contain pixel values and the
- "no data" value to be set on the bands of the new raster. The data array can
- have the full size of the new raster or be smaller. For arrays that are smaller
- than the full raster, the ``size``, ``shape``, and ``offset`` keys control the
- pixel values. The corresponding keys are passed to the :meth:`~GDALBand.data`
- method. Their functionality is the same as setting the band data with that
- method. The following table describes the keys that can be used.
- ================ ================================= ======================================================
- Key Default Usage
- ================ ================================= ======================================================
- ``nodata_value`` ``None`` Mapped to the :attr:`~GDALBand.nodata_value` attribute
- ``data`` Same as ``nodata_value`` or ``0`` Passed to the :meth:`~GDALBand.data` method
- ``size`` ``(with, height)`` of raster Passed to the :meth:`~GDALBand.data` method
- ``shape`` Same as size Passed to the :meth:`~GDALBand.data` method
- ``offset`` ``(0, 0)`` Passed to the :meth:`~GDALBand.data` method
- ================ ================================= ======================================================
- .. _gdal-raster-vsimem:
- Using GDAL's Virtual Filesystem
- -------------------------------
- GDAL can access files stored in the filesystem, but also supports virtual
- filesystems to abstract accessing other kind of files, such as compressed,
- encrypted, or remote files.
- Using memory-based Virtual Filesystem
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- GDAL has an internal memory-based filesystem, which allows treating blocks of
- memory as files. It can be used to read and write :class:`GDALRaster` objects
- to and from binary file buffers.
- This is useful in web contexts where rasters might be obtained as a buffer
- from a remote storage or returned from a view without being written to disk.
- :class:`GDALRaster` objects are created in the virtual filesystem when a
- ``bytes`` object is provided as input, or when the file path starts with
- ``/vsimem/``.
- Input provided as ``bytes`` has to be a full binary representation of a file.
- For instance:
- .. code-block:: pycon
- # Read a raster as a file object from a remote source.
- >>> from urllib.request import urlopen
- >>> dat = urlopen("https://example.com/raster.tif").read()
- # Instantiate a raster from the bytes object.
- >>> rst = GDALRaster(dat)
- # The name starts with /vsimem/, indicating that the raster lives in the
- # virtual filesystem.
- >>> rst.name
- '/vsimem/da300bdb-129d-49a8-b336-e410a9428dad'
- To create a new virtual file-based raster from scratch, use the ``ds_input``
- dictionary representation and provide a ``name`` argument that starts with
- ``/vsimem/`` (for detail of the dictionary representation, see
- :ref:`gdal-raster-ds-input`). For virtual file-based rasters, the
- :attr:`~GDALRaster.vsi_buffer` attribute returns the ``bytes`` representation
- of the raster.
- Here's how to create a raster and return it as a file in an
- :class:`~django.http.HttpResponse`:
- .. code-block:: pycon
- >>> from django.http import HttpResponse
- >>> rst = GDALRaster(
- ... {
- ... "name": "/vsimem/temporarymemfile",
- ... "driver": "tif",
- ... "width": 6,
- ... "height": 6,
- ... "srid": 3086,
- ... "origin": [500000, 400000],
- ... "scale": [100, -100],
- ... "bands": [{"data": range(36), "nodata_value": 99}],
- ... }
- ... )
- >>> HttpResponse(rast.vsi_buffer, "image/tiff")
- Using other Virtual Filesystems
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Depending on the local build of GDAL other virtual filesystems may be
- supported. You can use them by prepending the provided path with the
- appropriate ``/vsi*/`` prefix. See the `GDAL Virtual Filesystems
- documentation`_ for more details.
- .. warning:
- Rasters with names starting with `/vsi*/` will be treated as rasters from
- the GDAL virtual filesystems. Django doesn't perform any extra validation.
- Compressed rasters
- ^^^^^^^^^^^^^^^^^^
- Instead decompressing the file and instantiating the resulting raster, GDAL can
- directly access compressed files using the ``/vsizip/``, ``/vsigzip/``, or
- ``/vsitar/`` virtual filesystems:
- .. code-block:: pycon
- >>> from django.contrib.gis.gdal import GDALRaster
- >>> rst = GDALRaster("/vsizip/path/to/your/file.zip/path/to/raster.tif")
- >>> rst = GDALRaster("/vsigzip/path/to/your/file.gz")
- >>> rst = GDALRaster("/vsitar/path/to/your/file.tar/path/to/raster.tif")
- Network rasters
- ^^^^^^^^^^^^^^^
- GDAL can support online resources and storage providers transparently. As long
- as it's built with such capabilities.
- To access a public raster file with no authentication, you can use
- ``/vsicurl/``:
- .. code-block:: pycon
- >>> from django.contrib.gis.gdal import GDALRaster
- >>> rst = GDALRaster("/vsicurl/https://example.com/raster.tif")
- >>> rst.name
- '/vsicurl/https://example.com/raster.tif'
- For commercial storage providers (e.g. ``/vsis3/``) the system should be
- previously configured for authentication and possibly other settings (see the
- `GDAL Virtual Filesystems documentation`_ for available options).
- .. _`GDAL Virtual Filesystems documentation`: https://gdal.org/user/virtual_file_systems.html
- Settings
- ========
- .. setting:: GDAL_LIBRARY_PATH
- ``GDAL_LIBRARY_PATH``
- ---------------------
- A string specifying the location of the GDAL library. Typically,
- this setting is only used if the GDAL library is in a non-standard
- location (e.g., ``/home/john/lib/libgdal.so``).
- Exceptions
- ==========
- .. exception:: GDALException
- The base GDAL exception, indicating a GDAL-related error.
- .. exception:: SRSException
- An exception raised when an error occurs when constructing or using a
- spatial reference system object.
|