Skip to content

Commit

Permalink
[ZA] Add support for South Africa to MapIt
Browse files Browse the repository at this point in the history
  • Loading branch information
dracos committed Feb 11, 2015
1 parent 14e9f89 commit 1e422a1
Show file tree
Hide file tree
Showing 15 changed files with 208 additions and 1 deletion.
2 changes: 2 additions & 0 deletions mapit/countries/__init__.py
Expand Up @@ -6,5 +6,7 @@
from mapit_no.countries import * # noqa
elif settings.MAPIT_COUNTRY == 'IT':
from mapit_it.countries import * # noqa
elif settings.MAPIT_COUNTRY == 'ZA':
from mapit_za.countries import * # noqa
elif settings.MAPIT_COUNTRY == 'Global':
from mapit_global.countries import * # noqa
3 changes: 3 additions & 0 deletions mapit/templates/mapit/api/point.html
Expand Up @@ -46,6 +46,9 @@ <h3><em>lookup by</em> point</h3>
{% if country == 'NO' %}
<dd><a href="{% url "mapit_index" %}point/4326/10,59.html">Example of areas containing (59,10)</a>.</dd>
{% endif %}
{% if country == 'ZA' %}
<dd><a href="{% url "mapit_index" %}point/4326/18.42,-33.92.html">Example of areas containing (18.42,-33.92)</a>.</dd>
{% endif %}
{% if country == 'Global' %}
<dd><a href="{% url "mapit_index" %}point/4326/8.55,47.366667.html">Example of areas containing (47.366667,8.55)</a>.</dd>
{% endif %}
Expand Down
9 changes: 9 additions & 0 deletions mapit/templates/mapit/index.html
Expand Up @@ -38,6 +38,13 @@ <h1>Map<em>It</em><em class="mapit-type">: {% include "mapit/country.html" %}</e
kommune, or more it lies within. It&rsquo;s also great for looking up
the shapes of all those boundaries.
{% endif %}
{% if country == 'ZA' %}
MapIt is a service that maps geographical points to
administrative areas. It&rsquo;s useful for anyone who has
co-ordinates of a point in South Africa, and needs to find out what
Ward, Municipality and Province it lies within. It&rsquo;s also great for
looking up the shapes of all those boundaries.
{% endif %}
{% if country == 'Global' %}
MapIt is a service that maps geographical points to administrative areas.
This edition is based on source data from the totally amazing
Expand Down Expand Up @@ -218,6 +225,8 @@ <h3>Usage &amp; Licence</h3>
<p>If you use this service, you must attribute
{% if country == 'GB' %}
OS/RM/ONS
{% elif country == 'ZA' %}
Municipal Demarcation Board (www.demarcation.org.za)
{% else %}
OpenStreetMap
{% endif %}
Expand Down
37 changes: 37 additions & 0 deletions mapit_za/README
@@ -0,0 +1,37 @@
To import the data from MapIt for South Africa, first download the
shapefiles from:

http://www.demarcation.org.za/index.php/downloads/boundary-data/boundary-data-main-files

Then create a new generation to import the data into:

./manage.py mapit_generation_create --desc "Initial import" --commit

Create the MapIt country, types and code types from a fixture:

./manage.py loaddata south_africa

Then try importing the data unpacked from the .rar files:

./manage.py mapit_za_import_boundaries \
--wards=boundary-data/wards/Wards2011.shp \
--locals=boundary-data/local-municipalities/LocalMunicipalities2011.shp \
--districts=boundary-data/districts/DistrictMunicipalities2011.shp \
--provinces=boundary-data/provinces/Province_New_SANeighbours.shp

If that looks OK, then add `--commit` to this command.

Export the police districts choosing 'Shapefile' as the format from:

https://data.code4sa.org/Government/Police-Station-Boundaries/hr5e-pz98

Then import it with:

./manage.py mapit_import --commit \
--generation_id=1 --country_code=Z --area_type_code=POL \
--name_type_code=police --name_field=COMPNT_NM \
boundary-data/police/Police_bounds.shp

Now commit that generation with:

./manage.py mapit_generation_activate --commit
Empty file added mapit_za/__init__.py
Empty file.
Empty file added mapit_za/countries.py
Empty file.
13 changes: 13 additions & 0 deletions mapit_za/fixtures/south_africa.json
@@ -0,0 +1,13 @@
[
{ "pk": 1, "model": "mapit.country", "fields": { "code": "Z", "name": "South Africa" } },
{ "pk": 1, "model": "mapit.type", "fields": { "code": "WRD", "description": "Wards" } },
{ "pk": 2, "model": "mapit.type", "fields": { "code": "LMN", "description": "Local Municipality" } },
{ "pk": 3, "model": "mapit.type", "fields": { "code": "MMN", "description": "Metropolitan Municipality" } },
{ "pk": 4, "model": "mapit.type", "fields": { "code": "DMN", "description": "District Municipality" } },
{ "pk": 5, "model": "mapit.type", "fields": { "code": "PRV", "description": "Province" } },
{ "pk": 1, "model": "mapit.codetype", "fields": { "code": "w", "description": "Ward ID" } },
{ "pk": 2, "model": "mapit.codetype", "fields": { "code": "l", "description": "Local Municipality ID" } },
{ "pk": 3, "model": "mapit.codetype", "fields": { "code": "d", "description": "District Code" } },
{ "pk": 4, "model": "mapit.codetype", "fields": { "code": "p", "description": "Province Code" } },
{ "pk": 1, "model": "mapit.nametype", "fields": { "code": "S", "description": "Name from Shapefile" } }
]
Empty file added mapit_za/management/__init__.py
Empty file.
Empty file.
133 changes: 133 additions & 0 deletions mapit_za/management/commands/mapit_za_import_boundaries.py
@@ -0,0 +1,133 @@
# Create boundaries in MapIt for South Africa. You need four
# shapefiles for these from:
#
# http://www.demarcation.org.za/Downloads/Boundary/initial.html
#
# Example usage:
#
# ./manage.py south_africa_import_boundaries \
# --wards=south_africa/boundary-data/wards/Wards2011.shp \
# --locals=south_africa/boundary-data/local-municipalities/LocalMunicipalities2011.shp \
# --districts=south_africa/boundary-data/districts/DistrictMunicipalities2011.shp \
# --provinces=south_africa/boundary-data/provinces/Province_New_SANeighbours.shp
#
# ... and then adding --commit if that looks OK. Note that this
# doesn't check for invalid polygons yet, but there's an open pull
# request, one of whose commits would make it easy to add that:
#
# https://github.com/mysociety/mapit/pull/73

import os
import re
import sys

from collections import namedtuple
from optparse import make_option

from django.core.management import call_command
from django.core.management.base import NoArgsCommand

from mapit.models import Generation, NameType, Country


class Command(NoArgsCommand):
"""Import South African boundaries"""

help = 'Import shapefiles with South African boundary data'

option_list = NoArgsCommand.option_list + (
make_option(
'--wards', '-w',
help="The wards shapefile"),
make_option(
'--districts', '-d',
help="The district municipalities shapefile"),
make_option(
'--provinces', '-p',
help="The provinces shapefile"),
make_option(
'--locals', '-l',
help="The local municipalities shapefile"),
make_option(
'--commit',
action='store_true',
dest='commit',
help='Actually update the database'),)

def handle_noargs(self, **options):

stop = False
for k in ('wards',
'districts',
'provinces',
'locals'):
if options[k]:
if not os.path.exists(options[k]):
print >> sys.stderr, "The file %s didn't exist" % (options[k],)
stop = True
else:
print >> sys.stderr, "You must specify --" + re.sub(r'_', '-', k)
stop = True
if stop:
sys.exit(1)

new_generation = Generation.objects.new()
if not new_generation:
raise Exception, "There's no inactive generation for the import"

country = Country.objects.get(code='Z')

name_type = NameType.objects.get(code='S')

BoundaryType = namedtuple('BoundaryType',
['shapefile',
'area_type_code',
'code_field',
'code_type_code',
'name_field',
'name_suffix_field'])

boundary_types = [BoundaryType(shapefile=options['wards'],
area_type_code='WRD',
code_field='WARD_ID',
code_type_code='w',
name_field='MUNICNAME',
name_suffix_field='WARDNO'),
BoundaryType(shapefile=options['locals'],
area_type_code='LMN',
code_field='CAT_B',
code_type_code='l',
name_field='MUNICNAME',
name_suffix_field=None),
BoundaryType(shapefile=options['districts'],
area_type_code='DMN',
code_field='DISTRICT',
code_type_code='d',
name_field='MUNICNAME',
name_suffix_field=None),
BoundaryType(shapefile=options['provinces'],
area_type_code='PRV',
code_field='CODE',
code_type_code='p',
name_field='PROVINCE',
name_suffix_field=None)]

standard_options = {
'commit': options['commit']}

for b in boundary_types:
all_options = standard_options.copy()
all_options.update({'generation_id': new_generation.id,
'area_type_code': b.area_type_code,
'name_type_code': name_type.code,
'country_code': country.code,
'code_field': b.code_field,
'code_type': b.code_type_code,
'name_field': b.name_field,
'name_suffix_field': b.name_suffix_field,
'new': False,
'use_code_as_id': False,
'encoding': 'ISO-8859-1'})
call_command('mapit_import',
b.shapefile,
**all_options)
Empty file added mapit_za/models.py
Empty file.
5 changes: 5 additions & 0 deletions mapit_za/templates/mapit/copyright.html
@@ -0,0 +1,5 @@
<p id="copyright">
The boundary data used for this service is from
the <a href="http://www.demarcation.org.za/">Municipal
Demarcation Board (www.demarcation.org.za)</a>.
</p>
1 change: 1 addition & 0 deletions mapit_za/templates/mapit/country.html
@@ -0,0 +1 @@
South Africa
Empty file added mapit_za/views.py
Empty file.
6 changes: 5 additions & 1 deletion project/settings.py
Expand Up @@ -24,7 +24,7 @@
# WGS84. Optional, defaults to 4326.
MAPIT_AREA_SRID = int(config.get('AREA_SRID', 4326))

# Country is currently one of GB, NO, or KE. Optional; country specific things
# Country is currently one of GB, NO, KE or ZA. Optional; country specific things
# won't happen if not set.
MAPIT_COUNTRY = config.get('COUNTRY', '')

Expand Down Expand Up @@ -105,6 +105,10 @@
TIME_ZONE = 'Europe/Rome'
LANGUAGE_CODE = 'it'
POSTCODES_AVAILABLE = True
elif MAPIT_COUNTRY == 'ZA':
TIME_ZONE = 'Africa/Johannesburg'
LANGUAGE_CODE = 'en-za'
POSTCODES_AVAILABLE = False
elif MAPIT_COUNTRY == 'Global':
TIME_ZONE = 'Europe/London'
LANGUAGE_CODE = 'en'
Expand Down

0 comments on commit 1e422a1

Please sign in to comment.