1

I'm doing a project using the combination of GeoDjango, PostGIS, and OpenLayers

So far, I've imported OSM data with osm2pqsql, done settings and I knew the data is constructed by planet_osm_line, planet_osm_polygon, etc.

Now, I want to query all the villages boundaries under certain city and render with OpenLayers, I know I have to get the GeoJSON from the database and pass it to the template, but I have no idea how to make the queries using GeoManager, can somebody give me some instructions

Note: English is not my mother language, I try my best to explain my question

nmtoken
  • 13,355
  • 5
  • 38
  • 87
wtichentw
  • 11
  • 2
  • Welcome to GIS.SE! I think it's clear what you ask. Perhaps someone will edit your question to improve the language; I'm not a native English speaker, like you, so I'll leave this to others. I recommend you to read our [about] page to learn basics of using this site. – Pavel V. Nov 10 '15 at 18:52
  • haha thx for your introduction – wtichentw Nov 11 '15 at 05:10

1 Answers1

1

To filter your model instances with a polygon boundary, you can use the intersects lookup. So for instance

from django.contrib.gis.geos import Polygon
from myapp.models import MyVillages

poly = Polygon(((0.0, 0.0), (0.0, 50.0), (50.0, 50.0), (50.0, 0.0), (0.0, 0.0)))
villages = MyVillages.objects.filter(geom__intersects=poly)

The villages queryset will then be a list of MyVillage models of which the boundaries overlap with the query polygon (assuming your geometry field is called "geom").

To pass the data to your template, it depends on how you construct your map with openlayers, so you would probably run the query above within a view and return the villages queryset to the template as a context variable.

Another option would be to use the django-rest-framework to create an api endpoint and then query that directly through javascript, see this answer for more information.

Edit - Example for MyVillage model:

from django.contrib.gis.db import models

class MyVillage(models.Model):
    name = models.CharField(max_length=500)
    osmid = models.IntegerField()
    geom = models.MultiPolygonField()
    objects = models.GeoManager()

Then you can also filter by the osm id of course. Note that this is not a geographic query and the get method will give an error if the osmid does not exist in the database:

single_vilage = MyVillage.objects.get(osmid=3802015)

or if you want to see if it exists

MyVillage.objects.filter(osmid__in=3802015).exists()
yellowcap
  • 3,013
  • 22
  • 36
  • thx for your solution, I'll try it. I have one more question about constructing the model, should I always have GeometryField in my model, and how does your "MyVillage" actually looks like? cause now I am tring to query, while my model can map to the database, btw, I've set the postgis db in settings.py – wtichentw Nov 17 '15 at 16:52
  • how could I query with specific osm_id,
    qs = Unit.objects.filter(___=-3802015).geojson() the number is the osm_id i would like to query, but I dont know how to query with geometryfield
    – wtichentw Nov 17 '15 at 17:00
  • I updated the answer with an example for the model, you can store the osmid as a normal integer field. – yellowcap Nov 17 '15 at 17:35
  • yah, I got the error you mentioned, matching query does not exist., I've specified the DB in settings.py, but I don't know how to map the GeoDjango model to the DB, and I can't get why I don't need to specify the TABLE NAME, it's odd for me and what if I need to join two table ? thx for the advice by the way – wtichentw Nov 17 '15 at 18:20
  • If your table already exists, you need to tell Django that it does not have to manage it, see https://docs.djangoproject.com/en/1.8/ref/models/options/#managed. Otherwise you would have to create a migration and migrate the database, see https://docs.djangoproject.com/en/1.8/topics/migrations/. Its seems like you are new to Django, maybe try to follow the introduction tutorial for some of those details https://docs.djangoproject.com/en/1.8/intro/tutorial01/ – yellowcap Nov 18 '15 at 08:09
  • btw, the error you got is specific to the get command, which expects your filter to return exactly one result (usually its done using some unique property like the pirmary key or in your case the osmid). If none or more than one result is returned, you will see an error. – yellowcap Nov 18 '15 at 08:13
  • thx for your replies, I'm quite new to the django, so I keep exploring this framework, I can normally query right now, while it returns empty query, in postgresql command line, I input SELECT ST_AsGeoJSON(way) FROM planet_osm_polygon WHERE osm_id = -3802015; , the result exist, while in django, input MyVillage.objects.filter(osm_id=-3802015) return empty array, any idea why this happens? – wtichentw Nov 18 '15 at 11:13
  • That might be related to the table name. Make sure that if you have a table that is not managed by django, you set the table name on the model for it to find the data. But this is not really GIS related stuff, consider asking another question on stackoverflow if you have more specific questions around how to use django. – yellowcap Nov 20 '15 at 11:09
  • thx you very much for helping me a lot, I'll try to figure it out :) – wtichentw Nov 23 '15 at 17:02