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
Google maps for Jupyter notebooks

gmaps gmaps is a plugin for including interactive Google maps in the IPython Notebook. Let's plot a heatmap of taxi pickups in San Francisco: import g

Pascal Bugnion 747 Dec 19, 2022
Tools for the extraction of OpenStreetMap street network data

OSMnet Tools for the extraction of OpenStreetMap (OSM) street network data. Intended to be used in tandem with Pandana and UrbanAccess libraries to ex

Urban Data Science Toolkit 47 Sep 21, 2022
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
Python package for earth-observing satellite data processing

Satpy The Satpy package is a python library for reading and manipulating meteorological remote sensing data and writing it to various image and data f

PyTroll 882 Dec 27, 2022
Satellite imagery for dummies.

felicette Satellite imagery for dummies. What can you do with this tool? TL;DR: Generate JPEG earth imagery from coordinates/location name with public

Shivashis Padhi 1.8k Jan 03, 2023
LEOGPS - Satellite Navigation with GPS on Python!

LEOGPS is an open-source Python software which performs relative satellite navigation between two formation flying satellites, with the objective of high accuracy relative positioning. Specifically,

Samuel Low 50 Dec 13, 2022
Use Mapbox GL JS to visualize data in a Python Jupyter notebook

Location Data Visualization library for Jupyter Notebooks Library documentation at https://mapbox-mapboxgl-jupyter.readthedocs-hosted.com/en/latest/.

Mapbox 620 Dec 15, 2022
h3-js provides a JavaScript version of H3, a hexagon-based geospatial indexing system.

h3-js The h3-js library provides a pure-JavaScript version of the H3 Core Library, a hexagon-based geographic grid system. It can be used either in No

Uber Open Source 648 Jan 07, 2023
prettymaps - A minimal Python library to draw customized maps from OpenStreetMap data.

A small set of Python functions to draw pretty maps from OpenStreetMap data. Based on osmnx, matplotlib and shapely libraries.

Marcelo de Oliveira Rosa Prates 9k Jan 08, 2023
A service to auto provision devices in Aruba Central based on the Geo-IP location

Location Based Provisioning Service for Aruba Central A service to auto provision devices in Aruba Central based on the Geo-IP location Geo-IP auto pr

Will Smith 3 Mar 22, 2022
Get Landsat surface reflectance time-series from google earth engine

geextract Google Earth Engine data extraction tool. Quickly obtain Landsat multispectral time-series for exploratory analysis and algorithm testing On

Loïc Dutrieux 50 Dec 15, 2022
Python bindings and utilities for GeoJSON

geojson This Python library contains: Functions for encoding and decoding GeoJSON formatted data Classes for all GeoJSON Objects An implementation of

Jazzband 765 Jan 06, 2023
A light-weight, versatile XYZ tile server, built with Flask and Rasterio :earth_africa:

Terracotta is a pure Python tile server that runs as a WSGI app on a dedicated webserver or as a serverless app on AWS Lambda. It is built on a modern

DHI GRAS 531 Dec 28, 2022
A Python tool to display geolocation information in the traceroute.

IP2Trace Python IP2Trace Python is a Python tool allowing user to get IP address information such as country, region, city, latitude, longitude, zip c

IP2Location 22 Jan 08, 2023
A simple python script that, given a location and a date, uses the Nasa Earth API to show a photo taken by the Landsat 8 satellite. The script must be executed on the command-line.

What does it do? Given a location and a date, it uses the Nasa Earth API to show a photo taken by the Landsat 8 satellite. The script must be executed

Caio 42 Nov 26, 2022
A python package that extends Google Earth Engine.

A python package that extends Google Earth Engine GitHub: https://github.com/davemlz/eemont Documentation: https://eemont.readthedocs.io/ PyPI: https:

David Montero Loaiza 307 Jan 01, 2023
Histogram matching plugin for rasterio

rio-hist Histogram matching plugin for rasterio. Provides a CLI and python module for adjusting colors based on histogram matching in a variety of col

Mapbox 75 Sep 23, 2022
This app displays interesting statistical weather records and trends which can be used in climate related research including study of global warming.

This app displays interesting statistical weather records and trends which can be used in climate related research including study of global warming.

0 Dec 27, 2021
Platform for building statistical models of cities and regions

UrbanSim UrbanSim is a platform for building statistical models of cities and regions. These models help forecast long-range patterns in real estate d

Urban Data Science Toolkit 419 Dec 30, 2022
A simple reverse geocoder that resolves a location to a country

Reverse Geocoder This repository holds a small web service that performs reverse geocoding to determine whether a user specified location is within th

4 Dec 25, 2021