3

I am trying to implement dynamic query functionality in GeoDjango and OpenLayers. First, I filter the data and return it in GeoJSON format using Django serialize. Then, the return GeoJSON data visualize using OpenLayers 6. It works fine. But, When I try to filter data dynamically, it is not working. I don't understand the problem. How can I fix this?

// GeoDjango Model

    from django.contrib.gis.db import models

    class Boundary(models.Model):
        division = models.CharField(max_length=50)
        district = models.CharField(max_length=50)
        upazila = models.CharField(max_length=50)
        union = models.CharField(max_length=50)
        geom = models.MultiPolygonField(srid=4326)

    def __str__(self):
        return self.division

// views.py

    def boundary_data(request):
        """ bnd = Boundary.objects.filter(district="Khulna")""" // it is working fine
        name=request.GET.get("district")
        bnd = Boundary.objects.filter(district__iexact=name) // not working 
        boundary = serialize('geojson', bnd) 
        return HttpResponse(boundary, content_type='JSON') 

// urls.py 

    from django.urls import path
    from . import views 
    urlpatterns = [
        path('boundary-data/', views.boundary_data, name="boundary-data"),
        path('bgd/', views.MapView.as_view(), name="bgd"),
    ]

// query form

    <form method='GET' class="form-inline" action="">   
      <input class="form-control mr-sm-2" id="district" name="district" type="text" placeholder="Search">
      <button class="btn btn-success" type="submit">Search</button>
    </form>

//OpenLayers code

    var style = new ol.style.Style({
              fill: new ol.style.Fill({
                color: 'gray',
              }),
              stroke: new ol.style.Stroke({
                color: 'white',
                width: 1,
              }),
              text: new ol.style.Text()
            });

  

    var map = new ol.Map({
              target: 'map',
              layers: [
                new ol.layer.Tile({
                  source: new ol.source.OSM()
                }),
                new ol.layer.Vector({
                  source: new ol.source.Vector({
                      format: new ol.format.GeoJSON(),
                      url: "{% url 'boundary-data' %}"
                  }),
                  style: function (feature) {
                    style.getText().setText(feature.get('union'));
                    return style;
                  }
                })
              ],
              view: new ol.View({
                center: ol.proj.fromLonLat([89.5403, 22.8456]),
                zoom: 10
              })
            }); 
2
  • Can you provide the code of views.MapView.as_view() section as well? And another thing is, I think you need to provide the action parameter in your form.
    – gis
    Jan 10 at 13:22
  • class MapView(TemplateView): template_name = "bgd/index.html" Jan 11 at 15:20
1

There is no connection between your filter form and Geojson data called by OpenLayers. You can choose from a couple of solutions. If you want to fetch data in your OL code block, you can create an event handler to catch district change from a dropdown (prepopulated by district names) and include selection in url like:

url: "{% url 'boundary-data' id=district_id %}"


urlpatterns = [
    path('boundary-data/<int:id>', views.boundary_data, name="boundary-data"),
    path('bgd/', views.MapView.as_view(), name="bgd"),
]

def boundary_data(request, id):
    bnd = Boundary.objects.all()
    if(id):
        bnd = bnd.filter(pk=id)
    boundary = serialize('geojson', bnd) 
    return HttpResponse(boundary, content_type='JSON') 
1
  • Thanks for your reply. I follow your guideline and try several-time but failed to create an event handler. I can't figure out how to create an event handler. Can you give me a full example mentioned in yourscomment? Jan 15 at 1:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.