# dokumentasi Django 2.2.9.dev20191202104323

# API Basisdata GeoDjango

## Backend Spasial

GeoDjango saat ini menyediakan backend basisdata spasial berikut:

- django.contrib.gis.db.backends.postgis`
- `django.contrib.gis.db.backends.mysql`
- `django.contrib.gis.db.backends.oracle`
- `django.contrib.gis.db.backends.spatialite`

### Batasan Spasial MySQL

Perpanjangan spasial MySQL hanya mendukung membatasi tindakan kotak (apa MySQL sebut minimum bounding rectangles, atau MBR). Khususnya, MySQL does not conform to the OGC standard:

> Saat ini, MySQL tidak menerapkan fungsi-fungsi ini [`Contains`, `Crosses`, `Disjoint`, `Intersects`, `Overlaps`, `Touches`, `Within`] menurut ke spesifikasi. Itu yang diterapkan mengembalikan hasil sama seperti fungsi berdasarkan-MBR sesuai.

Dengan kata lain, selagi pencarian spasial seperti `contains 1` tersedia dalam GeoDjango ketika menggunakan MySQL, hasil dikembalikan sangat setara ke apa akan dikembalikan ketika menggunakan `bbcontains` pada backend spasial yang berbeda.

Peringatan

True spatial indexes (R-trees) hanya didukung dengan tabel MyISAM pada MySQL. [5] Dengan kata lain, ketika menggunakan tambahan spasial MySQL anda telah memilih diantara pencarian spasial cepat dan keutuhan data anda -- tabel MyISAM tidak mendukung transaksi atau batasan foreign key.

### Dukungan Raster

`RasterField` saat ini hanya diterapkan untuk backend PostGIS. Pencarian spasial tersedia untuk bidang raster, tetapi fungsi basisdata spasial dan pengumpulan tidak diterapkan untuk bidang taster.

## Membuat dan Menyimpan Model dengan Bidang Geometri

Ini adalah sebuah contoh bagaimana membuat obyek geometri (mengganggap model `Zipcode`):

    >>> from zipcode.models import Zipcode
    >>> z = Zipcode(code=77096, poly='POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))')
    >>> z.save()

Obyek `GEOSGeometry` mungkin juga digunakan untuk menyimpan model geometrik:

    >>> from django.contrib.gis.geos import GEOSGeometry
    >>> poly = GEOSGeometry('POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))')
    >>> z = Zipcode(code=77096, poly=poly)
    >>> z.save()

Bahkan, jika `GEOSGeometry` adalah dalam sistem kordinat berbeda (mempunyai nilai SRID berbeda) daripada itu dari bidan, kemudian itu akan secara jelas berubah kedalam SRID dari bidang model, menggunakan prosedur perubahan basisdata spasial:

    >>> poly_3084 = GEOSGeometry('POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))', srid=3084)  # SRID 3084 is 'NAD83(HARN) / Texas Centric Lambert Conformal'
    >>> z = Zipcode(code=78212, poly=poly_3084)
    >>> z.save()
    >>> from django.db import connection
    >>> print(connection.queries[-1]['sql']) # printing the last SQL statement executed (requires DEBUG=True)
    INSERT INTO "geoapp_zipcode" ("code", "poly") VALUES (78212, ST_Transform(ST_GeomFromWKB('\\001 ... ', 3084), 4326))

Dengan demikian, parameter geometri mungkin dilewatkan dalam menggunakan obyek GEOSGeometry`, WKT (Well Known Text [1]), HEXEWKB (PostGIS tertentu -- geometri WKB dalam heksadesimal [2]), dan GeoJSON [3]. Intinya, jika masukan bukan sebuah obyek `GEOSGeometry`, bidang geometri akan berusaha membuat sebuah instance `GEOSGeometry` dari masukan.

Untuk informasi lebih membuat obyek `GEOSGeometry` mengacu pada GEOS tutorial 1.

## Membuat dan Menyimpan Model dengan Bidang Raster

Ketika membuat model raster, bidang raster akan secara jelas merubah masukan kedalam `GDALRaster`.

Disini adalah sebuah contoh dari bagaimana membuat obyek raster dari berkas raster `volcano.tif` (berlagak model `Elevation`)

    >>> from elevation.models import Elevation
    >>> dem = Elevation(name='Volcano', rast='/path/to/raster/volcano.tif')
    >>> dem.save()

Obyek `GDALRaster` mungkin juga digunakan untuk menyimpan model raster:

    >>> from django.contrib.gis.gdal import GDALRaster
    >>> rast = GDALRaster({'width': 10, 'height': 10, 'name': 'Canyon', 'srid': 4326,
    ...                    'scale': [0.1, -0.1], 'bands': [{"data": range(100)}]})
    >>> dem = Elevation(name='Canyon', rast=rast)
    >>> dem.save()

Catat bahwa ini setara pada:

    >>> dem = Elevation.objects.create(
    ...     name='Canyon',
    ...     rast={'width': 10, 'height': 10, 'name': 'Canyon', 'srid': 4326,
    ...           'scale': [0.1, -0.1], 'bands': [{"data": range(100)}]},
    ... )

## Pencarian Spasial

Jenis-jenis pencarian GeoDjango mungkin digunakan dengan metode pengelola lain seperti `filter()`, `exclude()`, dll. Bagaimanapun, jenis-jenis pencarian unik pada GeoDjango hanya tersedia pada bidang-bidang spasial.

Penyaring pada bidang 'biasa' (misalnya `CharField`) mungkin dirantai dengan itu pada bidang geografis. Pencarian geografis menerima masukan geometri dan raster pada kedua sisi dan jenis masukan dapat digabung dengan bebas.

Struktur umum dari pencarian geografis akan digambarkan dibawah ini. Acuan lengkap dapat ditemukan dalam spatial lookup reference1.

### Pencarian Geometri

Permintaan geografis dengan geometri mengambil formulir umum berikut (menganggap mdoel `Zipcode` digunakan dalam API Model GeoDjango):

    >>> qs = Zipcode.objects.filter(<field>__<lookup_type>=<parameter>)
    >>> qs = Zipcode.objects.exclude(...)

Sebagai contoh:

    >>> qs = Zipcode.objects.filter(poly__contains=pnt)
    >>> qs = Elevation.objects.filter(poly__contains=rst)

Dalam kasus ini, `poly` adalah bidang geofgrafis, `contains 1` adalah jenis pencarian spasial, `pnt` adalah parameter (yang mungkin berupa obyek `GEOSGeometry` atau string dari GeoJSON , WKT, atau HEXEWKB), dan `rst` adalah sebuah obyek `GDALRaster`.

### Pencarian Raster

Sintaksis pencarian raster mitip pada sintaksis untuk geometri. Perbedaan hanya bahwa peta indesk dapat ditentukan sebagai input tambahan. Jika tidak ada pita indeks ditentukan, pita pertama digunakan secara awalan (indeks `0`). Dalam kasus itu sintaksis mirip ke sintaksis untuk pencarian geometri.

Untuk menentukan pita indeks, sebuah parameter tambahan dapat ditentukan pada kedua sisi dari pencarian. Pada sisi tangan kiri, sintaksis garis bawah ganda digunakan peta indeks. Pada sisi tangan kanan, tuple dari raster dan pita indeks dapat ditentukan.

Hasil ini dalam formulir umum berikut untuk pencarian melibarkan raster (menganggap model `Elevation` digunakan dalam API Model GeoDjango):

    >>> qs = Elevation.objects.filter(<field>__<lookup_type>=<parameter>)
    >>> qs = Elevation.objects.filter(<field>__<band_index>__<lookup_type>=<parameter>)
    >>> qs = Elevation.objects.filter(<field>__<lookup_type>=(<raster_input, <band_index>)

Sebagai contoh:

    >>> qs = Elevation.objects.filter(rast__contains=geom)
    >>> qs = Elevation.objects.filter(rast__contains=rst)
    >>> qs = Elevation.objects.filter(rast__1__contains=geom)
    >>> qs = Elevation.objects.filter(rast__contains=(rst, 1))
    >>> qs = Elevation.objects.filter(rast__1__contains=(rst, 1))

Pada sisi tangan kiri dari contoh, `rast` adalah bidang raster geografis dan `contains 1` adalah jenis pencarian spasial. Pada sisi tangan kanan, `geom` adalah masukan geometri dan `rst` adalah sebuah obyek `GDALRaster`. Pinta indeks awalan pada `0` dalam permintaan dua pertama dan disetel menjadi `1` pada lainnya.

Selagi semuan pencarian spasial dapat digunakan dengan obyek raster pada kedua sisi tidak semua penghubung pokok asli menerima masukan raster. Untuk kasus-kasus dimana penghubung mengharapkan masukan geometri, raster adalah secara otomatis dirubah kegeometri. itu adalah penting menjaga ini dalam pikiran ketika manafsirkan hasil pencarian.

Jenis dari dukungan raster terdaftar untuk semua pencarian dalam compatibility table 1. Pencarian melibatkan raster saat ini hanya tersedia untuk backend PostGIS.

## Permintaan Jarak

### Kata Pengantar

Perhitungan jarak dengan data spasial adalah rumit karena, sayangnya, Bumi tidak datar. Beberpa permintaan jarak dengan bidang dalam sistem kordinat geografis mungkin harus dinyatakan berbeda karena batasan dalam PostGIS. Silahkan lihat dokumentasi Memilih sebuah SRID section in the API Model GeoDjango untuk lebih rinci.

### Pencarian Jarak

Availability: PostGIS, MySQL, Oracle, SpatiaLite, PGRaster (Native)

Pencarian jarak berikut tersedia:

- `distance_lt`
- `distance_lte`
- `distance_gt`
- `distance_gte`
- `dwithin` (except MySQL)

Catatan

Untuk mengukur, daripada meminta pada jarak, gunakan fungsi `Distance`.

Pencarian jarak meliputi parameter tuple.

1. Geometri atau raster untuk perhitungan dasar dari; dan
2. Sejumlah atau obyek `Distance` mengandung jarak.

Jika obyek `Distance` digunakan, itu mungkin dinyatakan dalam satuan apapun (SQL dibangkitkan akan menggunakan unit untuk merubah ke bidang tersebut); sebaliknya parameter numerik dianggap berada dalam satuan dari bidang.

Catatan

Dalam PostGIS, `ST_Distance_Sphere` tidak membatasi permintaan jarak geografis jenis geometri dilakukan dengan. [4] Bagaimanapun, permintaan ini mungkin memakan waktu lama, ketika jarak lingkaran-besar harus dihitung dengan cepat untuk *setiap*baris dalam permintaan. Ini karena indeks spasial pada bidang geometri tradisional tidak dapat digunakan.

tUntuk penampilan lebih baik pada permintaan jarak WGS84, pertimbangkan menggunakan geography columns 1 dalam basisdata anda sebagai gantinya karena mereka dapat menggunakan indeks spasial mereka di permintaan jarak. Anda dapat memberitahu GeoDjango menggunakan kolom geografi dengan mengatur `geography=True` dalam penentuan bidang anda.

Sebagai contoh, mari kita katakan kami memiliki sebuah model `SouthTexasCity` (dari GeoDjango distance tests ) pada sebuah sistem kordinat sah diproyeksikan untuk kota-kota dalam Texas selatan:

    from django.contrib.gis.db import models

    class SouthTexasCity(models.Model):
        name = models.CharField(max_length=30)
        # A projected coordinate system (only valid for South Texas!)
        # is used, units are in meters.
        point = models.PointField(srid=32140)

Kemudian permintaan jarak mungkin dilakukan sebagai berikut:

    >>> from django.contrib.gis.geos import GEOSGeometry
    >>> from django.contrib.gis.measure import D # ``D`` is a shortcut for ``Distance``
    >>> from geoapp.models import SouthTexasCity
    # Distances will be calculated from this point, which does not have to be projected.
    >>> pnt = GEOSGeometry('POINT(-96.876369 29.905320)', srid=4326)
    # If numeric parameter, units of field (meters in this case) are assumed.
    >>> qs = SouthTexasCity.objects.filter(point__distance_lte=(pnt, 7000))
    # Find all Cities within 7 km, > 20 miles away, and > 100 chains away (an obscure unit)
    >>> qs = SouthTexasCity.objects.filter(point__distance_lte=(pnt, D(km=7)))
    >>> qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(mi=20)))
    >>> qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(chain=100)))

Permintaan raster bekerja cara sama dengan cukup menaruh bidang geometri `point` dengan bidang raster, atau obyek `pnt` dengan obyek raster, atau keduanya. Untuk menentukan index pita dari masukan raster pada sisi tangan kanan, 3-tuple dapat dilewatkan ke pencarian sebagai berikut:

    >>> qs = SouthTexasCity.objects.filter(point__distance_gte=(rst, 2, D(km=7)))

Dimana pita dengan indeks 2 (pita ketiga) dari raster `rst` akan digunakan untuk pencarian.

## Tabel Kesesuaian

### Pencarian Spasial

Tabel berikut menyediakan ringkasan dari apa pencarian spasial tersedia untuk setiap backend basisdata spasial. Pencarian PostGIS Raster (PGRaster) dibagi kedalam tiga kategori digambarkan dalam raster lookup details 1: dukungan asal `n`, dukungan asal bilateral `B`, dan dukungan perubahan geometri `C`.

Jenis Pencarian | PostGIS | Oracle | MySQL [6] | SpatiaLite | PGRaster
--- | --- | --- | --- | --- | ---
`bbcontains` | X |  | X | X | N
`bboverlaps` | X |  | X | X | N
`contained` | X |  | X | X | N
`contains` | X | X | X | X | B
`contains_properly` | X |  |  |  | B
`coveredby` | X | X |  | X | B
`covers` | X | X |  | X | B
`crosses` | X |  |  | X | C
`disjoint` | X | X | X | X | B
`distance_gt` | X | X | X | X | N
`distance_gte` | X | X | X | X | N
`distance_lt` | X | X | X | X | N
`distance_lte` | X | X | X | X | N
`dwithin` | X | X |  | X | B
`equals` | X | X | X | X | C
`exact` | X | X | X | X | B
`intersects` | X | X | X | X | B
`isvalid` | X | X | X (≥ 5.7.5) | X (LWGEOM) |
`overlaps` | X | X | X | X | B
`relate` | X | X |  | X | C
`same_as` | X | X | X | X | B
`touches` | X | X | X | X | B
`within` | X | X | X | X | B
`left` | X |  |  |  | C
`right` | X |  |  |  | C
`overlaps_left` | X |  |  |  | B
`overlaps_right` | X |  |  |  | B
`overlaps_above` | X |  |  |  | C
`overlaps_below` | X |  |  |  | C
`strictly_above` | X |  |  |  | C
`strictly_below` | X |  |  |  | C

### Fungsi basisdata

Tabel berikut menyediakan ringkasan dari apa fungsi-fungsi basisdata khusus-geografis tersedia pada setiap backend spasial.

Fungsi | PostGIS | Oracle | MySQL | SpatiaLite
--- | --- | --- | --- | ---
`Area` | X | X | X | X
`AsGeoJSON` | X |  | X (≥ 5.7.5) | X
`AsGML` | X | X |  | X
`AsKML` | X |  |  | X
`AsSVG` | X |  |  | X
`Azimuth` | X |  |  | X (LWGEOM)
`BoundingCircle` | X | X |  |
`Centroid` | X | X | X | X
`Difference` | X | X | X | X
`Distance` | X | X | X | X
`Envelope` | X | X | X | X
`ForcePolygonCW` | X |  |  | X
`ForceRHR` | X |  |  |
`GeoHash` | X |  | X (≥ 5.7.5) | X (LWGEOM)
`Intersection` | X | X | X | X
`IsValid` | X | X | X (≥ 5.7.5) | X (LWGEOM)
`Length` | X | X | X | X
`LineLocatePoint` | X |  |  | X
`MakeValid` | X |  |  | X (LWGEOM)
`MemSize` | X |  |  |
`NumGeometries` | X | X | X | X
`NumPoints` | X | X | X | X
`Perimeter` | X | X |  | X
`PointOnSurface` | X | X |  | X
`Reverse` | X | X |  | X
`Scale` | X |  |  | X
`SnapToGrid` | X |  |  | X
`SymDifference` | X | X | X | X
`Transform` | X | X |  | X
`Translate` | X |  |  | X
`Union` | X | X | X | X

### Fungsi Kumpulan

Tabel-tabel berikut menyediakan ringkasan dari apa fungsi-fungsi pengumpulan GIS-khusus tersedia pada setiap backend spasial. harap catcat bahwa MySQL tidak mendukung apapun dari pengumpulan ini, dan dengan demikian tidak disertakan dari tabel.

Kumpulan | PostGIS | Oracle | SpatiaLite
--- | --- | --- | ---
`Collect` | X |  | X
`Extent` | X | X | X
`Extent3D` | X |  |
`MakeLine` | X |  | X
`Union` | X | X | X

Catatan kaki

[1] | Lihat Open Geospatial Consortium, Inc., OpenGIS Simple Feature Specification For SQL, Document 99-049 (5 Mei 1999), pada bab 3.2.5, hal. 3-11 (Perwakilan Tekstual SQL dari Geometri).

[2] | Lihat PostGIS EWKB, EWKT and Canonical Forms, Dokumentasi PostGIS bab 4.1.2.

[3] | Lihat Howard Butler, Martin Daly, Allan Doyle, Tim Schaub, & Christopher Schmidt, The GeoJSON Format Specification, Perbaikan 1.0 (16 Juni 2008)

[4] | Lihat PostGIS documentation pada `ST_DistanceSphere`.

[5] | LIhat Creating Spatial Indexes di Manual Acuan MySQL: Untuk tabel MyISAM, `SPATIAL INDEX` membuat sebuah indeks R-tree. Untuk mesin penyimpanan yang mendukung pengindeksan bukan spasial dari kolom spasial, mesin membuat indeks B-tree. Sebuah indeks B-tree pada nilai-nilai spasial akan berguna untuk pencarian nilai-tepat, tetapi bukan untuk pemindaian jangkauan.

[6] | Mengacu bagian Batasan Spasial MySQL untuk rincian lebih.