Geographic add-ons for Django REST Framework. Maintained by the OpenWISP Project.

Overview

django-rest-framework-gis

Build Status Coverage Status Requirements Status PyPI version PyPI downloads Black

Geographic add-ons for Django Rest Framework - Mailing List.

Install last stable version from pypi

pip install djangorestframework-gis

Install development version

pip install https://github.com/openwisp/django-rest-framework-gis/tarball/master

Setup

Add rest_framework_gis in settings.INSTALLED_APPS, after rest_framework:

INSTALLED_APPS = [
    # ...
    'rest_framework',
    'rest_framework_gis',
    # ...
]

Compatibility with DRF, Django and Python

DRF-gis version DRF version Django version Python version
0.17.x 3.10 up to 3.12 2.2 to 3.1 3.6 to 3.8
0.16.x 3.10 2.2 to 3.1 3.6 to 3.8
0.15.x 3.10 1.11, 2.2 to 3.0 3.5 to 3.8
0.14.x 3.3 to 3.9 1.11 to 2.1 3.4 to 3.7
0.13.x 3.3 to 3.8 1.11 to 2.0 2.7 to 3.6
0.12.x 3.1 to 3.7 1.11 to 2.0 2.7 to 3.6
0.11.x 3.1 to 3.6 1.7 to 1.11 2.7 to 3.6
0.10.x 3.1 to 3.3 1.7 to 1.9 2.7 to 3.5
0.9.6 3.1 to 3.2 1.5 to 1.8 2.6 to 3.5
0.9.5 3.1 to 3.2 1.5 to 1.8 2.6 to 3.4
0.9.4 3.1 to 3.2 1.5 to 1.8 2.6 to 3.4
0.9.3 3.1 1.5 to 1.8 2.6 to 3.4
0.9.2 3.1 1.5 to 1.8 2.6 to 3.4
0.9.1 3.1 1.5 to 1.8 2.6 to 3.4
0.9 3.1 1.5 to 1.8 2.6, 2.7, 3.3, 3.4
0.9 3.1 1.5 to 1.8 2.6, 2.7, 3.3, 3.4
0.9 3.1 1.5 to 1.8 2.6, 2.7, 3.3, 3.4
0.8.2 3.0.4 to 3.1.1 1.5 to 1.8 2.6, 2.7, 3.3, 3.4
0.8.1 3.0.4 to 3.1.1 1.5 to 1.8 2.6, 2.7, 3.3, 3.4
0.8 3.0.4 1.5 to 1.7 2.6, 2.7, 3.3, 3.4
0.7 2.4.3 1.5 to 1.7 2.6, 2.7, 3.3, 3.4
0.6 2.4.3 1.5 to 1.7 2.6, 2.7, 3.3, 3.4
0.5 from 2.3.14 to 2.4.2 1.5 to 1.7 2.6, 2.7, 3.3, 3.4
0.4 from 2.3.14 to 2.4.2 1.5 to 1.7 2.6, 2.7, 3.3, 3.4
0.3 from 2.3.14 to 2.4.2 1.5, 1.6 2.6, 2.7
0.2 from 2.2.2 to 2.3.13 1.5, 1.6 2.6, 2.7

Fields

GeometryField

Provides a GeometryField, which is a subclass of Django Rest Framework (from now on DRF) WritableField. This field handles GeoDjango geometry fields, providing custom to_native and from_native methods for GeoJSON input/output.

This field takes two optional arguments:

precision: Passes coordinates through Python's builtin round() function (docs), rounding values to the provided level of precision. E.g. A Point with lat/lng of [51.0486, -114.0708] passed through a GeometryField(precision=2) would return a Point with a lat/lng of [51.05, -114.07].

remove_duplicates: Remove sequential duplicate coordinates from line and polygon geometries. This is particularly useful when used with the precision argument, as the likelihood of duplicate coordinates increase as precision of coordinates are reduced.

Note: While both above arguments are designed to reduce the byte size of the API response, they will also increase the processing time required to render the response. This will likely be negligible for small GeoJSON responses but may become an issue for large responses.

New in 0.9.3: there is no need to define this field explicitly in your serializer, it's mapped automatically during initialization in rest_framework_gis.apps.AppConfig.ready().

GeometrySerializerMethodField

Provides a GeometrySerializerMethodField, which is a subclass of DRF SerializerMethodField and handles values which are computed with a serializer method and are used as a geo_field. See example below.

Serializers

GeoModelSerializer (DEPRECATED)

Deprecated, will be removed in 1.0: Using this serializer is not needed anymore since 0.9.3, if you add rest_framework_gis in settings.INSTALLED_APPS the serialization will work out of the box with DRF. Refer Issue #156.

Provides a GeoModelSerializer, which is a subclass of DRF ModelSerializer. This serializer updates the field_mapping dictionary to include field mapping of GeoDjango geometry fields to the above GeometryField.

For example, the following model:

class Location(models.Model):
    """
    A model which holds information about a particular location
    """
    address = models.CharField(max_length=255)
    city = models.CharField(max_length=100)
    state = models.CharField(max_length=100)
    point = models.PointField()

By default, the DRF ModelSerializer ver < 0.9.3 will output:

{
    "id": 1,
    "address": "742 Evergreen Terrace",
    "city":  "Springfield",
    "state": "Oregon",
    "point": "POINT(-123.0208 44.0464)"
}

In contrast, the GeoModelSerializer will output:

{
    "id": 1,
    "address": "742 Evergreen Terrace",
    "city":  "Springfield",
    "state": "Oregon",
    "point": {
        "type": "Point",
        "coordinates": [-123.0208, 44.0464],
    }
}

Note: For ver>=0.9.3: The DRF model serializer will give the same output as above, if;

  • rest_framework_gis is set in settings.INSTALLED_APPS or
  • the field in the serializer is set explicitly as GeometryField.

GeoFeatureModelSerializer

GeoFeatureModelSerializer is a subclass of rest_framework.ModelSerializer which will output data in a format that is GeoJSON compatible. Using the above example, the GeoFeatureModelSerializer will output:

 {
    "id": 1,
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [-123.0208, 44.0464],
    },
    "properties": {
        "address": "742 Evergreen Terrace",
        "city":  "Springfield",
        "state": "Oregon"
    }
}

If you are serializing an object list, GeoFeatureModelSerializer will create a FeatureCollection:

{
    "type": "FeatureCollection",
    "features": [
    {
        "id": 1
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [-123.0208, 44.0464],
        },
        "properties": {
            "address": "742 Evergreen Terrace",
            "city":  "Springfield",
            "state": "Oregon",
        }
    }
    {
        "id": 2,
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [-123.0208, 44.0489],
        },
        "properties": {
            "address": "744 Evergreen Terrace",
            "city":  "Springfield",
            "state": "Oregon"
        }
    }
}
Specifying the geometry field: "geo_field"

GeoFeatureModelSerializer requires you to define a geo_field to be serialized as the "geometry". For example:

from rest_framework_gis.serializers import GeoFeatureModelSerializer

class LocationSerializer(GeoFeatureModelSerializer):
    """ A class to serialize locations as GeoJSON compatible data """

    class Meta:
        model = Location
        geo_field = "point"

        # you can also explicitly declare which fields you want to include
        # as with a ModelSerializer.
        fields = ('id', 'address', 'city', 'state')
Using GeometrySerializerMethodField as "geo_field"

geo_field may also be an instance of GeometrySerializerMethodField. In this case you can compute its value during serialization. For example:

from django.contrib.gis.geos import Point
from rest_framework_gis.serializers import GeoFeatureModelSerializer, GeometrySerializerMethodField

class LocationSerializer(GeoFeatureModelSerializer):
    """ A class to serialize locations as GeoJSON compatible data """

    # a field which contains a geometry value and can be used as geo_field
    other_point = GeometrySerializerMethodField()

    def get_other_point(self, obj):
        return Point(obj.point.lat / 2, obj.point.lon / 2)

    class Meta:
        model = Location
        geo_field = 'other_point'

Serializer for geo_field may also return None value, which will translate to null value for geojson geometry field.

Specifying the ID: "id_field"

The primary key of the model (usually the "id" attribute) is automatically used as the id field of each GeoJSON Feature Object.

The default behaviour follows the GeoJSON RFC, but it can be disabled by setting id_field to False:

from rest_framework_gis.serializers import GeoFeatureModelSerializer

class LocationSerializer(GeoFeatureModelSerializer):

    class Meta:
        model = Location
        geo_field = "point"
        id_field = False
        fields = ('id', 'address', 'city', 'state')

The id_field can also be set to use some other unique field in your model, eg: slug:

from rest_framework_gis.serializers import GeoFeatureModelSerializer

class LocationSerializer(GeoFeatureModelSerializer):

    class Meta:
        model = Location
        geo_field = 'point'
        id_field = 'slug'
        fields = ('slug', 'address', 'city', 'state')
Bounding Box: "auto_bbox" and "bbox_geo_field"

The GeoJSON specification allows a feature to contain a boundingbox of a feature. GeoFeatureModelSerializer allows two different ways to fill this property. The first is using the geo_field to calculate the bounding box of a feature. This only allows read access for a REST client and can be achieved using auto_bbox. Example:

from rest_framework_gis.serializers import GeoFeatureModelSerializer

class LocationSerializer(GeoFeatureModelSerializer):
    class Meta:
        model = Location
        geo_field = 'geometry'
        auto_bbox = True

The second approach uses the bbox_geo_field to specify an additional GeometryField of the model which will be used to calculate the bounding box. This allows boundingboxes differ from the exact extent of a features geometry. Additionally this enables read and write access for the REST client. Bounding boxes send from the client will be saved as Polygons. Example:

from rest_framework_gis.serializers import GeoFeatureModelSerializer

class LocationSerializer(GeoFeatureModelSerializer):

    class Meta:
        model = BoxedLocation
        geo_field = 'geometry'
        bbox_geo_field = 'bbox_geometry'
Custom GeoJSON properties source

In GeoJSON each feature can have a properties member containing the attributes of the feature. By default this field is filled with the attributes from your Django model, excluding the id, geometry and bounding box fields. It's possible to override this behaviour and implement a custom source for the properties member.

The following example shows how to use a PostgreSQL HStore field as a source for the properties member:

# models.py
class Link(models.Model):
    """
    Metadata is stored in a PostgreSQL HStore field, which allows us to
    store arbitrary key-value pairs with a link record.
    """
    metadata = HStoreField(blank=True, null=True, default=dict)
    geo = models.LineStringField()
    objects = models.GeoManager()

# serializers.py
class NetworkGeoSerializer(GeoFeatureModelSerializer):
    class Meta:
        model = models.Link
        geo_field = 'geo'
        auto_bbox = True

    def get_properties(self, instance, fields):
        # This is a PostgreSQL HStore field, which django maps to a dict
        return instance.metadata

    def unformat_geojson(self, feature):
        attrs = {
            self.Meta.geo_field: feature["geometry"],
            "metadata": feature["properties"]
        }

        if self.Meta.bbox_geo_field and "bbox" in feature:
            attrs[self.Meta.bbox_geo_field] = Polygon.from_bbox(feature["bbox"])

        return attrs

When the serializer renders GeoJSON, it calls the method get_properties for each object in the database. This function should return a dictionary containing the attributes for the feature. In the case of a HStore field, this function is easily implemented.

The reverse is also required: mapping a GeoJSON formatted structure to attributes of your model. This task is done by unformat_geojson. It should return a dictionary with your model attributes as keys, and the corresponding values retrieved from the GeoJSON feature data.

Pagination

We provide a GeoJsonPagination class.

GeoJsonPagination

Based on rest_framework.pagination.PageNumberPagination.

Code example:

from rest_framework_gis.pagination import GeoJsonPagination
# --- other omitted imports --- #

class GeojsonLocationList(generics.ListCreateAPIView):
    # -- other omitted view attributes --- #
    pagination_class = GeoJsonPagination

Example result response (cut to one element only instead of 10):

{
    "type": "FeatureCollection",
    "count": 25,
    "next": "http://localhost:8000/geojson/?page=2",
    "previous": null,
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    42.0,
                    50.0
                ]
            },
            "properties": {
                "name": "test"
            }
        }
    ]
}

Filters

note: this feature has been tested up to django-filter 1.0.

We provide a GeometryFilter field as well as a GeoFilterSet for usage with django_filter. You simply provide, in the query string, one of the textual types supported by GEOSGeometry. By default, this includes WKT, HEXEWKB, WKB (in a buffer), and GeoJSON.

GeometryFilter

from rest_framework_gis.filterset import GeoFilterSet
from rest_framework_gis.filters import GeometryFilter
from django_filters import filters

class RegionFilter(GeoFilterSet):
    slug = filters.CharFilter(name='slug', lookup_expr='istartswith')
    contains_geom = GeometryFilter(name='geom', lookup_expr='contains')

    class Meta:
        model = Region

We can then filter in the URL, using GeoJSON, and we will perform a __contains geometry lookup, e.g. /region/?contains_geom={ "type": "Point", "coordinates": [ -123.26436996459961, 44.564178042345375 ] }.

GeoFilterSet

The GeoFilterSet provides a django_filter compatible FilterSet that will automatically create GeometryFilters for GeometryFields.

InBBoxFilter

Provides a InBBoxFilter, which is a subclass of DRF BaseFilterBackend. Filters a queryset to only those instances within a certain bounding box.

views.py:

from rest_framework_gis.filters import InBBoxFilter

class LocationList(ListAPIView):

    queryset = models.Location.objects.all()
    serializer_class = serializers.LocationSerializer
    bbox_filter_field = 'point'
    filter_backends = (InBBoxFilter,)
    bbox_filter_include_overlapping = True # Optional

We can then filter in the URL, using Bounding Box format (min Lon, min Lat, max Lon, max Lat), and we can search for instances within the bounding box, e.g.: /location/?in_bbox=-90,29,-89,35.

By default, InBBoxFilter will only return those instances entirely within the stated bounding box. To include those instances which overlap the bounding box, include bbox_filter_include_overlapping = True in your view.

Note that if you are using other filters, you'll want to include your other filter backend in your view. For example:

filter_backends = (InBBoxFilter, DjangoFilterBackend,)

TMSTileFilter

Provides a TMSTileFilter, which is a subclass of InBBoxFilter. Filters a queryset to only those instances within a bounding box defined by a TMS tile address.

views.py:

from rest_framework_gis.filters import TMSTileFilter

class LocationList(ListAPIView):

    queryset = models.Location.objects.all()
    serializer_class = serializers.LocationSerializer
    bbox_filter_field = 'point'
    filter_backends = (TMSTileFilter,)
    bbox_filter_include_overlapping = True # Optional

We can then filter in the URL, using TMS tile addresses in the zoom/x/y format, eg:. /location/?tile=8/100/200 which is equivalent to filtering on the bbox (-39.37500,-71.07406,-37.96875,-70.61261).

For more information on configuration options see InBBoxFilter.

Note that the tile address start in the upper left, not the lower left origin used by some implementations.

DistanceToPointFilter

Provides a DistanceToPointFilter, which is a subclass of DRF BaseFilterBackend. Filters a queryset to only those instances within a certain distance of a given point.

views.py:

from rest_framework_gis.filters import DistanceToPointFilter

class LocationList(ListAPIView):

    queryset = models.Location.objects.all()
    serializer_class = serializers.LocationSerializer
    distance_filter_field = 'geometry'
    filter_backends = (DistanceToPointFilter,)

We can then filter in the URL, using a distance and a point in (lon, lat) format. The distance can be given in meters or in degrees.

eg:. /location/?dist=4000&point=-122.4862,37.7694&format=json which is equivalent to filtering within 4000 meters of the point (-122.4862, 37.7694).

By default, DistanceToPointFilter will pass the 'distance' in the URL directly to the database for the search. The effect depends on the srid of the database in use. If geo data is indexed in meters (srid 3875, aka 900913), a distance in meters can be passed in directly without conversion. For lat-lon databases such as srid 4326, which is indexed in degrees, the 'distance' will be interpreted as degrees. Set the flag, 'distance_filter_convert_meters' to 'True' in order to convert an input distance in meters to degrees. This conversion is approximate, and the errors at latitudes > 60 degrees are > 25%.

DistanceToPointOrderingFilter

Provides a DistanceToPointOrderingFilter, available on Django >= 3.0, which is a subclass of DistanceToPointFilter. Orders a queryset by distance to a given point, from the nearest to the most distant point.

views.py:

from rest_framework_gis.filters import DistanceToPointOrderingFilter

class LocationList(ListAPIView):

    queryset = models.Location.objects.all()
    serializer_class = serializers.LocationSerializer
    distance_ordering_filter_field = 'geometry'
    filter_backends = (DistanceToPointOrderingFilter,)

We can then order the results by passing a point in (lon, lat) format in the URL.

eg:. /location/?point=-122.4862,37.7694&format=json will order the results by the distance to the point (-122.4862, 37.7694).

We can also reverse the order of the results by passing order=desc: /location/?point=-122.4862,37.7694&order=desc&format=json

Schema Generation

Note: Schema generation support is available only for DRF >= 3.12.

Simplest Approach would be, change DEFAULT_SCHEMA_CLASS to rest_framework_gis.schema.GeoFeatureAutoSchema:

REST_FRAMEWORK = {
    ...
    'DEFAULT_SCHEMA_CLASS': 'rest_framework_gis.schema.GeoFeatureAutoSchema',
    ...
}

If you do not want to change default schema generator class:

  • You can pass this class as an argument to get_schema_view function [Ref].
  • You can pass this class as an argument to the generateschema command [Ref].

Running the tests

Required setup

You need one of the Spatial Database servers supported by GeoDjango, and create a database for the tests.

The following can be used with PostgreSQL:

createdb django_restframework_gis
psql -U postgres -d django_restframework_gis -c "CREATE EXTENSION postgis"

You might need to tweak the DB settings according to your DB configuration. You can copy the file local_settings.example.py to local_settings.py and change the DATABASES and/or INSTALLED_APPS directives there.

This should allow you to run the tests already.

For reference, the following steps will setup a development environment for contributing to the project:

  • create a spatial database named "django_restframework_gis"
  • create local_settings.py, eg: cp local_settings.example.py local_settings.py
  • tweak the DATABASES configuration directive according to your DB settings
  • uncomment INSTALLED_APPS
  • run python manage.py syncdb
  • run python manage.py collectstatic
  • run python manage.py runserver

Using tox

The recommended way to run the tests is by using tox, which can be installed using pip install tox.

You can use tox -l to list the available environments, and then e.g. use the following to run all tests with Python 3.6 and Django 1.11:

tox -e py36-django111

By default Django's test runner is used, but there is a variation of tox's envlist to use pytest (using the -pytest suffix).

You can pass optional arguments to the test runner like this:

tox -e py36-django111-pytest -- -k test_foo

Running tests manually

Please refer to the tox.ini file for reference/help in case you want to run tests manually / without tox.

To run tests in docker use

docker-compose build
docker-compose run --rm test

Running QA-checks

Install the test requirements:

pip install -r requirements-test.txt

Reformat the code according to our coding style conventions with:

openwisp-qa-format

Run the QA checks by using

./run-qa-checks

In docker testing, QA checks are executed automatically.

Contributing

  1. Join the Django REST Framework GIS Mailing List and announce your intentions
  2. Follow the PEP8 Style Guide for Python Code
  3. Fork this repo
  4. Write code
  5. Write tests for your code
  6. Ensure all tests pass
  7. Ensure test coverage is not under 90%
  8. Document your changes
  9. Send pull request
Comments
  • OpenAPI Schema Generation

    OpenAPI Schema Generation

    Hi @auvipy,

    This fixes: #219, #237

    You requested to wait for 3.12 Release. I will write code in such a way that it will be compatible will 3.12 Release.

    This will close: #186 and #219

    enhancement 
    opened by dhaval-mehta 51
  • Support faster serialization when there is raw JSON field available

    Support faster serialization when there is raw JSON field available

    (Work in progress.)

    The idea is that you add raw GeoJSON directly from the database to the queryset using AsGeoJSON annotation. So if original field was foo, you should add annotation foo_geojson. Because this JSON is coming from the database it is much faster to access than going though GDAL.

    When paired together with ujson renderer, which knows how to pass raw strings directly into serialization if they contain __json__ method, this means that one can get JSON directly from the database into the output without any conversion of data. Amazingly fast serialization.

    See this pull request for more details.

    enhancement 
    opened by mitar 25
  • check explicitly for not None on field values

    check explicitly for not None on field values

    This is a really subtle weird error, but I was getting errors serializing an optional ImageField with no file associated with it--the errors kept insisting that there ought to be a file. I tried adding allow_empty_file=True and that works fine for GeoModelSerializer and the regular DRF ModelSerializer, but broke with GeoFeatureModelSerializer.

    It turns out, in the GeoFeatureModelSerializer code, if I check explicitly for whether the value is None, I can get GeoFeatureModelSerializer to work. My hunch is that ImageField, when empty, is a value that is equal to None (i.e. <ImageFieldFile: None>), but will not pass a merely "falsey" condition. So I had to write it as; if value is not None: rather than if value:

    This is actually what DRF ModelSerializer itself does, more or less. https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/serializers.py#L430

    opened by mikeedwards 22
  • Output properly formatted GeoJson

    Output properly formatted GeoJson

    We need to properly format the outputted GeoJson so that it can be consumed by client-side mapping software (Leaflet, OpenLayers, etc)

    So, for example, lets look at the following Location model:

    class Location(models.Model):
        """
        A model which holds information about a particular location
       """
       address = models.Charfield(max_length=255)
       city = models.CharField(max_length=100)
       state = models.CharField(max_length=100)
       point = models.PointField()
    

    By default, DRF will format a json response as (for example):

    {
         "id": 1, 
         "address": "742 Evergreen Terrace", 
          "city":  "Springfield", 
          "state": "Oregon",
          "point": "POINT(-123.0208 44.0464)" 
    }
    

    With a new GeoDjango enabled GeometryField as an add on, it will output "point" as a GeoJson:

    {
         "id": 1, 
         "address": "742 Evergreen Terrace", 
          "city":  "Springfield", 
          "state": "Oregon",
          "point": {
                "type": "Point",
                "coordinates": [-123.0208, 44.0464],
           },
    }
    

    But, we now need to format the entire json response as GeoJson, for example:

    { 
        "type": "Feature",
         "geometry": {
               "type": "Point",
               "coordinates": [-123.0208, 44.0464],
         },
         "properties": {
             "id": 1, 
             "address": "742 Evergreen Terrace", 
             "city":  "Springfield", 
             "state": "Oregon",
         }
    }
    

    Need to investigate the best place in DRF to override for this behavior.

    For reference: http://geojson.org/geojson-spec.html

    enhancement 
    opened by dmeehan 22
  • [RFC] add tox.ini / support for pytest

    [RFC] add tox.ini / support for pytest

    This is rudimentary, but makes it a lot easier to run the tests.

    Please consider adopting it and mention it in the docs. It could also be used on Travis.

    opened by blueyed 20
  • Geofilter support

    Geofilter support

    Fixes #3.

    There's a lot more that's possible here, but we will have to do a lot more special-casing (e.g. for distance lookups). This, however, gives us all of the power that tastypie has in their GeoDjango support (which I wrote)

    opened by philipn 16
  • Error when model is rendered in drf html

    Error when model is rendered in drf html

    When im logged and drf tries to render the html form to make POST, drf-gis gets broken in serializers.py in from_native, line 115 with argument of type 'NoneType' is not iterable.

    opened by avances123 14
  • Custom source for feature metadata

    Custom source for feature metadata

    My current use case:

    • Model with geometry and variable metadata
    • Metadata is stored in PostgreSQL HStore field
    • I want to render a GeoJSON layer using the HStore field as source for the feature "properties"

    Looking at the source code for GeoFeatureModelSerializer (https://github.com/djangonauts/django-rest-framework-gis/blob/master/rest_framework_gis/serializers.py#L96), I can see that there is no possibility yet to override the source for feature properties.

    I have the following idea as a possible solution:

    • Add a method get_feature_properties to GeoFeatureModelSerializer, which accepts the current instance as parameter, and returns a dict containing the properties for the current feature.
    • By default returns the instance fields with current checks for id/bbox/geo field in place.
    • Subclasses can override this function (and thus return metadata from for example the HStore field).

    Any suggestions? I will open a pull request shortly.

    enhancement 
    opened by lrvdijk 12
  • Fields will not read what it writes

    Fields will not read what it writes

    When to_representation is run on a geo object json.load adds unicode strings so the result is something like:

    {u'type': u'Point', u'coordinates': [39.921092168090915, 28.04062843322754]}
    

    this is the string that rest_framework puts into the web form for any PUTs to edit the field. Therefore the PUT will send the string:

    "{u'type': u'Point', u'coordinates': [39.921092168090915, 28.04062843322754]}"
    

    which will not work with GEOSGeometry as it does not expect the u symbols. The way around this is to eval the string as a python dictionary and then dump the json. This creates the string:

    '{"type": "Point", "coordinates": [39.921092168090915, 28.04062843322754]}'
    

    which will then work.

    opened by nparley 12
  • support for geojson boundingboxes. auto-generated or using a seperate field on the model

    support for geojson boundingboxes. auto-generated or using a seperate field on the model

    This pull request adds support for bounding boxes as specified in the GeoJSON specification at http://geojson.org/geojson-spec.html#bounding-boxes.

    The patch implements tow ways how boundingboxes can be specifed, see the following extract of the README documentation:

    The GeoJSON specification allows a feature to contain a boundingbox of a feature. GeoFeatureModelSerializer allows two different ways to fill this property. The first is using the geo_field to calculate the bounding box of a feature. This only allows read access for a REST client and can be achieved using auto_bbox. Example:

    from rest_framework_gis.serializers import GeoFeatureModelSerializer
    
    class LocationSerializer(GeoFeatureModelSerializer):
        class Meta:
            auto_bbox = True
            model = Location
            geo_field = 'geometry'
    

    The second approach uses the bbox_geo_field to specify an addional GeometryField of the model which will be used to calculate the bounding box. This allows boundingboxes differ from the exact extent of a features geometry. Additionally this enables read and write access for the REST client. Bounding boxes send from the client will be saved as Polygons. Example:

    from rest_framework_gis.serializers import GeoFeatureModelSerializer
    
    class LocationSerializer(GeoFeatureModelSerializer):
    
        class Meta:
            model = BoxedLocation
            geo_field = 'geometry'
            bbox_geo_field = 'bbox_geometry'
            fields = ['name', 'id']
    
    opened by nmandery 12
  • Question: DistanceToPointFilter

    Question: DistanceToPointFilter

    Hi! I'm trying to use the DistanceToPointFilter, but I cannot get it working.

    This is my code:

    class RouteView(viewsets.ReadOnlyModelViewSet):
        queryset = Route.objects.all()
        serializer_class = RouteSerializer
        filter_backends = (InBBoxFilter, DistanceToPointFilter, DjangoFilterBackend)
        filter_class = RouteFilter
        distance_filter_field = 'start_point'
        bbox_filter_field = 'start_point'
        bbox_filter_include_overlapping = True
    

    I've tried all the combinations with these params:

    routes/?dist=4000&point=lon,lat
    routes/?dist=4000&point=lat,lon
    routes/?dist=4000&point=lon,lat&distance_filter_convert_meters=True
    

    etc... Am I missing something? [The other filters are properly working] Thanks for your help :D

    question 
    opened by yamila-moreno 11
  • Using GeoFeatureModelSerializer with files

    Using GeoFeatureModelSerializer with files

    Hello

    I was wondering if there is a possibility / example of using GeoFeatureModelSerializer with a model that has an image field. I am trying to do it in a single request using

    parser_classes = [MultiPartParser, JSONParser ]
    

    It works with different models, there creation is easy and possible, retaining all fields passed plus the file.

    Is it possible with the serializer above? What should be added / changed if so?

    opened by hvitis 0
  • [fix] Added missing float type to InBBoxFilter schema

    [fix] Added missing float type to InBBoxFilter schema

    Fix typing in InBBoxFilter and DistanceToPointFilter. The only possible values for type are ['array', 'boolean', 'integer', 'number', 'object', 'string']. But float can be used as format of number.

    Refarence to Swagger Documentation Data Types

    opened by astanishevskyi 5
  • [feat] add support for `dist` parameter on `DistanceToPointOrderingFilter`

    [feat] add support for `dist` parameter on `DistanceToPointOrderingFilter`

    The DistanceToPointOrderingFilter inherits from the DistanceToPointFilter but only supports the point param and no dist param. This adds support for the dist param (such that a user can query for all points within a certain dist of the given point and have the results returned in asc or desc order) by combining the filter_queryset logic of the existing DistanceToPointOrderingFilter#filter_queryset and the DistanceToPointFilter#filter_queryset.

    This also implements a get_schema_fields() method so the filter fields can be included in schema autogeneration provided by the Django REST framework (documentation linked)

    opened by carolinekessler 0
  • OpenAPI schema generation fails if the GeometryField is not in the model

    OpenAPI schema generation fails if the GeometryField is not in the model

    This piece of code will cause the schema generation to fail if the GeometryField is not in the model, e.g. it is an annotation or a custom property.

    I don't see any simple solution (without custom get_field), beside having multiple serializer fields: PointField, LineStringField, etc.)

    opened by AntoninRousset 1
  • GEOS_ERROR when using empty Point in GeometryField

    GEOS_ERROR when using empty Point in GeometryField

    Hi,

    When a user submits an empty point request: POINT ( ) this validation error is raised: Invalid format: string or unicode input unrecognized as GeoJSON, WKT EWKT or HEXEWKB.'

    Only internally we also see this error: django.contrib.gis:100 ERROR GEOS_ERROR: ParseException: Expected number but encountered ')'

    As this is the only information we are given it is a bit difficult to see what exactly caused the error but I believe it is coming from your package. If so, it would be great if you could catch this error :) otherwise please let me know what else caused it and feel free to close the issue.

    Example code:

    class RasterPointSerializer(serializers.Serializer):
        geom = GeometryField()
        ....
    

    Example request: ?geom=POINT ( )

    opened by daanvaningen 0
Releases(v1.0.0)
  • v1.0.0(May 9, 2022)

    Features

    • Added support Bounding Box to GeometryField via the auto_bbox initialization argument

    Bugfixes

    • Avoid default_app_config Deprecation Warning in Django >= 3.2
    • Fixed deserialization of the id_field
    Source code(tar.gz)
    Source code(zip)
  • v0.18.0(Jan 7, 2022)

    • [fix] Add schema generation support for plain GeometryFields #257
    • [fix] Fixed psycopg2 compatibility for Django 3.0
    • [feature] Added support and CI testing for Django 3.2 and Django 4.0
    Source code(tar.gz)
    Source code(zip)
  • v0.17.0(Jan 25, 2021)

  • v0.16.0(Sep 7, 2020)

    • [fix] Added support for representation of empty geometries (#168)
    • [fix] Don't override the additional arguments passed as style to GeometryField
    • [feature] Added DistanceToPointOrderingFilter (#210)
    • [deps] Added support for django 3.1 in the CI build
    • [deps] Dropped django 1.11 and Python 3.5 from the CI build, compatibility may still work but it's not guaranteed anymore, please upgrade!
    • [qa] Added QA checks to CI build (#230)
    Source code(tar.gz)
    Source code(zip)
  • v0.15.0(Dec 9, 2019)

    • Dropped Python 3.4 support
    • #190: Added django 2.2 on test matrix
    • #199: Dropped Django 2.0 support
    • #195: Updated the way that to_representation removes already processed
    • #197: Removed six dependency
    • #202: Updated DRF to 3.10, removed support for previous DRF versions
    • #200: Added Django 3.0 and Python 3.8 support
    Source code(tar.gz)
    Source code(zip)
  • v0.14.0(Dec 2, 2018)

    • #173: added support for django 2.1, DRF 3.9 and switched to django-filters >= 2.0 (which requires python >= 3.4)
    • #178: simplified setup.py and tox build
    Source code(tar.gz)
    Source code(zip)
  • 0.13.0(Apr 27, 2018)

  • v0.12.0(Nov 12, 2017)

    • #138: added support for GeometryCollection fields
    • #146: added compatibility with django-rest-framework 3.7
    • #147: added support to django 2.0 beta
    • dropped support for django 1.7, 1.8, 1.9 and 1.10
    Source code(tar.gz)
    Source code(zip)
  • v0.11.2(May 22, 2017)

  • v0.11.1(May 5, 2017)

  • v0.11.0(Nov 22, 2016)

    • #106: dropped support for django 1.7
    • #117: added support for django-filter 0.15
    • 6479949: fixed tests for latest DRF 3.5 version
    • 35e3b87: added official support to django 1.10
    Source code(tar.gz)
    Source code(zip)
  • v0.10.1(Jan 6, 2016)

    • #93 skipped a few tests if spatialite DB backend is being used
    • #95 fixed misunderstanding regarding 0.9.6 DRF compatibility in README
    • #96 added missing assets in python package source tarball
    Source code(tar.gz)
    Source code(zip)
  • v0.10.0(Dec 7, 2015)

  • v0.9.6(Nov 2, 2015)

    • #82: avoid KeyError id field not in fields (bug introduced in 0.9.5)
    • fbaf9b1: improved documentation for new default id_field behaviour
    • #84: switched to assertAlmostEqual in test_post_location_list_EWKT to ease testing for debian package
    • #85: fixed serialization of properties holding None values (bug introduced in 0.9.5)
    • #86: updated advertised compatibility to include python 3.5
    Source code(tar.gz)
    Source code(zip)
  • v0.9.5(Oct 12, 2015)

    • #71: added possibility to override GeoJSON properties in GeoFeatureModelSerializer
    • 52e15a5: Added default page_size_query_param in GeoJsonPagination
    Source code(tar.gz)
    Source code(zip)
  • v0.9.4(Sep 8, 2015)

    • #68: ensure not having drf-gis in INSTALLED_APPS works anyway
    • #76: avoid pickle errors in GeoJsonDict
    • #75: return GEOSGeometry instead of geojson property
    Source code(tar.gz)
    Source code(zip)
  • v0.9.3(Jul 22, 2015)

    • https://github.com/djangonauts/django-rest-framework-gis/commit/04fd1bf: Added GeoJsonPagination
    • https://github.com/djangonauts/django-rest-framework-gis/commit/fe47d86: Improved ValidationError message of GeometryField
    • https://github.com/djangonauts/django-rest-framework-gis/commit/a3ddd3d: Improved serialization performance between 25% and 29%
    • https://github.com/djangonauts/django-rest-framework-gis/commit/fb6ed36: GeoModelSerializer deprecated because obsolete
    • #66: geometry now allows None values according to the GeoJSON spec
    • #67: discern False or empty string values from None in GeoFeatureModelSerializer
    Source code(tar.gz)
    Source code(zip)
  • v0.9.2(Jul 15, 2015)

    • #59: Added GeometrySerializerMethodField
    • https://github.com/djangonauts/django-rest-framework-gis/commit/3fa2354>: removed broken/obsolete/untested code
    Source code(tar.gz)
    Source code(zip)
  • v0.9.1(Jun 28, 2015)

    • #63: added compatibility with python 3.2 and updated compatibility table in README
    • #60: ensure GeoJSON is rendered correctly in browsable API when using python 2
    • #62: updated django-rest-framework requirement to 3.1.3
    Source code(tar.gz)
    Source code(zip)
  • v0.9(May 31, 2015)

    • #55: Fixed exception in DistanceToPointFilter in case of invalid point
    • #58: Fixed handling of None values in GeoFeatureModelSerializer to avoid problems with FileField and ImageField
    • #57: Added support for GeoJSON Bounding Boxes in GeoFeatureModelSerializer
    Source code(tar.gz)
    Source code(zip)
  • v0.8.2(Apr 29, 2015)

  • v0.8.1(Mar 25, 2015)

  • v0.8(Mar 3, 2015)

  • v0.7(Oct 3, 2014)

    RELEASE NOTES:

    • upgraded development status classifer to Beta
    • avoid empty string in textarea widget if value is None
    • allow field definition in GeoFeatureModelSerializer to be list
    Source code(tar.gz)
    Source code(zip)
  • v0.6(Sep 24, 2014)

  • v0.5(Sep 7, 2014)

    RELEASE NOTES:

    • added TMSTileFilter by @JesseCrocker
    • added DistanceToPointFilter by @Suz
    • renamed InBBOXFilter to InBBoxFilter
    • ensured compatibility with DRF 2.4.0
    Source code(tar.gz)
    Source code(zip)
  • v0.4(Aug 25, 2014)

  • v0.3(Jul 7, 2014)

  • v0.2(Sep 24, 2014)

  • v0.1(Sep 24, 2014)

Owner
OpenWISP
A Hackable Network Management System for the 21st Century. Communication through electronic means is a human right!
OpenWISP
A utility to search, download and process Landsat 8 satellite imagery

Landsat-util Landsat-util is a command line utility that makes it easy to search, download, and process Landsat imagery. Docs For full documentation v

Development Seed 681 Dec 07, 2022
A Python interface between Earth Engine and xarray

eexarray A Python interface between Earth Engine and xarray Description eexarray was built to make processing gridded, mesoscale time series data quic

Aaron Zuspan 159 Dec 23, 2022
Blender addons to make the bridge between Blender and geographic data

Blender GIS Blender minimal version : 2.8 Mac users warning : currently the addon does not work on Mac with Blender 2.80 to 2.82. Please do not report

5.9k Jan 02, 2023
Python bindings to libpostal for fast international address parsing/normalization

pypostal These are the official Python bindings to https://github.com/openvenues/libpostal, a fast statistical parser/normalizer for street addresses

openvenues 651 Dec 16, 2022
Centroids as a Service

Centroids! This application reads a valid geojson FeatureCollection and returns a valid geojson FeatureColleciton of centroids. In the output: All pro

Lyzi Diamond 20 Aug 29, 2021
a Geolocator made in python

Geolocator A Geolocator made in python ✨ Features locates ur location using ur ip thats it! 💁‍♀️ How to use first download the locator.py file instal

Portgas D Ace 1 Oct 27, 2021
A package to fetch sentinel 2 Satellite data from Google.

Sentinel 2 Data Fetcher Installation Create a Virtual Environment and activate it. python3 -m venv venv . venv/bin/activate Install the Package via pi

1 Nov 18, 2021
gjf: A tool for fixing invalid GeoJSON objects

gjf: A tool for fixing invalid GeoJSON objects The goal of this tool is to make it as easy as possible to fix invalid GeoJSON objects through Python o

Yazeed Almuqwishi 91 Dec 06, 2022
Django model field that can hold a geoposition, and corresponding widget

django-geoposition A model field that can hold a geoposition (latitude/longitude), and corresponding admin/form widget. Prerequisites Starting with ve

Philipp Bosch 324 Oct 17, 2022
Ingest and query genomic intervals from multiple BED files

Ingest and query genomic intervals from multiple BED files.

4 May 29, 2021
How to use COG's (Cloud optimized GeoTIFFs) with Rasterio

How to use COG's (Cloud optimized GeoTIFFs) with Rasterio According to Cogeo.org: A Cloud Opdtimized GeoTIFF (COG) is a regular GeoTIFF file, aimed at

Marvin Gabler 8 Jul 29, 2022
Calculate the area inside of any GeoJSON geometry. This is a port of Mapbox's geojson-area for Python

geojson-area Calculate the area inside of any GeoJSON geometry. This is a port of Mapbox's geojson-area for Python. Installation $ pip install area U

Alireza 87 Dec 14, 2022
Search and download Copernicus Sentinel satellite images

sentinelsat Sentinelsat makes searching, downloading and retrieving the metadata of Sentinel satellite images from the Copernicus Open Access Hub easy

837 Dec 28, 2022
Streamlit Component for rendering Folium maps

streamlit-folium This Streamlit Component is a work-in-progress to determine what functionality is desirable for a Folium and Streamlit integration. C

Randy Zwitch 224 Dec 30, 2022
Python module to access the OpenCage geocoding API

OpenCage Geocoding Module for Python A Python module to access the OpenCage Geocoder. Build Status / Code Quality / etc Usage Supports Python 3.6 or n

OpenCage GmbH 57 Nov 01, 2022
WIP: extracting Geometry utilities from datacube-core

odc.geo This is still work in progress. This repository contains geometry related code extracted from Open Datacube. For details and motivation see OD

Open Data Cube 34 Jan 09, 2023
Manage your XYZ Hub or HERE Data Hub spaces from Python.

XYZ Spaces for Python Manage your XYZ Hub or HERE Data Hub spaces and Interactive Map Layer from Python. FEATURED IN: Online Python Machine Learning C

HERE Technologies 30 Oct 18, 2022
Yet Another Time Series Model

Yet Another Timeseries Model (YATSM) master v0.6.x-maintenance Build Coverage Docs DOI | About Yet Another Timeseries Model (YATSM) is a Python packag

Chris Holden 60 Sep 13, 2022
pure-Python (Numpy optional) 3D coordinate conversions for geospace ecef enu eci

Python 3-D coordinate conversions Pure Python (no prerequistes beyond Python itself) 3-D geographic coordinate conversions and geodesy. API similar to

Geospace code 292 Dec 29, 2022
Stitch image tiles into larger composite TIFs

untiler Utility to take a directory of {z}/{x}/{y}.(jpg|png) tiles, and stitch into a scenetiff (tif w/ exact merc tile bounds). Future versions will

Mapbox 38 Dec 16, 2022