Code Monkey home page Code Monkey logo

django-gisserver's Introduction

Documentation Actions PyPI MPL License Coverage

django-gisserver

Django speaking WFS 2.0 to expose geo data.

Features

  • WFS 2.0 Basic implementation.
  • GML 3.2 output.
  • Standard and spatial filtering (FES 2.0)
  • GeoJSON and CSV export formats.
  • Extensible view/operations.
  • Uses GeoDjango queries for filtering.
  • Streaming responses for large datasets.

Documentation

For more details, see: https://django-gisserver.readthedocs.io/

Quickstart

Install the module in your project:

pip install django-gisserver

Add it to the INSTALLED_APPS:

INSTALLED_APPS = [
    ...
    "gisserver",
]

Create a model that exposes a GeoDjango field:

from django.contrib.gis.db.models import PointField
from django.db import models


class Restaurant(models.Model):
    name = models.CharField(max_length=200)
    location = PointField(null=True)

    def __str__(self):
        return self.name

Write a view that exposes this model as a WFS feature:

from gisserver.features import FeatureType, ServiceDescription
from gisserver.geometries import CRS, WGS84
from gisserver.views import WFSView
from .models import Restaurant

RD_NEW = CRS.from_srid(28992)


class PlacesWFSView(WFSView):
    """An simple view that uses the WFSView against our test model."""

    xml_namespace = "http://example.org/gisserver"

    # The service metadata
    service_description = ServiceDescription(
        title="Places",
        abstract="Unittesting",
        keywords=["django-gisserver"],
        provider_name="Django",
        provider_site="https://www.example.com/",
        contact_person="django-gisserver",
    )

    # Each Django model is listed here as a feature.
    feature_types = [
        FeatureType(
            Restaurant.objects.all(),
            fields="__all__",
            other_crs=[RD_NEW]
        ),
    ]

Use that view in the URLConf:

from django.urls import path
from . import views

urlpatterns = [
    path("/wfs/places/", views.PlacesWFSView.as_view()),
]

You can now use http://localhost:8000/wfs/places/ in your GIS application. It will perform requests such as:

By adding &OUTPUTFORMAT=geojson or &OUTPUTFORMAT=csv to the GetFeature request, the GeoJSON and CSV outputs are returned. The CSV output has an unlimited page size, as it's quite performant.

Why this code is shared

The "datapunt" team of the Municipality of Amsterdam develops software for the municipality. Much of this software is then published as Open Source so that other municipalities, organizations and citizens can use the software as a basis and inspiration to develop similar software themselves. The Municipality of Amsterdam considers it important that software developed with public money is also publicly available.

This package is initially developed by the City of Amsterdam, but the tools and concepts created in this project can be used in any city.

django-gisserver's People

Contributors

adamchainz avatar barrydaniels-nl avatar jjmurre avatar lbam avatar tomdtp avatar vdboor avatar yrob avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-gisserver's Issues

Failing to add layer to ArcGIS

Did anyone bump into this issue before? I'm trying to use this to integrate with ArcGIS, but I always get an error like this:

The WFS service, URL, can't be added to the map. It's either not available or you have entered an invalid URL for the type of layer you want to reference.

When looking at the requests, I see that ArcGIS tries to access WFS 1.0.0, 1.1.0 and 2.0.0 before displaying the error message (only the 2.0.0 request succeeds).
Is there any way to force ArcGIS to only use the 2.0.0 version? Did anyone run into a similar issue?

Btw, this works perfectly on QGIS, but refuses to work on ArcGIS.

Is it necessary Geoserver or QGIS to use this server?

Hi, this is just a question. I don't quite understand if it is necessary to make requests to a provider like Geoserver, or with this functionality you can get what you need from postgis. Thanks for your approach!

Additional computed fields

Hi. I would like to add a new field to my FeatureType, not defined in my model, whose values are computed at runtime by a generic Python function.

I was able to add a computed field by subclassing XsdElement and overriding the get_value method, but I have to bind it to an existing field of my model (thus overriding the value read from the database). If I name my additional field with a name that does not exist in my model, I get a FieldDoesNotExist exception.

Exposing complex fields

Hi guys,

Is there any way to expose fields like ImageField (the url) or ManyToManyField (list of ids)?

I tried the following for ImageField but it didn't work:

  • subclassed ImageField class and overridden value_from_object to return the ImageField.url field
  • created a property (in the model that contains the ImageField) which returns the ImageField.url field

Thank you,
Robert

Coordinate axis order in northing/easting (Y/X) in WFS/GML

My project for City of Helsinki uses coordinate reference system EPSG:3879. We have a problem with latitude and longitude axis order in WFS GML output when using django-gisserver version 1.2.4.

WFS 2.0.0 (with GML 3.2) should respects the axis order defined by the EPSG definition (unlike WFS 1.0.0 which is always easting/northing or (X,Y)). EPSG:3879 defines coordinate axis order as northing/easting (Y,X).

For query <server url>/wfs/?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=signpost&OUTPUTFORMAT=application/gml+xml&srsName=urn:ogc:def:crs:EPSG::3879 we are expecting:

*snip*
<app:location>
  <gml:Point srsName="urn:ogc:def:crs:EPSG::3879" gml:id="signpost.1">
    <gml:pos srsDimension="3">6673364.2700978 25494172.7053077 0</gml:pos>
  </gml:Point>
</app:location>
*snip*

where 6673364.2700978 is latitude (Y) and 25494172.7053077 is longitude (X).

However, the actual result has invert latitude and longitude:

*snip*
<app:location>
  <gml:Point srsName="urn:ogc:def:crs:EPSG::3879" gml:id="signpost.1">
    <gml:pos srsDimension="3">25494172.7053077 6673364.2700978 0</gml:pos>
  </gml:Point>
</app:location>
*snip*

Do I have something wrong in my configuration? Or is this a missing feature or bug in django-gisserver?

GetCapabilities does not work with dotted model_attribute value

If a FeatureField has reference to a different model via FK reference, GetCapabilities query is not working.
eg.

FeatureField( "not_working", model_attribute="some_fk.field_name", abstract="does not work", )

Result from eg. http://localhost:8000/wfs/?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetCapabilities
Now would be 500 internal server error.
Reason would be that "<feature_type> has no attribute field_name"

This is because FeatureType.get_bounding_box function uses self.get_query_set() that does not check any feature relations.

Suggested fix:
Change function FeatureType.get_bounding_box not to use get_query_set() as such but add a .only(self.geometry_field.name)

so line:
bbox = self.get_queryset().aggregate(a=Extent(geo_expression))["a"]
to:
bbox = self.get_queryset().only(self.geometry_field.name).aggregate(a=Extent(geo_expression))["a"]
or even:
bbox = self.queryset.only(self.geometry_field.name).aggregate(a=Extent(geo_expression))["a"]

I am not so familiar with the codebase that really not sure if this is the way to go here, maybe someone who actually is doing dev on this will do the actual fix in a different way. Atleast this way there would be no need for any prefetches.

Non GeoDjango usage?

Hi. I have a spatial database (it's mysql, but I could port to postgress), and would like to deploy/migrate the beautiful OGC server you've made to my open source app.

Do you think such thing would be possible? What are the main changes or modifications would you point at as preffered to achieve such goal? I want to rehuse all the WFS work you've done, coding the queries to the database if necessary (it's not clear to me in the code how I could wire your code the specific spatial tables I do already have).

Thanks a lot, Pablo.

Allow GeneratedField as geometry field

We have some larger polygons in our database and in order to simplify calculations etc we have a GeneratedField, which builds a simplified version of the polygon.

geometry = models.MultiPolygonField(default=None, null=True)
geometry_simplified = models.GeneratedField(
    expression=Multi(SimplifyPreserveTopology("geometry", 0.0001)),
    output_field=models.MultiPolygonField(),
    db_persist=True,
)

I would really like to use this as geometry column for our WFS, but it is throwing an error:

django.core.exceptions.ImproperlyConfigured: FeatureType 'model' does not expose a geometry field.

I looked at the code and could not quickly come up with a PR, maybe someone of the team can look into this?

POST support?

Hi,
Excellent project, thank you for making it available as Open Source.

I'm wondering if you would have an estimate when the update/editing of feature will be possible? I see in the docs it's in the plans.

Thanks again

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.