Skip to content

Commit

Permalink
Store and load Post.shapes as GeoJSON
Browse files Browse the repository at this point in the history
  • Loading branch information
Jean Cochrane (Lead developer, DataMade) committed Jun 26, 2019
1 parent 77fdebf commit b3b7bf8
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 24 deletions.
56 changes: 47 additions & 9 deletions councilmatic_core/management/commands/import_shapes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import json

from django.core.management.base import BaseCommand
from django.core.management.base import BaseCommand, CommandError
from django.contrib.gis.geos import GEOSGeometry

from councilmatic_core import models


Expand All @@ -9,25 +11,47 @@ class Command(BaseCommand):

def add_arguments(self, parser):
parser.add_argument(
'shape_file',
'geojson_file',
help=(
'The location of the file containing shapes for each Division, '
'relative to the project root. The file should be formatted as JSON '
'with each key corresponding to a Division ID and each value corresponding'
'to a GeoJSON Feature object.'
'The location of the GeoJSON file containing shapes for each Division, '
'relative to the project root. The file should be formatted as a '
'GeoJSON FeatureCollection where each Feature A) corresponds to a distinct '
'Division and B) has a "division_id" attribute in the "properties" object. '
)
)

def handle(self, *args, **options):
self.stdout.write('Populating shapes for Posts...')
shapes_populated = 0

with open(options['shape_file']) as shapef:
with open(options['geojson_file']) as shapef:
shapes = json.load(shapef)

for division_id, shape in shapes.items():
features = self._get_or_raise(
shapes,
'features',
'Could not find the "features" array in the input file.'
)

for feature in features:
shape = self._get_or_raise(
feature,
'geometry',
'Could not find a "geometry" key in the Feature.'
)
properties = self._get_or_raise(
feature,
'properties',
'Could not find a "properties" key in the Feature.'
)
division_id = self._get_or_raise(
properties,
'division_id',
'Could not find a "division_id" key in the Feature properties.'
)

models.Post.objects.filter(division_id=division_id).update(
shape=shape
shape=GEOSGeometry(json.dumps(shape))
)
shapes_populated += 1

Expand All @@ -36,3 +60,17 @@ def handle(self, *args, **options):
'Populated {} shapes'.format(str(shapes_populated))
)
)

def _get_or_raise(self, dct, key, msg):
"""
Check to see if 'dct' has a key corresponding to 'key', and raise an
error if it doesn't.
"""
format_prompt = (
'Is the input file formatted as a GeoJSON FeatureCollection '
'where each feature has a "division_id" property?'
)
if not dct.get(key):
raise CommandError(msg + ' ' + format_prompt)
else:
return dct[key]
11 changes: 3 additions & 8 deletions councilmatic_core/migrations/0048_post_shape.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Generated by Django 2.1.9 on 2019-06-26 17:10
# Generated by Django 2.1.9 on 2019-06-26 21:17

import django.contrib.postgres.fields.jsonb
import django.contrib.gis.db.models.fields
import django.core.files.storage
from django.db import migrations, models
import django.db.models.deletion
Expand All @@ -17,16 +17,11 @@ class Migration(migrations.Migration):
migrations.DeleteModel(
name='Post',
),
migrations.AlterField(
model_name='person',
name='headshot',
field=models.FileField(default='images/headshot_placeholder.png', storage=django.core.files.storage.FileSystemStorage(base_url='/', location='/Users/goobzie/datamade/chi-councilmatic'), upload_to='images/headshots'),
),
migrations.CreateModel(
name='Post',
fields=[
('post', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='councilmatic_post', serialize=False, to='core.Post')),
('shape', django.contrib.postgres.fields.jsonb.JSONField()),
('shape', django.contrib.gis.db.models.fields.GeometryField(null=True, srid=4326)),
],
options={
'abstract': False,
Expand Down
4 changes: 2 additions & 2 deletions councilmatic_core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import os

from django.db import models
from django.contrib.postgres.fields import JSONField
from django.contrib.gis.db import models as geo_models
from django.core.exceptions import ImproperlyConfigured
from django.conf import settings
from django.urls import reverse, NoReverseMatch
Expand Down Expand Up @@ -247,7 +247,7 @@ class Post(opencivicdata.core.models.Post):
on_delete=models.CASCADE,
)

shape = JSONField()
shape = geo_models.GeometryField(null=True)

@cached_property
def current_member(self):
Expand Down
3 changes: 1 addition & 2 deletions councilmatic_core/signals/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,5 @@ def create_councilmatic_bill(sender, instance, created, **kwargs):
@receiver(post_save, sender=OCDPost)
def create_councilmatic_post(sender, instance, created, **kwargs):
if created:
cp = CouncilmaticPost(post=instance,
shape={})
cp = CouncilmaticPost(post=instance)
cp.save_base(raw=True)
1 change: 0 additions & 1 deletion councilmatic_core/templates/partials/map.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@
});

layer.on('mouseover', function(e){
console.log(e.target.feature.properties)
infoBox.update(e.target.feature.properties);
e.target.setStyle({'fillOpacity': 0.6, 'color': "{{MAP_CONFIG.highlight_color}}"});
});
Expand Down
4 changes: 2 additions & 2 deletions councilmatic_core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def map(self):

feature = {
'type': 'Feature',
'geometry': post.shape,
'geometry': json.loads(post.shape.json),
'properties': {
'district': post.label,
'council_member': council_member,
Expand Down Expand Up @@ -379,7 +379,7 @@ def get_context_data(self, **kwargs):

feature = {
'type': 'Feature',
'geometry': person.latest_council_membership.post.shape,
'geometry': json.loads(person.latest_council_membership.post.shape.json),
'properties': {
'district': person.latest_council_membership.post.label,
}
Expand Down

0 comments on commit b3b7bf8

Please sign in to comment.