-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
4,591 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,18 @@ | ||
'''Django admin configuration for bpz''' | ||
|
||
from django.contrib.gis import admin | ||
from .models import Case, HomeOwnersAssociation | ||
|
||
geo_admin = admin.OSMGeoAdmin | ||
|
||
|
||
class HomeOwnersAssociationAdmin(geo_admin): | ||
pass | ||
|
||
|
||
class CaseAdmin(geo_admin): | ||
pass | ||
|
||
|
||
admin.site.register(Case, CaseAdmin) | ||
admin.site.register(HomeOwnersAssociation, HomeOwnersAssociationAdmin) |
Large diffs are not rendered by default.
Oops, something went wrong.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
from datetime import datetime | ||
from json import loads | ||
from time import mktime | ||
|
||
from django.core.management.base import BaseCommand, CommandError | ||
from django.contrib.gis.gdal import DataSource | ||
from django.contrib.gis.geos import GEOSGeometry | ||
from parsedatetime import Calendar | ||
|
||
from bpz.models import Case | ||
|
||
'''Import Board of Adjustment cases data | ||
TODO: Refactor into utility function with other load_* commands | ||
''' | ||
|
||
|
||
class Command(BaseCommand): | ||
args = '<boa-cases.json>' | ||
help = 'Imports Board of Adjustment cases GeoJSON' | ||
|
||
def handle(self, *args, **options): | ||
if len(args) != 1: | ||
raise CommandError('Must pass exactly one json file to import') | ||
|
||
same, new, updated = 0, 0, 0 # Object counts | ||
calendar = Calendar() # date parser | ||
|
||
# Load data | ||
datasource = DataSource(args[0], encoding='iso-8859-1') | ||
layer = datasource[0] | ||
for feature in layer: | ||
# Gather and transform attributes | ||
attr = { | ||
'object_id': feature['OBJECTID'].value, | ||
'case_id': loads('"%s"' % feature['Case_'].value), | ||
'status': feature['Status'].value, | ||
'location': loads('"%s"' % feature['Location'].value), | ||
'link': loads('"%s"' % feature['Link'].value), | ||
} | ||
|
||
raw_date = loads('"%s"' % feature['Date_'].value) | ||
timestamp = mktime(calendar.parseDateText(raw_date)) | ||
attr['hearing_date'] = datetime.fromtimestamp(timestamp).date() | ||
|
||
attr['geom'] = GEOSGeometry(feature.geom.wkt) | ||
|
||
# Is there a case with this object ID? | ||
case_query = Case.objects.filter( | ||
object_id=attr['object_id'], domain=Case.DOMAIN_BOA) | ||
if case_query.exists(): | ||
case = case_query.get() | ||
|
||
# Did the data change? | ||
different = [] | ||
for name, new_value in attr.items(): | ||
existing = getattr(case, name) | ||
if existing != new_value: | ||
different.append((name, existing, new_value)) | ||
if different: | ||
updated += 1 | ||
diff_message = ', '.join( | ||
["%s:'%s' -> '%s'" % x for x in different]) | ||
msg = 'Updated case "%s" (%s)' % ( | ||
attr['case_id'], diff_message) | ||
self.stdout.write(msg) | ||
else: | ||
same += 1 | ||
self.stdout.write( | ||
'No change to case "%s"' % attr['case_id']) | ||
else: | ||
# Create new Case | ||
case = Case( | ||
object_id=attr['object_id'], domain=Case.DOMAIN_BOA, | ||
case_type="Board of Adjustment") | ||
self.stdout.write('New case "%s"' % attr['case_id']) | ||
new += 1 | ||
different = True | ||
|
||
if different: | ||
# Save changes | ||
for name, value in attr.items(): | ||
setattr(case, name, value) | ||
case.save() | ||
|
||
self.stdout.write( | ||
'Imported %d BOA cases (%d new, %d changed, %d unchanged)' % ( | ||
new + updated + same, new, updated, same)) |
101 changes: 101 additions & 0 deletions
101
bpz/management/commands/load_home_owners_associations.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
from json import loads | ||
|
||
from django.core.management.base import BaseCommand, CommandError | ||
from django.contrib.gis.gdal import DataSource, OGRException | ||
|
||
from bpz.models import HomeOwnersAssociation | ||
|
||
'''Import Home Owners Association data | ||
TODO: Refactor into utility function with other load_* commands | ||
''' | ||
|
||
|
||
class Command(BaseCommand): | ||
args = '<home-owners-associatons.json>' | ||
help = 'Imports Home Owners Association GeoJSON' | ||
|
||
def handle(self, *args, **options): | ||
if len(args) != 1: | ||
raise CommandError('Must pass exactly one json file to import') | ||
|
||
same, new, updated, skipped = 0, 0, 0, 0 # Object counts | ||
|
||
# Load data | ||
datasource = DataSource(args[0], encoding='iso-8859-1') | ||
layer = datasource[0] | ||
for feature in layer: | ||
# Gather and transform attributes | ||
attr = { | ||
'object_id': feature['OBJECTID'].value, | ||
'name': loads('"%s"' % feature['Name'].value), | ||
} | ||
|
||
raw_hoa_name = feature['HOA_Name'].value | ||
if '\r\n' in raw_hoa_name: | ||
self.stderr.write('Invalid HOA_Name %s' % repr(raw_hoa_name)) | ||
raw_hoa_name = raw_hoa_name.split('\r\n', 1)[0] | ||
attr['hoa_name'] = loads('"%s"' % raw_hoa_name) | ||
|
||
if not (attr['name'] or attr['hoa_name']): | ||
self.stderr.write('Unnamed HOA') | ||
skipped += 1 | ||
continue | ||
|
||
try: | ||
geom = feature.geom | ||
except OGRException: | ||
self.stderr.write( | ||
'No or invalid geometry for %s' % attr['name']) | ||
skipped += 1 | ||
continue | ||
attr['geom'] = geom.wkt | ||
|
||
# Is there a matching HOA? | ||
if attr['object_id']: | ||
hoa_query = HomeOwnersAssociation.objects.filter( | ||
object_id=attr['object_id']) | ||
else: | ||
self.stderr.write( | ||
'Useless object_id %d for %s' % | ||
(attr['object_id'], attr['name'])) | ||
assert attr['name'] | ||
hoa_query = HomeOwnersAssociation.objects.filter( | ||
name=attr['name']) | ||
if hoa_query.exists(): | ||
hoa = hoa_query.get() | ||
|
||
# Did the data change? | ||
different = [] | ||
for name, new_value in attr.items(): | ||
existing = getattr(hoa, name) | ||
if existing != new_value: | ||
different.append((name, existing, new_value)) | ||
if different: | ||
updated += 1 | ||
diff_message = ', '.join( | ||
["%s:'%s' -> '%s'" % x for x in different]) | ||
msg = 'Updated HOA "%s" (%s)' % ( | ||
attr['name'], diff_message) | ||
self.stdout.write(msg) | ||
else: | ||
same += 1 | ||
self.stdout.write( | ||
'No change to HOA "%s"' % attr['name']) | ||
else: | ||
# Create new HOA | ||
hoa = HomeOwnersAssociation() | ||
self.stdout.write('New HOA "%s"' % attr['name']) | ||
new += 1 | ||
different = True | ||
|
||
if different: | ||
# Save changes | ||
for name, value in attr.items(): | ||
setattr(hoa, name, value) | ||
hoa.save() | ||
|
||
self.stdout.write( | ||
'Imported %d Home Owner Associations (%d new, %d changed,' | ||
' %d unchanged, %d skipped)' % | ||
(new + updated + same, new, updated, same, skipped)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
from datetime import datetime | ||
from json import loads | ||
from time import mktime | ||
|
||
from django.core.management.base import BaseCommand, CommandError | ||
from django.contrib.gis.gdal import DataSource | ||
from django.contrib.gis.geos import GEOSGeometry | ||
from parsedatetime import Calendar | ||
|
||
from bpz.models import Case | ||
|
||
'''Import Tulsa Metropolitan Area Planning Commission case data | ||
TODO: Refactor into utility function with other load_* commands | ||
''' | ||
|
||
|
||
class Command(BaseCommand): | ||
args = '<tmapc-cases.json>' | ||
help = 'Imports Tulsa Metropolitan Area Planning Commission case GeoJSON' | ||
|
||
def handle(self, *args, **options): | ||
if len(args) != 1: | ||
raise CommandError('Must pass exactly one json file to import') | ||
|
||
same, new, updated = 0, 0, 0 # Object counts | ||
calendar = Calendar() # date parser | ||
|
||
# Load data | ||
datasource = DataSource(args[0], encoding='iso-8859-1') | ||
layer = datasource[0] | ||
for feature in layer: | ||
# Gather and transform attributes | ||
attr = { | ||
'object_id': feature['OBJECTID'].value, | ||
'case_id': loads('"%s"' % feature['Case_'].value), | ||
'status': feature['Status'].value, | ||
'link': loads('"%s"' % feature['Link'].value), | ||
} | ||
|
||
raw_location = feature['Location'].value | ||
if '\r\n' in raw_location: | ||
self.stderr.write('Invalid Location %s' % repr(raw_location)) | ||
raw_location = raw_location.split('\r\n', 1)[0] | ||
attr['location'] = loads('"%s"' % raw_location) | ||
|
||
raw_type = feature['Type'].value | ||
if '\r\n' in raw_type: | ||
self.stderr.write('Invalid Type %s' % repr(raw_type)) | ||
raw_type = raw_type.split('\r\n', 1)[0] | ||
attr['case_type'] = loads('"%s"' % raw_type) | ||
|
||
raw_date = loads('"%s"' % feature['Date_'].value) | ||
timestamp = mktime(calendar.parseDateText(raw_date)) | ||
attr['hearing_date'] = datetime.fromtimestamp(timestamp).date() | ||
|
||
attr['geom'] = GEOSGeometry(feature.geom.wkt) | ||
|
||
# Is there a case with this object ID? | ||
case_query = Case.objects.filter( | ||
object_id=attr['object_id'], domain=Case.DOMAIN_TMAPC) | ||
if case_query.exists(): | ||
case = case_query.get() | ||
|
||
# Did the data change? | ||
different = [] | ||
for name, new_value in attr.items(): | ||
existing = getattr(case, name) | ||
if existing != new_value: | ||
different.append((name, existing, new_value)) | ||
if different: | ||
updated += 1 | ||
diff_message = ', '.join( | ||
["%s:'%s' -> '%s'" % x for x in different]) | ||
msg = 'Updated case "%s" (%s)' % ( | ||
attr['case_id'], diff_message) | ||
self.stdout.write(msg) | ||
else: | ||
same += 1 | ||
self.stdout.write( | ||
'No change to case "%s"' % attr['case_id']) | ||
else: | ||
# Create new Case | ||
case = Case( | ||
object_id=attr['object_id'], domain=Case.DOMAIN_TMAPC) | ||
self.stdout.write('New case "%s"' % attr['case_id']) | ||
new += 1 | ||
different = True | ||
|
||
if different: | ||
# Save changes | ||
for name, value in attr.items(): | ||
setattr(case, name, value) | ||
case.save() | ||
|
||
self.stdout.write( | ||
'Imported %d BOA cases (%d new, %d changed, %d unchanged)' % ( | ||
new + updated + same, new, updated, same)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# -*- coding: utf-8 -*- | ||
# flake8: noqa | ||
from south.utils import datetime_utils as datetime | ||
from south.db import db | ||
from south.v2 import SchemaMigration | ||
from django.db import models | ||
|
||
|
||
class Migration(SchemaMigration): | ||
|
||
def forwards(self, orm): | ||
# Adding model 'Case' | ||
db.create_table(u'bpz_case', ( | ||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), | ||
('object_id', self.gf('django.db.models.fields.IntegerField')()), | ||
('case_id', self.gf('django.db.models.fields.CharField')(max_length=30)), | ||
('domain', self.gf('django.db.models.fields.CharField')(max_length=10)), | ||
('status', self.gf('django.db.models.fields.CharField')(max_length=10)), | ||
('location', self.gf('django.db.models.fields.CharField')(max_length=50)), | ||
('link', self.gf('django.db.models.fields.URLField')(max_length=200)), | ||
('hearing_date', self.gf('django.db.models.fields.DateField')()), | ||
('case_type', self.gf('django.db.models.fields.CharField')(max_length=30)), | ||
('geom', self.gf('django.contrib.gis.db.models.fields.GeometryField')()), | ||
)) | ||
db.send_create_signal(u'bpz', ['Case']) | ||
|
||
# Adding model 'HomeOwnersAssociation' | ||
db.create_table(u'bpz_homeownersassociation', ( | ||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), | ||
('object_id', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)), | ||
('name', self.gf('django.db.models.fields.CharField')(max_length=50)), | ||
('hoa_name', self.gf('django.db.models.fields.CharField')(max_length=50)), | ||
('geom', self.gf('django.contrib.gis.db.models.fields.GeometryField')()), | ||
)) | ||
db.send_create_signal(u'bpz', ['HomeOwnersAssociation']) | ||
|
||
|
||
def backwards(self, orm): | ||
# Deleting model 'Case' | ||
db.delete_table(u'bpz_case') | ||
|
||
# Deleting model 'HomeOwnersAssociation' | ||
db.delete_table(u'bpz_homeownersassociation') | ||
|
||
|
||
models = { | ||
u'bpz.case': { | ||
'Meta': {'object_name': 'Case'}, | ||
'case_id': ('django.db.models.fields.CharField', [], {'max_length': '30'}), | ||
'case_type': ('django.db.models.fields.CharField', [], {'max_length': '30'}), | ||
'domain': ('django.db.models.fields.CharField', [], {'max_length': '10'}), | ||
'geom': ('django.contrib.gis.db.models.fields.GeometryField', [], {}), | ||
'hearing_date': ('django.db.models.fields.DateField', [], {}), | ||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
'link': ('django.db.models.fields.URLField', [], {'max_length': '200'}), | ||
'location': ('django.db.models.fields.CharField', [], {'max_length': '50'}), | ||
'object_id': ('django.db.models.fields.IntegerField', [], {}), | ||
'status': ('django.db.models.fields.CharField', [], {'max_length': '10'}) | ||
}, | ||
u'bpz.homeownersassociation': { | ||
'Meta': {'object_name': 'HomeOwnersAssociation'}, | ||
'geom': ('django.contrib.gis.db.models.fields.GeometryField', [], {}), | ||
'hoa_name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), | ||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), | ||
'object_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) | ||
} | ||
} | ||
|
||
complete_apps = ['bpz'] |
Empty file.
Oops, something went wrong.