2

I am very new to Geodjango and have been running into some issues with a web mapping application. Currently, I am trying to make it so I can view all the schools on a map at once, as well as view individual schools on a map. I have been able to make it so I can view individual schools, but I am still unable to view all schools on a map at once.

This is how it looks when I am able to view a single school:

enter image description here

Here is what happens when I try to view all schools at once:

enter image description here

Am I going to the wrong url to do so or is there some other issue in the code that I am not seeing?

Here are my scripts:

schools_project/urls.py:

from django.conf.urls import url, include
from django.contrib import admin
from django.urls import include, path
...
urlpatterns = [
    url(r'^schools/', include('schools.urls')),
    path('admin/', admin.site.urls),
]

schools/models.py:

from django.db import models
from django.contrib.gis.db import models as geomodels
...
class School(models.Model):
    name = models.CharField(max_length=300, blank=False)
    geometry = geomodels.PointField()
...
class Meta:
    order = ('name',)

schools/apps.py:

from django.apps import AppConfig
...
class SchoolsConfig(AppConfig):
    name = 'schools'

schools/admin.py:

from django.contrib import admin
from .models import School
from leaflet.admin import LeafletGeoAdmin
...
class SchoolAdmin(LeafletGeoAdmin):
    list_display = ('name', 'geometry')
...
admin.site.register(School, SchoolAdmin)

schools/urls.py:

from django.conf.urls import url
from . import views
...
app_name = 'schools'
...
urlpatterns = [
    url(r^school/(?P<pk>[0-9]+)$',
        views.SchoolsDetailView.as_view(), name='school-detail'),
]

schools/views.py:

from django.views.generic import DetailView
from .models import School
...
class SchoolsDetailView(DetailView):
    """
        School detail view.
    """
template_name = r"C:\Users\Drew\Desktop\djangoproject\schools_project\templates\school-detail"
    model = School

school-detail.html (template):

<!DOCTYPE html>
<html>
<Title>Public Schools in Aurora, Colorado</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
{% load leaflet_tags %}
{% leaflet_css %}
{% leaflet_js %}

<div class="w3-container">
 <h1 style="text-align: center; color: #ffffff;"><b><font size="+3">Public Schools in Denver and Aurora, Colorado</font></b></h1>
    <h2 style= "color: #ffffff;"><b><i>{{ school.name }}</i></b></h2>
    {% leaflet_map "main" callback="map_init" %}
</div>

<style>

    .leaflet-container {  /* all maps */
        width:  1450px;
        height: 700px;
    }

    #specialbigmap {
        height: 800px;
    }

    /* Resize the "display_raw" textbox */
    .django-leaflet-raw-textarea {
        width: 100%;
    }

    body {
    background-color: #000000;
}
h1 {
  border-style: solid;
}
h2 {
  text-align: center;
}

</style>


<script type="text/javascript">
    function map_init(map, options) {

        // get point lat and lon
        var lon = "{{ school.geometry.x }}";
        var lat = "{{ school.geometry.y }}";
        // zoom to point & add it to map
        map.setView([lat, lon], 17);
        L.marker([lat, lon]).addTo(map);
    }
</script>
</html>

Does anybody have any ideas or tips on how I can view all points on a map at the same time?

2
  • is your data stored in a database or static files?
    – ziggy
    Commented Apr 24, 2019 at 20:45
  • @ziggy it is stored in a Post GIS database Commented Apr 24, 2019 at 21:24

1 Answer 1

1

I would use leaflet ajax instead of using the django tempalate to return your geospatial features. https://github.com/calvinmetcalf/leaflet-ajax.

Download this code, save it to your django static folder and in your index.html you need to reference it.

<script type="text/javascript" src="{% static 'dist/leaflet.ajax.js' %}" > </script>

for your views.py I would return a JSON response of the schools table. something like this

from django.db import connection as conn
cur=conn.cursor()

def schools_dataset(request):
   qry='''SELECT row_to_json(fc)
          FROM
           ( SELECT 'FeatureCollection' AS TYPE,
                   array_to_json(array_agg(f)) AS features
           FROM
             (SELECT 'Feature' AS TYPE,
                     ST_AsGeoJSON(st_transform(g.geom,4326))::JSON AS geometry,
                     row_to_json(
                                   (SELECT p
                                    FROM
                                      ( SELECT name) AS p)) AS properties
              FROM schools AS g
              ) AS f) AS fc;
      '''
   cur.execute(qry)
   row=cur.fetchone()
   return JsonResponse(row[0])

then in Javascript

schools=new L.GeoJSON.AJAX(schools_api_url)
school.addTo(map);
4
  • How do I get the Leaflet Ajax plugin working to do this? And for the code in views.py, should I be adding this code in, or should I be replacing the code that's in there entirely? Thank you for your help. Commented Apr 25, 2019 at 16:17
  • I would 1st run the SQL query I posted in postgres to make sure that is what you want to be returned. Then yes I would replace what you have in your school view. I am not exactly sure what you trying to do with your school url but you may need to change that so it can be called into the leaflet ajax geojson command
    – ziggy
    Commented Apr 25, 2019 at 18:53
  • how do I deal with the error that comes from this due to SchoolsDetailView not being a class any longer, and thus is not able to be called in schools/urls.py? The error is: File "C:\Users\Drew\Desktop\GEOG587\Final\final_proj\schools_project\schools\urls.py", line 9, in <module> views.SchoolsDetailView.as_view(), name='school-detail'), AttributeError: module 'schools.views' has no attribute 'SchoolsDetailView' Commented Apr 26, 2019 at 0:16
  • do something like this url(r'^school_data/$', views.school_dataset, name='school')
    – ziggy
    Commented Apr 26, 2019 at 13:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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