Skip to content

Commit ea568ab

Browse files
committed
commands to create and update admin2 tilesets by country iso. add option to prepare staging and production tiles
1 parent 384ac9d commit ea568ab

File tree

1 file changed

+110
-21
lines changed

1 file changed

+110
-21
lines changed

api/management/commands/update-mapbox-tilesets.py

Lines changed: 110 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,40 +20,66 @@ def add_arguments(self, parser):
2020
action='store_true',
2121
help='Update tileset for districts'
2222
)
23+
parser.add_argument(
24+
'--create-and-update-admin2',
25+
help='Create and update admin2 tileset for this country ISO'
26+
)
27+
parser.add_argument(
28+
'--update-admin2',
29+
help='Update admin2 tileset for this country ISO'
30+
)
2331
parser.add_argument(
2432
'--update-all',
2533
action='store_true',
2634
help='Update tileset for countries and districts'
2735
)
36+
parser.add_argument(
37+
'--production',
38+
action='store_true',
39+
help='Update production tilesets. Default is staging'
40+
)
41+
42+
db = settings.DATABASES['default']
43+
DB_HOST = db['HOST']
44+
DB_NAME = db['NAME']
45+
DB_USER = db['USER']
46+
DB_PASSWORD = db['PASSWORD']
47+
DB_PORT = 5432
48+
connection_string = 'PG:host={} dbname={} user={} password={} port={}'.format(DB_HOST, DB_NAME, DB_USER, DB_PASSWORD, DB_PORT)
2849

2950
def handle(self, *args, **options):
3051
try:
31-
db = settings.DATABASES['default']
32-
DB_HOST = db['HOST']
33-
DB_NAME = db['NAME']
34-
DB_USER = db['USER']
35-
DB_PASSWORD = db['PASSWORD']
36-
DB_PORT = 5432
37-
connection_string = 'PG:host={} dbname={} user={} password={} port={}'.format(DB_HOST, DB_NAME, DB_USER, DB_PASSWORD, DB_PORT)
3852

3953
if (os.getenv("MAPBOX_ACCESS_TOKEN") is None):
4054
raise Exception('MAPBOX_ACCESS_TOKEN must be set')
4155

56+
staging = True
57+
if (options['production']):
58+
staging = False
59+
4260
if options['update_countries'] or options['update_all']:
43-
self.update_countries(connection_string)
61+
self.update_countries(staging)
4462

4563
if options['update_districts'] or options['update_all']:
46-
self.update_districts(connection_string)
64+
self.update_districts(staging)
65+
66+
if options['create_and_update_admin2']:
67+
print(f'Creating source for {options["create_and_update_admin2"]}')
68+
self.create_and_update_admin2(options['create_and_update_admin2'], staging)
69+
70+
if options['update_admin2']:
71+
print(f'Updating tileset for {options["update_admin2"]}')
72+
self.update_admin2(options['update_admin2'], staging)
4773

4874
except BaseException as e:
4975
raise CommandError('Could not update tilesets: ' + str(e))
5076

51-
def update_countries(self, connection_string):
77+
def update_countries(self, staging):
5278
try:
5379
print('Exporting countries...')
5480
subprocess.check_call(['touch', '/tmp/countries.geojson'])
5581
subprocess.check_call(['rm', '/tmp/countries.geojson'])
56-
subprocess.check_call(['ogr2ogr', '-f', 'GeoJSON', '/tmp/countries.geojson', connection_string, '-sql', 'select cd.country_id, cd.geom, c.name, c.name_es, c.name_fr, c.name_ar, c.iso, c.region_id, c.iso3, c.independent, c.is_deprecated, c.disputed, c.fdrs, c.record_type from api_countrygeoms cd, api_country c where cd.country_id = c.id and c.record_type=1' ])
82+
subprocess.check_call(['ogr2ogr', '-f', 'GeoJSON', '/tmp/countries.geojson', self.connection_string, '-sql', 'select cd.country_id, cd.geom, c.name, c.name_es, c.name_fr, c.name_ar, c.iso, c.region_id, c.iso3, c.independent, c.is_deprecated, c.disputed, c.fdrs, c.record_type from api_countrygeoms cd, api_country c where cd.country_id = c.id and c.record_type=1' ])
5783
print('Countries written to /tmp/countries.geojson')
5884
except Exception as e:
5985
print('Failed to export countries', e)
@@ -70,42 +96,46 @@ def update_countries(self, connection_string):
7096

7197
try:
7298
print('Update Mapbox tileset source for countries...')
73-
subprocess.check_call(['tilesets', 'upload-source', '--replace', 'go-ifrc', 'go-countries-src', '/tmp/countries.geojson'])
99+
tileset_source_name = f'go-countries-src-staging' if staging else f'go-countries-src'
100+
subprocess.check_call(['tilesets', 'upload-source', '--replace', 'go-ifrc', tileset_source_name, '/tmp/countries.geojson'])
74101
except Exception as e:
75102
print('Failed to update tileset source for countries', e)
76103
raise
77104

78105
try:
79106
print('Update Mapbox tileset for countries... and sleeping a minute')
80-
subprocess.check_call(['tilesets', 'publish', 'go-ifrc.go-countries'])
107+
tileset_name = f'go-ifrc.go-countries-staging' if staging else f'go-ifrc.go-countries'
108+
subprocess.check_call(['tilesets', 'publish', tileset_name])
81109
time.sleep(60)
82110
except Exception as e:
83111
print('Failed to update tileset for countries', e)
84112
raise
85113

86114
try:
87115
print('Update Mapbox tileset source for country centroids...')
116+
tileset_source_name = f'go-country-centroids-staging' if staging else f'go-country-centroids'
88117
subprocess.check_call(['tilesets', 'upload-source', '--replace', 'go-ifrc', 'go-country-centroids', '/tmp/country-centroids.geojson'])
89118
except Exception as e:
90119
print('Failed to update tileset source for country centroids')
91120
raise
92121

93122
try:
94123
print('Update Mapbox tileset for country centroids... and sleeping a minute')
95-
subprocess.check_call(['tilesets', 'publish', 'go-ifrc.go-country-centroids'])
124+
tileset_name = f'go-ifrc.go-country-centroids-staging' if staging else f'go-ifrc.go-country-centroids'
125+
subprocess.check_call(['tilesets', 'publish', tileset_name])
96126
time.sleep(60)
97127
except Exception as e:
98128
print('Failed to update tileset for country centroids')
99129
raise
100130

101131

102-
def update_districts(self, connection_string):
132+
def update_districts(self, staging):
103133
try:
104134
print('Exporting districts...')
105135
subprocess.check_call(['touch', '/tmp/districts.geojson'])
106136
subprocess.check_call(['rm', '/tmp/districts.geojson'])
107137
# FIXME eventually should be name_en, name_es etc.
108-
subprocess.check_call(['ogr2ogr', '-lco', 'COORDINATE_PRECISION=5', '-f', 'GeoJSON', '/tmp/districts.geojson', connection_string, '-sql', 'select cd.district_id, cd.geom, c.name, c.code, c.country_id, c.is_enclave, c.is_deprecated, country.iso as country_iso, country.iso3 as country_iso3, country.name as country_name, country.name_es as country_name_es, country.name_fr as country_name_fr, country.name_ar as country_name_ar from api_districtgeoms cd, api_district c, api_country country where cd.district_id = c.id and cd.geom is not null and country.id=c.country_id' ])
138+
subprocess.check_call(['ogr2ogr', '-lco', 'COORDINATE_PRECISION=5', '-f', 'GeoJSON', '/tmp/districts.geojson', self.connection_string, '-sql', 'select cd.district_id, cd.geom, c.name, c.code, c.country_id, c.is_enclave, c.is_deprecated, country.iso as country_iso, country.iso3 as country_iso3, country.name as country_name, country.name_es as country_name_es, country.name_fr as country_name_fr, country.name_ar as country_name_ar from api_districtgeoms cd, api_district c, api_country country where cd.district_id = c.id and cd.geom is not null and country.id=c.country_id' ])
109139
print('Districts written to /tmp/districts.geojson')
110140
except Exception as e:
111141
print('Failed to export districts', e)
@@ -116,35 +146,94 @@ def update_districts(self, connection_string):
116146
subprocess.check_call(['touch', '/tmp/district-centroids.geojson'])
117147
subprocess.check_call(['rm', '/tmp/district-centroids.geojson'])
118148
# FIXME eventually should be name_en, name_es etc.
119-
subprocess.check_call(['ogr2ogr', '-lco', 'COORDINATE_PRECISION=4', '-f', 'GeoJSON', '/tmp/district-centroids.geojson', connection_string, '-sql', 'select d.id as district_id, d.country_id as country_id, d.name, d.code, d.is_deprecated, d.is_enclave, c.iso as country_iso, c.iso3 as country_iso3, c.name as country_name, c.name_es as country_name_es, c.name_fr as country_name_fr, c.name_ar as country_name_ar, d.centroid from api_district d join api_country c on d.country_id=c.id where d.centroid is not null'])
149+
subprocess.check_call(['ogr2ogr', '-lco', 'COORDINATE_PRECISION=4', '-f', 'GeoJSON', '/tmp/district-centroids.geojson', self.connection_string, '-sql', 'select d.id as district_id, d.country_id as country_id, d.name, d.code, d.is_deprecated, d.is_enclave, c.iso as country_iso, c.iso3 as country_iso3, c.name as country_name, c.name_es as country_name_es, c.name_fr as country_name_fr, c.name_ar as country_name_ar, d.centroid from api_district d join api_country c on d.country_id=c.id where d.centroid is not null'])
120150
except Exception as e:
121151
print('Failed to export district centroids', e)
122152
raise
123153

124154
try:
125155
print('Update Mapbox tileset source for districts...')
126-
subprocess.check_call(['tilesets', 'upload-source', '--replace', 'go-ifrc', 'go-districts-src-1', '/tmp/districts.geojson'])
156+
tileset_source_name = f'go-districts-src-staging' if staging else f'go-districts-src-1'
157+
subprocess.check_call(['tilesets', 'upload-source', '--replace', 'go-ifrc', tileset_source_name, '/tmp/districts.geojson'])
127158
except Exception as e:
128159
print('Failed to update tileset source for districts', e)
129160
raise
130161

131162
try:
132163
print('Update Mapbox tileset for districts... and sleeping a minute')
133-
subprocess.check_call(['tilesets', 'publish', 'go-ifrc.go-districts-1'])
164+
tileset_name = f'go-ifrc.go-districts-staging' if staging else f'go-ifrc.go-districts-1'
165+
subprocess.check_call(['tilesets', 'publish', tileset_name])
134166
time.sleep(60)
135167
except Exception as e:
136168
print('Failed to update tileset for districts')
137169
raise
138170

139171
try:
140172
print('Update Mapbox tileset source for district centroids...')
141-
subprocess.check_call(['tilesets', 'upload-source', '--replace', 'go-ifrc', 'go-district-centroids', '/tmp/district-centroids.geojson'])
173+
tileset_source_name = f'go-district-centroids-staging' if staging else f'go-district-centroids'
174+
subprocess.check_call(['tilesets', 'upload-source', '--replace', 'go-ifrc', tileset_source_name, '/tmp/district-centroids.geojson'])
142175
except Exception as e:
143176
print('Failed to update tileset source for district centroid')
144177
raise
145178
try:
146179
print('Update Mapbox tileset for district centroids... [no sleep]')
147-
subprocess.check_call(['tilesets', 'publish', 'go-ifrc.go-district-centroids'])
180+
tileset_name = f'go-ifrc.go-district-centroids-staging' if staging else f'go-ifrc.go-district-centroids'
181+
subprocess.check_call(['tilesets', 'publish', tileset_name])
148182
except Exception as e:
149183
print('Failed to update tileset for distrct centroids')
150184
raise
185+
186+
def create_and_update_admin2(self, iso, staging=True):
187+
# create a new tileset source
188+
189+
status = self.prepare_admin2_geojson(iso)
190+
if (status):
191+
update_status = self.update_admin2(iso, staging)
192+
if (update_status):
193+
tileset_name = f'go-ifrc.go-admin2-{iso}-staging'
194+
recipe_name = f'mapbox/admin2/{iso}-staging.json'
195+
if not staging:
196+
tileset_name = f'go-ifrc.go-admin2-{iso}'
197+
recipe_name = f'mapbox/admin2/{iso}.json'
198+
199+
create_status = subprocess.run(['tilesets', 'create', tileset_name, '--recipe', recipe_name, '--name', f'GO Admin2 {iso}'])
200+
if create_status:
201+
publish_status = self.publish_admin2(iso, staging, create=True)
202+
return publish_status
203+
204+
def update_admin2(self, iso, staging=True):
205+
# update tileset source
206+
# update tileset and publish
207+
tileset_source__name = f'go-admin2-{iso}-src-staging'
208+
if not staging:
209+
tileset_source__name = f'go-admin2-{iso}-src'
210+
211+
status = subprocess.run(['tilesets', 'upload-source', '--replace', 'go-ifrc', tileset_source__name, f'/tmp/{iso}.geojson'])
212+
return True if status.returncode == 0 else False
213+
214+
def publish_admin2(self, iso, staging=True, create=False):
215+
if (not create):
216+
update_status = self.update_admin2(iso, staging)
217+
else:
218+
update_status = True
219+
220+
if update_status:
221+
tileset_name = f'go-ifrc.go-admin2-{iso}-staging'
222+
if not staging:
223+
tileset_name = f'go-ifrc.go-admin2-{iso}'
224+
225+
publish_status = subprocess.run(['tilesets', 'publish', tileset_name])
226+
return True if publish_status.returncode == 0 else False
227+
else:
228+
return False
229+
230+
def prepare_admin2_geojson(self, iso):
231+
# query the database and create geojson
232+
try:
233+
os.remove(f'/tmp/{iso}.geojson')
234+
except FileNotFoundError as e:
235+
pass
236+
237+
status = subprocess.run(['ogr2ogr', '-f', 'GeoJSON', f'/tmp/{iso}.geojson', self.connection_string, '-sql', f'select d.id as admin1_id, d.name as admin1_name, ad.name, ad.id, adg.geom from api_country as c, api_district as d, api_admin2 as ad, api_admin2geoms as adg where c.id=d.country_id and c.iso3=\'{iso}\' and ad.admin1_id=d.id and adg.admin2_id = ad.id'])
238+
239+
return True if status.returncode == 0 else False

0 commit comments

Comments
 (0)