From 9dcea07f87ec48840464d73dd1afad6b96018df4 Mon Sep 17 00:00:00 2001 From: Adam Barnes Date: Fri, 9 Feb 2024 14:36:36 -0500 Subject: [PATCH 01/26] fix: update celery config to resolve remaining task issues --- compose/django/celery/flower/start | 2 +- config/settings/base.py | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/compose/django/celery/flower/start b/compose/django/celery/flower/start index 8986ccc0..a38fb259 100644 --- a/compose/django/celery/flower/start +++ b/compose/django/celery/flower/start @@ -5,4 +5,4 @@ set -o nounset export DJANGO_SETTINGS_MODULE=config.settings.production -celery -A config.celery_app.app flower --basic_auth="${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}" -l INFO +celery -A config.celery_app.app flower --url-prefix="/celery" --basic_auth="${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}" -l INFO diff --git a/config/settings/base.py b/config/settings/base.py index daf42af8..79b909f4 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -277,17 +277,26 @@ } # Celery - if USE_TZ: CELERY_TIMEZONE = TIME_ZONE CELERY_BROKER_URL = env("CELERY_BROKER_URL", default="redis://redis:6379/0") CELERY_RESULT_BACKEND = CELERY_BROKER_URL +CELERY_RESULT_EXTENDED = True +CELERY_RESULT_BACKEND_ALWAYS_RETRY = True +CELERY_RESULT_BACKEND_MAX_RETRIES = 5 CELERY_ACCEPT_CONTENT = ["json"] CELERY_TASK_SERIALIZER = "json" CELERY_RESULT_SERIALIZER = "json" -CELERY_TASK_TIME_LIMIT = 60 * 60 -CELERY_TASK_SOFT_TIME_LIMIT = 500 + +# 2700 = 45min before worker task exception + potential cleanup +# 3000 = 50min before forced termination of worker task +# Needed for long-running import & coding jobs +CELERY_TASK_TIME_LIMIT = 3000 +CELERY_TASK_SOFT_TIME_LIMIT = 2700 + CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler" +CELERY_WORKER_SEND_TASK_EVENTS = True +CELERY_TASK_SEND_SENT_EVENT = True # Allauth ACCOUNT_ALLOW_REGISTRATION = env.bool("DJANGO_ACCOUNT_ALLOW_REGISTRATION", False) From 02526c31dff34cd620914aa155960a753935420a Mon Sep 17 00:00:00 2001 From: Adam Barnes Date: Mon, 4 Mar 2024 07:56:25 -0500 Subject: [PATCH 02/26] feat: update locations model, ingest ops, and associated VA location mapping logic to use exact match --- requirements/base.txt | 1 + .../management/commands/load_locations.py | 255 +++++++++++++++++- .../migrations/0023_location_new_fields.py | 27 ++ va_explorer/va_data_management/models.py | 5 +- .../va_data_management/utils/loading.py | 87 +----- .../utils/location_assignment.py | 93 ++----- .../va_data_management/utils/validate.py | 31 ++- 7 files changed, 337 insertions(+), 162 deletions(-) create mode 100644 va_explorer/va_data_management/migrations/0023_location_new_fields.py diff --git a/requirements/base.txt b/requirements/base.txt index 3b25871f..59b72e45 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -7,6 +7,7 @@ pandas==1.5.1 fuzzywuzzy==0.18.0 python-Levenshtein==0.20.7 tqdm==4.65.0 +anytree==2.12.1 # Django django==4.1.2 diff --git a/va_explorer/va_data_management/management/commands/load_locations.py b/va_explorer/va_data_management/management/commands/load_locations.py index b5c65572..98978183 100644 --- a/va_explorer/va_data_management/management/commands/load_locations.py +++ b/va_explorer/va_data_management/management/commands/load_locations.py @@ -1,24 +1,265 @@ import argparse +import numpy as np +import pandas as pd +from anytree import LevelOrderIter, Node, RenderTree +from django.conf import settings from django.core.management.base import BaseCommand +from va_data_management.models import Location -from va_explorer.va_data_management.utils.loading import load_locations_from_file +required_columns = ["province", "district", "key", "name", "status"] +missing_column_error_msg = ", ".join(required_columns) class Command(BaseCommand): - # TODO: Need approach that supports loading of country-specific location information + """ + Takes a list of locations with supporting metadata, converts it to a tree + structure and then loads that tree into VA Explorer's database. + + Args: + csv_file: File containing info on all facilities that are or ever have produced VAs. + (See VA Spec choices tab for reference below and for their potential values) + + Province - the label::English value of the lstprovince the location is within + + District - the label::English value of the lstareas the location is within + + Name - the label::English value for the lsthospital + + Key - the choice name associated with the lsthospital + + Status - whether the facility is still actively producing VAs + + --delete_previous (bool): If True, clears database first and inserts a + new tree. If False (default), attempts to update existing Locations table + """ help = "Loads initial location data into the database from a CSV file with \ - Name, Type, and Parent columns" + relevant info. Required Columns: Province, District, Key, Name, Status." def add_arguments(self, parser): parser.add_argument("csv_file", type=argparse.FileType("r")) - parser.add_argument("--delete_previous", type=bool, nargs="?", default=False) + parser.add_argument("--delete-previous", type=bool, nargs="?", default=False) def handle(self, *args, **options): - # Load the CSV file + print(options) csv_file = options["csv_file"] delete_previous = options["delete_previous"] - # see loading.py in va_data_management_utils for implementation - load_locations_from_file(csv_file, delete_previous=delete_previous) + tree = _treeify_facilities(csv_file) + _process_facility_tree(tree, delete_previous=delete_previous) + + +def _process_csv(csv_file): + try: + df = pd.read_csv(csv_file, keep_default_na=False).rename( + columns=lambda c: c.lower() + ) + except FileNotFoundError: + print(f"File '{csv_file}' not found.") + exit(-1) + + if len(df.columns) < len(required_columns): + print( + f"Missing required columns ({missing_column_error_msg}). " + + "Please ensure the provided CSV contains them." + ) + exit(-1) + elif set(df.columns) != set(required_columns): + print( + "CSV columns do not match the required format " + + f"[{missing_column_error_msg}]." + ) + exit(-1) + + # Do some post-processing. In this case turning human-readable 'Status' + # into machine-readable is_active: + df = df.rename(columns={"status": "is_active"}) + df["is_active"] = df["is_active"].map({"Active": True, "Inactive": False}) + return df + + +def _has_child(parent, *args): + """ + Helper method to check if a specific child exists under its parent. + Check if all elements in args sequence exist as children. + """ + current = parent + for label in args[:-1]: + found = False + for child in current.children: + if child.name == label: + current = child + found = True + break + if not found: + return False + # Check last item directly since there could be more siblings at lower levels. + return any(child.name == args[-1] for child in current.children) + + +def _treeify_facilities(csv_file): + """ + Converts csv_file input into a tree datastructure to validate readiness for + database insertion. + + Tree has country root node and handles multiple facilities (leaf nodes) with + the same name, as long as the path from the root to the leaf is unique for + each name. For example: + Zambia->Lusaka Province->Kafue District->Other Facility + Zambia->Lusaka Province->Lusaka District->Other Facility are both valid. + but adding a second + Zambia->Lusaka Province->Lusaka District->Other Facility + after the first would be a duplicate that is ignored. + + All nodes should contain name and location_type (one of 'province', + 'district', or 'facility' based on column name). Leaf nodes (facilities) + contain additional info such as status and key. + """ + df = _process_csv(csv_file) + + # TODO: turn this value into an env variable or make country requirement of csv + root = Node("Zambia", location_type="country") + node_lookup = {} + for _, row in df.iterrows(): + province, district, _key, name, status = ( + row["province"], + row["district"], + row["key"], + row["name"], + row["is_active"], + ) + + # Create nodes along the way while checking uniqueness. + p_node = None + d_node = None + f_node = None + + if province != "": + province = f"{province} Province" + if _has_child(root, province): + p_node = node_lookup[tuple(root.name, province)] + else: + p_node = Node(province, location_type="province", parent=root) + node_lookup[tuple(root.name, province)] = p_node + + if district != "" and p_node is not None: + district = f"{district} District" + if _has_child(p_node, district): + d_node = node_lookup[tuple(p_node.name, district)] + else: + d_node = Node(district, location_type="district", parent=p_node) + node_lookup[tuple(p_node.name, district)] = d_node + + if name != "" and d_node is not None: + if _has_child(d_node, name): + f_node = node_lookup[tuple(d_node.name, name)] + else: + f_node = Node(name, location_type="facility", parent=d_node) + node_lookup[tuple(d_node.name, name)] = f_node + + # Add extra information only when reaching facility level. + if f_node is not None: + f_node.is_active = status + f_node.key = _key + + if settings.DEBUG: + for pre, _, node in RenderTree(root): + print(f"{pre}{node.name}") + + return root + + +def _get_node_path(node): + return "%s" % node.separator.join([""] + [str(node.name) for node in node.path]) + + +def _process_facility_tree(tree, delete_previous=False): + """ + Handle a given facility tree by processing each node to determine if they + should be added to, removed from, or updated in the database. + Report actions taken to the user at the end. + """ + # Clear out existing locations if requested (typically for initialization only) + if delete_previous: + Location.objects.all().delete() + + # Only consider fields in both input and Location schema + db_fields = {field.name for field in Location._meta.get_fields()} + data_fields = set(vars(tree.leaves[0]).keys()) + common_fields = list(data_fields.intersection(db_fields)) + + db = {location.path_string: location for location in Location.objects.all()} + + # Use anytree datastructure to insert or update database locations stored + # as django-treebeard style models. Also track actions for reporting + location_ct = update_ct = delete_ct = 0 + for node in LevelOrderIter(tree): + model_data = {k: v for k, v in node.__dict__.items() if k in common_fields} + model_data["path_string"] = path = _get_node_path(node) + + if node.parent: + # first, check that parent exists. If not, skip location due to + # integrity issues + parent_node = db.get(_get_node_path(node.parent), None) + if parent_node: + # update parent to get latest state + parent_node.refresh_from_db() + # next, check for current node in db to update. If not, create new child. + current_node = db.get(path, None) + if current_node: + # update existing location fields with data from csv + old_values = { + k: v + for k, v in vars(current_node).items() + if k in common_fields + } + for field, value in model_data.items(): + if value not in [np.nan, "", None]: + setattr(current_node, field, value) + new_values = { + k: v + for k, v in vars(current_node).items() + if k in common_fields + } + # only update if values changed + if old_values != new_values: + current_node.save() + update_ct += 1 + else: + db[path] = parent_node.add_child(**model_data) + location_ct += 1 + else: + print( + f"Couldn't find location {node.name}'s " + + f"parent ({node.parent.name}) in system. Skipping.." + ) + else: + # add root node if it doesn't already exist + if not db.get(path, None): + print(f"Adding root node for {node.name}") + db[path] = Location.add_root(**model_data) + location_ct += 1 + + # handle removals by checking if there are additional values in the db that + # are not in the csv. + paths = [_get_node_path(node) for node in tree.descendants] + [ + _get_node_path(tree.root), + None, + ] + db_paths = list( + Location.objects.all().only("path_string").values_list("path_string", flat=True) + ) + extras = set(db_paths) - set(paths) + if extras: + for extra in extras: + Location.objects.filter(path_string=extra).delete() + delete_ct += 1 + + # if non existent, add 'Null' location to database to account for VAs with + # completely unknown locations + if not Location.objects.filter(name="Unknown").exists(): + print("Adding NULL location to handle unknowns") + Location.add_root( + name="Unknown", key="other", location_type="facility", is_active=False + ) + location_ct += 1 + + print(f" added {location_ct} new locations to system") + print(f" updated {update_ct} locations with new data") + print(f" deleted {delete_ct} locations no longer in csv_file") diff --git a/va_explorer/va_data_management/migrations/0023_location_new_fields.py b/va_explorer/va_data_management/migrations/0023_location_new_fields.py new file mode 100644 index 00000000..f92a2f33 --- /dev/null +++ b/va_explorer/va_data_management/migrations/0023_location_new_fields.py @@ -0,0 +1,27 @@ +# Generated by Django 4.1.2 on 2024-02-28 19:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('va_data_management', '0022_historicalverbalautopsy_instancename_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='location', + name='is_active', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='location', + name='key', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='location', + name='path_string', + field=models.TextField(null=True, unique=True), + ), + ] diff --git a/va_explorer/va_data_management/models.py b/va_explorer/va_data_management/models.py index 0e04bbe9..e9196001 100644 --- a/va_explorer/va_data_management/models.py +++ b/va_explorer/va_data_management/models.py @@ -30,6 +30,9 @@ class Location(MP_Node): # implementation for efficiency of tree operations name = models.TextField() location_type = models.TextField() + is_active = models.BooleanField(default=False) + key = models.TextField(blank=True) + path_string = models.TextField(unique=True, null=True) node_order_by = ["name"] # A user can have their access scoped by one or more locations @@ -40,7 +43,7 @@ class Location(MP_Node): updated = models.DateTimeField(auto_now=True) def __str__(self): - return self.name + return f"{self.name} (is_active: {self.is_active})" def get_descendant_ids(self): return [descendant.id for descendant in self.get_descendants()] diff --git a/va_explorer/va_data_management/utils/loading.py b/va_explorer/va_data_management/utils/loading.py index d96b3bbf..70541621 100644 --- a/va_explorer/va_data_management/utils/loading.py +++ b/va_explorer/va_data_management/utils/loading.py @@ -13,7 +13,6 @@ from va_explorer.va_data_management.utils.date_parsing import parse_date from va_explorer.va_data_management.utils.location_assignment import ( assign_va_location, - build_location_mapper, ) from va_explorer.va_data_management.utils.validate import validate_vas_for_dashboard @@ -135,7 +134,12 @@ def load_records_from_dataframe(record_df, random_locations=False, debug=False): # build location mapper to map csv locations to known db locations if "hospital" in record_df.columns: hospitals = record_df["hospital"].unique().tolist() - location_map = build_location_mapper(hospitals) + location_map = { + key_name_pair[0]: key_name_pair[1] + for key_name_pair in Location.objects.filter(key__in=hospitals) + .only("name", "key") + .values_list("key", "name") + } # if random locations, assign random locations via a random field worker. if random_locations: @@ -268,85 +272,6 @@ def format_multi_select_fields(row): ) -# load locations from a csv file into the django database. If delete_previous -# is true, will clear location db before loading. -def load_locations_from_file(csv_file, delete_previous=False): - # Delete existing locations ONLY IF DELETE_PREVIOUS IS TRUE. - if delete_previous: - # Clear out any existing locations (this is for initialization only) - Location.objects.all().delete() - - # Load the CSV file - csv_data = pd.read_csv(csv_file, keep_default_na=False).rename( - columns=lambda c: c.lower() - ) - - # rename type column to match model field name - if "type" in csv_data.columns: - csv_data = csv_data.rename(columns={"type": "location_type"}) - - # only consider fields in both csv and Location schema - db_fields = {field.name for field in Location._meta.get_fields()} - common_fields = csv_data.columns.intersection(db_fields).tolist() - - # track number of new locations added to system - location_ct = update_ct = 0 - db_locations = {location.name: location for location in Location.objects.all()} - # Store it into the database in a tree structure - # *** assumes locations have following fields: name, parent, location_type - for _, row in csv_data.iterrows(): - model_data = row.loc[common_fields].dropna() - if row["parent"]: - # first, check that parent exists. If not, skip location due to - # integrity issues - parent_node = db_locations.get(row["parent"], None) - if parent_node: - # update parent to get latest state - parent_node.refresh_from_db() - # next, check for current node in db. If not, create new child. - # If so, ensure parent matches parent_node - row_location = db_locations.get(row["name"], None) - if row_location: - # if child node points to right parent - if row_location.get_parent().name != parent_node.name: - print( - f"WARNING: Updating {row_location.name}'s \ - parent to {parent_node.name}" - ) - row_location.move(parent_node, pos="sorted-child") - # update existing location fields with data from csv - for field, value in model_data.items(): - if value not in [np.nan, "", None]: - setattr(row_location, field, value) - row_location.save() - update_ct += 1 - else: - print(f"Adding {row['name']} as child node of {row['parent']}") - db_locations[row["name"]] = parent_node.add_child(**model_data) - location_ct += 1 - else: - print( - f"Couldn't find location {row['name']}'s \ - parent ({row['parent']}) in system. Skipping.." - ) - else: - # add root node if it doesn't already exist - if not db_locations.get(row["name"], None): - print(f"Adding root node for {row['name']}") - db_locations[row["name"]] = Location.add_root(**model_data) - location_ct += 1 - - # if non existent, add 'Null' location to database to account for VAs with - # unknown locations - if not Location.objects.filter(name="Unknown").exists(): - print("Adding NULL location to handle unknowns") - Location.add_root(name="Unknown", location_type="facility") - location_ct += 1 - - print(f"added {location_ct} new locations to system") - print(f"updated {update_ct} locations with new data") - - # combine fields ending with _other for their normal counterparts # (e.x. Id10010_other, Id10010). # in Zambia data, often either the normal or _other field has a value but not both. diff --git a/va_explorer/va_data_management/utils/location_assignment.py b/va_explorer/va_data_management/utils/location_assignment.py index 94618f28..6f29634d 100644 --- a/va_explorer/va_data_management/utils/location_assignment.py +++ b/va_explorer/va_data_management/utils/location_assignment.py @@ -1,68 +1,9 @@ -import re - import pandas as pd from fuzzywuzzy import fuzz from va_explorer.va_data_management.models import Location -def build_location_mapper( - va_locations, - db_locations=None, - loc_type="facility", - drop_terms=None, - similarity_thresh=75, - prnt=False, -): - if va_locations and len(va_locations) > 0: - # store database locations of type location_type in a df - try: - if not db_locations: - db_locations = list( - Location.objects.filter(location_type=loc_type).values_list( - "name", flat=True - ) - ) - if len(db_locations) == 0: - raise RuntimeWarning( - "No known facilities found. Have you initialized location data?" - ) - except RuntimeWarning as warn: - print("%s", warn) - - location_df = pd.DataFrame({"name": db_locations}).assign( - key=lambda df: df["name"].astype(str).str.lower() - ) - - # store unique va_locations in mapper dataframe - va_locations = list(set(va_locations).difference({"other"})) - mapper = pd.DataFrame({"va_name": va_locations}).dropna() - if not mapper.empty: - mapper["va_key"] = ( - mapper["va_name"].str.lower().replace(r"\_", " ", regex=True) - ) - - # preprocess dataframes - if not drop_terms: - drop_terms = ["general", "central", "teaching"] - - for term in drop_terms: - location_df["key"] = location_df["key"].replace( - f" {term}", "", regex=True - ) - mapper["va_key"] = mapper["va_key"].replace(f" {term}", "", regex=True) - - # matching - mapper["db_name"] = mapper["va_key"].apply( - lambda x: fuzzy_match(x, location_df, threshold=similarity_thresh) - ) - - return mapper.set_index("va_name")["db_name"].to_dict() - if prnt: - print("WARNING: no va locations provided, returning empty dict") - return {} - - def assign_va_location(va, location_mapper=None, location_fields=None): # check if the hospital or place of death fields are known locations location_fields = ( @@ -75,14 +16,33 @@ def assign_va_location(va, location_mapper=None, location_fields=None): break if raw_location: if not location_mapper: - location_mapper = build_location_mapper([raw_location]) + # no mapper provided, create a one-off for this assignment + location_mapper = dict( + Location.objects.filter(key=raw_location) + .only("name", "key") + .values_list("key", "name") + ) db_location_name = location_mapper.get(raw_location, None) # if matching db location, retrieve it. Otherwise, record location as unknown if db_location_name: # TODO: make this more generic to other location hierarchies db_location = Location.objects.filter( location_type="facility", name=db_location_name - ).first() + ) + if len(db_location) > 1: + # attempt to find specific facility based on match with other + # va location data. warn if that doesn't narrow it down completely + search_string = ( + f"{va.province} Province/{va.area} District/{va.hospital}" + ) + db_location = db_location.filter(path_string__icontains=search_string) + if len(db_location) > 1: + print( + f"WARNING: ambiguous location: {search_string} " + + "using most likely match" + ) + # need to take first anyway to get (ideally 1) Location out of QuerySet + db_location = db_location.first() # if any db location found, update VA with found location if db_location: @@ -103,8 +63,6 @@ def fuzzy_match( option_df, options=None, threshold=75, - preprocess=False, - drop_terms=None, prnt=False, return_str=True, ): @@ -127,16 +85,7 @@ def fuzzy_match( # if threshold is a decimal, convert to percent if threshold > 0 and threshold <= 1: threshold = int(100 * threshold) - # if preprocess=True, clean search term and options before comparing search_term = search - if preprocess: - if not drop_terms: - drop_terms = ["general", "central", "teaching"] - - search_term = re.sub(r"\_", " ", search.lower()) - for term in drop_terms: - search_term = search_term.replace(f" {term}", "") - option_df["key"] = option_df["key"].replace(f" {term}", "", regex=True) # matching option_df["score"] = option_df["key"].apply( diff --git a/va_explorer/va_data_management/utils/validate.py b/va_explorer/va_data_management/utils/validate.py index 98bd4a22..614ee57b 100644 --- a/va_explorer/va_data_management/utils/validate.py +++ b/va_explorer/va_data_management/utils/validate.py @@ -111,9 +111,38 @@ def validate_vas_for_dashboard(verbal_autopsies): ) issues.append(issue) + # if location is valid but inactive record a warning + if va.location and not va.location.is_active: + issue_text = "Warning: VA location was matched to facility known \ + to be inactive. Consider updating the location to an active \ + facility instead." + issue = CauseCodingIssue( + verbalautopsy_id=va.id, + text=issue_text, + severity="warning", + algorithm="", + settings="", + ) + issues.append(issue) + + # if location is "Other" (a valid, but non-informative location stemming + # stemming from bad data) record a warning + if va.location and va.location.name.casefold() == "Other Facility": + issue_text = "Warning: location field (parsed from hospital): provided \ + location was parsed as 'Other Facility'. Will not show on dashboards \ + until underlying data is corrected to actual location." + issue = CauseCodingIssue( + verbalautopsy_id=va.id, + text=issue_text, + severity="warning", + algorithm="", + settings="", + ) + issues.append(issue) + # if location is "Unknown" (couldn't find match for provided location) # record a warning - if va.location and va.location.name == "Unknown": + if va.location and va.location.name.casefold() == "Unknown": issue_text = "Warning: location field (parsed from hospital): provided \ location was not a known facility. Set location to 'Unknown'" issue = CauseCodingIssue( From 567a12b6cbfd0d1dfb6b20af0cf58b1ec81a1004 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Thu, 7 Mar 2024 17:25:35 -0500 Subject: [PATCH 03/26] updated docs to reflect location changes --- docs/training/admin_guides.md | 38 ++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/docs/training/admin_guides.md b/docs/training/admin_guides.md index 3fcbb220..cea7ceb7 100644 --- a/docs/training/admin_guides.md +++ b/docs/training/admin_guides.md @@ -12,10 +12,7 @@ as individuals described below. To set up VA Explorer for the Geographic Access mentioned in that section, you must load location data into the system. -Locations in VA Explorer follow a hierarchical structure. A specific geographic -region or jurisdiction has a name ("Name"), a type ("Type"), and a parent -("Parent"). By specifying the Parent field, you can achieve the arbitrary level -of nesting required to make a tree. +Locations in VA Explorer follow an assumed three-level hierarchical structure by which each facility or hospital maps to an associated Level 2 ("District") and Level 1 ("Province) hierarchy. Each facility also has a corresponding `key`, which represents the XML option used in the dropdown list within ODK or Kobo, and a `status` which indicates if the Facility is actively producing VAs or not. The table below shows an example location hierarchy for States, Counties, and Cities in the United States. In this example, we have one state (California), two @@ -24,25 +21,26 @@ Los Angeles). ```{csv-table} An example geographic hierarchy in tabular format :header-rows: 1 -Name,Type,Parent -California,State, -Marin County,County,California -Sausalito,City,Marin County -San Rafael,City,Marin County -Los Angeles County,County,California -Los Angeles,City,Los Angeles County -``` - -```{figure} ../_static/img/geo_hierarchy.png -:width: 75% - - A tree data structure showing the example geographic hierarchy from the previous table +Province,District,Name,Key,Status +California,Marin County,Sausalito Hospital, sausalito_hospital, True +California,Marin County,San Rafael Clinic, san_rafael_clinic, False +California,Los Angeles County,Los Angeles Hospital, los_angeles_hospital, True ``` The input is similarly structured to support any number of geographic hierarchies for VA Explorer users. With a {term}`CSV` file in hand, you can now supplement your initial system set up with the `load_locations` management command. Full usage details -for this are provided in [Management Commands](#management-commands). +for this are provided in [Management Commands](#management-commands). The specification of the input CSV file is as follows: + +```{csv-table} Expected columns for the location file +:header-rows: 1 +Column Name, Description, Specifics +Province, Level 1 Administrative Boundary Name, One of the `label::English` values as defined in the VA XLSForm +District, Level 2 Administrative Boundary Name, One of the `label::English` values as defined in the VA XLSForm +Name, Facility or Hospital Name, One of the `label::English` values as defined in the VA XLSForm +Key, Facility or Hospital XML Value, The choice name associated with the `label::English` defined in the previous column +Status, Whether the facility is still actively producing VAs, Boolean +``` Following this command, VA Explorer should support geographic restrictions to any area or facility you’ve provide, making them available during user creation and @@ -51,6 +49,10 @@ access for that geographic area as well as all its children-geographies. For example, in the above tree a user with access to California also has access to Marin County, Los Angeles County, Sausalito, San Rafael, and Los Angeles. +#### Updating locations in VA Explorer + +When VAs are imported into VA Explorer, they are matched exactly on the locations loaded into the system in this step. If a VA does not have a valid location field, VA Explorer will track that mismatch as an error that either needs to be corrected in the VA Explorer locations file or in the underlying VA data. To add a location to VA Explorer, re-upload a revised location file following the `load_locations` management command. If a row is deleted from the locations file, it will also be deletd from VA Explorer (and any underlying VA data previously matched to that location will no longer match and have an error). + ### Creating & Editing Users Click "Users" in the navigation bar to visit the Users page. Click the "Create From fc15a538ff1fb0e242709b13c1ba734947d073ef Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Thu, 7 Mar 2024 20:14:32 -0500 Subject: [PATCH 04/26] update to admin training - correct expected values for active facility column --- docs/training/admin_guides.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/training/admin_guides.md b/docs/training/admin_guides.md index cea7ceb7..33a0a8c0 100644 --- a/docs/training/admin_guides.md +++ b/docs/training/admin_guides.md @@ -22,9 +22,9 @@ Los Angeles). ```{csv-table} An example geographic hierarchy in tabular format :header-rows: 1 Province,District,Name,Key,Status -California,Marin County,Sausalito Hospital, sausalito_hospital, True -California,Marin County,San Rafael Clinic, san_rafael_clinic, False -California,Los Angeles County,Los Angeles Hospital, los_angeles_hospital, True +California,Marin County,Sausalito Hospital, sausalito_hospital, Active +California,Marin County,San Rafael Clinic, san_rafael_clinic, Inactive +California,Los Angeles County,Los Angeles Hospital, los_angeles_hospital, Active ``` The input is similarly structured to support any number of geographic hierarchies @@ -39,7 +39,7 @@ Province, Level 1 Administrative Boundary Name, One of the `label::English` valu District, Level 2 Administrative Boundary Name, One of the `label::English` values as defined in the VA XLSForm Name, Facility or Hospital Name, One of the `label::English` values as defined in the VA XLSForm Key, Facility or Hospital XML Value, The choice name associated with the `label::English` defined in the previous column -Status, Whether the facility is still actively producing VAs, Boolean +Status, Whether the facility is still actively producing VAs, One of: 'Active' or 'Inactive' ``` Following this command, VA Explorer should support geographic restrictions to any From 73687cb15091c94f288f8d9ba6e063750fe3a17a Mon Sep 17 00:00:00 2001 From: Adam Barnes Date: Fri, 15 Mar 2024 10:47:21 -0400 Subject: [PATCH 05/26] refactor: correct ruff B905: zip() without an explicit strict --- .../management/commands/randomize_va_dates.py | 2 +- .../va_data_management/management/commands/run_dhis.py | 4 +++- va_explorer/va_data_management/views.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/va_explorer/va_data_management/management/commands/randomize_va_dates.py b/va_explorer/va_data_management/management/commands/randomize_va_dates.py index 007f2f02..196fa6d6 100644 --- a/va_explorer/va_data_management/management/commands/randomize_va_dates.py +++ b/va_explorer/va_data_management/management/commands/randomize_va_dates.py @@ -38,7 +38,7 @@ def handle(self, *args, **options): dates_list.sort() for va, new_date in tqdm( - zip(VerbalAutopsy.objects.all(), dates_list), total=count + zip(VerbalAutopsy.objects.all(), dates_list, strict=True), total=count ): # Set Id10023 and created and updated all to same date va.Id10023 = va.created = va.updated = va.Id10012 = new_date diff --git a/va_explorer/va_data_management/management/commands/run_dhis.py b/va_explorer/va_data_management/management/commands/run_dhis.py index ffe47705..f1cd1c11 100644 --- a/va_explorer/va_data_management/management/commands/run_dhis.py +++ b/va_explorer/va_data_management/management/commands/run_dhis.py @@ -212,7 +212,9 @@ def handle(self, *args, **options): query_cod_codes = pd.DataFrame.from_records(cod_codes) query_cod_codes = query_cod_codes[{"codname", "codcode"}] - dhis_cod_codes = dict(zip(query_cod_codes.codname, query_cod_codes.codcode)) + dhis_cod_codes = dict( + zip(query_cod_codes.codname, query_cod_codes.codcode, strict=True) + ) dhis_cod_codes = {} args_dhis = [settings_dhis, dhis_cod_codes] diff --git a/va_explorer/va_data_management/views.py b/va_explorer/va_data_management/views.py index 8995d8f9..5bfeaa11 100644 --- a/va_explorer/va_data_management/views.py +++ b/va_explorer/va_data_management/views.py @@ -162,7 +162,7 @@ def get_context_data(self, **kwargs): # TODO: date in diff info should be formatted in local time history = self.object.history.all().reverse() - history_pairs = zip(history, history[1:]) + history_pairs = zip(history, history[1:]) # noqa: B905 context["diffs"] = [ new.diff_against(old, excluded_fields=["unique_va_identifier", "duplicate"]) for (old, new) in history_pairs From 6f2e08791054f9eacf74d9cecb4d5287705e24b3 Mon Sep 17 00:00:00 2001 From: Adam Barnes Date: Fri, 15 Mar 2024 10:56:20 -0400 Subject: [PATCH 06/26] fix: correct test_views of va_export to account for new location properties. Remove support for name based export filtering regarding locations since names no longer likely to be unique --- va_explorer/home/va_trends.py | 6 +- .../management/commands/load_locations.py | 15 ++--- va_explorer/va_data_management/models.py | 2 +- .../va_data_management/tests/test_loading.py | 24 +++++--- va_explorer/va_export/tests/test_views.py | 55 +++++++++++++++---- va_explorer/va_export/utils.py | 44 --------------- va_explorer/va_export/views.py | 14 +++-- 7 files changed, 79 insertions(+), 81 deletions(-) delete mode 100644 va_explorer/va_export/utils.py diff --git a/va_explorer/home/va_trends.py b/va_explorer/home/va_trends.py index 4f499411..0c48be4f 100644 --- a/va_explorer/home/va_trends.py +++ b/va_explorer/home/va_trends.py @@ -2,7 +2,7 @@ import pandas as pd from django.db.models import F -from pandas._libs.tslibs.offsets import relativedelta +from pandas.tseries.offsets import DateOffset from va_explorer.va_data_management.constants import REDACTED_STRING from va_explorer.va_data_management.utils.date_parsing import ( @@ -40,7 +40,7 @@ VA_TABLE_COLUMNS = ["24", "1 week", "1 month", "Overall"] VA_GRAPH_TYPES = VA_TABLE_ROWS -MONTHS = [START_MONTH + relativedelta(months=i) for i in range(12)] +MONTHS = [START_MONTH + DateOffset(months=i) for i in range(12)] VA_GRAPH_Y_DATA = 12 * [0.0] VA_GRAPH_X_DATA = [month.strftime("%Y-%m") for month in MONTHS] @@ -145,7 +145,7 @@ def get_trends_data(user): # Load the VAs that are collected over various periods of time vas_24_hours = va_df[va_df["date"] == TODAY].index vas_1_week = va_df[va_df["date"] >= (TODAY - timedelta(days=7))].index - vas_1_month = va_df[va_df["date"] >= (TODAY - relativedelta(months=1))].index + vas_1_month = va_df[va_df["date"] >= (TODAY - DateOffset(months=1))].index vas_overall = va_df.sort_values(by="id").index # Graphs of the past 12 months, not including this month diff --git a/va_explorer/va_data_management/management/commands/load_locations.py b/va_explorer/va_data_management/management/commands/load_locations.py index 98978183..aa3ab883 100644 --- a/va_explorer/va_data_management/management/commands/load_locations.py +++ b/va_explorer/va_data_management/management/commands/load_locations.py @@ -5,7 +5,8 @@ from anytree import LevelOrderIter, Node, RenderTree from django.conf import settings from django.core.management.base import BaseCommand -from va_data_management.models import Location + +from va_explorer.va_data_management.models import Location required_columns = ["province", "district", "key", "name", "status"] missing_column_error_msg = ", ".join(required_columns) @@ -133,25 +134,25 @@ def _treeify_facilities(csv_file): if province != "": province = f"{province} Province" if _has_child(root, province): - p_node = node_lookup[tuple(root.name, province)] + p_node = node_lookup[(root.name, province)] else: p_node = Node(province, location_type="province", parent=root) - node_lookup[tuple(root.name, province)] = p_node + node_lookup[(root.name, province)] = p_node if district != "" and p_node is not None: district = f"{district} District" if _has_child(p_node, district): - d_node = node_lookup[tuple(p_node.name, district)] + d_node = node_lookup[(p_node.name, district)] else: d_node = Node(district, location_type="district", parent=p_node) - node_lookup[tuple(p_node.name, district)] = d_node + node_lookup[(p_node.name, district)] = d_node if name != "" and d_node is not None: if _has_child(d_node, name): - f_node = node_lookup[tuple(d_node.name, name)] + f_node = node_lookup[(d_node.name, name)] else: f_node = Node(name, location_type="facility", parent=d_node) - node_lookup[tuple(d_node.name, name)] = f_node + node_lookup[(d_node.name, name)] = f_node # Add extra information only when reaching facility level. if f_node is not None: diff --git a/va_explorer/va_data_management/models.py b/va_explorer/va_data_management/models.py index e9196001..eb92d613 100644 --- a/va_explorer/va_data_management/models.py +++ b/va_explorer/va_data_management/models.py @@ -43,7 +43,7 @@ class Location(MP_Node): updated = models.DateTimeField(auto_now=True) def __str__(self): - return f"{self.name} (is_active: {self.is_active})" + return self.name def get_descendant_ids(self): return [descendant.id for descendant in self.get_descendants()] diff --git a/va_explorer/va_data_management/tests/test_loading.py b/va_explorer/va_data_management/tests/test_loading.py index 994dd4fe..35f8a03c 100644 --- a/va_explorer/va_data_management/tests/test_loading.py +++ b/va_explorer/va_data_management/tests/test_loading.py @@ -14,7 +14,9 @@ def test_loading_from_dataframe(): # Location gets assigned w/ field hospital by name or by user's default location - loc = Location.add_root(name="test location", location_type="facility") + loc = Location.add_root( + name="Test Location", key="test_location", location_type="facility" + ) data = [ { @@ -25,7 +27,7 @@ def test_loading_from_dataframe(): "instancename": "_Dec---name 1---2021-03-21", "testing-dashes-Id10007": "name 1", "Id10023": "03/01/2021", - "hospital": "test location", + "hospital": "test_location", }, { "instanceid": "instance2", @@ -35,7 +37,7 @@ def test_loading_from_dataframe(): "instancename": "_Dec---name 2---2021-03-22", "testing-dashes-Id10007": "name 2", "Id10023": "dk", - "hospital": "test location", + "hospital": "test_location", }, ] @@ -58,7 +60,9 @@ def test_loading_from_dataframe(): def test_loading_from_dataframe_with_ignored(): # Location gets assigned automatically/randomly. # If that changes in loading.py we'll need to change that here too. - Location.add_root(name="test location", location_type="facility") + Location.add_root( + name="Test Location", key="test_location", location_type="facility" + ) data = [ { @@ -122,7 +126,9 @@ def test_loading_from_dataframe_with_ignored(): def test_loading_from_dataframe_with_key(): # Location gets assigned automatically/randomly if hospital is not a facility # If that changes in loading.py it needs to change here too - loc = Location.add_root(name="test location", location_type="facility") + loc = Location.add_root( + name="Test Location", key="test_location", location_type="facility" + ) data = [ { @@ -132,7 +138,7 @@ def test_loading_from_dataframe_with_key(): "Id10012": "2021-03-21", "instancename": "_Dec---name 1---2021-03-21", "testing-dashes-Id10007": "name 1", - "hospital": "test location", + "hospital": "test_location", }, { "key": "instance2", @@ -164,7 +170,9 @@ def test_loading_from_dataframe_with_key(): def test_load_va_csv_command(): # Location gets assigned automatically/randomly if hospital is not a facility # If that changes in loading.py it needs to change here too - Location.add_root(name="test location", location_type="facility") + Location.add_root( + name="Test Location", key="test_location", location_type="facility" + ) # Find path to data file test_data = Path(__file__).parent / "test-input-data.csv" @@ -265,5 +273,3 @@ def test_loading_duplicate_vas(settings): # TODO add tests for date of death, location, and age_group - -# TODO add tests for date of death, location, and age_group diff --git a/va_explorer/va_export/tests/test_views.py b/va_explorer/va_export/tests/test_views.py index 9760ea0c..58bfe814 100644 --- a/va_explorer/va_export/tests/test_views.py +++ b/va_explorer/va_export/tests/test_views.py @@ -31,11 +31,31 @@ def build_test_db(): # Build locations province = LocationFactory.create() district1 = province.add_child(name="District1", location_type="district") - facility_a = district1.add_child(name="Facility1", location_type="facility") + facility_a = district1.add_child( + name="Facility1", + location_type="facility", + key="facility_1", + path_string=f"{province.name} Province/District1 District/Facility1", + ) district2 = province.add_child(name="District2", location_type="district") - facility_b = district2.add_child(name="Facility2", location_type="facility") - facility_c = district2.add_child(name="Facility2", location_type="facility") - district2.add_child(name="No VA Facility", location_type="facility") + facility_b = district2.add_child( + name="Facility1", + location_type="facility", + key="facility_1", + path_string=f"{province.name} Province/District2 District/Facility1", + ) + facility_c = district2.add_child( + name="Facility2", + location_type="facility", + key="facility_2", + path_string=f"{province.name} Province/District2 District/Facility2", + ) + district2.add_child( + name="Empty Facility", + location_type="facility", + key="empty", + path_string=f"{province.name} Province/District2 District/Empty Facility", + ) # create VAs va1 = VerbalAutopsyFactory.create(location=facility_a, Id10023="2019-01-01") @@ -118,12 +138,14 @@ def test_json_download(self, user: User): def test_download_csv_with_no_matching_vas(self, user: User): build_test_db() # only download data from "No VA Facility", which will have no matching VAs - no_va_facility = Location.objects.get(name="No VA Facility") + no_va_facility = Location.objects.get(name="Empty Facility") c = Client() c.force_login(user=user) - response = c.post(POST_URL, data={"format": "csv", "locations": no_va_facility}) + response = c.post( + POST_URL, data={"format": "csv", "locations": no_va_facility.pk} + ) assert response.status_code == 200 # Django 3.2 has response.headers. For now, we'll access them per below @@ -146,13 +168,13 @@ def test_download_csv_with_no_matching_vas(self, user: User): def test_download_json_with_no_matching_vas(self, user: User): build_test_db() # only download data from "No VA Facility", which will have no matching VAs - no_va_facility = Location.objects.get(name="No VA Facility") + no_va_facility = Location.objects.get(name="Empty Facility") c = Client() c.force_login(user=user) response = c.post( - POST_URL, data={"format": "json", "locations": no_va_facility} + POST_URL, data={"format": "json", "locations": no_va_facility.pk} ) assert response.status_code == 200 @@ -177,12 +199,15 @@ def test_download_json_with_no_matching_vas(self, user: User): def test_location_filtering(self, user: User): build_test_db() # only download data from location a - facility_1 = Location.objects.get(name="Facility1") + province = Location.objects.get(location_type="province") + facility_1 = Location.objects.get( + path_string=f"{province.name} Province/District1 District/Facility1" + ) c = Client() c.force_login(user=user) - response = c.post(POST_URL, data={"format": "csv", "locations": facility_1}) + response = c.post(POST_URL, data={"format": "csv", "locations": facility_1.pk}) assert response.status_code == 200 # Django 3.2 has response.headers. For now, we'll access them per below @@ -258,7 +283,10 @@ def test_combined_filter_csv(self, user: User): # 1. Download from facility A after 1/1/2020 with COD_a in CSV format. # Assert only VA 4 is downloaded start_date = "2020-01-01" - loc_a = Location.objects.get(name="Facility1") + province = Location.objects.get(location_type="province") + loc_a = Location.objects.get( + path_string=f"{province.name} Province/District1 District/Facility1" + ) cod_name = "cod_a" query_data = { @@ -296,7 +324,10 @@ def test_combined_filter_json(self, user: User): # If this structure changes, need to update this test end_date = "2020-01-01" - loc_a = Location.objects.get(name="Facility1") + province = Location.objects.get(location_type="province") + loc_a = Location.objects.get( + path_string=f"{province.name} Province/District1 District/Facility1" + ) cod_name = "cod_b" query_data = { diff --git a/va_explorer/va_export/utils.py b/va_explorer/va_export/utils.py deleted file mode 100644 index dd716499..00000000 --- a/va_explorer/va_export/utils.py +++ /dev/null @@ -1,44 +0,0 @@ -import pandas as pd - -from va_explorer.va_data_management.models import Location -from va_explorer.va_data_management.utils.location_assignment import fuzzy_match - -# Get all relevant location ids (including descendants) for filtering. -# loc_query is a comma-separated list of either location ids or location names. -# If location names, perform name-based matching against all known locations in db. - - -# returns a list of location IDs matching location query. -def get_loc_ids_for_filter(loc_query): - locs = loc_query.split(",") - # first, assume locations are given as ids. If not, treat as names and - # perform name-based matching. - try: - loc_ids = [int(loc) for loc in locs] - match_list = [] - for loc_id in loc_ids: - # make sure location id is valid. Only proceed it matching location found - loc_obj = Location.objects.filter(pk=loc_id).first() - if loc_obj: - match_list.append(loc_id) - # add location descendants to match list - match_list += list( - loc_obj.get_descendants().values_list("id", flat=True) - ) - except: # noqa E722 - Intent is to simply handle invalid location case - # check query against all locations in db. If a match, get all - # location descendants if not already facility - loc_df = pd.DataFrame(Location.objects.values("id", "name", "location_type")) - for loc in locs: - # perform name-based matching - res = fuzzy_match(loc.lower(), loc_df, return_str=False) - if res: - if "id" in res: - match = Location.objects.get(pk=res["id"]) - else: - match = Location.objects.get(name=res["name"]) - - # get descendants - descendants = match.get_descendants().values_list("id", flat=True) - match_list = [match.id, *list(descendants)] - return match_list diff --git a/va_explorer/va_export/views.py b/va_explorer/va_export/views.py index db65e654..404e65e4 100644 --- a/va_explorer/va_export/views.py +++ b/va_explorer/va_export/views.py @@ -17,7 +17,6 @@ from va_explorer.va_data_management.constants import PII_FIELDS, REDACTED_STRING from va_explorer.va_data_management.models import Location from va_explorer.va_export.forms import VADownloadForm -from va_explorer.va_export.utils import get_loc_ids_for_filter @method_decorator(csrf_exempt, name="dispatch") @@ -69,11 +68,16 @@ def post(self, request, *args, **kwargs): # if location query, filter down VAs within chosen location's jurisdiction loc_query = params.get("locations", None) if loc_query: - # get ids of all provided locations and their descendants - match_list = get_loc_ids_for_filter(loc_query) + id_list = loc_query.split(",") - # filter VA queryset down to just those with matching location_ids - matching_vas = matching_vas.filter(location__id__in=match_list) + # also add location descendants to id list + locations_cache = Location.objects.filter(pk__in=id_list) + for location in locations_cache: + id_list.extend( + location.get_descendants().values_list("id", flat=True) + ) + + matching_vas = matching_vas.filter(location__id__in=id_list) # =========DATE FILTER LOGIC===================# # if start/end dates specified, filter to only VAs within time range From ab5e0821db442153ce88901600b3eef2e9ab00ca Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Thu, 7 Mar 2024 22:26:39 -0500 Subject: [PATCH 07/26] BUG FIX: load_locations.py --- .../va_data_management/management/commands/load_locations.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/va_explorer/va_data_management/management/commands/load_locations.py b/va_explorer/va_data_management/management/commands/load_locations.py index aa3ab883..2057089f 100644 --- a/va_explorer/va_data_management/management/commands/load_locations.py +++ b/va_explorer/va_data_management/management/commands/load_locations.py @@ -35,7 +35,7 @@ class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument("csv_file", type=argparse.FileType("r")) - parser.add_argument("--delete-previous", type=bool, nargs="?", default=False) + parser.add_argument("--delete_previous", type=bool, nargs="?", default=False) def handle(self, *args, **options): print(options) @@ -145,10 +145,12 @@ def _treeify_facilities(csv_file): d_node = node_lookup[(p_node.name, district)] else: d_node = Node(district, location_type="district", parent=p_node) + node_lookup[tuple([p_node.name, district])] = d_node node_lookup[(p_node.name, district)] = d_node if name != "" and d_node is not None: if _has_child(d_node, name): + f_node = node_lookup[tuple([d_node.name, name])] f_node = node_lookup[(d_node.name, name)] else: f_node = Node(name, location_type="facility", parent=d_node) From b8692bc6b07ca4b054fa53d5eb91bbfbaf1f4e9a Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Thu, 7 Mar 2024 22:27:16 -0500 Subject: [PATCH 08/26] BUG FIX: making dashboard work with new location tree structure --- va_explorer/static/js/dashboard.js | 1 + va_explorer/va_analytics/utils/loading.py | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/va_explorer/static/js/dashboard.js b/va_explorer/static/js/dashboard.js index 52174b93..4fdd3166 100644 --- a/va_explorer/static/js/dashboard.js +++ b/va_explorer/static/js/dashboard.js @@ -244,6 +244,7 @@ const dashboard = new Vue({ geojson.features = this.geojson.features.filter(feature => { return borders.includes(feature.properties.area_level_label) }) + this.layer = L.geoJson(geojson, { style: function (feature) { if (feature.properties.area_level_label !== 'Country') { diff --git a/va_explorer/va_analytics/utils/loading.py b/va_explorer/va_analytics/utils/loading.py index bd096840..b74ec849 100644 --- a/va_explorer/va_analytics/utils/loading.py +++ b/va_explorer/va_analytics/utils/loading.py @@ -85,7 +85,7 @@ def load_va_data( user_vas_filtered.annotate( district_name=Subquery( Location.objects.values("name").filter( - Q(path=Substr(OuterRef("location__path"), 1, 8)), Q(depth=2) + Q(path=Substr(OuterRef("location__path"), 1, 12)), Q(depth=3) )[:1] ) ) @@ -98,7 +98,7 @@ def load_va_data( user_vas_filtered.annotate( province_name=Subquery( Location.objects.values("name").filter( - Q(path=Substr(OuterRef("location__path"), 1, 4)), Q(depth=1) + Q(path=Substr(OuterRef("location__path"), 1, 8)), Q(depth=2) )[:1] ) ) @@ -211,7 +211,7 @@ def load_va_data( user_vas_filtered.annotate( province_name=Subquery( Location.objects.values("name").filter( - Q(path=Substr(OuterRef("location__path"), 1, 4)), Q(depth=1) + Q(path=Substr(OuterRef("location__path"), 1, 8)), Q(depth=2) )[:1] ) ) @@ -225,7 +225,7 @@ def load_va_data( user_vas_filtered.annotate( district_name=Subquery( Location.objects.values("name").filter( - Q(path=Substr(OuterRef("location__path"), 1, 8)), Q(depth=2) + Q(path=Substr(OuterRef("location__path"), 1, 12)), Q(depth=3) )[:1] ) ) From aaca7f3437bf3e37ef788482ecf5d80f962d3b65 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Fri, 8 Mar 2024 15:04:31 -0500 Subject: [PATCH 09/26] FIX: change how we flag to the users what Errors and Warnings occur due to location matches --- .../va_data_management/utils/validate.py | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/va_explorer/va_data_management/utils/validate.py b/va_explorer/va_data_management/utils/validate.py index 614ee57b..0cbc8993 100644 --- a/va_explorer/va_data_management/utils/validate.py +++ b/va_explorer/va_data_management/utils/validate.py @@ -112,10 +112,11 @@ def validate_vas_for_dashboard(verbal_autopsies): issues.append(issue) # if location is valid but inactive record a warning - if va.location and not va.location.is_active: + if va.location and not va.location.is_active and not va.location.name.casefold() == "unknown" and not va.hospital.casefold() == "other": + issue_text = "Warning: VA location was matched to facility known \ to be inactive. Consider updating the location to an active \ - facility instead." + facility instead, or update the facility list." issue = CauseCodingIssue( verbalautopsy_id=va.id, text=issue_text, @@ -127,10 +128,10 @@ def validate_vas_for_dashboard(verbal_autopsies): # if location is "Other" (a valid, but non-informative location stemming # stemming from bad data) record a warning - if va.location and va.location.name.casefold() == "Other Facility": - issue_text = "Warning: location field (parsed from hospital): provided \ - location was parsed as 'Other Facility'. Will not show on dashboards \ - until underlying data is corrected to actual location." + if va.location and va.location.name.casefold() == "unknown" and va.hospital.casefold() == "other": + issue_text = "Warning: location field (parsed from hospital) \ + was parsed as 'Other Facility'. May not fully show on \ + dashboards until underlying data is corrected to actual location." issue = CauseCodingIssue( verbalautopsy_id=va.id, text=issue_text, @@ -142,13 +143,15 @@ def validate_vas_for_dashboard(verbal_autopsies): # if location is "Unknown" (couldn't find match for provided location) # record a warning - if va.location and va.location.name.casefold() == "Unknown": - issue_text = "Warning: location field (parsed from hospital): provided \ - location was not a known facility. Set location to 'Unknown'" + if va.location and va.location.name.casefold() == "unknown" and not va.hospital.casefold() == "other": + issue_text = "ERROR: location field (parsed from hospital) did not \ + match any known facilities in the facility list. VA Explorer set \ + the location to 'Unknown.' This VA will not show on \ + dashboards until underlying data is corrected to actual location." issue = CauseCodingIssue( verbalautopsy_id=va.id, text=issue_text, - severity="warning", + severity="error", algorithm="", settings="", ) From fae9ce591a65427113aca9b68cf5783c3ba6caa7 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Fri, 8 Mar 2024 17:17:45 -0500 Subject: [PATCH 10/26] ADD: new management command to refresh locations for existing VA data --- .../management/commands/refresh_locations.py | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 va_explorer/va_data_management/management/commands/refresh_locations.py diff --git a/va_explorer/va_data_management/management/commands/refresh_locations.py b/va_explorer/va_data_management/management/commands/refresh_locations.py new file mode 100644 index 00000000..49224844 --- /dev/null +++ b/va_explorer/va_data_management/management/commands/refresh_locations.py @@ -0,0 +1,57 @@ +import argparse + +import pandas as pd +from django.core.management.base import BaseCommand + +from va_explorer.va_data_management.models import Location, VerbalAutopsy +from va_explorer.va_data_management.utils.location_assignment import assign_va_location +from va_explorer.va_data_management.utils.validate import validate_vas_for_dashboard + + +class Command(BaseCommand): + help = "Reassigns locations based on most recent facility list" + + # def add_arguments(self, parser): + # # parser.add_argument("csv_file", type=argparse.FileType("r")) + # # parser.add_argument("--random_locations", type=str, nargs="?", default=False) + + def handle(self, *args, **options): + + # verbal_autopsies = VerbalAutopsy.objects + count = VerbalAutopsy.objects.count() + print("Refreshing locations for all " + str(count) + " VAs in the database.") + + location_map = {} + + verbal_autopsies = list( + VerbalAutopsy.objects.filter()[0:count] + ) + + # build location mapper to map csv locations to known db locations + h = [va.hospital for va in verbal_autopsies] + # using list comprehension to remove duplicated from list + hospitals = [] + [hospitals.append(x) for x in h if x not in hospitals] + + location_map = { + key_name_pair[0]: key_name_pair[1] + for key_name_pair in Location.objects.filter(key__in=hospitals) + .only("name", "key") + .values_list("key", "name") + } + + changedcount = 0 + + for va in verbal_autopsies: + oldlocation = va.location + newva = assign_va_location(va, location_map) + newlocation = newva.location + + if oldlocation != newlocation: + changedcount += 1 + va.location = newva.location + va.save_without_historical_record() + validate_vas_for_dashboard(va) + + + print(" changed locations for " + str(changedcount) + " VA(s).") From 66b5bc514b05caa5189ea3bd1db8af1a1120661a Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Fri, 8 Mar 2024 17:19:33 -0500 Subject: [PATCH 11/26] FIX: when a row is deleted from the locations CSV and it already exists in the data model, mark it as inactive instead of deleting --- .../management/commands/load_locations.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/va_explorer/va_data_management/management/commands/load_locations.py b/va_explorer/va_data_management/management/commands/load_locations.py index 2057089f..4c111ddc 100644 --- a/va_explorer/va_data_management/management/commands/load_locations.py +++ b/va_explorer/va_data_management/management/commands/load_locations.py @@ -251,8 +251,11 @@ def _process_facility_tree(tree, delete_previous=False): extras = set(db_paths) - set(paths) if extras: for extra in extras: - Location.objects.filter(path_string=extra).delete() - delete_ct += 1 + if str(extra).count('/')==4: ##i.e., if it is level 5 (hospital) + node = db.get(extra, None) + node.is_active = False + node.save() + delete_ct += 1 # if non existent, add 'Null' location to database to account for VAs with # completely unknown locations @@ -265,4 +268,4 @@ def _process_facility_tree(tree, delete_previous=False): print(f" added {location_ct} new locations to system") print(f" updated {update_ct} locations with new data") - print(f" deleted {delete_ct} locations no longer in csv_file") + print(f" marked {delete_ct} locations as inactive") From 779e125303b4b97387cf81933876c0279378e893 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Fri, 8 Mar 2024 18:29:42 -0500 Subject: [PATCH 12/26] added management command to export the current list of locations to a CSV, for updating purposes --- .../management/commands/export_locations.py | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 va_explorer/va_data_management/management/commands/export_locations.py diff --git a/va_explorer/va_data_management/management/commands/export_locations.py b/va_explorer/va_data_management/management/commands/export_locations.py new file mode 100644 index 00000000..96ad4d73 --- /dev/null +++ b/va_explorer/va_data_management/management/commands/export_locations.py @@ -0,0 +1,60 @@ +import argparse + +import pandas as pd +from datetime import datetime +from django.core.management.base import BaseCommand + +from va_explorer.va_data_management.models import Location, VerbalAutopsy +from va_explorer.va_data_management.utils.location_assignment import assign_va_location +from va_explorer.va_data_management.utils.validate import validate_vas_for_dashboard + + +class Command(BaseCommand): + help = "Exports current facility list as a CSV" + + def add_arguments(self, parser): + parser.add_argument( + "--output_file", type=str, nargs="?", default="locations_"+datetime.now().strftime("%Y_%m_%d-%I_%M_%S_%p")+".csv" + ) + + def handle(self, *args, **options): + location_map = {} + count = Location.objects.count() + locations = list( + Location.objects.filter(location_type = "facility").all() + ) + + keys = [location.path_string for location in locations] + loc_df = pd.DataFrame( + {'path_string':keys} + ) + + loc_df[['null', 'country', 'province', 'district', 'name']] = loc_df['path_string'].str.split('\/', expand=True) + + loc_df["key"] = "" + loc_df["status"] = "" + + for index, row in loc_df.iterrows(): + loc = Location.objects.filter(path_string = row["path_string"]) + row["key"] = [location.key for location in loc][0] + + status_b = [location.is_active for location in loc][0] + row["status"] = "Active" if status_b else "Inactive" + + loc_df = loc_df.drop(columns=['path_string', 'null', 'country']) + + loc_df = loc_df.loc[loc_df['name'] != "Unknown"] + + loc_df = loc_df[["province", "district", "name", "key", "status"]] + + + fname = options["output_file"] + + try: + loc_df.to_csv(fname, index=False) + print(f"Exported current location file to {fname}") + except Exception as err: + print( + f"Error {err} occurred while exporting location file. Check \ + provided filename is a valid path." + ) From 9925222dcb32596fe6f6d016641ad40c9b942a84 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Fri, 8 Mar 2024 19:07:06 -0500 Subject: [PATCH 13/26] FIX: on loading locations, only mark one inactive if it is not already inactive --- .../management/commands/load_locations.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/va_explorer/va_data_management/management/commands/load_locations.py b/va_explorer/va_data_management/management/commands/load_locations.py index 4c111ddc..2af91dfc 100644 --- a/va_explorer/va_data_management/management/commands/load_locations.py +++ b/va_explorer/va_data_management/management/commands/load_locations.py @@ -253,9 +253,10 @@ def _process_facility_tree(tree, delete_previous=False): for extra in extras: if str(extra).count('/')==4: ##i.e., if it is level 5 (hospital) node = db.get(extra, None) - node.is_active = False - node.save() - delete_ct += 1 + if (node.is_active): + node.is_active = False + node.save() + delete_ct += 1 # if non existent, add 'Null' location to database to account for VAs with # completely unknown locations From 9652ed60d1c95d826dd00b6b05378271993eb2ab Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Wed, 20 Mar 2024 10:37:27 -0400 Subject: [PATCH 14/26] bug fix in refresh locations management command --- .../management/commands/refresh_locations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/va_explorer/va_data_management/management/commands/refresh_locations.py b/va_explorer/va_data_management/management/commands/refresh_locations.py index 49224844..23e0f2ea 100644 --- a/va_explorer/va_data_management/management/commands/refresh_locations.py +++ b/va_explorer/va_data_management/management/commands/refresh_locations.py @@ -39,7 +39,6 @@ def handle(self, *args, **options): .only("name", "key") .values_list("key", "name") } - changedcount = 0 for va in verbal_autopsies: @@ -51,7 +50,8 @@ def handle(self, *args, **options): changedcount += 1 va.location = newva.location va.save_without_historical_record() - validate_vas_for_dashboard(va) + + validate_vas_for_dashboard(verbal_autopsies) print(" changed locations for " + str(changedcount) + " VA(s).") From 9b65bbc0b8405d0cfff203816110fd453facbd19 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Wed, 20 Mar 2024 10:37:50 -0400 Subject: [PATCH 15/26] updated user guides to reflect new location management commands --- docs/training/admin_guides.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/training/admin_guides.md b/docs/training/admin_guides.md index 33a0a8c0..deca13f4 100644 --- a/docs/training/admin_guides.md +++ b/docs/training/admin_guides.md @@ -51,7 +51,7 @@ Marin County, Los Angeles County, Sausalito, San Rafael, and Los Angeles. #### Updating locations in VA Explorer -When VAs are imported into VA Explorer, they are matched exactly on the locations loaded into the system in this step. If a VA does not have a valid location field, VA Explorer will track that mismatch as an error that either needs to be corrected in the VA Explorer locations file or in the underlying VA data. To add a location to VA Explorer, re-upload a revised location file following the `load_locations` management command. If a row is deleted from the locations file, it will also be deletd from VA Explorer (and any underlying VA data previously matched to that location will no longer match and have an error). +When VAs are imported into VA Explorer, they are matched exactly on the locations loaded into the system in this step. If a VA does not have a valid location field, VA Explorer will track that mismatch as an error that either needs to be corrected in the VA Explorer locations file or in the underlying VA data. To add a location to VA Explorer, re-upload a revised location file following the `load_locations` management command. If a row is deleted from the locations file, it will also be kept in VA Explorer and marked inactive. To permanently delete locations in VA Explorer, re-upload a revised location file following the `load_locations` management command with the `--delete_previous` flag. Warning: doing so may delete all VAs in the database, so make sure to backup the system first. ### Creating & Editing Users @@ -176,7 +176,7 @@ generally useful to admins. An even fuller list of these can be found under * - :rspan:`1` ``load_locations`` - ``--csv_file`` (*) - - :rspan:`1` Used to load initial location date data needed to support + - :rspan:`1` Used to load initial location data needed to support Geographic access. ``csv_file`` is a filename in the local folder or ``unix:path`` format location of the file. Can be used with ``delete_previous`` to delete existing location data and start fresh with @@ -185,6 +185,25 @@ generally useful to admins. An even fuller list of these can be found under * - ``--delete_previous`` + * - :rspan:`1` ``refresh_locations`` + - :rspan:`1` Used to refresh the locations assigned to all of the VAs in + the database if a new location file is loaded into the system using the + ``load_locations`` management command. This command does not add or + delete any VAs from the database; it simply remaps the existing VAs + to the new locations. + + * - :rspan:`1` ``export_locations`` + - ``--output_file`` + - :rspan:`1` Utility to obtainthe current list of locations in the VA + Explorer system in the CSV format with header fields + corresponding to fields expected by the system. The intended use case + for this utility is when administrators need to update the location file + by first downloading the existing locations, making any necessary updates, + and re-uploading a revised version using ``load_locations``. ``output_file`` + is a filename or ``unix:path`` format location to save template to. Default is + ``locations_[[date]].csv`` where [[date]] is the date and time of export. + + * - :rspan:`1` ``run_coding_algorithms`` - ``--overwrite`` - :rspan:`1` Used to call supported algorithms for assignment of cause of From f6bb5255dac606217c740735f3569bba82148d91 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Wed, 20 Mar 2024 10:45:42 -0400 Subject: [PATCH 16/26] added yes/no catch to uploading a new location file with delete_previous=T --- .../va_data_management/management/commands/load_locations.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/va_explorer/va_data_management/management/commands/load_locations.py b/va_explorer/va_data_management/management/commands/load_locations.py index 2af91dfc..5a06fd0a 100644 --- a/va_explorer/va_data_management/management/commands/load_locations.py +++ b/va_explorer/va_data_management/management/commands/load_locations.py @@ -180,7 +180,10 @@ def _process_facility_tree(tree, delete_previous=False): """ # Clear out existing locations if requested (typically for initialization only) if delete_previous: - Location.objects.all().delete() + answer = input("Loading a new location file with delete_previous=True may delete all of the VAs currently in the VAE database. By continuining, please make sure you have a backup of all data. Are you sure you want to continue? yes/no ") + if answer.upper() in ["Y", "YES"]: + Location.objects.all().delete() + # Only consider fields in both input and Location schema db_fields = {field.name for field in Location._meta.get_fields()} From 4ec3c4097cfc5ea72247b9a88061796c5ed6661e Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Wed, 20 Mar 2024 11:33:58 -0400 Subject: [PATCH 17/26] fix lint errors --- .../management/commands/export_locations.py | 19 +++++++------------ .../management/commands/load_locations.py | 8 ++++---- .../management/commands/refresh_locations.py | 8 +++----- .../commands/run_coding_algorithms.py | 4 +--- .../va_data_management/utils/multi_select.py | 2 +- .../va_data_management/utils/validate.py | 6 +++--- 6 files changed, 19 insertions(+), 28 deletions(-) diff --git a/va_explorer/va_data_management/management/commands/export_locations.py b/va_explorer/va_data_management/management/commands/export_locations.py index 96ad4d73..61acf4e5 100644 --- a/va_explorer/va_data_management/management/commands/export_locations.py +++ b/va_explorer/va_data_management/management/commands/export_locations.py @@ -1,12 +1,10 @@ -import argparse -import pandas as pd from datetime import datetime + +import pandas as pd from django.core.management.base import BaseCommand -from va_explorer.va_data_management.models import Location, VerbalAutopsy -from va_explorer.va_data_management.utils.location_assignment import assign_va_location -from va_explorer.va_data_management.utils.validate import validate_vas_for_dashboard +from va_explorer.va_data_management.models import Location class Command(BaseCommand): @@ -18,8 +16,6 @@ def add_arguments(self, parser): ) def handle(self, *args, **options): - location_map = {} - count = Location.objects.count() locations = list( Location.objects.filter(location_type = "facility").all() ) @@ -28,8 +24,8 @@ def handle(self, *args, **options): loc_df = pd.DataFrame( {'path_string':keys} ) - - loc_df[['null', 'country', 'province', 'district', 'name']] = loc_df['path_string'].str.split('\/', expand=True) + + loc_df[['null', 'country', 'province', 'district', 'name']] = loc_df['path_string'].str.split(r'\/', expand=True) loc_df["key"] = "" loc_df["status"] = "" @@ -43,10 +39,9 @@ def handle(self, *args, **options): loc_df = loc_df.drop(columns=['path_string', 'null', 'country']) - loc_df = loc_df.loc[loc_df['name'] != "Unknown"] - - loc_df = loc_df[["province", "district", "name", "key", "status"]] + loc_df = loc_df.loc[(loc_df['name'].notnull()) & (loc_df['province'].notnull()) & (loc_df['district'].notnull()) ] + loc_df = loc_df[["province", "district", "name", "key", "status"]] fname = options["output_file"] diff --git a/va_explorer/va_data_management/management/commands/load_locations.py b/va_explorer/va_data_management/management/commands/load_locations.py index 5a06fd0a..f949d3ef 100644 --- a/va_explorer/va_data_management/management/commands/load_locations.py +++ b/va_explorer/va_data_management/management/commands/load_locations.py @@ -145,12 +145,12 @@ def _treeify_facilities(csv_file): d_node = node_lookup[(p_node.name, district)] else: d_node = Node(district, location_type="district", parent=p_node) - node_lookup[tuple([p_node.name, district])] = d_node + node_lookup[(p_node.name, district)] = d_node node_lookup[(p_node.name, district)] = d_node if name != "" and d_node is not None: if _has_child(d_node, name): - f_node = node_lookup[tuple([d_node.name, name])] + f_node = node_lookup[(d_node.name, name)] f_node = node_lookup[(d_node.name, name)] else: f_node = Node(name, location_type="facility", parent=d_node) @@ -183,7 +183,7 @@ def _process_facility_tree(tree, delete_previous=False): answer = input("Loading a new location file with delete_previous=True may delete all of the VAs currently in the VAE database. By continuining, please make sure you have a backup of all data. Are you sure you want to continue? yes/no ") if answer.upper() in ["Y", "YES"]: Location.objects.all().delete() - + # Only consider fields in both input and Location schema db_fields = {field.name for field in Location._meta.get_fields()} @@ -255,7 +255,7 @@ def _process_facility_tree(tree, delete_previous=False): if extras: for extra in extras: if str(extra).count('/')==4: ##i.e., if it is level 5 (hospital) - node = db.get(extra, None) + node = db.get(extra) if (node.is_active): node.is_active = False node.save() diff --git a/va_explorer/va_data_management/management/commands/refresh_locations.py b/va_explorer/va_data_management/management/commands/refresh_locations.py index 23e0f2ea..09bb7656 100644 --- a/va_explorer/va_data_management/management/commands/refresh_locations.py +++ b/va_explorer/va_data_management/management/commands/refresh_locations.py @@ -1,6 +1,4 @@ -import argparse -import pandas as pd from django.core.management.base import BaseCommand from va_explorer.va_data_management.models import Location, VerbalAutopsy @@ -38,19 +36,19 @@ def handle(self, *args, **options): for key_name_pair in Location.objects.filter(key__in=hospitals) .only("name", "key") .values_list("key", "name") - } + } changedcount = 0 for va in verbal_autopsies: oldlocation = va.location newva = assign_va_location(va, location_map) newlocation = newva.location - + if oldlocation != newlocation: changedcount += 1 va.location = newva.location va.save_without_historical_record() - + validate_vas_for_dashboard(verbal_autopsies) diff --git a/va_explorer/va_data_management/management/commands/run_coding_algorithms.py b/va_explorer/va_data_management/management/commands/run_coding_algorithms.py index 12537cc3..5c262d8f 100644 --- a/va_explorer/va_data_management/management/commands/run_coding_algorithms.py +++ b/va_explorer/va_data_management/management/commands/run_coding_algorithms.py @@ -36,9 +36,7 @@ def handle(self, **options): num_issues = len(stats["issues"]) self.stdout.write(f"DONE. Total time: {time.time() - ti} secs") self.stdout.write( - "Coded {} verbal autopsies (out of {}) [{} issues]".format( - num_coded, num_total, num_issues - ) + f"Coded {num_coded} verbal autopsies (out of {num_total}) [{num_issues} issues]" ) else: print( diff --git a/va_explorer/va_data_management/utils/multi_select.py b/va_explorer/va_data_management/utils/multi_select.py index 3a84fb47..1fb07cd9 100644 --- a/va_explorer/va_data_management/utils/multi_select.py +++ b/va_explorer/va_data_management/utils/multi_select.py @@ -172,7 +172,7 @@ def get_list(obj): display = [] if getattr(obj, fieldname): for value in getattr(obj, fieldname): - item_display = choicedict.get(value, None) + item_display = choicedict.get(value) if item_display is None: try: item_display = choicedict.get(int(value), value) diff --git a/va_explorer/va_data_management/utils/validate.py b/va_explorer/va_data_management/utils/validate.py index 0cbc8993..bda92154 100644 --- a/va_explorer/va_data_management/utils/validate.py +++ b/va_explorer/va_data_management/utils/validate.py @@ -112,8 +112,8 @@ def validate_vas_for_dashboard(verbal_autopsies): issues.append(issue) # if location is valid but inactive record a warning - if va.location and not va.location.is_active and not va.location.name.casefold() == "unknown" and not va.hospital.casefold() == "other": - + if va.location and not va.location.is_active and va.location.name.casefold() != "unknown" and va.hospital.casefold() != "other": + issue_text = "Warning: VA location was matched to facility known \ to be inactive. Consider updating the location to an active \ facility instead, or update the facility list." @@ -143,7 +143,7 @@ def validate_vas_for_dashboard(verbal_autopsies): # if location is "Unknown" (couldn't find match for provided location) # record a warning - if va.location and va.location.name.casefold() == "unknown" and not va.hospital.casefold() == "other": + if va.location and va.location.name.casefold() == "unknown" and va.hospital.casefold() != "other": issue_text = "ERROR: location field (parsed from hospital) did not \ match any known facilities in the facility list. VA Explorer set \ the location to 'Unknown.' This VA will not show on \ From a65a86cada9fcb83c0693e3934c8cb028fa59ffb Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Wed, 20 Mar 2024 11:36:10 -0400 Subject: [PATCH 18/26] fix lint errors - one more --- .../va_data_management/management/commands/export_locations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/va_explorer/va_data_management/management/commands/export_locations.py b/va_explorer/va_data_management/management/commands/export_locations.py index 61acf4e5..31be4a8a 100644 --- a/va_explorer/va_data_management/management/commands/export_locations.py +++ b/va_explorer/va_data_management/management/commands/export_locations.py @@ -30,7 +30,7 @@ def handle(self, *args, **options): loc_df["key"] = "" loc_df["status"] = "" - for index, row in loc_df.iterrows(): + for _, row in loc_df.iterrows(): loc = Location.objects.filter(path_string = row["path_string"]) row["key"] = [location.key for location in loc][0] From d6c1694446de659d3e232daf3d8f1c9a79eea050 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Wed, 20 Mar 2024 11:38:02 -0400 Subject: [PATCH 19/26] fixed black formatting errors --- config/settings/base.py | 1 + config/wsgi.py | 1 + va_explorer/home/va_trends.py | 12 +++---- va_explorer/users/views.py | 6 ++-- va_explorer/va_analytics/utils/loading.py | 3 +- va_explorer/va_data_cleanup/views.py | 8 +++-- .../management/commands/export_locations.py | 32 +++++++++++-------- .../management/commands/load_locations.py | 9 +++--- .../management/commands/refresh_locations.py | 16 ++++------ .../va_data_management/utils/validate.py | 19 +++++++++-- va_explorer/va_data_management/views.py | 6 ++-- 11 files changed, 67 insertions(+), 46 deletions(-) diff --git a/config/settings/base.py b/config/settings/base.py index 79b909f4..fb5729da 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -1,6 +1,7 @@ """ Base settings to build other settings files upon. """ + import os from pathlib import Path diff --git a/config/wsgi.py b/config/wsgi.py index d7a675f1..66f0e786 100644 --- a/config/wsgi.py +++ b/config/wsgi.py @@ -13,6 +13,7 @@ framework. """ + import os from django.core.wsgi import get_wsgi_application diff --git a/va_explorer/home/va_trends.py b/va_explorer/home/va_trends.py index 0c48be4f..252c2517 100644 --- a/va_explorer/home/va_trends.py +++ b/va_explorer/home/va_trends.py @@ -77,14 +77,14 @@ def get_context_for_va_table(va_list, user): "id": va.id, "deceased": f"{va.Id10017} {va.Id10018}", "interviewer": va.Id10010, - "interviewed": parse_date(va.Id10012) - if (va.Id10012 != "dk") - else "Unknown", + "interviewed": ( + parse_date(va.Id10012) if (va.Id10012 != "dk") else "Unknown" + ), "dod": parse_date(va.Id10023) if (va.Id10023 != "dk") else "Unknown", "facility": va.location.name if va.location else "Not Provided", - "cause": va.causes.all()[0].cause - if len(va.causes.all()) > 0 - else "Not Coded", + "cause": ( + va.causes.all()[0].cause if len(va.causes.all()) > 0 else "Not Coded" + ), "warnings": len( [ issue diff --git a/va_explorer/users/views.py b/va_explorer/users/views.py index d3e90d21..799068d4 100644 --- a/va_explorer/users/views.py +++ b/va_explorer/users/views.py @@ -109,9 +109,9 @@ def get_initial(self): if self.get_object().location_restrictions.exists() else "national" ) - initial[ - "facility_restrictions" - ] = self.get_object().location_restrictions.filter(location_type="facility") + initial["facility_restrictions"] = ( + self.get_object().location_restrictions.filter(location_type="facility") + ) initial["view_pii"] = self.get_object().can_view_pii initial["download_data"] = self.get_object().can_download_data diff --git a/va_explorer/va_analytics/utils/loading.py b/va_explorer/va_analytics/utils/loading.py index b74ec849..ea66f306 100644 --- a/va_explorer/va_analytics/utils/loading.py +++ b/va_explorer/va_analytics/utils/loading.py @@ -85,7 +85,8 @@ def load_va_data( user_vas_filtered.annotate( district_name=Subquery( Location.objects.values("name").filter( - Q(path=Substr(OuterRef("location__path"), 1, 12)), Q(depth=3) + Q(path=Substr(OuterRef("location__path"), 1, 12)), + Q(depth=3), )[:1] ) ) diff --git a/va_explorer/va_data_cleanup/views.py b/va_explorer/va_data_cleanup/views.py index 85863740..649f03ca 100644 --- a/va_explorer/va_data_cleanup/views.py +++ b/va_explorer/va_data_cleanup/views.py @@ -54,9 +54,11 @@ def get_context_data(self, **kwargs): "dod": parse_date(va.Id10023) if (va.Id10023 != "dk") else "Unknown", "facility": va.location.name if va.location else "Not Provided", "deceased": va.deceased, - "cause": va.causes.all()[0].cause - if len(va.causes.all()) > 0 - else "Not Coded", + "cause": ( + va.causes.all()[0].cause + if len(va.causes.all()) > 0 + else "Not Coded" + ), "warnings": len( [ issue diff --git a/va_explorer/va_data_management/management/commands/export_locations.py b/va_explorer/va_data_management/management/commands/export_locations.py index 31be4a8a..0537c19f 100644 --- a/va_explorer/va_data_management/management/commands/export_locations.py +++ b/va_explorer/va_data_management/management/commands/export_locations.py @@ -1,4 +1,3 @@ - from datetime import datetime import pandas as pd @@ -12,34 +11,41 @@ class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument( - "--output_file", type=str, nargs="?", default="locations_"+datetime.now().strftime("%Y_%m_%d-%I_%M_%S_%p")+".csv" + "--output_file", + type=str, + nargs="?", + default="locations_" + + datetime.now().strftime("%Y_%m_%d-%I_%M_%S_%p") + + ".csv", ) def handle(self, *args, **options): - locations = list( - Location.objects.filter(location_type = "facility").all() - ) + locations = list(Location.objects.filter(location_type="facility").all()) keys = [location.path_string for location in locations] - loc_df = pd.DataFrame( - {'path_string':keys} - ) + loc_df = pd.DataFrame({"path_string": keys}) - loc_df[['null', 'country', 'province', 'district', 'name']] = loc_df['path_string'].str.split(r'\/', expand=True) + loc_df[["null", "country", "province", "district", "name"]] = loc_df[ + "path_string" + ].str.split(r"\/", expand=True) loc_df["key"] = "" loc_df["status"] = "" for _, row in loc_df.iterrows(): - loc = Location.objects.filter(path_string = row["path_string"]) + loc = Location.objects.filter(path_string=row["path_string"]) row["key"] = [location.key for location in loc][0] status_b = [location.is_active for location in loc][0] - row["status"] = "Active" if status_b else "Inactive" + row["status"] = "Active" if status_b else "Inactive" - loc_df = loc_df.drop(columns=['path_string', 'null', 'country']) + loc_df = loc_df.drop(columns=["path_string", "null", "country"]) - loc_df = loc_df.loc[(loc_df['name'].notnull()) & (loc_df['province'].notnull()) & (loc_df['district'].notnull()) ] + loc_df = loc_df.loc[ + (loc_df["name"].notnull()) + & (loc_df["province"].notnull()) + & (loc_df["district"].notnull()) + ] loc_df = loc_df[["province", "district", "name", "key", "status"]] diff --git a/va_explorer/va_data_management/management/commands/load_locations.py b/va_explorer/va_data_management/management/commands/load_locations.py index f949d3ef..ca99949d 100644 --- a/va_explorer/va_data_management/management/commands/load_locations.py +++ b/va_explorer/va_data_management/management/commands/load_locations.py @@ -180,11 +180,12 @@ def _process_facility_tree(tree, delete_previous=False): """ # Clear out existing locations if requested (typically for initialization only) if delete_previous: - answer = input("Loading a new location file with delete_previous=True may delete all of the VAs currently in the VAE database. By continuining, please make sure you have a backup of all data. Are you sure you want to continue? yes/no ") + answer = input( + "Loading a new location file with delete_previous=True may delete all of the VAs currently in the VAE database. By continuining, please make sure you have a backup of all data. Are you sure you want to continue? yes/no " + ) if answer.upper() in ["Y", "YES"]: Location.objects.all().delete() - # Only consider fields in both input and Location schema db_fields = {field.name for field in Location._meta.get_fields()} data_fields = set(vars(tree.leaves[0]).keys()) @@ -254,9 +255,9 @@ def _process_facility_tree(tree, delete_previous=False): extras = set(db_paths) - set(paths) if extras: for extra in extras: - if str(extra).count('/')==4: ##i.e., if it is level 5 (hospital) + if str(extra).count("/") == 4: ##i.e., if it is level 5 (hospital) node = db.get(extra) - if (node.is_active): + if node.is_active: node.is_active = False node.save() delete_ct += 1 diff --git a/va_explorer/va_data_management/management/commands/refresh_locations.py b/va_explorer/va_data_management/management/commands/refresh_locations.py index 09bb7656..ac572fb1 100644 --- a/va_explorer/va_data_management/management/commands/refresh_locations.py +++ b/va_explorer/va_data_management/management/commands/refresh_locations.py @@ -1,4 +1,3 @@ - from django.core.management.base import BaseCommand from va_explorer.va_data_management.models import Location, VerbalAutopsy @@ -21,9 +20,7 @@ def handle(self, *args, **options): location_map = {} - verbal_autopsies = list( - VerbalAutopsy.objects.filter()[0:count] - ) + verbal_autopsies = list(VerbalAutopsy.objects.filter()[0:count]) # build location mapper to map csv locations to known db locations h = [va.hospital for va in verbal_autopsies] @@ -32,11 +29,11 @@ def handle(self, *args, **options): [hospitals.append(x) for x in h if x not in hospitals] location_map = { - key_name_pair[0]: key_name_pair[1] - for key_name_pair in Location.objects.filter(key__in=hospitals) - .only("name", "key") - .values_list("key", "name") - } + key_name_pair[0]: key_name_pair[1] + for key_name_pair in Location.objects.filter(key__in=hospitals) + .only("name", "key") + .values_list("key", "name") + } changedcount = 0 for va in verbal_autopsies: @@ -51,5 +48,4 @@ def handle(self, *args, **options): validate_vas_for_dashboard(verbal_autopsies) - print(" changed locations for " + str(changedcount) + " VA(s).") diff --git a/va_explorer/va_data_management/utils/validate.py b/va_explorer/va_data_management/utils/validate.py index bda92154..80218de7 100644 --- a/va_explorer/va_data_management/utils/validate.py +++ b/va_explorer/va_data_management/utils/validate.py @@ -112,7 +112,12 @@ def validate_vas_for_dashboard(verbal_autopsies): issues.append(issue) # if location is valid but inactive record a warning - if va.location and not va.location.is_active and va.location.name.casefold() != "unknown" and va.hospital.casefold() != "other": + if ( + va.location + and not va.location.is_active + and va.location.name.casefold() != "unknown" + and va.hospital.casefold() != "other" + ): issue_text = "Warning: VA location was matched to facility known \ to be inactive. Consider updating the location to an active \ @@ -128,7 +133,11 @@ def validate_vas_for_dashboard(verbal_autopsies): # if location is "Other" (a valid, but non-informative location stemming # stemming from bad data) record a warning - if va.location and va.location.name.casefold() == "unknown" and va.hospital.casefold() == "other": + if ( + va.location + and va.location.name.casefold() == "unknown" + and va.hospital.casefold() == "other" + ): issue_text = "Warning: location field (parsed from hospital) \ was parsed as 'Other Facility'. May not fully show on \ dashboards until underlying data is corrected to actual location." @@ -143,7 +152,11 @@ def validate_vas_for_dashboard(verbal_autopsies): # if location is "Unknown" (couldn't find match for provided location) # record a warning - if va.location and va.location.name.casefold() == "unknown" and va.hospital.casefold() != "other": + if ( + va.location + and va.location.name.casefold() == "unknown" + and va.hospital.casefold() != "other" + ): issue_text = "ERROR: location field (parsed from hospital) did not \ match any known facilities in the facility list. VA Explorer set \ the location to 'Unknown.' This VA will not show on \ diff --git a/va_explorer/va_data_management/views.py b/va_explorer/va_data_management/views.py index 5bfeaa11..e24c89b5 100644 --- a/va_explorer/va_data_management/views.py +++ b/va_explorer/va_data_management/views.py @@ -115,9 +115,9 @@ def get_context_data(self, **kwargs): "deceased": va["deceased"], "interviewer": va["Id10010"], "interviewed": parse_date(va["Id10012"]), - "dod": parse_date(va["Id10023"]) - if (va["Id10023"] != "dk") - else "Unknown", + "dod": ( + parse_date(va["Id10023"]) if (va["Id10023"] != "dk") else "Unknown" + ), "facility": va["location__name"], "cause": va["causes__cause"], "warnings": va["warnings"], From 2fe0944c698fccd3f974be5e5afa3087a9ea4fe7 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Wed, 20 Mar 2024 11:41:06 -0400 Subject: [PATCH 20/26] fix black mismatch in views.py --- va_explorer/users/views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/va_explorer/users/views.py b/va_explorer/users/views.py index 799068d4..d3e90d21 100644 --- a/va_explorer/users/views.py +++ b/va_explorer/users/views.py @@ -109,9 +109,9 @@ def get_initial(self): if self.get_object().location_restrictions.exists() else "national" ) - initial["facility_restrictions"] = ( - self.get_object().location_restrictions.filter(location_type="facility") - ) + initial[ + "facility_restrictions" + ] = self.get_object().location_restrictions.filter(location_type="facility") initial["view_pii"] = self.get_object().can_view_pii initial["download_data"] = self.get_object().can_download_data From 53af11e6b927e1674f3f5dba8320b3ee0c526a69 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Wed, 20 Mar 2024 11:47:17 -0400 Subject: [PATCH 21/26] admin training guides formatting error --- docs/training/admin_guides.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/training/admin_guides.md b/docs/training/admin_guides.md index deca13f4..eecfa347 100644 --- a/docs/training/admin_guides.md +++ b/docs/training/admin_guides.md @@ -186,6 +186,7 @@ generally useful to admins. An even fuller list of these can be found under * - ``--delete_previous`` * - :rspan:`1` ``refresh_locations`` + - None - :rspan:`1` Used to refresh the locations assigned to all of the VAs in the database if a new location file is loaded into the system using the ``load_locations`` management command. This command does not add or @@ -194,7 +195,7 @@ generally useful to admins. An even fuller list of these can be found under * - :rspan:`1` ``export_locations`` - ``--output_file`` - - :rspan:`1` Utility to obtainthe current list of locations in the VA + - Utility to obtainthe current list of locations in the VA Explorer system in the CSV format with header fields corresponding to fields expected by the system. The intended use case for this utility is when administrators need to update the location file @@ -206,7 +207,7 @@ generally useful to admins. An even fuller list of these can be found under * - :rspan:`1` ``run_coding_algorithms`` - ``--overwrite`` - - :rspan:`1` Used to call supported algorithms for assignment of cause of + - Used to call supported algorithms for assignment of cause of death to all uncoded verbal autopsies. ``overwrite`` allows this command to clear (and save) all existing CoD assignments before running on every verbal autopsy regardless of whether it's coded or not. ``True`` or From 4fdc76c2cbecd466772ddd50616840fb7b2b8014 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Wed, 20 Mar 2024 11:49:41 -0400 Subject: [PATCH 22/26] remove blank lines for linting --- .../va_data_management/management/commands/refresh_locations.py | 1 - va_explorer/va_data_management/utils/validate.py | 1 - 2 files changed, 2 deletions(-) diff --git a/va_explorer/va_data_management/management/commands/refresh_locations.py b/va_explorer/va_data_management/management/commands/refresh_locations.py index ac572fb1..582dbbe5 100644 --- a/va_explorer/va_data_management/management/commands/refresh_locations.py +++ b/va_explorer/va_data_management/management/commands/refresh_locations.py @@ -13,7 +13,6 @@ class Command(BaseCommand): # # parser.add_argument("--random_locations", type=str, nargs="?", default=False) def handle(self, *args, **options): - # verbal_autopsies = VerbalAutopsy.objects count = VerbalAutopsy.objects.count() print("Refreshing locations for all " + str(count) + " VAs in the database.") diff --git a/va_explorer/va_data_management/utils/validate.py b/va_explorer/va_data_management/utils/validate.py index 80218de7..f0f58fd6 100644 --- a/va_explorer/va_data_management/utils/validate.py +++ b/va_explorer/va_data_management/utils/validate.py @@ -118,7 +118,6 @@ def validate_vas_for_dashboard(verbal_autopsies): and va.location.name.casefold() != "unknown" and va.hospital.casefold() != "other" ): - issue_text = "Warning: VA location was matched to facility known \ to be inactive. Consider updating the location to an active \ facility instead, or update the facility list." From e690dbe2926e0ce27416c9d473a3dd9809cbbaa3 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Wed, 20 Mar 2024 11:57:55 -0400 Subject: [PATCH 23/26] re-attempt for location admin guides in docs --- docs/training/admin_guides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/training/admin_guides.md b/docs/training/admin_guides.md index eecfa347..35a55a04 100644 --- a/docs/training/admin_guides.md +++ b/docs/training/admin_guides.md @@ -187,7 +187,7 @@ generally useful to admins. An even fuller list of these can be found under * - :rspan:`1` ``refresh_locations`` - None - - :rspan:`1` Used to refresh the locations assigned to all of the VAs in + - Used to refresh the locations assigned to all of the VAs in the database if a new location file is loaded into the system using the ``load_locations`` management command. This command does not add or delete any VAs from the database; it simply remaps the existing VAs From f6a6c86ea83c65e2c299a5733e0265b9f4b698fd Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Wed, 20 Mar 2024 12:03:19 -0400 Subject: [PATCH 24/26] re-attempt for location admin guides in docs - redo --- docs/training/admin_guides.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/training/admin_guides.md b/docs/training/admin_guides.md index 35a55a04..71e4ff29 100644 --- a/docs/training/admin_guides.md +++ b/docs/training/admin_guides.md @@ -185,7 +185,7 @@ generally useful to admins. An even fuller list of these can be found under * - ``--delete_previous`` - * - :rspan:`1` ``refresh_locations`` + * - ``refresh_locations`` - None - Used to refresh the locations assigned to all of the VAs in the database if a new location file is loaded into the system using the @@ -193,7 +193,7 @@ generally useful to admins. An even fuller list of these can be found under delete any VAs from the database; it simply remaps the existing VAs to the new locations. - * - :rspan:`1` ``export_locations`` + * - ``export_locations`` - ``--output_file`` - Utility to obtainthe current list of locations in the VA Explorer system in the CSV format with header fields From f7b0e4743d117e56b4699aeba2c8c6a0f5350c15 Mon Sep 17 00:00:00 2001 From: Matt Boyas Date: Wed, 20 Mar 2024 12:07:37 -0400 Subject: [PATCH 25/26] rename North-Western to North_Western in static geojson to force map to parallel the formatting in the data --- va_explorer/static/data/zambia_geojson.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/va_explorer/static/data/zambia_geojson.json b/va_explorer/static/data/zambia_geojson.json index b4343838..98c144ea 100644 --- a/va_explorer/static/data/zambia_geojson.json +++ b/va_explorer/static/data/zambia_geojson.json @@ -12,7 +12,7 @@ { "type": "Feature", "properties": { "area_id": "ZMB_1_16", "area_name": "Northern", "area_level": 1.0, "parent_area_id": "ZMB", "spectrum_region_code": 16.0, "area_sort_order": 8, "center_x": 31.053795996935598, "center_y": -9.8893844, "area_level_label": "Province", "display": true, "spectrum_level": true, "epp_level": true, "naomi_level": false, "pepfar_psnu_level": false }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 30.650963699999874, -11.334511499999817 ], [ 30.623350200000058, -11.335783100000262 ], [ 30.600625500000326, -11.342184899999969 ], [ 30.606971600000119, -11.363646800000357 ], [ 30.59285340000028, -11.39279610000024 ], [ 30.584154400000372, -11.398667599999806 ], [ 30.547789400000351, -11.406635700000075 ], [ 30.548332099999872, -11.426497599999912 ], [ 30.53987470000018, -11.447381800000439 ], [ 30.501655899999555, -11.48937979999957 ], [ 30.46920899999974, -11.506145299999897 ], [ 30.469166700000279, -11.506238899999921 ], [ 30.46309319999968, -11.499679499999809 ], [ 30.461362499999822, -11.498848800000053 ], [ 30.464337899999762, -11.490876300000233 ], [ 30.115137899999869, -11.221376299999619 ], [ 30.003437899999941, -11.228076299999763 ], [ 29.819393199999951, -11.427599499999921 ], [ 29.813337899999954, -11.41217630000043 ], [ 29.909837900000394, -11.011276300000395 ], [ 29.864537899999814, -10.86727630000007 ], [ 29.843237899999785, -10.8533763 ], [ 29.826637900000399, -10.815376299999965 ], [ 29.787137899999809, -10.797776300000232 ], [ 29.767637900000427, -10.769976300000282 ], [ 29.7272379, -10.740876300000089 ], [ 29.659737900000376, -10.704076299999667 ], [ 29.637737899999944, -10.701876299999899 ], [ 29.60893790000036, -10.7055763 ], [ 29.590237899999771, -10.720176299999892 ], [ 29.589537900000266, -10.742676299999738 ], [ 29.578037899999568, -10.759076299999764 ], [ 29.537737900000192, -10.765476300000174 ], [ 29.50863790000005, -10.77737629999967 ], [ 29.486737899999802, -10.803376299999895 ], [ 29.449237900000231, -10.823076300000386 ], [ 29.431037899999673, -10.838176299999661 ], [ 29.402637899999934, -10.847476299999755 ], [ 29.370137899999769, -10.875476299999658 ], [ 29.360737900000274, -10.896076300000082 ], [ 29.361137900000116, -10.912676299999767 ], [ 29.375437899999728, -10.930776299999847 ], [ 29.401537899999685, -10.952476300000436 ], [ 29.39433789999979, -11.000476299999903 ], [ 29.428037900000394, -11.031176300000405 ], [ 29.427837900000018, -11.09117630000007 ], [ 29.393737899999575, -11.105476300000381 ], [ 29.37763790000022, -11.102376300000108 ], [ 29.360237900000243, -11.075976299999981 ], [ 29.304637900000298, -11.067076300000158 ], [ 29.292437900000103, -11.059876299999793 ], [ 29.28263789999987, -11.041476299999987 ], [ 29.263337899999961, -11.028576300000111 ], [ 29.2488379, -11.0081763 ], [ 29.206037899999554, -10.974676300000038 ], [ 29.0887379, -10.924876300000017 ], [ 29.090837900000317, -10.920576299999617 ], [ 29.091792399999758, -10.919868100000359 ], [ 29.116967700000046, -10.899016500000354 ], [ 29.122369399999879, -10.894742400000123 ], [ 29.154237900000371, -10.891976299999849 ], [ 29.15429689999986, -10.891906700000277 ], [ 29.180929200000282, -10.870234399999806 ], [ 29.194892100000306, -10.860224499999841 ], [ 29.201706200000171, -10.851366099999671 ], [ 29.199707000000117, -10.832885699999979 ], [ 29.19030759999978, -10.814209 ], [ 29.19345460000044, -10.798109100000179 ], [ 29.1966016000002, -10.790792500000016 ], [ 29.198843300000103, -10.785099899999876 ], [ 29.199473599999681, -10.780589100000165 ], [ 29.197885499999938, -10.772038400000202 ], [ 29.192707300000166, -10.762333799999935 ], [ 29.193481399999968, -10.749206500000097 ], [ 29.216190599999756, -10.732865300000423 ], [ 29.225545800000031, -10.725912000000227 ], [ 29.227042999999892, -10.72463610000014 ], [ 29.23250459999975, -10.71811790000025 ], [ 29.241180000000398, -10.712290400000299 ], [ 29.263970900000214, -10.697846700000291 ], [ 29.270669999999548, -10.6945574 ], [ 29.277619099999804, -10.687804700000266 ], [ 29.285457199999929, -10.682900900000361 ], [ 29.293681099999613, -10.679250400000162 ], [ 29.303537500000022, -10.669476800000336 ], [ 29.318502099999794, -10.654429499999814 ], [ 29.32569770000023, -10.635552299999985 ], [ 29.327223699999767, -10.630982600000255 ], [ 29.335824800000111, -10.604524200000403 ], [ 29.347047099999848, -10.6009181 ], [ 29.3484458000001, -10.600907900000424 ], [ 29.360541300000186, -10.602694300000163 ], [ 29.3638191, -10.603508199999592 ], [ 29.395687399999563, -10.610901199999855 ], [ 29.410182899999615, -10.580731799999846 ], [ 29.409673600000165, -10.570394099999699 ], [ 29.410411, -10.560363699999806 ], [ 29.412445000000307, -10.553782100000056 ], [ 29.41967660000012, -10.528511899999975 ], [ 29.430337300000119, -10.514731099999842 ], [ 29.434512, -10.5106361 ], [ 29.440839700000051, -10.504170199999621 ], [ 29.439003599999563, -10.486463000000448 ], [ 29.436344199999706, -10.4844899 ], [ 29.426898499999581, -10.47889089999962 ], [ 29.422862499999951, -10.475697000000295 ], [ 29.416478799999748, -10.459145500000091 ], [ 29.419608799999903, -10.447549699999984 ], [ 29.42786869999987, -10.438346799999954 ], [ 29.428688999999892, -10.437559300000199 ], [ 29.448565199999841, -10.4107675 ], [ 29.454488400000141, -10.39133520000002 ], [ 29.472343499999575, -10.350501699999729 ], [ 29.480680599999644, -10.340529499999578 ], [ 29.53088379999971, -10.303588899999912 ], [ 29.537205100000143, -10.299734399999721 ], [ 29.554877199999712, -10.291783900000027 ], [ 29.555276499999948, -10.29161630000041 ], [ 29.596333099999921, -10.277893599999754 ], [ 29.60024519999963, -10.277133099999775 ], [ 29.632761299999778, -10.265781100000282 ], [ 29.637764599999905, -10.253284099999696 ], [ 29.638233400000054, -10.251503300000424 ], [ 29.642517099999949, -10.24279789999974 ], [ 29.706049900000213, -10.220063300000062 ], [ 29.735838099999782, -10.210219099999604 ], [ 29.74090670000037, -10.208374899999619 ], [ 29.758468199999772, -10.202928500000382 ], [ 29.7618046, -10.201900699999786 ], [ 29.779623099999931, -10.197483899999659 ], [ 29.780877599999929, -10.197388200000175 ], [ 29.7961934, -10.200703700000309 ], [ 29.79837650000044, -10.201233899999728 ], [ 29.817722499999668, -10.211578099999976 ], [ 29.826368299999661, -10.214087699999745 ], [ 29.832795300000303, -10.212726699999694 ], [ 29.83807370000028, -10.208190900000329 ], [ 29.844482399999851, -10.19488530000006 ], [ 29.886039300000334, -10.169838800000411 ], [ 29.888337400000403, -10.1662352 ], [ 29.890580399999958, -10.160472700000085 ], [ 29.891348100000123, -10.158100199999584 ], [ 29.899944699999647, -10.139681799999869 ], [ 29.901959900000122, -10.118269500000185 ], [ 29.911926299999742, -10.075378399999838 ], [ 29.918698500000186, -10.062382100000086 ], [ 29.919155999999852, -10.062425599999596 ], [ 29.922695199999712, -10.067934399999819 ], [ 29.923437800000038, -10.066945699999872 ], [ 29.934935399999638, -10.047702699999775 ], [ 29.924411500000176, -10.014974899999748 ], [ 29.909485299999982, -9.9817371 ], [ 29.910911399999797, -9.95673620000008 ], [ 29.924126299999941, -9.934261899999607 ], [ 29.924791799999738, -9.896192499999657 ], [ 29.934631700000125, -9.873058299999789 ], [ 29.922985499999918, -9.84790869999985 ], [ 29.923650999999712, -9.830719600000295 ], [ 29.900501000000286, -9.815122300000372 ], [ 29.871694299999699, -9.809782400000259 ], [ 29.861854400000208, -9.797744099999944 ], [ 29.863565599999802, -9.771839200000231 ], [ 29.8442186, -9.767482499999753 ], [ 29.816267499999704, -9.735016100000255 ], [ 29.813605499999628, -9.710371400000355 ], [ 29.803908200000254, -9.701234599999681 ], [ 29.803547499999617, -9.70094180000021 ], [ 29.803151199999625, -9.700878400000148 ], [ 29.799032400000339, -9.702197999999575 ], [ 29.797870600000373, -9.701235700000394 ], [ 29.788928699999694, -9.7010862 ], [ 29.773651900000154, -9.704576999999732 ], [ 29.769472300000327, -9.7027775 ], [ 29.769281600000273, -9.702695199999983 ], [ 29.765667500000063, -9.700990300000186 ], [ 29.7649734, -9.701046200000091 ], [ 29.756926500000276, -9.703534500000215 ], [ 29.755640299999904, -9.703975499999821 ], [ 29.755220500000217, -9.703928799999947 ], [ 29.745574799999719, -9.705102699999694 ], [ 29.728271500000105, -9.701904299999956 ], [ 29.717842999999544, -9.685300899999595 ], [ 29.700255099999755, -9.688557399999915 ], [ 29.676367, -9.678964999999833 ], [ 29.66955929999968, -9.677134599999716 ], [ 29.66601250000009, -9.67568819999981 ], [ 29.661858600000151, -9.67286799999977 ], [ 29.639883300000417, -9.667327199999802 ], [ 29.630507900000261, -9.666256399999597 ], [ 29.621670800000164, -9.66258990000015 ], [ 29.615949600000409, -9.662972499999713 ], [ 29.598079600000187, -9.65130709999983 ], [ 29.596222800000231, -9.651771299999574 ], [ 29.592390000000343, -9.654064600000352 ], [ 29.586909900000308, -9.660887099999911 ], [ 29.571420799999824, -9.656729599999682 ], [ 29.563900099999909, -9.653815599999826 ], [ 29.544640400000191, -9.644103 ], [ 29.539372400000172, -9.644121900000368 ], [ 29.527710000000425, -9.644897500000367 ], [ 29.518184900000016, -9.623228900000147 ], [ 29.517883300000232, -9.620737700000186 ], [ 29.514965299999641, -9.605485999999731 ], [ 29.511925200000185, -9.60764170000021 ], [ 29.500189700000227, -9.61195059999987 ], [ 29.497670100000253, -9.609151299999878 ], [ 29.477893, -9.593386700000345 ], [ 29.476137600000307, -9.593806499999923 ], [ 29.463582299999921, -9.597508200000421 ], [ 29.461060400000207, -9.598368600000047 ], [ 29.454894999999635, -9.590881299999964 ], [ 29.459703699999832, -9.562334599999776 ], [ 29.461909400000351, -9.556990799999761 ], [ 29.457306300000084, -9.551711500000152 ], [ 29.45684050000019, -9.551581700000106 ], [ 29.447235000000319, -9.551007899999931 ], [ 29.446054300000135, -9.55107540000002 ], [ 29.445304900000139, -9.55091479999982 ], [ 29.439565000000183, -9.549371899999963 ], [ 29.428870700000097, -9.54040530000035 ], [ 29.42695389999967, -9.54040530000035 ], [ 29.418172100000106, -9.540563100000025 ], [ 29.41503190000001, -9.539901599999661 ], [ 29.412382300000058, -9.539188200000146 ], [ 29.403587399999857, -9.539462499999836 ], [ 29.394714599999954, -9.539841 ], [ 29.392289599999714, -9.542909 ], [ 29.389888300000095, -9.546980299999721 ], [ 29.387750500000255, -9.550654699999914 ], [ 29.38148039999956, -9.551426200000064 ], [ 29.381283600000351, -9.551385700000298 ], [ 29.369436500000141, -9.536951499999933 ], [ 29.368884799999879, -9.53679 ], [ 29.367202399999975, -9.534741800000017 ], [ 29.361795499999712, -9.530403899999706 ], [ 29.361074799999844, -9.53009220000035 ], [ 29.360062199999643, -9.530303199999695 ], [ 29.353210500000252, -9.532806699999938 ], [ 29.351456800000289, -9.533667000000444 ], [ 29.340881300000145, -9.516906699999765 ], [ 29.343004600000135, -9.506276200000402 ], [ 29.344669600000394, -9.500168799999724 ], [ 29.337215000000107, -9.488318000000149 ], [ 29.336340700000111, -9.486356199999713 ], [ 29.336704899999688, -9.478173500000061 ], [ 29.336654000000422, -9.477312599999745 ], [ 29.331886500000032, -9.4649392 ], [ 29.32802279999984, -9.45996769999962 ], [ 29.316474500000087, -9.443229999999879 ], [ 29.315266800000369, -9.438735 ], [ 29.319313599999987, -9.412550499999968 ], [ 29.319791899999569, -9.411592500000163 ], [ 29.319049100000118, -9.392914200000181 ], [ 29.321737899999711, -9.387076399999879 ], [ 29.326497899999929, -9.385192100000337 ], [ 29.327746899999923, -9.385147800000068 ], [ 29.341026400000022, -9.382438300000015 ], [ 29.341128899999962, -9.382381300000336 ], [ 29.345689200000283, -9.376248500000139 ], [ 29.34826, -9.367681600000143 ], [ 29.348680799999769, -9.364700099999741 ], [ 29.35086330000016, -9.353045600000451 ], [ 29.350543299999742, -9.349045799999669 ], [ 29.34999040000028, -9.347893800000367 ], [ 29.3480373, -9.344540300000263 ], [ 29.342793900000224, -9.318778999999768 ], [ 29.342720899999577, -9.318348500000393 ], [ 29.332210499999881, -9.299931199999676 ], [ 29.326534799999841, -9.280143699999703 ], [ 29.32998590000005, -9.269048 ], [ 29.332884400000371, -9.259045199999585 ], [ 29.333279599999816, -9.256324199999742 ], [ 29.332382000000138, -9.246842999999776 ], [ 29.330637900000077, -9.239176300000434 ], [ 29.317937899999844, -9.204376299999636 ], [ 29.300237900000212, -9.219276300000397 ], [ 29.288037900000013, -9.193176299999662 ], [ 29.267937900000415, -9.191176299999656 ], [ 29.256637900000097, -9.168476299999769 ], [ 29.237737900000027, -9.146276300000231 ], [ 29.217837899999907, -9.141976300000277 ], [ 29.191837900000127, -9.151076299999657 ], [ 29.154137900000194, -9.122576300000208 ], [ 29.140337899999714, -9.125176299999724 ], [ 29.098537900000242, -9.094976300000399 ], [ 29.109237900000348, -9.073676299999905 ], [ 29.107537899999887, -9.06147629999978 ], [ 29.130137899999639, -9.047776300000036 ], [ 29.15943790000015, -9.04187630000027 ], [ 29.168037899999952, -9.033376300000413 ], [ 29.168637900000167, -9.009876299999767 ], [ 29.184437899999864, -8.990876300000084 ], [ 29.182537899999925, -8.962576299999951 ], [ 29.195037899999786, -8.943276300000162 ], [ 29.236837900000157, -8.926876299999602 ], [ 29.256637900000097, -8.923776300000283 ], [ 29.283637899999931, -8.890676299999681 ], [ 29.292337899999918, -8.874976300000387 ], [ 29.296637899999816, -8.850276299999884 ], [ 29.310837900000138, -8.808176299999635 ], [ 29.2996379, -8.743176299999945 ], [ 29.316137900000093, -8.723176299999857 ], [ 29.355837900000161, -8.724776300000345 ], [ 29.373737900000162, -8.7090763 ], [ 29.378137900000251, -8.692076299999975 ], [ 29.401737900000057, -8.679776299999952 ], [ 29.420837899999597, -8.640976299999751 ], [ 29.433337900000353, -8.623576299999765 ], [ 29.465537899999958, -8.598176300000373 ], [ 29.480937899999809, -8.578576300000075 ], [ 29.480737900000342, -8.522776299999599 ], [ 29.500137900000436, -8.49337630000023 ], [ 29.522137899999965, -8.47947629999963 ], [ 29.544237899999686, -8.44917629999977 ], [ 29.592137899999706, -8.393676300000315 ], [ 29.607737899999929, -8.416976300000284 ], [ 29.619237899999725, -8.418976300000329 ], [ 29.638137899999791, -8.407676299999897 ], [ 29.67713790000035, -8.39537629999981 ], [ 29.697937900000351, -8.369576299999753 ], [ 30.21298299999971, -8.301781299999673 ], [ 30.429537899999819, -8.273276299999683 ], [ 30.440137899999741, -8.281476299999689 ], [ 30.4644379, -8.271976300000077 ], [ 30.501937900000417, -8.293576299999939 ], [ 30.537037900000026, -8.278976299999689 ], [ 30.56403789999986, -8.297176300000332 ], [ 30.716237900000433, -8.283476299999672 ], [ 30.796037900000407, -8.276676300000149 ], [ 30.842137899999774, -8.357176300000443 ], [ 31.016937900000098, -8.576676299999583 ], [ 31.031737899999733, -8.590076300000101 ], [ 31.062337899999967, -8.608576300000276 ], [ 31.103637900000308, -8.622676300000188 ], [ 31.136537900000317, -8.621976300000233 ], [ 31.164937900000055, -8.614876300000111 ], [ 31.181137899999598, -8.602576299999859 ], [ 31.190237900000326, -8.584576300000338 ], [ 31.212037900000386, -8.576176299999934 ], [ 31.254937900000108, -8.583876300000204 ], [ 31.270637899999617, -8.61267630000024 ], [ 31.268095699999563, -8.626444600000362 ], [ 31.289914700000306, -8.628559499999643 ], [ 31.315037399999831, -8.607268899999607 ], [ 31.330367699999758, -8.615728900000349 ], [ 31.347623199999912, -8.616527899999628 ], [ 31.3605767, -8.607644899999835 ], [ 31.359221999999793, -8.594226100000293 ], [ 31.373482700000192, -8.587575200000112 ], [ 31.387577099999863, -8.607762400000311 ], [ 31.394327199999825, -8.628160099999588 ], [ 31.414054600000053, -8.639721399999837 ], [ 31.459736500000325, -8.639509900000286 ], [ 31.475114399999697, -8.657203599999697 ], [ 31.484835500000145, -8.680512100000449 ], [ 31.497242300000377, -8.685868999999878 ], [ 31.513309400000153, -8.679196299999974 ], [ 31.551868600000194, -8.687579699999857 ], [ 31.565868, -8.7050833 ], [ 31.581293299999789, -8.736939900000067 ], [ 31.567507899999622, -8.771495200000246 ], [ 31.573402399999793, -8.802124900000374 ], [ 31.568292299999818, -8.811989699999742 ], [ 31.583622599999746, -8.842475100000046 ], [ 31.595672899999691, -8.845199399999807 ], [ 31.612025300000155, -8.863165100000204 ], [ 31.661367499999983, -8.888620999999832 ], [ 31.678884400000189, -8.916517199999968 ], [ 31.700299300000289, -8.924054400000159 ], [ 31.716604100000417, -8.919687099999576 ], [ 31.734002300000242, -8.923279599999901 ], [ 31.765090700000442, -8.894820399999652 ], [ 31.787218600000219, -8.889583799999917 ], [ 31.8014556, -8.88512210000018 ], [ 31.826174300000257, -8.895712700000388 ], [ 31.856145600000154, -8.9009726 ], [ 31.925191400000021, -8.924453600000016 ], [ 31.945037699999745, -8.919099999999675 ], [ 31.9505043, -8.93591169999967 ], [ 31.929505299999725, -8.982233699999856 ], [ 31.93725370000006, -9.000450999999694 ], [ 31.936849600000322, -9.018878599999619 ], [ 31.951300500000283, -9.032681099999984 ], [ 31.967771699999798, -9.060871300000276 ], [ 31.988069499999586, -9.075258900000371 ], [ 32.013683800000251, -9.071413499999755 ], [ 32.015276199999896, -9.062118999999798 ], [ 32.069443300000366, -9.048129900000134 ], [ 32.139447399999987, -9.064298100000308 ], [ 32.160081100000156, -9.057742100000212 ], [ 32.172845900000361, -9.082058999999839 ], [ 32.183303799999756, -9.085462100000024 ], [ 32.183208700000428, -9.109822900000108 ], [ 32.176751200000403, -9.142002499999855 ], [ 32.163512399999632, -9.177575199999795 ], [ 32.165485200000198, -9.185365100000231 ], [ 32.149465600000305, -9.206739300000416 ], [ 32.151010500000062, -9.224499399999635 ], [ 32.164059100000372, -9.260955200000165 ], [ 32.177131499999959, -9.269118600000221 ], [ 32.18490360000002, -9.286945900000196 ], [ 32.21998499999988, -9.320440000000229 ], [ 32.232724599999791, -9.32644420000034 ], [ 32.245915800000212, -9.357448699999882 ], [ 32.244085700000227, -9.3707924 ], [ 32.2583227, -9.37681920000014 ], [ 32.253283900000099, -9.425709700000024 ], [ 32.2660235, -9.462472700000314 ], [ 32.258975100000072, -9.478269799999875 ], [ 32.258940699999918, -9.478531800000338 ], [ 32.258860899999604, -9.47941190000043 ], [ 32.28079, -9.569355599999854 ], [ 32.291240600000151, -9.588886200000221 ], [ 32.316025, -9.615783600000027 ], [ 32.326247200000118, -9.6324589 ], [ 32.348747399999702, -9.64193859999963 ], [ 32.34623469999984, -9.653302899999749 ], [ 32.355395199999741, -9.670436300000222 ], [ 32.354670699999559, -9.672264600000142 ], [ 32.340581100000279, -9.716291999999617 ], [ 32.346719899999549, -9.742981499999731 ], [ 32.320637900000179, -9.741076300000396 ], [ 32.304737900000298, -9.749876300000153 ], [ 32.296237899999781, -9.773976300000029 ], [ 32.28193790000018, -9.7777763 ], [ 32.246637900000202, -9.799276300000169 ], [ 32.236337899999938, -9.811076299999767 ], [ 32.205837899999892, -9.819076300000269 ], [ 32.188937899999949, -9.833776299999769 ], [ 32.175837899999877, -9.868976300000048 ], [ 32.184137900000017, -9.8825763000003 ], [ 32.159637900000334, -9.921976300000139 ], [ 32.140437899999711, -9.929276300000403 ], [ 32.13773790000009, -9.949476300000404 ], [ 32.144437899999957, -9.961376299999673 ], [ 32.124537899999829, -9.99797630000036 ], [ 32.126137900000103, -10.006776299999713 ], [ 32.072537900000277, -10.04677630000023 ], [ 32.055537900000154, -10.037876299999798 ], [ 32.04033789999977, -10.039976300000315 ], [ 32.028837899999978, -10.072676299999552 ], [ 31.999537900000362, -10.099476300000383 ], [ 31.992337899999566, -10.115776299999771 ], [ 32.007437899999765, -10.134376299999882 ], [ 32.008837899999669, -10.159976299999697 ], [ 31.999537900000362, -10.174276300000235 ], [ 32.005737900000199, -10.184676300000392 ], [ 32.005437899999642, -10.20797630000008 ], [ 31.995037900000089, -10.236076299999869 ], [ 31.976337900000395, -10.251876299999774 ], [ 31.982537900000228, -10.262876299999808 ], [ 31.965737899999574, -10.296476300000339 ], [ 31.94523790000013, -10.305576300000254 ], [ 31.924637899999606, -10.30037629999973 ], [ 31.910137899999629, -10.306076299999686 ], [ 31.897037899999553, -10.320576299999731 ], [ 31.880937900000198, -10.317376299999635 ], [ 31.855837900000303, -10.341276300000283 ], [ 31.843637900000104, -10.361876300000123 ], [ 31.844637900000162, -10.377876300000132 ], [ 31.837037900000425, -10.395576300000146 ], [ 31.845437899999855, -10.417376300000074 ], [ 31.82843789999972, -10.443076299999571 ], [ 31.802937899999979, -10.458676300000111 ], [ 31.790937900000156, -10.456376300000342 ], [ 31.769337899999567, -10.466276300000288 ], [ 31.741437899999859, -10.463676299999856 ], [ 31.730837899999933, -10.480176299999806 ], [ 31.700537900000263, -10.494976299999841 ], [ 31.699320500000187, -10.505805800000195 ], [ 31.66913790000034, -10.528976299999778 ], [ 31.646337900000219, -10.515476299999882 ], [ 31.6128379, -10.524976299999802 ], [ 31.580537900000195, -10.555976300000076 ], [ 31.557537899999708, -10.565476300000032 ], [ 31.539737899999885, -10.558276299999795 ], [ 31.5231379, -10.552676299999801 ], [ 31.506737899999692, -10.574776300000382 ], [ 31.495437900000262, -10.578976300000322 ], [ 31.476837899999857, -10.561476299999866 ], [ 31.460137900000287, -10.55947629999973 ], [ 31.432837899999896, -10.5894763 ], [ 31.399337899999665, -10.603676300000114 ], [ 31.338637900000133, -10.619876300000151 ], [ 31.326637900000303, -10.628076299999853 ], [ 31.341837899999792, -10.651476299999885 ], [ 31.307537899999872, -10.656476300000431 ], [ 31.30523790000009, -10.675576300000344 ], [ 31.310937899999892, -10.706476300000441 ], [ 31.268237899999651, -10.736676299999882 ], [ 31.258837900000159, -10.722476299999649 ], [ 31.217337900000352, -10.719376300000228 ], [ 31.177637900000285, -10.726076299999608 ], [ 31.1481379000003, -10.742776299999599 ], [ 31.13543790000007, -10.754776299999721 ], [ 31.136937900000159, -10.76637629999966 ], [ 31.155037899999638, -10.775276300000336 ], [ 31.164737899999686, -10.793976299999684 ], [ 31.177837899999762, -10.7806763 ], [ 31.193937900000012, -10.783576299999606 ], [ 31.204237900000276, -10.805076299999721 ], [ 31.191437899999858, -10.819476299999613 ], [ 31.169837900000168, -10.808076299999803 ], [ 31.148537900000147, -10.818076299999623 ], [ 31.152137899999641, -10.841376299999961 ], [ 31.171737900000107, -10.853776299999589 ], [ 31.180837899999936, -10.867676299999578 ], [ 31.155037899999638, -10.897276300000259 ], [ 31.15103790000029, -10.914176300000328 ], [ 31.128937899999681, -10.930676300000101 ], [ 31.100521399999923, -10.963900700000433 ], [ 31.100201800000438, -10.964056200000069 ], [ 31.100093700000034, -10.964108799999563 ], [ 31.072702599999744, -10.959277400000405 ], [ 31.081948300000391, -10.939115800000113 ], [ 31.07814539999983, -10.92688740000013 ], [ 31.059606399999979, -10.922126599999645 ], [ 31.064003500000279, -10.940982699999635 ], [ 31.04693810000013, -10.956804000000393 ], [ 31.011001, -10.936992200000269 ], [ 30.99048930000005, -10.941892700000155 ], [ 30.984048199999588, -11.000273199999956 ], [ 30.958331300000321, -11.017467800000132 ], [ 30.919613400000188, -11.023300200000321 ], [ 30.8861006, -11.035874500000071 ], [ 30.902096400000413, -11.073360899999802 ], [ 30.885506400000065, -11.073570800000367 ], [ 30.868631200000376, -11.050151199999648 ], [ 30.858125699999736, -11.052810399999752 ], [ 30.84940289999966, -11.071704700000167 ], [ 30.845671300000053, -11.094399600000175 ], [ 30.823781099999721, -11.109303099999615 ], [ 30.821927199999557, -11.129173200000025 ], [ 30.792573800000014, -11.165108600000124 ], [ 30.761936899999874, -11.178935899999868 ], [ 30.751930600000101, -11.197285799999859 ], [ 30.735625799999976, -11.211904199999662 ], [ 30.739999100000105, -11.222255599999704 ], [ 30.734936599999571, -11.241838199999792 ], [ 30.721293800000417, -11.2642867 ], [ 30.717728600000203, -11.286360499999917 ], [ 30.687234300000181, -11.320551699999765 ], [ 30.68431090000005, -11.331784800000388 ], [ 30.650963699999874, -11.334511499999817 ] ] ] } }, { "type": "Feature", "properties": { "area_id": "ZMB_1_17", "area_name": "Southern", "area_level": 1.0, "parent_area_id": "ZMB", "spectrum_region_code": 17.0, "area_sort_order": 9, "center_x": 26.712548143625526, "center_y": -16.801226299999879, "area_level_label": "Province", "display": true, "spectrum_level": true, "epp_level": true, "naomi_level": false, "pepfar_psnu_level": false }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 25.907537899999671, -17.983576300000415 ], [ 25.902037900000231, -17.978176299999838 ], [ 25.859937900000205, -17.96827629999984 ], [ 25.847537899999637, -17.934376299999894 ], [ 25.85293789999978, -17.909576300000126 ], [ 25.831037900000439, -17.885276299999727 ], [ 25.800737899999866, -17.877176299999785 ], [ 25.761237900000172, -17.842076300000041 ], [ 25.705437899999854, -17.829976299999878 ], [ 25.688637900000096, -17.804176299999707 ], [ 25.67133790000031, -17.806176300000377 ], [ 25.654537899999657, -17.817076300000142 ], [ 25.642037899999796, -17.827376299999816 ], [ 25.618137900000328, -17.835376300000149 ], [ 25.549337900000122, -17.833776300000107 ], [ 25.527537900000063, -17.853376300000207 ], [ 25.513137900000274, -17.854276299999782 ], [ 25.473837900000049, -17.840276299999957 ], [ 25.403037899999728, -17.838876299999626 ], [ 25.379237900000444, -17.828476299999583 ], [ 25.34333790000025, -17.829476300000383 ], [ 25.27683789999983, -17.786876300000383 ], [ 25.251237899999897, -17.777476300000139 ], [ 25.222737899999974, -17.756876300000311 ], [ 25.196237900000167, -17.757376300000317 ], [ 25.167637900000056, -17.738476299999896 ], [ 25.155137900000199, -17.699676300000242 ], [ 25.118637899999786, -17.682976300000124 ], [ 25.095237900000352, -17.684476299999691 ], [ 25.103037899999567, -17.660676300000368 ], [ 25.098337899999819, -17.645876299999568 ], [ 25.080037899999969, -17.638876299999982 ], [ 25.059437900000344, -17.604276299999579 ], [ 25.039837899999878, -17.607676299999909 ], [ 25.040837899999943, -17.584176299999797 ], [ 25.021337899999658, -17.578076300000141 ], [ 25.005137900000115, -17.581876300000335 ], [ 24.987437899999591, -17.569076299999722 ], [ 24.970937900000386, -17.548576299999958 ], [ 24.975637900000134, -17.498276299999947 ], [ 24.987637899999957, -17.467876299999574 ], [ 25.019637900000092, -17.440976299999608 ], [ 25.033137900000014, -17.410876299999952 ], [ 25.016537899999729, -17.384376300000053 ], [ 25.020037899999938, -17.369776300000186 ], [ 25.011737899999801, -17.338276299999702 ], [ 25.016637899999914, -17.327976300000056 ], [ 25.056137899999605, -17.285276300000032 ], [ 25.07393790000032, -17.254676299999723 ], [ 25.092337900000359, -17.243676300000118 ], [ 25.11043789999983, -17.218776300000133 ], [ 25.10593789999956, -17.199376300000104 ], [ 25.087637899999713, -17.179576299999876 ], [ 25.091637899999952, -17.156676299999734 ], [ 25.106437899999587, -17.126276300000011 ], [ 25.128237899999654, -17.107876300000246 ], [ 25.156337899999734, -17.095676299999727 ], [ 25.165437899999564, -17.085676299999971 ], [ 25.169837899999646, -17.056976300000127 ], [ 25.155491899999834, -17.02074229999965 ], [ 25.172237899999619, -16.955476299999852 ], [ 25.189137899999558, -16.974276299999733 ], [ 25.244637900000221, -16.947176300000045 ], [ 25.260337899999726, -16.906376300000307 ], [ 25.219037900000284, -16.774776300000056 ], [ 25.239237900000074, -16.695476299999676 ], [ 25.222337900000124, -16.690676299999971 ], [ 25.213437899999771, -16.678576300000408 ], [ 25.182637900000064, -16.674876299999809 ], [ 25.088837900000144, -16.644376300000047 ], [ 25.098337899999819, -16.622476300000312 ], [ 25.090737900000082, -16.603376299999709 ], [ 25.073837900000139, -16.588376300000018 ], [ 25.05783790000007, -16.585376300000341 ], [ 25.055237899999732, -16.573176300000348 ], [ 25.007737899999558, -16.546076299999957 ], [ 25.027137899999651, -16.500376300000017 ], [ 25.048637900000053, -16.457276299999631 ], [ 25.063737900000245, -16.449776300000217 ], [ 25.100537900000315, -16.396676300000252 ], [ 25.124637900000149, -16.376976300000308 ], [ 25.181437899999629, -16.342676300000253 ], [ 25.19083790000002, -16.332976299999977 ], [ 25.222237899999943, -16.31837630000016 ], [ 25.242537899999913, -16.291676299999597 ], [ 25.27193789999971, -16.286376299999901 ], [ 25.288937899999841, -16.273976300000296 ], [ 25.299237900000104, -16.221676300000354 ], [ 25.319137900000225, -16.185576300000307 ], [ 25.338937900000165, -16.168776299999717 ], [ 25.357737900000043, -16.143776300000177 ], [ 25.430437900000307, -16.101176300000418 ], [ 25.433237900000115, -16.100076300000257 ], [ 25.448337900000308, -16.130676299999891 ], [ 25.465937899999755, -16.150776300000373 ], [ 25.47943789999967, -16.183676300000364 ], [ 25.494037899999839, -16.194176300000279 ], [ 25.537237900000111, -16.182876300000025 ], [ 25.556837899999678, -16.194776299999749 ], [ 25.578437900000264, -16.192476300000223 ], [ 25.6039379, -16.18127630000021 ], [ 25.641537899999761, -16.186176300000312 ], [ 25.668237899999941, -16.180776299999813 ], [ 25.68173789999986, -16.191476299999668 ], [ 25.683537899999607, -16.203676300000325 ], [ 25.673337900000426, -16.220876300000256 ], [ 25.6871379, -16.236176300000221 ], [ 25.685637899999914, -16.257576300000284 ], [ 25.667337900000064, -16.281476299999738 ], [ 25.662237899999578, -16.296076300000191 ], [ 25.673037899999873, -16.313476299999678 ], [ 25.667537900000436, -16.334776299999781 ], [ 25.690837899999689, -16.356576300000317 ], [ 25.691637900000277, -16.365176299999895 ], [ 25.67133790000031, -16.378276300000117 ], [ 25.670037899999688, -16.396676300000252 ], [ 25.658737900000268, -16.4048763 ], [ 25.671637899999965, -16.430876299999888 ], [ 25.663837899999855, -16.447276299999825 ], [ 25.659037899999927, -16.475676300000341 ], [ 25.662437899999947, -16.487676299999684 ], [ 25.686537899999788, -16.518376300000085 ], [ 25.678337899999832, -16.529676300000339 ], [ 25.677037900000112, -16.549276300000145 ], [ 25.699337900000202, -16.556276300000381 ], [ 26.020837899999869, -16.414776299999687 ], [ 26.146337900000262, -16.359776299999751 ], [ 26.173637899999758, -16.354276299999938 ], [ 26.471137899999771, -16.2991763 ], [ 26.333737899999726, -16.093176300000401 ], [ 26.327937899999739, -16.07007630000027 ], [ 26.337537899999599, -16.054776299999961 ], [ 26.402737900000307, -15.987676300000034 ], [ 26.429637899999953, -15.962676299999858 ], [ 26.439237899999817, -15.926276300000049 ], [ 26.441137899999749, -15.845676300000036 ], [ 26.435337899999762, -15.824576299999759 ], [ 26.410437900000229, -15.784276299999847 ], [ 26.404637900000242, -15.736376299999973 ], [ 26.395037900000379, -15.7113763 ], [ 26.416137900000038, -15.707576299999975 ], [ 26.423837899999963, -15.6864763 ], [ 26.439237899999817, -15.682676300000079 ], [ 26.454537900000382, -15.66727630000014 ], [ 26.490937899999704, -15.669176300000109 ], [ 26.504437899999623, -15.657676299999864 ], [ 26.525537900000181, -15.6500763 ], [ 26.561937900000402, -15.625076299999892 ], [ 26.575337900000132, -15.638576299999785 ], [ 26.56963790000033, -15.661576300000158 ], [ 26.571537900000262, -15.682676300000079 ], [ 26.588837900000051, -15.697976300000398 ], [ 26.606037899999656, -15.690276300000271 ], [ 26.625237900000272, -15.673076299999613 ], [ 26.636737900000075, -15.678776300000218 ], [ 26.6502379, -15.697976300000398 ], [ 26.667437899999591, -15.692276300000279 ], [ 26.669337900000421, -15.669176300000109 ], [ 26.69813790000001, -15.684576300000174 ], [ 26.700037899999945, -15.665376300000274 ], [ 26.719237899999669, -15.678776300000218 ], [ 26.742237900000159, -15.673076299999613 ], [ 26.778737899999665, -15.676876299999792 ], [ 26.797937900000289, -15.669176300000109 ], [ 26.836237899999549, -15.67117630000037 ], [ 26.842037900000438, -15.661576300000158 ], [ 26.82093789999988, -15.625076299999892 ], [ 26.849637900000179, -15.625076299999892 ], [ 26.859237900000043, -15.598276300000332 ], [ 26.893837899999614, -15.584776299999623 ], [ 26.911037900000117, -15.586776300000267 ], [ 26.926437899999968, -15.579076299999629 ], [ 26.939837899999699, -15.582876299999819 ], [ 26.957137900000387, -15.577176299999762 ], [ 26.970537900000117, -15.588676299999943 ], [ 26.980137899999978, -15.615476300000315 ], [ 26.995437899999647, -15.615476300000315 ], [ 27.001237899999641, -15.603976300000072 ], [ 27.022337900000192, -15.596376300000211 ], [ 27.04533789999979, -15.600176300000097 ], [ 27.053037899999712, -15.592476300000337 ], [ 27.079837900000076, -15.594376299999695 ], [ 27.081737900000011, -15.607876299999958 ], [ 27.100937899999732, -15.621276299999712 ], [ 27.125937900000348, -15.628976300000325 ], [ 27.15273789999981, -15.623176299999807 ], [ 27.1585379, -15.632776299999753 ], [ 27.160437899999735, -15.66727630000014 ], [ 27.1757379000003, -15.682676300000079 ], [ 27.187237900000099, -15.713376299999601 ], [ 27.209937900000032, -15.741476300000089 ], [ 27.245437900000379, -15.722376300000036 ], [ 27.279237900000265, -15.720176299999975 ], [ 27.295437899999808, -15.742676300000177 ], [ 27.306637899999945, -15.746976300000309 ], [ 27.306701699999831, -15.746887199999858 ], [ 27.328308100000047, -15.723999000000111 ], [ 27.365295399999887, -15.656494099999978 ], [ 27.379882799999908, -15.634277299999962 ], [ 27.388305699999883, -15.599487299999904 ], [ 27.400878900000404, -15.587585399999698 ], [ 27.4016724, -15.569396999999748 ], [ 27.411315900000318, -15.561279300000109 ], [ 27.423278800000222, -15.574585000000262 ], [ 27.4577026, -15.5863037 ], [ 27.474121099999696, -15.56408690000014 ], [ 27.491516100000151, -15.558898899999678 ], [ 27.516113299999788, -15.542602500000275 ], [ 27.521728499999771, -15.516479499999576 ], [ 27.56277620000035, -15.480134200000181 ], [ 27.564903499999772, -15.479900900000144 ], [ 27.567030800000094, -15.479729499999975 ], [ 27.5757787, -15.485663899999714 ], [ 27.574663500000295, -15.491560999999862 ], [ 27.577026600000352, -15.500248399999801 ], [ 27.57999860000001, -15.503217599999729 ], [ 27.5950202, -15.510633099999852 ], [ 27.597845099999628, -15.510932199999697 ], [ 27.606376199999573, -15.515653400000282 ], [ 27.608624700000036, -15.518614800000403 ], [ 27.62074699999965, -15.523906000000226 ], [ 27.626957899999933, -15.522473799999759 ], [ 27.635189499999807, -15.521208099999848 ], [ 27.636872000000171, -15.520999799999821 ], [ 27.639735199999812, -15.522974399999624 ], [ 27.641006500000309, -15.527230400000207 ], [ 27.641885199999766, -15.534778900000257 ], [ 27.644531800000365, -15.545357099999865 ], [ 27.645155500000293, -15.546055599999892 ], [ 27.64798149999956, -15.549267700000302 ], [ 27.663879399999718, -15.566894500000412 ], [ 27.670359099999782, -15.591867899999977 ], [ 27.671148199999916, -15.592453899999891 ], [ 27.675161299999893, -15.606682400000375 ], [ 27.671580799999759, -15.611475900000233 ], [ 27.667349400000145, -15.615589399999845 ], [ 27.6660871000004, -15.616786299999834 ], [ 27.659025900000305, -15.623857699999782 ], [ 27.656503599999656, -15.627141599999742 ], [ 27.660307599999857, -15.64326 ], [ 27.661714800000357, -15.6443405 ], [ 27.673862799999849, -15.650994999999623 ], [ 27.674688100000282, -15.651367699999845 ], [ 27.676320099999611, -15.652361099999984 ], [ 27.680121499999597, -15.656415899999612 ], [ 27.681473199999548, -15.659151199999769 ], [ 27.682231000000243, -15.661216000000127 ], [ 27.693463899999955, -15.672859099999803 ], [ 27.711483800000444, -15.661664600000423 ], [ 27.72092710000037, -15.66465050000021 ], [ 27.722992299999596, -15.666696800000011 ], [ 27.732275700000223, -15.675884500000356 ], [ 27.734388299999772, -15.676341200000019 ], [ 27.735947599999829, -15.676668199999824 ], [ 27.754126299999974, -15.653743199999683 ], [ 27.758779399999884, -15.652341799999597 ], [ 27.76417699999983, -15.650729200000233 ], [ 27.764299499999634, -15.650696899999835 ], [ 27.768132399999978, -15.65094910000005 ], [ 27.782289200000317, -15.664714800000011 ], [ 27.783396600000277, -15.666036499999825 ], [ 27.790396900000275, -15.665971100000187 ], [ 27.795640100000028, -15.664602600000094 ], [ 27.806816099999981, -15.663208000000294 ], [ 27.835876500000438, -15.674682599999583 ], [ 27.844909700000134, -15.690307599999725 ], [ 27.84228520000002, -15.70739749999986 ], [ 27.815918000000419, -15.728088399999681 ], [ 27.8129272000001, -15.73797610000007 ], [ 27.830322300000113, -15.750488299999756 ], [ 27.843872099999661, -15.749206500000039 ], [ 27.882324200000273, -15.724792499999801 ], [ 27.910522499999949, -15.728393599999775 ], [ 27.913085899999952, -15.745788599999614 ], [ 27.9276733, -15.763000499999825 ], [ 27.959716799999669, -15.764404300000036 ], [ 27.984680199999943, -15.748596199999923 ], [ 27.999084499999643, -15.722900399999739 ], [ 28.009277300000022, -15.7258911 ], [ 28.044227699999833, -15.759155399999598 ], [ 28.062137899999783, -15.76357629999969 ], [ 28.087337899999866, -15.760776300000336 ], [ 28.096237900000226, -15.773576300000197 ], [ 28.120637899999725, -15.788076300000229 ], [ 28.152437900000386, -15.791176299999981 ], [ 28.182537899999694, -15.801476299999665 ], [ 28.195037900000447, -15.820076299999675 ], [ 28.228437899999587, -15.844676300000433 ], [ 28.243537899999787, -15.851076300000434 ], [ 28.2663379, -15.844776299999912 ], [ 28.292837899999707, -15.810176299999842 ], [ 28.318537899999821, -15.818676300000385 ], [ 28.358337900000073, -15.795776300000243 ], [ 28.374637899999797, -15.801176300000311 ], [ 28.410037899999967, -15.804176299999616 ], [ 28.428737899999653, -15.815876299999772 ], [ 28.447237899999873, -15.850976300000063 ], [ 28.464137899999816, -15.856576299999865 ], [ 28.478437900000323, -15.849276300000225 ], [ 28.4922379, -15.860776300000175 ], [ 28.509237900000031, -15.861676300000363 ], [ 28.51903790000026, -15.873376299999693 ], [ 28.540937899999609, -15.875276299999712 ], [ 28.6001379, -15.918276300000311 ], [ 28.614883, -15.912365800000236 ], [ 28.583679200000123, -15.949401899999721 ], [ 28.5756836, -15.967895500000338 ], [ 28.547912600000185, -15.995300299999672 ], [ 28.539123499999565, -16.050781200000262 ], [ 28.506286599999832, -16.063598600000436 ], [ 28.49670410000007, -16.065979000000322 ], [ 28.503295899999969, -16.066223099999583 ], [ 28.497314500000247, -16.284912099999612 ], [ 28.838317899999574, -16.434020999999706 ], [ 28.835083000000182, -16.443786599999719 ], [ 28.840270999999863, -16.474304200000415 ], [ 28.829284699999878, -16.491699199999566 ], [ 28.783874500000064, -16.524292000000379 ], [ 28.772094699999585, -16.544189499999643 ], [ 28.753112800000384, -16.555603 ], [ 28.693481400000291, -16.558410600000059 ], [ 28.6674805, -16.566711399999846 ], [ 28.410437899999806, -16.672476299999584 ], [ 28.275737900000291, -16.727876299999622 ], [ 28.169637899999987, -16.827676299999702 ], [ 28.057837899999882, -16.879076300000261 ], [ 27.92713789999971, -16.923376300000072 ], [ 27.837637899999695, -16.963376299999599 ], [ 27.833537900000159, -16.968976299999603 ], [ 27.629837900000073, -17.247576299999956 ], [ 27.620337900000397, -17.334376299999597 ], [ 27.561737900000267, -17.40167630000024 ], [ 27.520937899999961, -17.436976299999873 ], [ 27.425637899999952, -17.50967630000034 ], [ 27.398237900000272, -17.535376300000269 ], [ 27.343837899999862, -17.575376299999657 ], [ 27.303537899999576, -17.61977630000035 ], [ 27.131737900000338, -17.801876300000281 ], [ 27.146137900000127, -17.841476300000263 ], [ 27.074037900000086, -17.903776300000207 ], [ 27.034737899999865, -17.962176299999676 ], [ 27.005437900000253, -17.9535763 ], [ 26.988337899999934, -17.962976299999838 ], [ 26.957437900000045, -17.964476300000285 ], [ 26.88403790000028, -17.987176299999803 ], [ 26.866737899999595, -17.984576299999777 ], [ 26.847837900000428, -17.992776299999985 ], [ 26.826237899999843, -17.990076300000378 ], [ 26.797237899999885, -18.02747630000016 ], [ 26.753037899999551, -18.041176299999815 ], [ 26.717837899999758, -18.077376300000218 ], [ 26.697637899999979, -18.07827630000028 ], [ 26.64713789999962, -18.054676299999635 ], [ 26.614837899999827, -18.054676299999635 ], [ 26.586837899999928, -18.0423763 ], [ 26.578537899999787, -18.012676300000315 ], [ 26.554037900000104, -17.98577629999966 ], [ 26.489537899999799, -17.982276300000059 ], [ 26.450237899999582, -17.958476299999717 ], [ 26.399237900000092, -17.935876299999919 ], [ 26.389237900000385, -17.934876299999694 ], [ 26.348537900000267, -17.928976299999597 ], [ 26.309037899999673, -17.931576300000422 ], [ 26.281737900000181, -17.915276299999686 ], [ 26.238137900000062, -17.913076300000288 ], [ 26.22043790000043, -17.885776300000064 ], [ 26.209237900000293, -17.880476299999831 ], [ 26.179337899999563, -17.899376299999972 ], [ 26.145437900000388, -17.913976300000371 ], [ 26.100937900000396, -17.921076299999807 ], [ 26.10183790000027, -17.9419763 ], [ 26.091837899999664, -17.96727630000025 ], [ 26.072437899999571, -17.975976300000198 ], [ 26.037737899999811, -17.969076300000307 ], [ 25.999237900000178, -17.97507629999977 ], [ 25.973437899999876, -17.997676300000137 ], [ 25.956737900000306, -17.991476300000137 ], [ 25.919737899999866, -17.989576299999612 ], [ 25.907537899999671, -17.983576300000415 ] ], [ [ 28.031564800000428, -16.317537200000178 ], [ 28.157937899999823, -16.349976299999845 ], [ 28.055114700000136, -16.322875999999578 ], [ 28.031564800000428, -16.317537200000178 ] ] ] } }, { "type": "Feature", "properties": { "area_id": "ZMB_1_18", "area_name": "Western", "area_level": 1.0, "parent_area_id": "ZMB", "spectrum_region_code": 18.0, "area_sort_order": 10, "center_x": 23.622116930445678, "center_y": -15.6872263000001, "area_level_label": "Province", "display": true, "spectrum_level": true, "epp_level": true, "naomi_level": false, "pepfar_psnu_level": false }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 25.155491899999834, -17.02074229999965 ], [ 25.169837899999646, -17.056976300000127 ], [ 25.165437899999564, -17.085676299999971 ], [ 25.156337899999734, -17.095676299999727 ], [ 25.128237899999654, -17.107876300000246 ], [ 25.106437899999587, -17.126276300000011 ], [ 25.091637899999952, -17.156676299999734 ], [ 25.087637899999713, -17.179576299999876 ], [ 25.10593789999956, -17.199376300000104 ], [ 25.11043789999983, -17.218776300000133 ], [ 25.092337900000359, -17.243676300000118 ], [ 25.07393790000032, -17.254676299999723 ], [ 25.056137899999605, -17.285276300000032 ], [ 25.016637899999914, -17.327976300000056 ], [ 25.011737899999801, -17.338276299999702 ], [ 25.020037899999938, -17.369776300000186 ], [ 25.016537899999729, -17.384376300000053 ], [ 25.033137900000014, -17.410876299999952 ], [ 25.019637900000092, -17.440976299999608 ], [ 24.987637899999957, -17.467876299999574 ], [ 24.975637900000134, -17.498276299999947 ], [ 24.970937900000386, -17.548576299999958 ], [ 24.947837899999708, -17.551976299999968 ], [ 24.931937899999831, -17.543876300000228 ], [ 24.899437899999661, -17.540876300000289 ], [ 24.877337899999944, -17.525976300000114 ], [ 24.8217379, -17.516976300000188 ], [ 24.793937899999577, -17.523176299999932 ], [ 24.772437900000071, -17.508876300000207 ], [ 24.745037900000394, -17.507376300000065 ], [ 24.701937900000303, -17.493276300000403 ], [ 24.683837899999929, -17.497476300000269 ], [ 24.650937899999917, -17.493576300000075 ], [ 24.639437900000122, -17.498176300000022 ], [ 24.608637900000414, -17.528876299999911 ], [ 24.574237900000313, -17.536576300000103 ], [ 24.556337900000308, -17.526776299999955 ], [ 24.538037899999559, -17.50857630000019 ], [ 24.514737900000309, -17.509176299999854 ], [ 24.477237899999842, -17.485876299999809 ], [ 24.457137900000244, -17.477176300000345 ], [ 24.444337899999827, -17.480576300000315 ], [ 24.412737900000433, -17.470976300000409 ], [ 24.374037900000435, -17.471476300000351 ], [ 24.334637900000029, -17.487076299999959 ], [ 24.270937900000312, -17.480876300000329 ], [ 24.243337900000263, -17.468776300000272 ], [ 24.224937900000224, -17.471576300000059 ], [ 23.734937900000265, -17.573776299999604 ], [ 23.438037899999571, -17.635676299999783 ], [ 23.436737899999851, -17.619576300000041 ], [ 23.424037899999625, -17.59677630000014 ], [ 23.401337899999689, -17.580976300000234 ], [ 23.349137899999771, -17.5556763000004 ], [ 23.313037900000104, -17.545076300000407 ], [ 23.257137899999599, -17.538076299999791 ], [ 23.239737899999625, -17.52877629999967 ], [ 23.17833789999969, -17.460576299999641 ], [ 23.131539999999639, -17.431877800000208 ], [ 23.103881800000163, -17.413696300000314 ], [ 23.087524400000184, -17.394592300000298 ], [ 23.072509799999867, -17.350585900000407 ], [ 23.034484899999551, -17.308288599999834 ], [ 23.02111820000033, -17.2896118 ], [ 22.998474100000077, -17.272094700000149 ], [ 22.966637900000013, -17.257976300000163 ], [ 22.91833790000015, -17.237976299999591 ], [ 22.888537899999605, -17.214476300000356 ], [ 22.863837900000444, -17.18767630000006 ], [ 22.828637899999762, -17.163676299999704 ], [ 22.785637899999855, -17.113576300000432 ], [ 22.712237900000094, -17.042076300000407 ], [ 22.697537899999745, -17.022276299999586 ], [ 22.6483379, -16.986376300000138 ], [ 22.622037899999672, -16.958476299999944 ], [ 22.608737900000122, -16.937976299999814 ], [ 22.590837900000121, -16.927476300000201 ], [ 22.570537900000151, -16.903476300000278 ], [ 22.530037900000401, -16.873976299999839 ], [ 22.493737900000362, -16.841376300000348 ], [ 22.43963789999961, -16.779176299999797 ], [ 22.366637899999692, -16.709976300000179 ], [ 22.354937900000422, -16.689076300000274 ], [ 22.323937900000345, -16.646776300000315 ], [ 22.281737900000131, -16.619676299999863 ], [ 22.256137900000201, -16.581476300000279 ], [ 22.224137900000063, -16.5699763 ], [ 22.189337900000119, -16.540976300000263 ], [ 22.177937899999609, -16.522876300000384 ], [ 22.153937899999953, -16.499376300000403 ], [ 22.141337899999908, -16.476076300000319 ], [ 22.133037899999771, -16.4124763 ], [ 22.121237900000313, -16.355276300000064 ], [ 22.092237900000356, -16.310076300000318 ], [ 22.07643789999976, -16.295876300000035 ], [ 22.082137899999569, -16.27987630000014 ], [ 22.053437900000169, -16.257776300000184 ], [ 22.027937900000424, -16.224676299999889 ], [ 22.001337900000436, -16.211876299999822 ], [ 22.00113790000006, -16.197576299999895 ], [ 22.000808099999734, -16.170839400000428 ], [ 21.980037900000404, -14.513876300000177 ], [ 21.980819599999926, -14.468698499999828 ], [ 21.986937899999742, -14.048176299999753 ], [ 21.988524000000218, -13.990454500000071 ], [ 21.99246749999983, -13.727905300000318 ], [ 22.048680900000203, -13.740783699999932 ], [ 22.076085700000277, -13.758789099999872 ], [ 22.107640899999559, -13.771606400000138 ], [ 22.134679499999891, -13.771606400000138 ], [ 22.146093000000167, -13.765197799999763 ], [ 22.192479700000344, -13.770507800000033 ], [ 22.213048599999649, -13.763793900000264 ], [ 22.254247300000142, -13.757690399999921 ], [ 22.283483200000298, -13.763305699999981 ], [ 22.30545580000026, -13.776794399999813 ], [ 22.330480200000192, -13.805175799999837 ], [ 22.355443599999575, -13.811889600000143 ], [ 22.388646699999953, -13.836486800000388 ], [ 22.413243899999589, -13.844604499999862 ], [ 22.430883099999583, -13.856079100000091 ], [ 22.448888399999763, -13.876403799999906 ], [ 22.484044699999977, -13.884887699999727 ], [ 22.515050499999639, -13.902099599999785 ], [ 22.526891400000231, -13.914306599999682 ], [ 22.564244899999814, -13.934509300000427 ], [ 22.618444099999788, -13.94140620000041 ], [ 22.635045700000202, -13.95019529999988 ], [ 22.668248799999684, -13.991210900000278 ], [ 22.694676999999835, -13.986877400000383 ], [ 22.715245900000035, -13.998901399999962 ], [ 22.736241999999635, -13.989990200000049 ], [ 22.754247299999811, -13.925903300000048 ], [ 22.799047100000351, -13.926208499999902 ], [ 22.859655, -13.885986299999793 ], [ 22.879247300000181, -13.888000499999674 ], [ 22.88828049999988, -13.897705099999635 ], [ 22.915868400000274, -13.904785200000314 ], [ 22.939244900000016, -13.930297900000157 ], [ 22.947057399999814, -13.931396499999588 ], [ 22.978856699999969, -13.956481900000385 ], [ 22.993077900000241, -13.984985399999886 ], [ 23.008092499999663, -14.005493199999837 ], [ 23.027257599999643, -14.007812499999902 ], [ 23.095494899999576, -13.992004400000388 ], [ 23.133641899999652, -14.030700700000121 ], [ 23.15445480000027, -14.038391099999806 ], [ 23.185460700000384, -14.028198200000379 ], [ 23.218297600000117, -14.004211399999891 ], [ 23.23428880000036, -14.012390099999795 ], [ 23.250890399999875, -14.040100099999961 ], [ 23.250890399999875, -14.056884800000308 ], [ 23.222448000000224, -14.118286099999972 ], [ 23.207860600000203, -14.130310099999654 ], [ 23.196263900000048, -14.173278799999833 ], [ 23.205480200000068, -14.179687500000016 ], [ 23.228063200000204, -14.1640015 ], [ 23.242650600000221, -14.197692899999916 ], [ 23.263097399999758, -14.186706500000176 ], [ 23.305455799999596, -14.186279300000233 ], [ 23.313451399999714, -14.164184600000379 ], [ 23.338842099999855, -14.161377000000133 ], [ 23.370275200000261, -14.164184600000379 ], [ 23.390844, -14.1547852 ], [ 23.427281999999781, -14.107605000000335 ], [ 23.447240499999804, -14.100402799999687 ], [ 23.52847830000011, -14.094604500000431 ], [ 23.567052499999594, -14.070495600000086 ], [ 23.597140099999663, -14.043196899999757 ], [ 23.604283900000301, -14.035888699999859 ], [ 23.643895799999818, -14.025390600000284 ], [ 23.660680400000096, -14.025085399999986 ], [ 23.688268299999596, -14.010192900000145 ], [ 23.706273700000231, -14.027099600000401 ], [ 23.729467099999649, -14.022705099999806 ], [ 23.765844000000207, -13.989379900000252 ], [ 23.801671599999807, -13.983276400000049 ], [ 23.8222405, -13.964294399999636 ], [ 23.836278599999961, -13.965087899999808 ], [ 23.852452899999623, -13.986511199999894 ], [ 23.868444099999859, -13.976501499999873 ], [ 23.923863999999732, -13.984985399999886 ], [ 23.938695600000184, -13.996704100000365 ], [ 23.953466099999627, -13.981994600000039 ], [ 23.975255600000168, -14.000000000000297 ], [ 23.999242399999627, -13.997375499999714 ], [ 24.018651599999583, -14.005004899999873 ], [ 24.019078900000338, -13.990295400000347 ], [ 24.034093499999759, -13.986999500000035 ], [ 24.054479299999638, -13.964294399999636 ], [ 24.063695599999658, -13.978088399999649 ], [ 24.077245400000098, -13.978576699999856 ], [ 24.090245899999577, -13.950500499999862 ], [ 24.104894300000151, -13.936523399999775 ], [ 24.12387620000025, -13.955200200000016 ], [ 24.153844499999888, -13.9470825 ], [ 24.165258099999729, -13.927490199999951 ], [ 24.198644300000424, -13.923095700000133 ], [ 24.21848069999978, -13.910888699999918 ], [ 24.248449000000321, -13.899475099999687 ], [ 24.250096899999615, -13.915527300000203 ], [ 24.270238499999962, -13.908386199999679 ], [ 24.279454799999975, -13.922485399999864 ], [ 24.30386890000019, -13.935485799999872 ], [ 24.318456300000211, -13.928100600000104 ], [ 24.3006951, -13.910278300000389 ], [ 24.317845999999591, -13.888793900000231 ], [ 24.339696499999789, -13.898010299999667 ], [ 24.345975800000339, -13.911611499999651 ], [ 24.34387210000018, -13.919006299999596 ], [ 24.364685100000354, -13.942382799999587 ], [ 24.382324199999889, -13.946594200000403 ], [ 24.41387940000007, -13.941894499999979 ], [ 24.436279299999889, -13.958190900000057 ], [ 24.452270500000129, -13.946411100000164 ], [ 24.467529299999981, -13.952880900000153 ], [ 24.485473599999608, -13.948303200000277 ], [ 24.492126499999618, -13.910888699999918 ], [ 24.511901900000218, -13.920776400000181 ], [ 24.534912099999755, -13.946106 ], [ 24.579101599999671, -13.969604499999777 ], [ 24.585876499999891, -13.98510740000042 ], [ 24.60412599999961, -13.974792499999834 ], [ 24.611084000000151, -13.95770260000036 ], [ 24.624084499999629, -13.973083500000239 ], [ 24.628723099999686, -13.993591300000164 ], [ 24.644681000000318, -14.015329899999783 ], [ 24.6572876, -14.006591800000132 ], [ 24.641479500000088, -13.970703099999565 ], [ 24.671081500000422, -13.95361329999958 ], [ 24.684326200000339, -13.956787099999602 ], [ 24.727294899999897, -13.993103 ], [ 24.750488300000214, -14.027099600000401 ], [ 24.754272499999676, -14.056579599999679 ], [ 24.740112299999954, -14.079711900000198 ], [ 24.754272499999676, -14.106994600000426 ], [ 24.768127399999749, -14.118896499999883 ], [ 24.806518600000263, -14.129089399999668 ], [ 24.815307600000423, -14.140380899999672 ], [ 24.843689000000428, -14.143310500000235 ], [ 24.864685100000024, -14.150390599999895 ], [ 24.914672900000241, -14.159484899999766 ], [ 24.942077599999859, -14.181579599999658 ], [ 24.978698699999953, -14.195007299999707 ], [ 24.996883500000152, -14.192079500000313 ], [ 25.02508540000013, -14.194885299999962 ], [ 25.039916999999683, -14.209289599999927 ], [ 25.074890100000026, -14.199585000000297 ], [ 25.102722199999956, -14.208801300000319 ], [ 25.109130900000437, -14.248290999999719 ], [ 25.1265259, -14.256591800000256 ], [ 25.116516100000375, -14.271606400000106 ], [ 25.127929700000209, -14.278503399999567 ], [ 25.135314900000154, -14.296203599999908 ], [ 25.119873, -14.300781199999976 ], [ 25.089721699999579, -14.355590800000197 ], [ 25.077880900000345, -14.3693848 ], [ 25.0759277, -14.404480000000174 ], [ 25.045288099999684, -14.43188479999989 ], [ 24.991837899999673, -14.486176299999808 ], [ 24.969837900000144, -14.532376299999804 ], [ 24.975637900000134, -14.582176299999761 ], [ 24.988837900000391, -14.59567630000033 ], [ 25.029737899999986, -14.619476300000265 ], [ 25.034086700000334, -14.621650700000265 ], [ 25.038137900000311, -14.623676299999863 ], [ 25.083137900000338, -14.623076300000315 ], [ 25.137537899999856, -14.628776300000181 ], [ 25.14473789999975, -14.619576299999808 ], [ 25.195678699999732, -14.622802700000355 ], [ 25.236328100000165, -14.597900399999618 ], [ 25.267883300000342, -14.590698199999606 ], [ 25.31170650000006, -14.588989300000225 ], [ 25.338068199999654, -14.58258130000042 ], [ 25.372237900000023, -14.583576300000157 ], [ 25.389437899999628, -14.588376299999837 ], [ 25.441894500000103, -14.579406699999957 ], [ 25.487914999999635, -14.559875500000354 ], [ 25.530937900000087, -14.532376299999804 ], [ 25.557537900000078, -14.525576299999978 ], [ 25.593437900000271, -14.525376299999644 ], [ 25.596937899999585, -14.536378799999945 ], [ 25.58013789999983, -14.567576299999907 ], [ 25.553837900000392, -14.587676299999867 ], [ 25.537637899999954, -14.621476300000133 ], [ 25.516337899999925, -14.645376299999663 ], [ 25.512737900000428, -14.657076300000353 ], [ 25.482137900000193, -14.682376300000227 ], [ 25.481337899999609, -14.701676299999926 ], [ 25.497237900000389, -14.727376300000198 ], [ 25.491837900000242, -14.749476300000435 ], [ 25.491537899999685, -14.782376300000374 ], [ 25.467137900000186, -14.793076300000036 ], [ 25.456537900000264, -14.80727629999976 ], [ 25.447837900000277, -14.847676299999851 ], [ 25.430137899999746, -14.874376299999854 ], [ 25.433437899999586, -14.901576299999901 ], [ 25.466037899999939, -14.960876299999622 ], [ 25.461137899999823, -14.987776300000085 ], [ 25.467337899999659, -15.020076300000412 ], [ 25.463437899999604, -15.040476299999868 ], [ 25.450137900000055, -15.052276300000127 ], [ 25.439337899999764, -15.071876300000262 ], [ 25.421137900000101, -15.081076299999985 ], [ 25.424837899999787, -15.127476300000353 ], [ 25.417537899999704, -15.142976299999633 ], [ 25.384337900000034, -15.139076299999784 ], [ 25.326937900000335, -15.172576299999639 ], [ 25.317014099999749, -15.203113000000215 ], [ 25.327337900000181, -15.212476299999738 ], [ 25.336037900000168, -15.237176299999886 ], [ 25.332137900000113, -15.253276299999692 ], [ 25.31723790000029, -15.276776300000172 ], [ 25.319137900000225, -15.301576300000232 ], [ 25.340737899999915, -15.33787630000009 ], [ 25.3401379, -15.348176299999659 ], [ 25.315537899999828, -15.3690763 ], [ 25.309537900000368, -15.387876300000354 ], [ 25.320237899999576, -15.408676299999687 ], [ 25.315837900000385, -15.427076299999911 ], [ 25.294737899999831, -15.45807629999978 ], [ 25.267137899999781, -15.4591763000003 ], [ 25.249437900000146, -15.465576300000198 ], [ 25.248237899999715, -15.489176299999775 ], [ 25.277937900000072, -15.510376299999876 ], [ 25.278137900000445, -15.520076300000012 ], [ 25.258537899999979, -15.538776299999654 ], [ 25.245537900000091, -15.558076299999659 ], [ 25.219937900000161, -15.582276299999917 ], [ 25.228437899999776, -15.608976299999982 ], [ 25.261137900000314, -15.619176300000213 ], [ 25.276337899999795, -15.636676300000046 ], [ 25.279337899999977, -15.664476300000125 ], [ 25.253237900000016, -15.675676300000326 ], [ 25.245737899999561, -15.698776299999848 ], [ 25.2706379, -15.723276300000173 ], [ 25.289537900000056, -15.754976299999729 ], [ 25.31323790000005, -15.758276299999851 ], [ 25.340637899999727, -15.73827630000026 ], [ 25.355037900000418, -15.715076299999948 ], [ 25.366837899999876, -15.711776300000144 ], [ 25.399037900000383, -15.73887630000038 ], [ 25.40163789999982, -15.768876299999679 ], [ 25.386137899999781, -15.798276300000396 ], [ 25.3838379, -15.827476299999827 ], [ 25.3896379, -15.846076299999837 ], [ 25.354737899999865, -15.909076300000194 ], [ 25.348737900000398, -15.924776299999856 ], [ 25.353837899999988, -15.950476299999632 ], [ 25.337837899999922, -15.972976299999925 ], [ 25.314737900000143, -16.015276299999869 ], [ 25.323537900000314, -16.0503763 ], [ 25.34773790000034, -16.063676299999582 ], [ 25.367737899999749, -16.088376299999666 ], [ 25.386937900000373, -16.081676299999842 ], [ 25.415337900000111, -16.0893763 ], [ 25.433237900000115, -16.100076300000257 ], [ 25.430437900000307, -16.101176300000418 ], [ 25.357737900000043, -16.143776300000177 ], [ 25.338937900000165, -16.168776299999717 ], [ 25.319137900000225, -16.185576300000307 ], [ 25.299237900000104, -16.221676300000354 ], [ 25.288937899999841, -16.273976300000296 ], [ 25.27193789999971, -16.286376299999901 ], [ 25.242537899999913, -16.291676299999597 ], [ 25.222237899999943, -16.31837630000016 ], [ 25.19083790000002, -16.332976299999977 ], [ 25.181437899999629, -16.342676300000253 ], [ 25.124637900000149, -16.376976300000308 ], [ 25.100537900000315, -16.396676300000252 ], [ 25.063737900000245, -16.449776300000217 ], [ 25.048637900000053, -16.457276299999631 ], [ 25.027137899999651, -16.500376300000017 ], [ 25.007737899999558, -16.546076299999957 ], [ 25.055237899999732, -16.573176300000348 ], [ 25.05783790000007, -16.585376300000341 ], [ 25.073837900000139, -16.588376300000018 ], [ 25.090737900000082, -16.603376299999709 ], [ 25.098337899999819, -16.622476300000312 ], [ 25.088837900000144, -16.644376300000047 ], [ 25.182637900000064, -16.674876299999809 ], [ 25.213437899999771, -16.678576300000408 ], [ 25.222337900000124, -16.690676299999971 ], [ 25.239237900000074, -16.695476299999676 ], [ 25.219037900000284, -16.774776300000056 ], [ 25.260337899999726, -16.906376300000307 ], [ 25.244637900000221, -16.947176300000045 ], [ 25.189137899999558, -16.974276299999733 ], [ 25.172237899999619, -16.955476299999852 ], [ 25.155491899999834, -17.02074229999965 ] ], [ [ 23.687500000000284, -16.720214800000139 ], [ 23.693253400000014, -16.724272499999845 ], [ 23.694837900000355, -16.721476300000116 ], [ 23.687500000000284, -16.720214800000139 ] ], [ [ 24.115131499999709, -16.21256819999962 ], [ 24.1161379000003, -16.206676299999781 ], [ 24.115497700000354, -16.19407449999963 ], [ 24.115131499999709, -16.21256819999962 ] ], [ [ 24.227741300000314, -15.9363841 ], [ 24.270537899999567, -15.878976300000321 ], [ 24.241535300000297, -15.916791799999633 ], [ 24.227741300000314, -15.9363841 ] ], [ [ 24.432331199999897, -15.611371900000306 ], [ 24.446581599999895, -15.60553170000027 ], [ 24.43831259999962, -15.608381200000354 ], [ 24.432331199999897, -15.611371900000306 ] ], [ [ 24.541706199999769, -15.517194599999971 ], [ 24.563837899999861, -15.511176299999947 ], [ 24.578937599999584, -15.500776199999805 ], [ 24.541706199999769, -15.517194599999971 ] ] ] } }, -{ "type": "Feature", "properties": { "area_id": "ZMB_1_19", "area_name": "North-Western", "area_level": 1.0, "parent_area_id": "ZMB", "spectrum_region_code": 19.0, "area_sort_order": 11, "center_x": 25.409011386058857, "center_y": -12.8091334, "area_level_label": "Province", "display": true, "spectrum_level": true, "epp_level": true, "naomi_level": false, "pepfar_psnu_level": false }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 26.875337900000297, -13.437376299999885 ], [ 26.857237899999923, -13.448776300000064 ], [ 26.840637899999635, -13.510776299999902 ], [ 26.812737899999924, -13.554976299999598 ], [ 26.783937900000343, -13.611076300000116 ], [ 26.773437899999706, -13.656076299999871 ], [ 26.778237899999638, -13.682376300000062 ], [ 26.7977379, -13.704176300000256 ], [ 26.831237900000144, -13.725576299999773 ], [ 26.835876500000204, -13.728698700000086 ], [ 26.867126500000296, -13.752807599999706 ], [ 26.877319299999776, -13.79577640000038 ], [ 26.887512199999716, -13.806091300000176 ], [ 26.933288600000175, -13.819274899999987 ], [ 26.94268799999961, -13.845092800000385 ], [ 26.925720200000345, -13.890808100000047 ], [ 26.910705600000032, -13.918884300000016 ], [ 26.905090299999596, -13.983398400000238 ], [ 26.891479500000397, -13.999694800000087 ], [ 26.859680200000241, -14.021911599999887 ], [ 26.861511199999857, -14.03887940000042 ], [ 26.8869019, -14.074096700000036 ], [ 26.941101099999969, -14.126098600000304 ], [ 26.964294399999829, -14.141296399999932 ], [ 26.972717299999807, -14.15417480000035 ], [ 26.978881799999851, -14.214294399999797 ], [ 26.977477999999632, -14.231384300000265 ], [ 26.9766564, -14.235718499999827 ], [ 26.976537899999581, -14.235776300000047 ], [ 26.971737899999649, -14.289576299999906 ], [ 26.975137899999677, -14.310276299999758 ], [ 26.976537899999581, -14.375576300000432 ], [ 26.972137900000394, -14.394376299999935 ], [ 26.955637900000294, -14.42007630000017 ], [ 26.924937899999875, -14.414176300000287 ], [ 26.891937899999679, -14.4181763000001 ], [ 26.855337899999984, -14.411376299999915 ], [ 26.831237900000144, -14.419776300000166 ], [ 26.8021379, -14.413176300000304 ], [ 26.779337899999881, -14.427376300000232 ], [ 26.754837900000201, -14.431276300000194 ], [ 26.745337899999626, -14.447376300000089 ], [ 26.71483789999958, -14.450376300000285 ], [ 26.686337899999653, -14.459276300000248 ], [ 26.660837899999912, -14.444076299999585 ], [ 26.625137900000091, -14.442876300000247 ], [ 26.613237900000446, -14.4614763 ], [ 26.599837899999816, -14.462276299999655 ], [ 26.582937899999873, -14.452976299999854 ], [ 26.556037900000224, -14.455076299999709 ], [ 26.538337899999696, -14.46917630000031 ], [ 26.526237899999682, -14.49047629999961 ], [ 26.526637900000424, -14.529276299999671 ], [ 26.52053789999988, -14.539676299999586 ], [ 26.490837900000418, -14.549776299999916 ], [ 26.464337899999713, -14.563576300000323 ], [ 26.442637899999838, -14.58027629999969 ], [ 26.40243789999975, -14.639576299999693 ], [ 26.3827379, -14.659576300000328 ], [ 26.386437899999681, -14.691076300000315 ], [ 26.379137899999598, -14.70147630000042 ], [ 26.335437900000191, -14.730676299999647 ], [ 26.324737900000084, -14.723976300000267 ], [ 26.312537899999882, -14.696476300000205 ], [ 26.269937899999828, -14.682576300000242 ], [ 26.241337899999717, -14.667776300000208 ], [ 26.193237900000227, -14.654176300000108 ], [ 26.2006374, -14.615587 ], [ 26.200177599999702, -14.615451399999742 ], [ 26.185737899999769, -14.612876300000071 ], [ 26.185729999999566, -14.612793000000336 ], [ 25.61427890000007, -14.538629299999975 ], [ 25.596937899999585, -14.536378799999945 ], [ 25.593437900000271, -14.525376299999644 ], [ 25.557537900000078, -14.525576299999978 ], [ 25.530937900000087, -14.532376299999804 ], [ 25.487914999999635, -14.559875500000354 ], [ 25.441894500000103, -14.579406699999957 ], [ 25.389437899999628, -14.588376299999837 ], [ 25.372237900000023, -14.583576300000157 ], [ 25.338068199999654, -14.58258130000042 ], [ 25.31170650000006, -14.588989300000225 ], [ 25.267883300000342, -14.590698199999606 ], [ 25.236328100000165, -14.597900399999618 ], [ 25.195678699999732, -14.622802700000355 ], [ 25.14473789999975, -14.619576299999808 ], [ 25.137537899999856, -14.628776300000181 ], [ 25.083137900000338, -14.623076300000315 ], [ 25.038137900000311, -14.623676299999863 ], [ 25.034086700000334, -14.621650700000265 ], [ 25.029737899999986, -14.619476300000265 ], [ 24.988837900000391, -14.59567630000033 ], [ 24.975637900000134, -14.582176299999761 ], [ 24.969837900000144, -14.532376299999804 ], [ 24.991837899999673, -14.486176299999808 ], [ 25.045288099999684, -14.43188479999989 ], [ 25.0759277, -14.404480000000174 ], [ 25.077880900000345, -14.3693848 ], [ 25.089721699999579, -14.355590800000197 ], [ 25.119873, -14.300781199999976 ], [ 25.135314900000154, -14.296203599999908 ], [ 25.127929700000209, -14.278503399999567 ], [ 25.116516100000375, -14.271606400000106 ], [ 25.1265259, -14.256591800000256 ], [ 25.109130900000437, -14.248290999999719 ], [ 25.102722199999956, -14.208801300000319 ], [ 25.074890100000026, -14.199585000000297 ], [ 25.039916999999683, -14.209289599999927 ], [ 25.02508540000013, -14.194885299999962 ], [ 24.996883500000152, -14.192079500000313 ], [ 24.978698699999953, -14.195007299999707 ], [ 24.942077599999859, -14.181579599999658 ], [ 24.914672900000241, -14.159484899999766 ], [ 24.864685100000024, -14.150390599999895 ], [ 24.843689000000428, -14.143310500000235 ], [ 24.815307600000423, -14.140380899999672 ], [ 24.806518600000263, -14.129089399999668 ], [ 24.768127399999749, -14.118896499999883 ], [ 24.754272499999676, -14.106994600000426 ], [ 24.740112299999954, -14.079711900000198 ], [ 24.754272499999676, -14.056579599999679 ], [ 24.750488300000214, -14.027099600000401 ], [ 24.727294899999897, -13.993103 ], [ 24.684326200000339, -13.956787099999602 ], [ 24.671081500000422, -13.95361329999958 ], [ 24.641479500000088, -13.970703099999565 ], [ 24.6572876, -14.006591800000132 ], [ 24.644681000000318, -14.015329899999783 ], [ 24.628723099999686, -13.993591300000164 ], [ 24.624084499999629, -13.973083500000239 ], [ 24.611084000000151, -13.95770260000036 ], [ 24.60412599999961, -13.974792499999834 ], [ 24.585876499999891, -13.98510740000042 ], [ 24.579101599999671, -13.969604499999777 ], [ 24.534912099999755, -13.946106 ], [ 24.511901900000218, -13.920776400000181 ], [ 24.492126499999618, -13.910888699999918 ], [ 24.485473599999608, -13.948303200000277 ], [ 24.467529299999981, -13.952880900000153 ], [ 24.452270500000129, -13.946411100000164 ], [ 24.436279299999889, -13.958190900000057 ], [ 24.41387940000007, -13.941894499999979 ], [ 24.382324199999889, -13.946594200000403 ], [ 24.364685100000354, -13.942382799999587 ], [ 24.34387210000018, -13.919006299999596 ], [ 24.345975800000339, -13.911611499999651 ], [ 24.339696499999789, -13.898010299999667 ], [ 24.317845999999591, -13.888793900000231 ], [ 24.3006951, -13.910278300000389 ], [ 24.318456300000211, -13.928100600000104 ], [ 24.30386890000019, -13.935485799999872 ], [ 24.279454799999975, -13.922485399999864 ], [ 24.270238499999962, -13.908386199999679 ], [ 24.250096899999615, -13.915527300000203 ], [ 24.248449000000321, -13.899475099999687 ], [ 24.21848069999978, -13.910888699999918 ], [ 24.198644300000424, -13.923095700000133 ], [ 24.165258099999729, -13.927490199999951 ], [ 24.153844499999888, -13.9470825 ], [ 24.12387620000025, -13.955200200000016 ], [ 24.104894300000151, -13.936523399999775 ], [ 24.090245899999577, -13.950500499999862 ], [ 24.077245400000098, -13.978576699999856 ], [ 24.063695599999658, -13.978088399999649 ], [ 24.054479299999638, -13.964294399999636 ], [ 24.034093499999759, -13.986999500000035 ], [ 24.019078900000338, -13.990295400000347 ], [ 24.018651599999583, -14.005004899999873 ], [ 23.999242399999627, -13.997375499999714 ], [ 23.975255600000168, -14.000000000000297 ], [ 23.953466099999627, -13.981994600000039 ], [ 23.938695600000184, -13.996704100000365 ], [ 23.923863999999732, -13.984985399999886 ], [ 23.868444099999859, -13.976501499999873 ], [ 23.852452899999623, -13.986511199999894 ], [ 23.836278599999961, -13.965087899999808 ], [ 23.8222405, -13.964294399999636 ], [ 23.801671599999807, -13.983276400000049 ], [ 23.765844000000207, -13.989379900000252 ], [ 23.729467099999649, -14.022705099999806 ], [ 23.706273700000231, -14.027099600000401 ], [ 23.688268299999596, -14.010192900000145 ], [ 23.660680400000096, -14.025085399999986 ], [ 23.643895799999818, -14.025390600000284 ], [ 23.604283900000301, -14.035888699999859 ], [ 23.597140099999663, -14.043196899999757 ], [ 23.567052499999594, -14.070495600000086 ], [ 23.52847830000011, -14.094604500000431 ], [ 23.447240499999804, -14.100402799999687 ], [ 23.427281999999781, -14.107605000000335 ], [ 23.390844, -14.1547852 ], [ 23.370275200000261, -14.164184600000379 ], [ 23.338842099999855, -14.161377000000133 ], [ 23.313451399999714, -14.164184600000379 ], [ 23.305455799999596, -14.186279300000233 ], [ 23.263097399999758, -14.186706500000176 ], [ 23.242650600000221, -14.197692899999916 ], [ 23.228063200000204, -14.1640015 ], [ 23.205480200000068, -14.179687500000016 ], [ 23.196263900000048, -14.173278799999833 ], [ 23.207860600000203, -14.130310099999654 ], [ 23.222448000000224, -14.118286099999972 ], [ 23.250890399999875, -14.056884800000308 ], [ 23.250890399999875, -14.040100099999961 ], [ 23.23428880000036, -14.012390099999795 ], [ 23.218297600000117, -14.004211399999891 ], [ 23.185460700000384, -14.028198200000379 ], [ 23.15445480000027, -14.038391099999806 ], [ 23.133641899999652, -14.030700700000121 ], [ 23.095494899999576, -13.992004400000388 ], [ 23.027257599999643, -14.007812499999902 ], [ 23.008092499999663, -14.005493199999837 ], [ 22.993077900000241, -13.984985399999886 ], [ 22.978856699999969, -13.956481900000385 ], [ 22.947057399999814, -13.931396499999588 ], [ 22.939244900000016, -13.930297900000157 ], [ 22.915868400000274, -13.904785200000314 ], [ 22.88828049999988, -13.897705099999635 ], [ 22.879247300000181, -13.888000499999674 ], [ 22.859655, -13.885986299999793 ], [ 22.799047100000351, -13.926208499999902 ], [ 22.754247299999811, -13.925903300000048 ], [ 22.736241999999635, -13.989990200000049 ], [ 22.715245900000035, -13.998901399999962 ], [ 22.694676999999835, -13.986877400000383 ], [ 22.668248799999684, -13.991210900000278 ], [ 22.635045700000202, -13.95019529999988 ], [ 22.618444099999788, -13.94140620000041 ], [ 22.564244899999814, -13.934509300000427 ], [ 22.526891400000231, -13.914306599999682 ], [ 22.515050499999639, -13.902099599999785 ], [ 22.484044699999977, -13.884887699999727 ], [ 22.448888399999763, -13.876403799999906 ], [ 22.430883099999583, -13.856079100000091 ], [ 22.413243899999589, -13.844604499999862 ], [ 22.388646699999953, -13.836486800000388 ], [ 22.355443599999575, -13.811889600000143 ], [ 22.330480200000192, -13.805175799999837 ], [ 22.30545580000026, -13.776794399999813 ], [ 22.283483200000298, -13.763305699999981 ], [ 22.254247300000142, -13.757690399999921 ], [ 22.213048599999649, -13.763793900000264 ], [ 22.192479700000344, -13.770507800000033 ], [ 22.146093000000167, -13.765197799999763 ], [ 22.134679499999891, -13.771606400000138 ], [ 22.107640899999559, -13.771606400000138 ], [ 22.076085700000277, -13.758789099999872 ], [ 22.048680900000203, -13.740783699999932 ], [ 21.99246749999983, -13.727905300000318 ], [ 21.995727499999955, -13.463928199999776 ], [ 22.002890100000354, -12.997291300000123 ], [ 23.089294400000146, -12.992797900000026 ], [ 23.533081099999904, -12.995300300000343 ], [ 23.946899399999559, -12.997589700000084 ], [ 24.065918000000202, -12.998383100000439 ], [ 24.058105500000401, -12.983673700000173 ], [ 24.035522500000265, -12.962067199999916 ], [ 24.031921400000225, -12.943878700000223 ], [ 24.008728, -12.914581899999947 ], [ 23.9780884, -12.894867499999613 ], [ 23.953674299999779, -12.883576000000295 ], [ 23.934082000000402, -12.864472000000188 ], [ 23.922729499999775, -12.84188900000018 ], [ 23.906677200000324, -12.822662900000228 ], [ 23.905883800000282, -12.795990500000178 ], [ 23.900085400000425, -12.783295200000012 ], [ 23.912902799999582, -12.7314764000003 ], [ 23.926879899999879, -12.716583799999761 ], [ 23.931884800000137, -12.6910711 ], [ 23.930481, -12.664276700000416 ], [ 23.952087400000135, -12.590790399999657 ], [ 23.951721200000396, -12.534576999999784 ], [ 23.978437899999705, -12.504876299999765 ], [ 23.995337899999647, -12.491876300000296 ], [ 24.020337900000261, -12.461376300000051 ], [ 24.033537899999619, -12.452576299999631 ], [ 24.05793790000002, -12.426276299999861 ], [ 24.074537900000301, -12.3919763 ], [ 24.077537899999584, -12.372476300000233 ], [ 24.072237899999621, -12.351176300000349 ], [ 24.053637900000115, -12.335076299999931 ], [ 24.064937900000441, -12.315476300000343 ], [ 24.067937899999723, -12.2951763 ], [ 24.060437900000171, -12.277676299999859 ], [ 24.026437899999909, -12.224076299999927 ], [ 23.999537900000259, -12.195676299999985 ], [ 23.975437900000426, -12.1247763 ], [ 23.973737899999957, -12.070476300000205 ], [ 23.977537899999827, -12.059376299999801 ], [ 23.982937899999975, -11.967376299999748 ], [ 23.981637900000255, -11.946876300000406 ], [ 23.990137899999869, -11.886876299999889 ], [ 24.002337900000072, -11.847276299999818 ], [ 24.017437900000264, -11.82517629999967 ], [ 24.017037900000421, -11.809576299999614 ], [ 23.987337900000064, -11.708776300000148 ], [ 23.967137900000282, -11.661876300000207 ], [ 23.98683790000003, -11.597076299999909 ], [ 24.016037900000359, -11.543876300000083 ], [ 24.028837899999878, -11.510376300000265 ], [ 24.015737899999802, -11.476476300000432 ], [ 24.016837900000048, -11.454376299999737 ], [ 24.029937900000121, -11.429376300000387 ], [ 24.05753790000017, -11.415276300000231 ], [ 24.080073400000426, -11.379273699999695 ], [ 24.049283900000241, -11.301082299999941 ], [ 24.028883900000089, -11.269482300000194 ], [ 24.023583900000126, -11.247682299999743 ], [ 24.029583899999594, -11.155682300000187 ], [ 24.025083900000215, -11.139982300000257 ], [ 23.998883900000074, -11.122282300000281 ], [ 23.999583899999571, -11.109382300000432 ], [ 24.013483900000235, -11.0906823 ], [ 24.0036839, -11.043582300000326 ], [ 24.002983899999599, -11.022682300000382 ], [ 24.017583899999764, -10.975582300000083 ], [ 24.010583900000238, -10.951782300000147 ], [ 23.985683899999813, -10.921482299999663 ], [ 23.978583900000103, -10.904482299999771 ], [ 24.01488390000014, -10.889582299999645 ], [ 24.059783899999978, -10.890182299999804 ], [ 24.104983900000374, -10.9035823 ], [ 24.115883899999954, -10.913782299999585 ], [ 24.113483899999988, -10.9515823 ], [ 24.126483899999876, -10.9681823 ], [ 24.127983899999968, -11.009282299999724 ], [ 24.136183899999924, -11.024482299999891 ], [ 24.150783900000086, -11.029482300000387 ], [ 24.175283899999769, -11.016982300000107 ], [ 24.190483900000149, -11.021282299999655 ], [ 24.232183900000329, -11.041982299999647 ], [ 24.293083900000241, -11.043782300000277 ], [ 24.331483899999686, -11.058982300000213 ], [ 24.374083899999746, -11.088782300000451 ], [ 24.384183899999638, -11.106882300000253 ], [ 24.384483900000191, -11.125382299999677 ], [ 24.375283900000177, -11.170782300000072 ], [ 24.38858389999972, -11.197882299999749 ], [ 24.394283900000428, -11.2273823 ], [ 24.38308390000029, -11.277482299999715 ], [ 24.353683899999591, -11.334882300000167 ], [ 24.337583900000233, -11.354082299999739 ], [ 24.315883900000362, -11.363182300000187 ], [ 24.286283900000189, -11.368382300000366 ], [ 24.274883899999683, -11.384082300000232 ], [ 24.297883900000173, -11.399182299999978 ], [ 24.331983899999717, -11.402382300000024 ], [ 24.350983899999967, -11.395982299999947 ], [ 24.3664839, -11.399282299999699 ], [ 24.421083899999893, -11.433682299999882 ], [ 24.43428390000015, -11.454382299999825 ], [ 24.465783900000254, -11.453282300000412 ], [ 24.501683899999549, -11.457182299999662 ], [ 24.541883899999643, -11.439882299999677 ], [ 24.568583899999823, -11.441382300000125 ], [ 24.579283899999925, -11.435882300000413 ], [ 24.595658100000403, -11.406490899999982 ], [ 24.628537899999642, -11.393776299999709 ], [ 24.645137899999924, -11.370776300000303 ], [ 24.672137899999758, -11.344376300000292 ], [ 24.697537900000217, -11.326276300000234 ], [ 24.72733789999986, -11.318476300000194 ], [ 24.746637899999772, -11.29927630000042 ], [ 24.768537900000016, -11.295576300000116 ], [ 24.794537899999792, -11.299676299999737 ], [ 24.846437900000048, -11.287276299999739 ], [ 24.874037900000101, -11.265876300000439 ], [ 24.914337900000383, -11.266476299999644 ], [ 24.949337899999797, -11.252376300000416 ], [ 24.96863789999971, -11.253076299999838 ], [ 25.017437899999603, -11.240776299999586 ], [ 25.071137899999616, -11.249976299999654 ], [ 25.118937900000347, -11.2413763 ], [ 25.15813790000038, -11.230776299999739 ], [ 25.195837900000324, -11.227976299999865 ], [ 25.223437900000373, -11.222176299999678 ], [ 25.283237900000035, -11.190276299999585 ], [ 25.338037900000291, -11.190376300000171 ], [ 25.343237900000069, -11.214876300000151 ], [ 25.320937899999976, -11.249676299999944 ], [ 25.323837899999972, -11.2642763 ], [ 25.316037899999856, -11.27887630000029 ], [ 25.297037899999612, -11.291476300000049 ], [ 25.291937900000022, -11.306276300000249 ], [ 25.303837899999664, -11.329676299999569 ], [ 25.280337900000038, -11.348376300000433 ], [ 25.277137900000387, -11.368076299999831 ], [ 25.291237899999619, -11.401176300000357 ], [ 25.298237900000043, -11.4322763 ], [ 25.295837900000077, -11.458076299999826 ], [ 25.311837900000146, -11.488476299999688 ], [ 25.311637899999774, -11.496776299999683 ], [ 25.287337899999564, -11.511076299999738 ], [ 25.310437900000238, -11.563176300000316 ], [ 25.324737899999846, -11.579076300000247 ], [ 25.331337900000424, -11.620076299999912 ], [ 25.348937899999871, -11.631576299999761 ], [ 25.386137899999781, -11.644376300000133 ], [ 25.416537899999643, -11.668476299999854 ], [ 25.442537900000318, -11.668476299999854 ], [ 25.477537899999735, -11.678276299999915 ], [ 25.474000199999551, -11.7103417 ], [ 25.495633200000174, -11.719844100000074 ], [ 25.498464700000341, -11.7518954 ], [ 25.488851700000303, -11.773215400000176 ], [ 25.508839200000025, -11.78707339999964 ], [ 25.51597760000022, -11.778050499999736 ], [ 25.531910400000122, -11.781591100000197 ], [ 25.55486750000021, -11.760518599999648 ], [ 25.573598600000228, -11.759319299999696 ], [ 25.587475599999884, -11.7489259 ], [ 25.595641900000199, -11.731907899999765 ], [ 25.625394700000427, -11.727453600000354 ], [ 25.654576399999691, -11.72899550000013 ], [ 25.666111999999739, -11.747612399999815 ], [ 25.670337999999809, -11.768970399999853 ], [ 25.706058400000419, -11.804393499999955 ], [ 25.745533700000308, -11.809461699999774 ], [ 25.780797299999971, -11.827164899999758 ], [ 25.804068399999977, -11.821168699999781 ], [ 25.8352632, -11.826236899999982 ], [ 25.856892499999862, -11.808105400000438 ], [ 25.8877303, -11.805963900000329 ], [ 25.891870500000159, -11.826451100000188 ], [ 25.888943800000199, -11.844439799999671 ], [ 25.901864300000252, -11.850364700000011 ], [ 25.909645099999672, -11.867282600000381 ], [ 25.933701500000396, -11.883843700000025 ], [ 25.967894300000431, -11.875705900000373 ], [ 25.99009470000037, -11.895193700000146 ], [ 25.997233099999658, -11.912611400000017 ], [ 25.9842412, -11.925888700000257 ], [ 25.984740899999551, -11.944591299999704 ], [ 26.011141799999692, -11.935485600000218 ], [ 26.040437900000331, -11.929776299999851 ], [ 26.124437900000014, -11.937476299999764 ], [ 26.15283789999976, -11.936076300000094 ], [ 26.1718379, -11.930576300000228 ], [ 26.223837899999559, -11.923776300000197 ], [ 26.28813790000039, -11.939876300000247 ], [ 26.322937900000333, -11.958576300000042 ], [ 26.330037900000047, -11.958576300000042 ], [ 26.37953790000034, -11.936976299999772 ], [ 26.414137899999915, -11.928076299999796 ], [ 26.4300379, -11.917876299999808 ], [ 26.457337900000191, -11.913576299999827 ], [ 26.47333790000026, -11.916376299999831 ], [ 26.546437900000363, -11.957676300000273 ], [ 26.557837899999974, -11.971276299999889 ], [ 26.571437900000078, -11.974276299999932 ], [ 26.6128379, -11.967576299999903 ], [ 26.658837899999792, -11.983476299999758 ], [ 26.68283790000034, -11.980876299999936 ], [ 26.711437899999552, -12.001076299999605 ], [ 26.727337900000336, -11.993576300000306 ], [ 26.754737900000016, -11.968476299999887 ], [ 26.795237899999766, -11.959576300000229 ], [ 26.836037900000075, -11.980176299999599 ], [ 26.849162599999946, -11.982366600000134 ], [ 26.877038800000385, -11.982256299999579 ], [ 26.886747000000209, -11.976831200000419 ], [ 26.894932300000296, -11.957605100000251 ], [ 26.912730699999983, -11.946564399999845 ], [ 26.914919800000025, -11.934762299999795 ], [ 26.939190300000043, -11.936665899999751 ], [ 26.957178999999741, -11.917439799999812 ], [ 26.969837699999697, -11.876798600000019 ], [ 26.986779500000406, -11.85566899999964 ], [ 27.008194599999626, -11.839679000000421 ], [ 26.993632300000332, -11.822356500000335 ], [ 27.003435699999951, -11.803415999999565 ], [ 27.006671800000344, -11.760585699999783 ], [ 27.037977300000083, -11.7173602000003 ], [ 27.046186499999902, -11.711221200000276 ], [ 27.041832000000433, -11.675243800000024 ], [ 27.032694899999782, -11.66981860000004 ], [ 27.022344299999826, -11.644477300000341 ], [ 27.030910300000407, -11.636268199999906 ], [ 27.016276599999699, -11.615638299999578 ], [ 27.052325500000084, -11.590011500000136 ], [ 27.081164500000199, -11.606001499999813 ], [ 27.099367399999647, -11.594437300000161 ], [ 27.122852700000305, -11.587584399999944 ], [ 27.159187099999595, -11.599362799999763 ], [ 27.173892100000359, -11.58458630000005 ], [ 27.191238399999932, -11.581445400000263 ], [ 27.209013000000343, -11.566026499999673 ], [ 27.2215051, -11.626131700000156 ], [ 27.228286599999866, -11.636981999999692 ], [ 27.22835800000038, -11.65911100000012 ], [ 27.236709899999873, -11.680383399999936 ], [ 27.227287199999854, -11.69351799999972 ], [ 27.233045500000436, -11.711625699999713 ], [ 27.220672300000288, -11.747793500000121 ], [ 27.23161790000005, -11.766734 ], [ 27.2312371, -11.78262880000011 ], [ 27.257411200000245, -11.799475400000194 ], [ 27.26407370000015, -11.793193699999865 ], [ 27.292341699999753, -11.802997000000413 ], [ 27.351161999999686, -11.845732100000257 ], [ 27.375337299999916, -11.855630699999878 ], [ 27.396942799999607, -11.871239999999862 ], [ 27.398941599999631, -11.88399389999962 ], [ 27.426067399999987, -11.895129799999586 ], [ 27.438345400000347, -11.909787200000126 ], [ 27.4688025, -11.930631299999822 ], [ 27.476702300000273, -11.94862 ], [ 27.4688025, -11.969464100000375 ], [ 27.461727, -12.005384499999854 ], [ 27.465210500000254, -12.04238980000023 ], [ 27.474333300000175, -12.054049200000202 ], [ 27.49604590000019, -12.056547599999893 ], [ 27.494915700000146, -12.069158799999792 ], [ 27.511334000000222, -12.090871399999626 ], [ 27.510203699999717, -12.121947100000375 ], [ 27.522196200000273, -12.15828149999985 ], [ 27.570987099999865, -12.206928000000397 ], [ 27.5897848, -12.205738300000254 ], [ 27.61619679999971, -12.222275500000308 ], [ 27.614329599999799, -12.239289799999677 ], [ 27.62890379999962, -12.256065000000405 ], [ 27.622370099999589, -12.265999800000216 ], [ 27.619821699999925, -12.266057500000349 ], [ 27.61726760000024, -12.265998099999628 ], [ 27.58339370000008, -12.271063100000088 ], [ 27.572370900000223, -12.265918700000151 ], [ 27.558850399999962, -12.276638400000154 ], [ 27.523878099999685, -12.289076800000219 ], [ 27.51039550000031, -12.297910900000211 ], [ 27.508518, -12.29896229999965 ], [ 27.500456900000291, -12.314330099999772 ], [ 27.499049200000197, -12.315118100000383 ], [ 27.492908799999906, -12.301817700000244 ], [ 27.500998900000202, -12.282306099999609 ], [ 27.48034520000018, -12.27707129999963 ], [ 27.470008799999597, -12.287651900000293 ], [ 27.4583971, -12.276706399999737 ], [ 27.473743600000365, -12.255104699999606 ], [ 27.455869100000225, -12.247223900000346 ], [ 27.43897260000012, -12.264962800000262 ], [ 27.425686599999935, -12.256550199999673 ], [ 27.395794599999871, -12.28317039999985 ], [ 27.362333499999714, -12.296554900000446 ], [ 27.356384799999553, -12.320646899999577 ], [ 27.335564500000121, -12.313805900000402 ], [ 27.306118700000123, -12.32793399999975 ], [ 27.292585500000154, -12.364815599999718 ], [ 27.287835499999872, -12.362104100000256 ], [ 27.251688499999908, -12.352472199999788 ], [ 27.193094300000261, -12.344441500000125 ], [ 27.122602799999846, -12.346226100000308 ], [ 27.058005599999589, -12.332448699999734 ], [ 27.083531500000127, -12.415272199999583 ], [ 27.063358499999882, -12.448674799999624 ], [ 27.06857100000024, -12.490664200000252 ], [ 27.093478000000349, -12.521295799999855 ], [ 27.039351200000077, -12.536286399999891 ], [ 27.002450399999756, -12.557205799999801 ], [ 26.967759700000318, -12.59125059999964 ], [ 26.962500199999663, -12.617205699999671 ], [ 26.935345700000074, -12.632624600000414 ], [ 26.902849599999783, -12.631652500000275 ], [ 26.882637900000375, -12.655476300000309 ], [ 26.872337900000112, -12.686676299999734 ], [ 26.869837899999961, -12.710876300000258 ], [ 26.858337900000166, -12.7367763 ], [ 26.858737900000012, -12.755776299999937 ], [ 26.873837900000204, -12.773176300000125 ], [ 26.900337900000011, -12.791876299999602 ], [ 26.920437899999605, -12.822276299999757 ], [ 26.910637900000268, -12.8503763 ], [ 26.886137899999685, -12.879776299999907 ], [ 26.892537899999894, -12.890576300000397 ], [ 26.914337899999957, -12.904976299999971 ], [ 26.946937900000311, -12.933276299999608 ], [ 26.980337900000354, -12.94357630000022 ], [ 27.01213790000012, -12.946876300000076 ], [ 27.026337900000438, -12.955076300000439 ], [ 27.042937899999821, -12.986076300000219 ], [ 27.059037900000074, -12.997776300000057 ], [ 27.094437900000241, -12.996176300000359 ], [ 27.082637899999888, -13.050876300000098 ], [ 27.081937900000383, -13.07917629999962 ], [ 27.075537900000175, -13.1102763 ], [ 27.064837900000068, -13.127376299999778 ], [ 27.021137899999761, -13.146876299999912 ], [ 26.995237900000177, -13.181676299999666 ], [ 26.963037899999666, -13.213976299999661 ], [ 26.955737899999583, -13.230176300000359 ], [ 26.956637900000359, -13.256776300000348 ], [ 26.975437900000234, -13.306176299999958 ], [ 26.975337900000049, -13.342176300000169 ], [ 26.966637900000062, -13.362176299999913 ], [ 26.923137900000128, -13.370276300000249 ], [ 26.915837900000046, -13.38037630000011 ], [ 26.910237900000428, -13.422276300000419 ], [ 26.875337900000297, -13.437376299999885 ] ] ] } }, +{ "type": "Feature", "properties": { "area_id": "ZMB_1_19", "area_name": "North_Western", "area_level": 1.0, "parent_area_id": "ZMB", "spectrum_region_code": 19.0, "area_sort_order": 11, "center_x": 25.409011386058857, "center_y": -12.8091334, "area_level_label": "Province", "display": true, "spectrum_level": true, "epp_level": true, "naomi_level": false, "pepfar_psnu_level": false }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 26.875337900000297, -13.437376299999885 ], [ 26.857237899999923, -13.448776300000064 ], [ 26.840637899999635, -13.510776299999902 ], [ 26.812737899999924, -13.554976299999598 ], [ 26.783937900000343, -13.611076300000116 ], [ 26.773437899999706, -13.656076299999871 ], [ 26.778237899999638, -13.682376300000062 ], [ 26.7977379, -13.704176300000256 ], [ 26.831237900000144, -13.725576299999773 ], [ 26.835876500000204, -13.728698700000086 ], [ 26.867126500000296, -13.752807599999706 ], [ 26.877319299999776, -13.79577640000038 ], [ 26.887512199999716, -13.806091300000176 ], [ 26.933288600000175, -13.819274899999987 ], [ 26.94268799999961, -13.845092800000385 ], [ 26.925720200000345, -13.890808100000047 ], [ 26.910705600000032, -13.918884300000016 ], [ 26.905090299999596, -13.983398400000238 ], [ 26.891479500000397, -13.999694800000087 ], [ 26.859680200000241, -14.021911599999887 ], [ 26.861511199999857, -14.03887940000042 ], [ 26.8869019, -14.074096700000036 ], [ 26.941101099999969, -14.126098600000304 ], [ 26.964294399999829, -14.141296399999932 ], [ 26.972717299999807, -14.15417480000035 ], [ 26.978881799999851, -14.214294399999797 ], [ 26.977477999999632, -14.231384300000265 ], [ 26.9766564, -14.235718499999827 ], [ 26.976537899999581, -14.235776300000047 ], [ 26.971737899999649, -14.289576299999906 ], [ 26.975137899999677, -14.310276299999758 ], [ 26.976537899999581, -14.375576300000432 ], [ 26.972137900000394, -14.394376299999935 ], [ 26.955637900000294, -14.42007630000017 ], [ 26.924937899999875, -14.414176300000287 ], [ 26.891937899999679, -14.4181763000001 ], [ 26.855337899999984, -14.411376299999915 ], [ 26.831237900000144, -14.419776300000166 ], [ 26.8021379, -14.413176300000304 ], [ 26.779337899999881, -14.427376300000232 ], [ 26.754837900000201, -14.431276300000194 ], [ 26.745337899999626, -14.447376300000089 ], [ 26.71483789999958, -14.450376300000285 ], [ 26.686337899999653, -14.459276300000248 ], [ 26.660837899999912, -14.444076299999585 ], [ 26.625137900000091, -14.442876300000247 ], [ 26.613237900000446, -14.4614763 ], [ 26.599837899999816, -14.462276299999655 ], [ 26.582937899999873, -14.452976299999854 ], [ 26.556037900000224, -14.455076299999709 ], [ 26.538337899999696, -14.46917630000031 ], [ 26.526237899999682, -14.49047629999961 ], [ 26.526637900000424, -14.529276299999671 ], [ 26.52053789999988, -14.539676299999586 ], [ 26.490837900000418, -14.549776299999916 ], [ 26.464337899999713, -14.563576300000323 ], [ 26.442637899999838, -14.58027629999969 ], [ 26.40243789999975, -14.639576299999693 ], [ 26.3827379, -14.659576300000328 ], [ 26.386437899999681, -14.691076300000315 ], [ 26.379137899999598, -14.70147630000042 ], [ 26.335437900000191, -14.730676299999647 ], [ 26.324737900000084, -14.723976300000267 ], [ 26.312537899999882, -14.696476300000205 ], [ 26.269937899999828, -14.682576300000242 ], [ 26.241337899999717, -14.667776300000208 ], [ 26.193237900000227, -14.654176300000108 ], [ 26.2006374, -14.615587 ], [ 26.200177599999702, -14.615451399999742 ], [ 26.185737899999769, -14.612876300000071 ], [ 26.185729999999566, -14.612793000000336 ], [ 25.61427890000007, -14.538629299999975 ], [ 25.596937899999585, -14.536378799999945 ], [ 25.593437900000271, -14.525376299999644 ], [ 25.557537900000078, -14.525576299999978 ], [ 25.530937900000087, -14.532376299999804 ], [ 25.487914999999635, -14.559875500000354 ], [ 25.441894500000103, -14.579406699999957 ], [ 25.389437899999628, -14.588376299999837 ], [ 25.372237900000023, -14.583576300000157 ], [ 25.338068199999654, -14.58258130000042 ], [ 25.31170650000006, -14.588989300000225 ], [ 25.267883300000342, -14.590698199999606 ], [ 25.236328100000165, -14.597900399999618 ], [ 25.195678699999732, -14.622802700000355 ], [ 25.14473789999975, -14.619576299999808 ], [ 25.137537899999856, -14.628776300000181 ], [ 25.083137900000338, -14.623076300000315 ], [ 25.038137900000311, -14.623676299999863 ], [ 25.034086700000334, -14.621650700000265 ], [ 25.029737899999986, -14.619476300000265 ], [ 24.988837900000391, -14.59567630000033 ], [ 24.975637900000134, -14.582176299999761 ], [ 24.969837900000144, -14.532376299999804 ], [ 24.991837899999673, -14.486176299999808 ], [ 25.045288099999684, -14.43188479999989 ], [ 25.0759277, -14.404480000000174 ], [ 25.077880900000345, -14.3693848 ], [ 25.089721699999579, -14.355590800000197 ], [ 25.119873, -14.300781199999976 ], [ 25.135314900000154, -14.296203599999908 ], [ 25.127929700000209, -14.278503399999567 ], [ 25.116516100000375, -14.271606400000106 ], [ 25.1265259, -14.256591800000256 ], [ 25.109130900000437, -14.248290999999719 ], [ 25.102722199999956, -14.208801300000319 ], [ 25.074890100000026, -14.199585000000297 ], [ 25.039916999999683, -14.209289599999927 ], [ 25.02508540000013, -14.194885299999962 ], [ 24.996883500000152, -14.192079500000313 ], [ 24.978698699999953, -14.195007299999707 ], [ 24.942077599999859, -14.181579599999658 ], [ 24.914672900000241, -14.159484899999766 ], [ 24.864685100000024, -14.150390599999895 ], [ 24.843689000000428, -14.143310500000235 ], [ 24.815307600000423, -14.140380899999672 ], [ 24.806518600000263, -14.129089399999668 ], [ 24.768127399999749, -14.118896499999883 ], [ 24.754272499999676, -14.106994600000426 ], [ 24.740112299999954, -14.079711900000198 ], [ 24.754272499999676, -14.056579599999679 ], [ 24.750488300000214, -14.027099600000401 ], [ 24.727294899999897, -13.993103 ], [ 24.684326200000339, -13.956787099999602 ], [ 24.671081500000422, -13.95361329999958 ], [ 24.641479500000088, -13.970703099999565 ], [ 24.6572876, -14.006591800000132 ], [ 24.644681000000318, -14.015329899999783 ], [ 24.628723099999686, -13.993591300000164 ], [ 24.624084499999629, -13.973083500000239 ], [ 24.611084000000151, -13.95770260000036 ], [ 24.60412599999961, -13.974792499999834 ], [ 24.585876499999891, -13.98510740000042 ], [ 24.579101599999671, -13.969604499999777 ], [ 24.534912099999755, -13.946106 ], [ 24.511901900000218, -13.920776400000181 ], [ 24.492126499999618, -13.910888699999918 ], [ 24.485473599999608, -13.948303200000277 ], [ 24.467529299999981, -13.952880900000153 ], [ 24.452270500000129, -13.946411100000164 ], [ 24.436279299999889, -13.958190900000057 ], [ 24.41387940000007, -13.941894499999979 ], [ 24.382324199999889, -13.946594200000403 ], [ 24.364685100000354, -13.942382799999587 ], [ 24.34387210000018, -13.919006299999596 ], [ 24.345975800000339, -13.911611499999651 ], [ 24.339696499999789, -13.898010299999667 ], [ 24.317845999999591, -13.888793900000231 ], [ 24.3006951, -13.910278300000389 ], [ 24.318456300000211, -13.928100600000104 ], [ 24.30386890000019, -13.935485799999872 ], [ 24.279454799999975, -13.922485399999864 ], [ 24.270238499999962, -13.908386199999679 ], [ 24.250096899999615, -13.915527300000203 ], [ 24.248449000000321, -13.899475099999687 ], [ 24.21848069999978, -13.910888699999918 ], [ 24.198644300000424, -13.923095700000133 ], [ 24.165258099999729, -13.927490199999951 ], [ 24.153844499999888, -13.9470825 ], [ 24.12387620000025, -13.955200200000016 ], [ 24.104894300000151, -13.936523399999775 ], [ 24.090245899999577, -13.950500499999862 ], [ 24.077245400000098, -13.978576699999856 ], [ 24.063695599999658, -13.978088399999649 ], [ 24.054479299999638, -13.964294399999636 ], [ 24.034093499999759, -13.986999500000035 ], [ 24.019078900000338, -13.990295400000347 ], [ 24.018651599999583, -14.005004899999873 ], [ 23.999242399999627, -13.997375499999714 ], [ 23.975255600000168, -14.000000000000297 ], [ 23.953466099999627, -13.981994600000039 ], [ 23.938695600000184, -13.996704100000365 ], [ 23.923863999999732, -13.984985399999886 ], [ 23.868444099999859, -13.976501499999873 ], [ 23.852452899999623, -13.986511199999894 ], [ 23.836278599999961, -13.965087899999808 ], [ 23.8222405, -13.964294399999636 ], [ 23.801671599999807, -13.983276400000049 ], [ 23.765844000000207, -13.989379900000252 ], [ 23.729467099999649, -14.022705099999806 ], [ 23.706273700000231, -14.027099600000401 ], [ 23.688268299999596, -14.010192900000145 ], [ 23.660680400000096, -14.025085399999986 ], [ 23.643895799999818, -14.025390600000284 ], [ 23.604283900000301, -14.035888699999859 ], [ 23.597140099999663, -14.043196899999757 ], [ 23.567052499999594, -14.070495600000086 ], [ 23.52847830000011, -14.094604500000431 ], [ 23.447240499999804, -14.100402799999687 ], [ 23.427281999999781, -14.107605000000335 ], [ 23.390844, -14.1547852 ], [ 23.370275200000261, -14.164184600000379 ], [ 23.338842099999855, -14.161377000000133 ], [ 23.313451399999714, -14.164184600000379 ], [ 23.305455799999596, -14.186279300000233 ], [ 23.263097399999758, -14.186706500000176 ], [ 23.242650600000221, -14.197692899999916 ], [ 23.228063200000204, -14.1640015 ], [ 23.205480200000068, -14.179687500000016 ], [ 23.196263900000048, -14.173278799999833 ], [ 23.207860600000203, -14.130310099999654 ], [ 23.222448000000224, -14.118286099999972 ], [ 23.250890399999875, -14.056884800000308 ], [ 23.250890399999875, -14.040100099999961 ], [ 23.23428880000036, -14.012390099999795 ], [ 23.218297600000117, -14.004211399999891 ], [ 23.185460700000384, -14.028198200000379 ], [ 23.15445480000027, -14.038391099999806 ], [ 23.133641899999652, -14.030700700000121 ], [ 23.095494899999576, -13.992004400000388 ], [ 23.027257599999643, -14.007812499999902 ], [ 23.008092499999663, -14.005493199999837 ], [ 22.993077900000241, -13.984985399999886 ], [ 22.978856699999969, -13.956481900000385 ], [ 22.947057399999814, -13.931396499999588 ], [ 22.939244900000016, -13.930297900000157 ], [ 22.915868400000274, -13.904785200000314 ], [ 22.88828049999988, -13.897705099999635 ], [ 22.879247300000181, -13.888000499999674 ], [ 22.859655, -13.885986299999793 ], [ 22.799047100000351, -13.926208499999902 ], [ 22.754247299999811, -13.925903300000048 ], [ 22.736241999999635, -13.989990200000049 ], [ 22.715245900000035, -13.998901399999962 ], [ 22.694676999999835, -13.986877400000383 ], [ 22.668248799999684, -13.991210900000278 ], [ 22.635045700000202, -13.95019529999988 ], [ 22.618444099999788, -13.94140620000041 ], [ 22.564244899999814, -13.934509300000427 ], [ 22.526891400000231, -13.914306599999682 ], [ 22.515050499999639, -13.902099599999785 ], [ 22.484044699999977, -13.884887699999727 ], [ 22.448888399999763, -13.876403799999906 ], [ 22.430883099999583, -13.856079100000091 ], [ 22.413243899999589, -13.844604499999862 ], [ 22.388646699999953, -13.836486800000388 ], [ 22.355443599999575, -13.811889600000143 ], [ 22.330480200000192, -13.805175799999837 ], [ 22.30545580000026, -13.776794399999813 ], [ 22.283483200000298, -13.763305699999981 ], [ 22.254247300000142, -13.757690399999921 ], [ 22.213048599999649, -13.763793900000264 ], [ 22.192479700000344, -13.770507800000033 ], [ 22.146093000000167, -13.765197799999763 ], [ 22.134679499999891, -13.771606400000138 ], [ 22.107640899999559, -13.771606400000138 ], [ 22.076085700000277, -13.758789099999872 ], [ 22.048680900000203, -13.740783699999932 ], [ 21.99246749999983, -13.727905300000318 ], [ 21.995727499999955, -13.463928199999776 ], [ 22.002890100000354, -12.997291300000123 ], [ 23.089294400000146, -12.992797900000026 ], [ 23.533081099999904, -12.995300300000343 ], [ 23.946899399999559, -12.997589700000084 ], [ 24.065918000000202, -12.998383100000439 ], [ 24.058105500000401, -12.983673700000173 ], [ 24.035522500000265, -12.962067199999916 ], [ 24.031921400000225, -12.943878700000223 ], [ 24.008728, -12.914581899999947 ], [ 23.9780884, -12.894867499999613 ], [ 23.953674299999779, -12.883576000000295 ], [ 23.934082000000402, -12.864472000000188 ], [ 23.922729499999775, -12.84188900000018 ], [ 23.906677200000324, -12.822662900000228 ], [ 23.905883800000282, -12.795990500000178 ], [ 23.900085400000425, -12.783295200000012 ], [ 23.912902799999582, -12.7314764000003 ], [ 23.926879899999879, -12.716583799999761 ], [ 23.931884800000137, -12.6910711 ], [ 23.930481, -12.664276700000416 ], [ 23.952087400000135, -12.590790399999657 ], [ 23.951721200000396, -12.534576999999784 ], [ 23.978437899999705, -12.504876299999765 ], [ 23.995337899999647, -12.491876300000296 ], [ 24.020337900000261, -12.461376300000051 ], [ 24.033537899999619, -12.452576299999631 ], [ 24.05793790000002, -12.426276299999861 ], [ 24.074537900000301, -12.3919763 ], [ 24.077537899999584, -12.372476300000233 ], [ 24.072237899999621, -12.351176300000349 ], [ 24.053637900000115, -12.335076299999931 ], [ 24.064937900000441, -12.315476300000343 ], [ 24.067937899999723, -12.2951763 ], [ 24.060437900000171, -12.277676299999859 ], [ 24.026437899999909, -12.224076299999927 ], [ 23.999537900000259, -12.195676299999985 ], [ 23.975437900000426, -12.1247763 ], [ 23.973737899999957, -12.070476300000205 ], [ 23.977537899999827, -12.059376299999801 ], [ 23.982937899999975, -11.967376299999748 ], [ 23.981637900000255, -11.946876300000406 ], [ 23.990137899999869, -11.886876299999889 ], [ 24.002337900000072, -11.847276299999818 ], [ 24.017437900000264, -11.82517629999967 ], [ 24.017037900000421, -11.809576299999614 ], [ 23.987337900000064, -11.708776300000148 ], [ 23.967137900000282, -11.661876300000207 ], [ 23.98683790000003, -11.597076299999909 ], [ 24.016037900000359, -11.543876300000083 ], [ 24.028837899999878, -11.510376300000265 ], [ 24.015737899999802, -11.476476300000432 ], [ 24.016837900000048, -11.454376299999737 ], [ 24.029937900000121, -11.429376300000387 ], [ 24.05753790000017, -11.415276300000231 ], [ 24.080073400000426, -11.379273699999695 ], [ 24.049283900000241, -11.301082299999941 ], [ 24.028883900000089, -11.269482300000194 ], [ 24.023583900000126, -11.247682299999743 ], [ 24.029583899999594, -11.155682300000187 ], [ 24.025083900000215, -11.139982300000257 ], [ 23.998883900000074, -11.122282300000281 ], [ 23.999583899999571, -11.109382300000432 ], [ 24.013483900000235, -11.0906823 ], [ 24.0036839, -11.043582300000326 ], [ 24.002983899999599, -11.022682300000382 ], [ 24.017583899999764, -10.975582300000083 ], [ 24.010583900000238, -10.951782300000147 ], [ 23.985683899999813, -10.921482299999663 ], [ 23.978583900000103, -10.904482299999771 ], [ 24.01488390000014, -10.889582299999645 ], [ 24.059783899999978, -10.890182299999804 ], [ 24.104983900000374, -10.9035823 ], [ 24.115883899999954, -10.913782299999585 ], [ 24.113483899999988, -10.9515823 ], [ 24.126483899999876, -10.9681823 ], [ 24.127983899999968, -11.009282299999724 ], [ 24.136183899999924, -11.024482299999891 ], [ 24.150783900000086, -11.029482300000387 ], [ 24.175283899999769, -11.016982300000107 ], [ 24.190483900000149, -11.021282299999655 ], [ 24.232183900000329, -11.041982299999647 ], [ 24.293083900000241, -11.043782300000277 ], [ 24.331483899999686, -11.058982300000213 ], [ 24.374083899999746, -11.088782300000451 ], [ 24.384183899999638, -11.106882300000253 ], [ 24.384483900000191, -11.125382299999677 ], [ 24.375283900000177, -11.170782300000072 ], [ 24.38858389999972, -11.197882299999749 ], [ 24.394283900000428, -11.2273823 ], [ 24.38308390000029, -11.277482299999715 ], [ 24.353683899999591, -11.334882300000167 ], [ 24.337583900000233, -11.354082299999739 ], [ 24.315883900000362, -11.363182300000187 ], [ 24.286283900000189, -11.368382300000366 ], [ 24.274883899999683, -11.384082300000232 ], [ 24.297883900000173, -11.399182299999978 ], [ 24.331983899999717, -11.402382300000024 ], [ 24.350983899999967, -11.395982299999947 ], [ 24.3664839, -11.399282299999699 ], [ 24.421083899999893, -11.433682299999882 ], [ 24.43428390000015, -11.454382299999825 ], [ 24.465783900000254, -11.453282300000412 ], [ 24.501683899999549, -11.457182299999662 ], [ 24.541883899999643, -11.439882299999677 ], [ 24.568583899999823, -11.441382300000125 ], [ 24.579283899999925, -11.435882300000413 ], [ 24.595658100000403, -11.406490899999982 ], [ 24.628537899999642, -11.393776299999709 ], [ 24.645137899999924, -11.370776300000303 ], [ 24.672137899999758, -11.344376300000292 ], [ 24.697537900000217, -11.326276300000234 ], [ 24.72733789999986, -11.318476300000194 ], [ 24.746637899999772, -11.29927630000042 ], [ 24.768537900000016, -11.295576300000116 ], [ 24.794537899999792, -11.299676299999737 ], [ 24.846437900000048, -11.287276299999739 ], [ 24.874037900000101, -11.265876300000439 ], [ 24.914337900000383, -11.266476299999644 ], [ 24.949337899999797, -11.252376300000416 ], [ 24.96863789999971, -11.253076299999838 ], [ 25.017437899999603, -11.240776299999586 ], [ 25.071137899999616, -11.249976299999654 ], [ 25.118937900000347, -11.2413763 ], [ 25.15813790000038, -11.230776299999739 ], [ 25.195837900000324, -11.227976299999865 ], [ 25.223437900000373, -11.222176299999678 ], [ 25.283237900000035, -11.190276299999585 ], [ 25.338037900000291, -11.190376300000171 ], [ 25.343237900000069, -11.214876300000151 ], [ 25.320937899999976, -11.249676299999944 ], [ 25.323837899999972, -11.2642763 ], [ 25.316037899999856, -11.27887630000029 ], [ 25.297037899999612, -11.291476300000049 ], [ 25.291937900000022, -11.306276300000249 ], [ 25.303837899999664, -11.329676299999569 ], [ 25.280337900000038, -11.348376300000433 ], [ 25.277137900000387, -11.368076299999831 ], [ 25.291237899999619, -11.401176300000357 ], [ 25.298237900000043, -11.4322763 ], [ 25.295837900000077, -11.458076299999826 ], [ 25.311837900000146, -11.488476299999688 ], [ 25.311637899999774, -11.496776299999683 ], [ 25.287337899999564, -11.511076299999738 ], [ 25.310437900000238, -11.563176300000316 ], [ 25.324737899999846, -11.579076300000247 ], [ 25.331337900000424, -11.620076299999912 ], [ 25.348937899999871, -11.631576299999761 ], [ 25.386137899999781, -11.644376300000133 ], [ 25.416537899999643, -11.668476299999854 ], [ 25.442537900000318, -11.668476299999854 ], [ 25.477537899999735, -11.678276299999915 ], [ 25.474000199999551, -11.7103417 ], [ 25.495633200000174, -11.719844100000074 ], [ 25.498464700000341, -11.7518954 ], [ 25.488851700000303, -11.773215400000176 ], [ 25.508839200000025, -11.78707339999964 ], [ 25.51597760000022, -11.778050499999736 ], [ 25.531910400000122, -11.781591100000197 ], [ 25.55486750000021, -11.760518599999648 ], [ 25.573598600000228, -11.759319299999696 ], [ 25.587475599999884, -11.7489259 ], [ 25.595641900000199, -11.731907899999765 ], [ 25.625394700000427, -11.727453600000354 ], [ 25.654576399999691, -11.72899550000013 ], [ 25.666111999999739, -11.747612399999815 ], [ 25.670337999999809, -11.768970399999853 ], [ 25.706058400000419, -11.804393499999955 ], [ 25.745533700000308, -11.809461699999774 ], [ 25.780797299999971, -11.827164899999758 ], [ 25.804068399999977, -11.821168699999781 ], [ 25.8352632, -11.826236899999982 ], [ 25.856892499999862, -11.808105400000438 ], [ 25.8877303, -11.805963900000329 ], [ 25.891870500000159, -11.826451100000188 ], [ 25.888943800000199, -11.844439799999671 ], [ 25.901864300000252, -11.850364700000011 ], [ 25.909645099999672, -11.867282600000381 ], [ 25.933701500000396, -11.883843700000025 ], [ 25.967894300000431, -11.875705900000373 ], [ 25.99009470000037, -11.895193700000146 ], [ 25.997233099999658, -11.912611400000017 ], [ 25.9842412, -11.925888700000257 ], [ 25.984740899999551, -11.944591299999704 ], [ 26.011141799999692, -11.935485600000218 ], [ 26.040437900000331, -11.929776299999851 ], [ 26.124437900000014, -11.937476299999764 ], [ 26.15283789999976, -11.936076300000094 ], [ 26.1718379, -11.930576300000228 ], [ 26.223837899999559, -11.923776300000197 ], [ 26.28813790000039, -11.939876300000247 ], [ 26.322937900000333, -11.958576300000042 ], [ 26.330037900000047, -11.958576300000042 ], [ 26.37953790000034, -11.936976299999772 ], [ 26.414137899999915, -11.928076299999796 ], [ 26.4300379, -11.917876299999808 ], [ 26.457337900000191, -11.913576299999827 ], [ 26.47333790000026, -11.916376299999831 ], [ 26.546437900000363, -11.957676300000273 ], [ 26.557837899999974, -11.971276299999889 ], [ 26.571437900000078, -11.974276299999932 ], [ 26.6128379, -11.967576299999903 ], [ 26.658837899999792, -11.983476299999758 ], [ 26.68283790000034, -11.980876299999936 ], [ 26.711437899999552, -12.001076299999605 ], [ 26.727337900000336, -11.993576300000306 ], [ 26.754737900000016, -11.968476299999887 ], [ 26.795237899999766, -11.959576300000229 ], [ 26.836037900000075, -11.980176299999599 ], [ 26.849162599999946, -11.982366600000134 ], [ 26.877038800000385, -11.982256299999579 ], [ 26.886747000000209, -11.976831200000419 ], [ 26.894932300000296, -11.957605100000251 ], [ 26.912730699999983, -11.946564399999845 ], [ 26.914919800000025, -11.934762299999795 ], [ 26.939190300000043, -11.936665899999751 ], [ 26.957178999999741, -11.917439799999812 ], [ 26.969837699999697, -11.876798600000019 ], [ 26.986779500000406, -11.85566899999964 ], [ 27.008194599999626, -11.839679000000421 ], [ 26.993632300000332, -11.822356500000335 ], [ 27.003435699999951, -11.803415999999565 ], [ 27.006671800000344, -11.760585699999783 ], [ 27.037977300000083, -11.7173602000003 ], [ 27.046186499999902, -11.711221200000276 ], [ 27.041832000000433, -11.675243800000024 ], [ 27.032694899999782, -11.66981860000004 ], [ 27.022344299999826, -11.644477300000341 ], [ 27.030910300000407, -11.636268199999906 ], [ 27.016276599999699, -11.615638299999578 ], [ 27.052325500000084, -11.590011500000136 ], [ 27.081164500000199, -11.606001499999813 ], [ 27.099367399999647, -11.594437300000161 ], [ 27.122852700000305, -11.587584399999944 ], [ 27.159187099999595, -11.599362799999763 ], [ 27.173892100000359, -11.58458630000005 ], [ 27.191238399999932, -11.581445400000263 ], [ 27.209013000000343, -11.566026499999673 ], [ 27.2215051, -11.626131700000156 ], [ 27.228286599999866, -11.636981999999692 ], [ 27.22835800000038, -11.65911100000012 ], [ 27.236709899999873, -11.680383399999936 ], [ 27.227287199999854, -11.69351799999972 ], [ 27.233045500000436, -11.711625699999713 ], [ 27.220672300000288, -11.747793500000121 ], [ 27.23161790000005, -11.766734 ], [ 27.2312371, -11.78262880000011 ], [ 27.257411200000245, -11.799475400000194 ], [ 27.26407370000015, -11.793193699999865 ], [ 27.292341699999753, -11.802997000000413 ], [ 27.351161999999686, -11.845732100000257 ], [ 27.375337299999916, -11.855630699999878 ], [ 27.396942799999607, -11.871239999999862 ], [ 27.398941599999631, -11.88399389999962 ], [ 27.426067399999987, -11.895129799999586 ], [ 27.438345400000347, -11.909787200000126 ], [ 27.4688025, -11.930631299999822 ], [ 27.476702300000273, -11.94862 ], [ 27.4688025, -11.969464100000375 ], [ 27.461727, -12.005384499999854 ], [ 27.465210500000254, -12.04238980000023 ], [ 27.474333300000175, -12.054049200000202 ], [ 27.49604590000019, -12.056547599999893 ], [ 27.494915700000146, -12.069158799999792 ], [ 27.511334000000222, -12.090871399999626 ], [ 27.510203699999717, -12.121947100000375 ], [ 27.522196200000273, -12.15828149999985 ], [ 27.570987099999865, -12.206928000000397 ], [ 27.5897848, -12.205738300000254 ], [ 27.61619679999971, -12.222275500000308 ], [ 27.614329599999799, -12.239289799999677 ], [ 27.62890379999962, -12.256065000000405 ], [ 27.622370099999589, -12.265999800000216 ], [ 27.619821699999925, -12.266057500000349 ], [ 27.61726760000024, -12.265998099999628 ], [ 27.58339370000008, -12.271063100000088 ], [ 27.572370900000223, -12.265918700000151 ], [ 27.558850399999962, -12.276638400000154 ], [ 27.523878099999685, -12.289076800000219 ], [ 27.51039550000031, -12.297910900000211 ], [ 27.508518, -12.29896229999965 ], [ 27.500456900000291, -12.314330099999772 ], [ 27.499049200000197, -12.315118100000383 ], [ 27.492908799999906, -12.301817700000244 ], [ 27.500998900000202, -12.282306099999609 ], [ 27.48034520000018, -12.27707129999963 ], [ 27.470008799999597, -12.287651900000293 ], [ 27.4583971, -12.276706399999737 ], [ 27.473743600000365, -12.255104699999606 ], [ 27.455869100000225, -12.247223900000346 ], [ 27.43897260000012, -12.264962800000262 ], [ 27.425686599999935, -12.256550199999673 ], [ 27.395794599999871, -12.28317039999985 ], [ 27.362333499999714, -12.296554900000446 ], [ 27.356384799999553, -12.320646899999577 ], [ 27.335564500000121, -12.313805900000402 ], [ 27.306118700000123, -12.32793399999975 ], [ 27.292585500000154, -12.364815599999718 ], [ 27.287835499999872, -12.362104100000256 ], [ 27.251688499999908, -12.352472199999788 ], [ 27.193094300000261, -12.344441500000125 ], [ 27.122602799999846, -12.346226100000308 ], [ 27.058005599999589, -12.332448699999734 ], [ 27.083531500000127, -12.415272199999583 ], [ 27.063358499999882, -12.448674799999624 ], [ 27.06857100000024, -12.490664200000252 ], [ 27.093478000000349, -12.521295799999855 ], [ 27.039351200000077, -12.536286399999891 ], [ 27.002450399999756, -12.557205799999801 ], [ 26.967759700000318, -12.59125059999964 ], [ 26.962500199999663, -12.617205699999671 ], [ 26.935345700000074, -12.632624600000414 ], [ 26.902849599999783, -12.631652500000275 ], [ 26.882637900000375, -12.655476300000309 ], [ 26.872337900000112, -12.686676299999734 ], [ 26.869837899999961, -12.710876300000258 ], [ 26.858337900000166, -12.7367763 ], [ 26.858737900000012, -12.755776299999937 ], [ 26.873837900000204, -12.773176300000125 ], [ 26.900337900000011, -12.791876299999602 ], [ 26.920437899999605, -12.822276299999757 ], [ 26.910637900000268, -12.8503763 ], [ 26.886137899999685, -12.879776299999907 ], [ 26.892537899999894, -12.890576300000397 ], [ 26.914337899999957, -12.904976299999971 ], [ 26.946937900000311, -12.933276299999608 ], [ 26.980337900000354, -12.94357630000022 ], [ 27.01213790000012, -12.946876300000076 ], [ 27.026337900000438, -12.955076300000439 ], [ 27.042937899999821, -12.986076300000219 ], [ 27.059037900000074, -12.997776300000057 ], [ 27.094437900000241, -12.996176300000359 ], [ 27.082637899999888, -13.050876300000098 ], [ 27.081937900000383, -13.07917629999962 ], [ 27.075537900000175, -13.1102763 ], [ 27.064837900000068, -13.127376299999778 ], [ 27.021137899999761, -13.146876299999912 ], [ 26.995237900000177, -13.181676299999666 ], [ 26.963037899999666, -13.213976299999661 ], [ 26.955737899999583, -13.230176300000359 ], [ 26.956637900000359, -13.256776300000348 ], [ 26.975437900000234, -13.306176299999958 ], [ 26.975337900000049, -13.342176300000169 ], [ 26.966637900000062, -13.362176299999913 ], [ 26.923137900000128, -13.370276300000249 ], [ 26.915837900000046, -13.38037630000011 ], [ 26.910237900000428, -13.422276300000419 ], [ 26.875337900000297, -13.437376299999885 ] ] ] } }, { "type": "Feature", "properties": { "area_id": "ZMB_2_1", "area_name": "Chibombo", "area_level": 2.0, "parent_area_id": "ZMB_1_10", "spectrum_region_code": 10.0, "area_sort_order": 12, "center_x": 27.637333899963458, "center_y": -14.846387349999874, "area_level_label": "District", "display": true, "spectrum_level": false, "epp_level": false, "naomi_level": true, "pepfar_psnu_level": true }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 28.004089399999902, -14.513610800000095 ], [ 28.034118700000096, -14.514099100000033 ], [ 28.08673100000043, -14.530212399999845 ], [ 28.141296400000151, -14.53839109999989 ], [ 28.169677699999689, -14.536377 ], [ 28.2019508000004, -14.520895600000062 ], [ 28.20953790000042, -14.528376300000184 ], [ 28.240737899999974, -14.525076300000023 ], [ 28.250037900000176, -14.544476299999621 ], [ 28.248637900000272, -14.574876300000017 ], [ 28.22793789999956, -14.589476300000229 ], [ 28.209237899999867, -14.619376300000392 ], [ 28.189537900000111, -14.63597629999958 ], [ 28.154937899999641, -14.656876300000135 ], [ 28.127137900000115, -14.667176299999909 ], [ 28.12193790000034, -14.681876299999802 ], [ 28.102416300000073, -14.686864199999642 ], [ 28.08251320000014, -14.703678800000301 ], [ 28.049227100000085, -14.795301499999734 ], [ 28.049570299999726, -14.870795799999806 ], [ 28.063350500000357, -14.871331300000193 ], [ 28.097515899999919, -14.841798399999661 ], [ 28.132646500000259, -14.798367800000159 ], [ 28.170479500000422, -14.798560800000018 ], [ 28.19981430000022, -14.761048200000266 ], [ 28.209356899999829, -14.769611300000395 ], [ 28.239859799999664, -14.771779099999723 ], [ 28.251022800000335, -14.779144699999634 ], [ 28.265697800000414, -14.815499100000014 ], [ 28.254231999999849, -14.819027400000092 ], [ 28.183823999999607, -14.902105200000136 ], [ 28.180772799999684, -14.918855400000233 ], [ 28.188739800000132, -14.939856799999765 ], [ 28.178067100000039, -14.967261899999729 ], [ 28.162565400000307, -14.987339500000159 ], [ 28.154265400000167, -15.081342800000225 ], [ 28.165460799999924, -15.091573100000351 ], [ 28.191133199999555, -15.101803500000145 ], [ 28.217742800000334, -15.121438600000085 ], [ 28.316213600000278, -15.113578000000176 ], [ 28.328374100000357, -15.12573860000037 ], [ 28.342078900000143, -15.162413399999629 ], [ 28.366801100000238, -15.166280299999693 ], [ 28.350037899999929, -15.166576299999756 ], [ 28.348937899999683, -15.207176299999963 ], [ 28.335337899999583, -15.229176299999919 ], [ 28.34723790000012, -15.237776299999611 ], [ 28.328537900000427, -15.270776299999895 ], [ 28.320937899999787, -15.270276299999724 ], [ 28.3108379, -15.295776300000389 ], [ 28.329837900000147, -15.310776299999917 ], [ 28.339637900000383, -15.3325763 ], [ 28.335513299999715, -15.341017000000125 ], [ 28.3082728000002, -15.333783999999667 ], [ 28.308671799999964, -15.319763199999896 ], [ 28.27477640000027, -15.333200599999826 ], [ 28.276147000000442, -15.351652900000287 ], [ 28.25042990000026, -15.356497 ], [ 28.2248092, -15.345693300000274 ], [ 28.206140800000192, -15.341069200000224 ], [ 28.152940800000209, -15.314169200000411 ], [ 28.110840800000179, -15.302669199999633 ], [ 28.081540799999665, -15.301269199999643 ], [ 28.012840799999648, -15.281269200000242 ], [ 27.993140799999896, -15.304369200000425 ], [ 27.874540799999739, -15.248369199999642 ], [ 27.868340799999896, -15.247469200000129 ], [ 27.832640800000078, -15.289669199999768 ], [ 27.820840799999726, -15.293269200000223 ], [ 27.796435199999763, -15.318075900000318 ], [ 27.769737900000258, -15.313376299999588 ], [ 27.754737900000251, -15.284976300000331 ], [ 27.7381379, -15.267576300000346 ], [ 27.722237900000085, -15.2362763 ], [ 27.687537900000322, -15.210776300000026 ], [ 27.683837899999741, -15.189676299999851 ], [ 27.646337900000169, -15.13167629999985 ], [ 27.637137900000155, -15.10597630000011 ], [ 27.612137900000441, -15.062476299999874 ], [ 27.59893790000018, -15.03007630000031 ], [ 27.574592800000278, -15.019872900000433 ], [ 27.566537900000199, -15.000576299999592 ], [ 27.440437899999583, -14.953276299999736 ], [ 27.414037899999965, -14.941076300000452 ], [ 27.38903790000025, -14.938176299999812 ], [ 27.36223789999989, -14.923976300000394 ], [ 27.294437899999746, -14.904576299999778 ], [ 27.2689379, -14.893876300000331 ], [ 27.238737899999617, -14.8736763 ], [ 27.226437900000125, -14.850976300000088 ], [ 27.21783790000033, -14.818876300000221 ], [ 27.200037899999614, -14.609876299999977 ], [ 27.16813789999966, -14.581576300000021 ], [ 27.163237899999544, -14.497376299999909 ], [ 27.17703790000002, -14.409276300000085 ], [ 27.17833789999974, -14.373976300000326 ], [ 27.19953789999958, -14.357676299999577 ], [ 27.19933790000011, -14.34307629999976 ], [ 27.809082, -14.336486800000358 ], [ 27.829711899999936, -14.360290499999591 ], [ 27.837707500000057, -14.396789599999979 ], [ 27.886474600000376, -14.483703600000149 ], [ 27.890319800000391, -14.493896500000343 ], [ 27.959289600000265, -14.510009800000283 ], [ 28.004089399999902, -14.513610800000095 ] ] ] } }, { "type": "Feature", "properties": { "area_id": "ZMB_2_2", "area_name": "Chisamba", "area_level": 2.0, "parent_area_id": "ZMB_1_10", "spectrum_region_code": 10.0, "area_sort_order": 13, "center_x": 28.556926226196833, "center_y": -14.7770322, "area_level_label": "District", "display": true, "spectrum_level": false, "epp_level": false, "naomi_level": true, "pepfar_psnu_level": true }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 28.872639199999906, -14.789996199999743 ], [ 28.881537899999707, -14.794076300000199 ], [ 28.886901899999568, -14.794189499999687 ], [ 28.888012600000252, -14.794267300000154 ], [ 28.902437899999892, -14.798276299999632 ], [ 28.908637899999725, -14.81367630000036 ], [ 28.935637899999559, -14.815476300000263 ], [ 28.977037900000088, -14.836776299999704 ], [ 28.994237899999689, -14.867976300000311 ], [ 29.0021379, -14.904976299999706 ], [ 28.99593790000015, -14.94307630000041 ], [ 29.007737899999601, -14.973176299999682 ], [ 29.007037900000103, -14.991476300000325 ], [ 28.975837899999654, -14.996076300000398 ], [ 28.888737899999608, -15.158076300000294 ], [ 28.88113789999986, -15.162776299999795 ], [ 28.842237900000391, -15.154976300000135 ], [ 28.824463000000396, -15.162158099999951 ], [ 28.803137899999637, -15.179476299999836 ], [ 28.745637899999757, -15.177376299999725 ], [ 28.717237900000022, -15.18547630000033 ], [ 28.694737899999559, -15.180576299999872 ], [ 28.663437899999821, -15.189276299999783 ], [ 28.644337900000288, -15.185576299999859 ], [ 28.605237900000439, -15.193376299999978 ], [ 28.567737899999969, -15.187276300000041 ], [ 28.554037899999681, -15.179476299999836 ], [ 28.514337899999617, -15.137576299999628 ], [ 28.484337899999602, -15.127676299999681 ], [ 28.444537900000249, -15.127476300000353 ], [ 28.391637899999928, -15.135076300000277 ], [ 28.360037899999636, -15.144476299999647 ], [ 28.366801100000238, -15.166280299999693 ], [ 28.342078900000143, -15.162413399999629 ], [ 28.328374100000357, -15.12573860000037 ], [ 28.316213600000278, -15.113578000000176 ], [ 28.217742800000334, -15.121438600000085 ], [ 28.191133199999555, -15.101803500000145 ], [ 28.165460799999924, -15.091573100000351 ], [ 28.154265400000167, -15.081342800000225 ], [ 28.162565400000307, -14.987339500000159 ], [ 28.178067100000039, -14.967261899999729 ], [ 28.188739800000132, -14.939856799999765 ], [ 28.180772799999684, -14.918855400000233 ], [ 28.183823999999607, -14.902105200000136 ], [ 28.254231999999849, -14.819027400000092 ], [ 28.265697800000414, -14.815499100000014 ], [ 28.251022800000335, -14.779144699999634 ], [ 28.239859799999664, -14.771779099999723 ], [ 28.209356899999829, -14.769611300000395 ], [ 28.19981430000022, -14.761048200000266 ], [ 28.170479500000422, -14.798560800000018 ], [ 28.132646500000259, -14.798367800000159 ], [ 28.097515899999919, -14.841798399999661 ], [ 28.063350500000357, -14.871331300000193 ], [ 28.049570299999726, -14.870795799999806 ], [ 28.049227100000085, -14.795301499999734 ], [ 28.08251320000014, -14.703678800000301 ], [ 28.102416300000073, -14.686864199999642 ], [ 28.12193790000034, -14.681876299999802 ], [ 28.12523790000018, -14.705676300000119 ], [ 28.205237899999627, -14.658476300000151 ], [ 28.244337900000371, -14.65987630000005 ], [ 28.273937899999641, -14.670476300000285 ], [ 28.32953789999959, -14.683976300000065 ], [ 28.39133790000027, -14.690976299999857 ], [ 28.422337900000347, -14.6836763 ], [ 28.424137900000094, -14.693376299999958 ], [ 28.465037899999693, -14.700376299999647 ], [ 28.476137899999646, -14.68767630000009 ], [ 28.47443790000008, -14.640276299999586 ], [ 28.483037899999882, -14.626076299999976 ], [ 28.491037900000364, -14.596276299999904 ], [ 28.493837900000173, -14.563776300000045 ], [ 28.56203790000016, -14.544776299999789 ], [ 28.584237900000065, -14.526076299999881 ], [ 28.589137900000182, -14.511876300000297 ], [ 28.569437900000434, -14.476876299999752 ], [ 28.558437899999763, -14.465176300000232 ], [ 28.537537899999577, -14.42637630000031 ], [ 28.547837899999841, -14.404876299999863 ], [ 28.567337900000126, -14.398676300000183 ], [ 28.612337900000153, -14.37187630000019 ], [ 28.625237899999849, -14.3589763 ], [ 28.645493400000184, -14.380752199999629 ], [ 28.645452400000384, -14.381702799999644 ], [ 28.645176600000031, -14.385677200000412 ], [ 28.64657350000013, -14.388311800000332 ], [ 28.650219699999855, -14.38919990000033 ], [ 28.651896300000178, -14.389224700000254 ], [ 28.673442200000334, -14.395088599999983 ], [ 28.677947800000169, -14.399140399999597 ], [ 28.688493299999628, -14.409047299999804 ], [ 28.6925057, -14.418710399999854 ], [ 28.698593100000398, -14.425811600000321 ], [ 28.700568799999857, -14.429763100000347 ], [ 28.72246419999972, -14.446591099999674 ], [ 28.723776700000023, -14.44723800000034 ], [ 28.73762599999964, -14.453470899999822 ], [ 28.751419099999989, -14.464038600000114 ], [ 28.753402699999658, -14.465941000000349 ], [ 28.758339599999676, -14.471073099999685 ], [ 28.775811000000168, -14.501223699999908 ], [ 28.787722799999891, -14.526627200000306 ], [ 28.787767699999559, -14.526860699999894 ], [ 28.796756500000072, -14.54209479999972 ], [ 28.799610000000268, -14.547496199999886 ], [ 28.805739700000128, -14.563079500000365 ], [ 28.810345100000134, -14.576240200000248 ], [ 28.831115700000399, -14.590393100000131 ], [ 28.831137900000432, -14.590476300000278 ], [ 28.844919799999857, -14.611200900000213 ], [ 28.849121100000133, -14.625976599999829 ], [ 28.836573299999916, -14.651057499999933 ], [ 28.829133200000371, -14.662308700000422 ], [ 28.827255700000052, -14.677856199999622 ], [ 28.83083800000033, -14.688498599999594 ], [ 28.833964000000158, -14.695015600000083 ], [ 28.833837900000056, -14.697192 ], [ 28.833516899999559, -14.6994395 ], [ 28.835656699999564, -14.715007600000291 ], [ 28.838275400000104, -14.721938500000411 ], [ 28.840602299999862, -14.727788899999602 ], [ 28.840798299999904, -14.728131900000296 ], [ 28.847647500000431, -14.735676100000173 ], [ 28.848823000000181, -14.739509000000421 ], [ 28.861472300000258, -14.770194899999813 ], [ 28.861519200000096, -14.770395999999753 ], [ 28.864954499999893, -14.774919700000408 ], [ 28.872639199999906, -14.789996199999743 ] ] ] } }, { "type": "Feature", "properties": { "area_id": "ZMB_2_3", "area_name": "Chitambo", "area_level": 2.0, "parent_area_id": "ZMB_1_10", "spectrum_region_code": 10.0, "area_sort_order": 14, "center_x": 30.506954845942857, "center_y": -12.888251849999888, "area_level_label": "District", "display": true, "spectrum_level": false, "epp_level": false, "naomi_level": true, "pepfar_psnu_level": true }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 31.441844100000051, -13.426833800000324 ], [ 31.4377379, -13.44887629999962 ], [ 31.428137900000149, -13.45257630000023 ], [ 31.394737900000109, -13.443076300000413 ], [ 31.3754379000002, -13.46287630000036 ], [ 31.338437899999764, -13.469776300000404 ], [ 31.329137899999562, -13.477876299999647 ], [ 31.315437900000173, -13.510376300000154 ], [ 31.295637900000234, -13.5073763000002 ], [ 31.275737900000102, -13.523376300000107 ], [ 31.254637899999544, -13.556476300000403 ], [ 31.225737899999775, -13.58877629999961 ], [ 31.217737900000195, -13.578476299999824 ], [ 31.202937899999657, -13.579676299999683 ], [ 31.157937899999634, -13.604276300000199 ], [ 31.142837900000334, -13.616376299999903 ], [ 31.132537900000074, -13.638076300000135 ], [ 31.132837899999739, -13.652876300000298 ], [ 31.147337899999712, -13.691676300000269 ], [ 31.1345379000002, -13.699576300000183 ], [ 31.124437900000302, -13.720276300000444 ], [ 31.104937900000021, -13.726376299999959 ], [ 31.083037899999781, -13.743276299999723 ], [ 31.079837900000125, -13.7650763 ], [ 31.052030999999577, -13.757272299999594 ], [ 31.050064299999967, -13.746978799999962 ], [ 31.024364699999882, -13.746978799999962 ], [ 31.011514899999845, -13.718377599999952 ], [ 31.018976099999783, -13.700139199999652 ], [ 31.004468199999607, -13.668636399999674 ], [ 31.029753299999985, -13.634646600000051 ], [ 31.052965900000096, -13.59029399999983 ], [ 30.894623099999922, -13.569153999999713 ], [ 30.923638799999836, -13.359412000000187 ], [ 30.905814900000284, -13.327909300000142 ], [ 30.672445800000148, -13.49454220000028 ], [ 30.680736000000376, -13.458894399999892 ], [ 30.6779121, -13.420077799999754 ], [ 30.6655837, -13.409323199999928 ], [ 30.673059500000143, -13.385191 ], [ 30.656927600000401, -13.35056640000025 ], [ 30.616250600000384, -13.342444600000395 ], [ 30.599152000000188, -13.318506699999633 ], [ 30.586095, -13.317574000000224 ], [ 30.575835799999595, -13.29767760000029 ], [ 30.563711400000258, -13.28772930000026 ], [ 30.556250200000314, -13.264102300000385 ], [ 30.538529900000356, -13.2538431 ], [ 30.533555799999952, -13.227418100000438 ], [ 30.53842629999987, -13.185967099999653 ], [ 30.523089499999852, -13.158195000000132 ], [ 30.552105100000205, -13.104723199999901 ], [ 30.5413279, -13.073634900000188 ], [ 30.501120399999735, -13.064930199999921 ], [ 30.476664299999637, -13.035085500000045 ], [ 30.458011399999798, -13.021821200000327 ], [ 30.434798799999687, -13.0222357 ], [ 30.440602, -12.99902319999976 ], [ 30.433969800000298, -12.988245900000054 ], [ 30.411171800000343, -12.984515299999936 ], [ 30.388865999999776, -12.992572300000345 ], [ 30.362285500000048, -12.97601789999977 ], [ 30.352026400000021, -12.957598099999741 ], [ 30.331274999999554, -12.943375200000244 ], [ 30.288606400000106, -12.933349199999784 ], [ 30.269297699999928, -12.897340300000387 ], [ 30.266543399999858, -12.880815000000229 ], [ 30.252641199999911, -12.856813900000201 ], [ 30.264532399999723, -12.830583200000392 ], [ 30.249843200000271, -12.787448200000238 ], [ 30.223029599999684, -12.781852300000157 ], [ 30.207174599999924, -12.741748499999732 ], [ 30.216967399999564, -12.715168100000072 ], [ 30.230957100000012, -12.696515099999827 ], [ 30.239350899999824, -12.647551100000085 ], [ 30.214868899999828, -12.626566600000174 ], [ 30.213936299999954, -12.6095458 ], [ 30.233988199999615, -12.583431600000161 ], [ 30.227692799999975, -12.549156799999819 ], [ 30.215801600000159, -12.543327799999837 ], [ 30.189887299999842, -12.476248599999932 ], [ 30.170631999999586, -12.464349199999671 ], [ 30.1686849, -12.448988300000252 ], [ 30.152945299999704, -12.440875100000099 ], [ 30.13980189999964, -12.45986000000036 ], [ 30.144669800000241, -12.474139200000316 ], [ 30.125360500000014, -12.491339100000072 ], [ 30.123702700000351, -12.505089299999742 ], [ 30.109479800000379, -12.528405399999976 ], [ 30.103883899999751, -12.553586899999738 ], [ 30.107381299999748, -12.562913399999937 ], [ 30.095723300000362, -12.577602599999604 ], [ 30.072640199999732, -12.574804599999762 ], [ 30.061215300000306, -12.584364300000344 ], [ 30.056785199999979, -12.601151899999712 ], [ 30.03486800000011, -12.605115699999919 ], [ 30.0288058, -12.624001799999773 ], [ 30.015748700000323, -12.641255800000021 ], [ 30.026707300000258, -12.646385299999706 ], [ 30.019712500000264, -12.678328500000168 ], [ 30.032303199999987, -12.691618699999738 ], [ 30.052355200000104, -12.724494499999713 ], [ 30.061914800000221, -12.729157800000307 ], [ 30.050956200000282, -12.765764200000362 ], [ 30.052665999999761, -12.7896244000002 ], [ 30.066888899999729, -12.800349900000217 ], [ 30.036811, -12.8115416 ], [ 30.020722900000287, -12.824598699999935 ], [ 29.993676100000172, -12.8234329 ], [ 29.964297700000365, -12.846515900000245 ], [ 29.953339100000427, -12.868666299999601 ], [ 29.927924499999662, -12.881256999999675 ], [ 29.913002099999783, -12.895246700000101 ], [ 29.906007200000232, -12.922293499999915 ], [ 29.87126610000022, -12.970791100000012 ], [ 29.845851500000347, -12.986179800000386 ], [ 29.818409699999904, -12.982015300000178 ], [ 29.825737899999627, -12.495376300000434 ], [ 29.822337899999599, -12.147576300000223 ], [ 29.817598799999768, -12.148055900000436 ], [ 29.841604399999884, -12.132041199999943 ], [ 29.8459420000002, -12.116936599999812 ], [ 29.844099999999674, -12.089746299999748 ], [ 29.854617300000388, -12.057032899999896 ], [ 29.865063300000152, -12.045448500000155 ], [ 29.928975300000332, -12.015368300000189 ], [ 30.000754400000336, -12.002884199999771 ], [ 30.020713, -12.050671100000436 ], [ 30.043233099999799, -12.05293739999972 ], [ 30.054760599999621, -12.073449399999861 ], [ 30.048117399999956, -12.0981024 ], [ 30.051848999999564, -12.116600800000272 ], [ 30.071505099999726, -12.122154800000148 ], [ 30.082985000000107, -12.133076399999895 ], [ 30.087714799999624, -12.1504338 ], [ 30.105421900000294, -12.174713800000429 ], [ 30.15074710000026, -12.201017499999585 ], [ 30.159917800000098, -12.198609299999788 ], [ 30.26684000000013, -12.253606800000435 ], [ 30.308196199999728, -12.249832400000026 ], [ 30.324952600000373, -12.258716500000393 ], [ 30.331607600000108, -12.274422599999658 ], [ 30.353593000000231, -12.281041599999927 ], [ 30.371003000000137, -12.270677700000126 ], [ 30.408823699999729, -12.280809299999651 ], [ 30.4377611, -12.28049 ], [ 30.448694399999987, -12.273812999999832 ], [ 30.468213800000072, -12.298197799999935 ], [ 30.483662899999942, -12.301594000000421 ], [ 30.5053215, -12.330649200000368 ], [ 30.506688099999824, -12.393885999999656 ], [ 30.498785300000193, -12.408771599999824 ], [ 30.465926099999962, -12.430938799999875 ], [ 30.436780699999659, -12.48208440000001 ], [ 30.475284800000079, -12.485855300000305 ], [ 30.502439600000137, -12.514976999999675 ], [ 30.519849600000047, -12.524200099999868 ], [ 30.557640600000326, -12.530348600000186 ], [ 30.569465200000025, -12.539513200000314 ], [ 30.560074699999966, -12.568348000000405 ], [ 30.560424199999673, -12.594254500000185 ], [ 30.578528200000381, -12.609610500000358 ], [ 30.593261399999882, -12.634945799999574 ], [ 30.603248499999872, -12.642058099999916 ], [ 30.623773400000026, -12.641698599999742 ], [ 30.650075799999655, -12.628315800000152 ], [ 30.659231300000037, -12.612666500000037 ], [ 30.693584099999828, -12.62237780000026 ], [ 30.704857000000157, -12.646736700000067 ], [ 30.752225699999801, -12.679458499999866 ], [ 30.740615400000312, -12.699862899999609 ], [ 30.740896600000216, -12.727450199999716 ], [ 30.733278199999855, -12.755500499999771 ], [ 30.739899299999934, -12.775527899999906 ], [ 30.759023899999704, -12.790638899999733 ], [ 30.760500499999658, -12.835557099999605 ], [ 30.771005899999839, -12.851917400000408 ], [ 30.745217699999618, -12.8766413 ], [ 30.746703900000362, -12.895622700000406 ], [ 30.762331300000159, -12.910218400000415 ], [ 30.789961500000011, -12.909639299999885 ], [ 30.812481599999888, -12.919890500000401 ], [ 30.844152399999743, -12.947225199999753 ], [ 30.8572841000002, -12.948035899999773 ], [ 30.877724599999663, -12.930604700000027 ], [ 30.890618700000221, -12.929504300000431 ], [ 30.923180700000124, -12.957938099999737 ], [ 30.952118199999855, -12.955448099999561 ], [ 30.961863, -12.939233600000026 ], [ 30.983254200000399, -12.956374599999929 ], [ 30.999059799999657, -12.956895800000101 ], [ 31.019619099999964, -12.968303200000223 ], [ 31.041188499999816, -12.968592699999956 ], [ 31.053488399999743, -12.986252899999604 ], [ 31.068699800000168, -12.991869100000102 ], [ 31.076602700000251, -13.02504289999983 ], [ 31.099538699999943, -13.041830699999677 ], [ 31.107144500000171, -13.036157700000437 ], [ 31.149629600000157, -13.034247400000385 ], [ 31.170783100000193, -13.02950049999987 ], [ 31.172684500000244, -13.01798010000023 ], [ 31.193422, -12.982663 ], [ 31.216061000000295, -12.959559499999573 ], [ 31.228776800000031, -12.961296699999988 ], [ 31.246127400000415, -12.94716720000039 ], [ 31.259378000000364, -12.965755399999571 ], [ 31.269954800000164, -12.957532800000026 ], [ 31.298773400000385, -12.97455679999986 ], [ 31.324442700000212, -12.965060500000014 ], [ 31.35623230000002, -12.999743200000152 ], [ 31.337812199999668, -13.070830500000445 ], [ 31.358490299999914, -13.092418900000073 ], [ 31.366155400000093, -13.123958899999824 ], [ 31.360213400000038, -13.155031900000235 ], [ 31.365680099999864, -13.177770099999721 ], [ 31.377682899999918, -13.179737099999954 ], [ 31.384278500000136, -13.202791099999816 ], [ 31.364075700000118, -13.255890900000141 ], [ 31.396756600000426, -13.284691899999851 ], [ 31.407689899999617, -13.304006200000082 ], [ 31.43656790000027, -13.330835600000153 ], [ 31.429199800000386, -13.355118299999944 ], [ 31.422960800000023, -13.401133000000272 ], [ 31.441844100000051, -13.426833800000324 ] ] ] } }, From a1337ee246a631ccfc2c28936dc216208278f701 Mon Sep 17 00:00:00 2001 From: Adam Barnes Date: Wed, 27 Mar 2024 13:15:54 -0400 Subject: [PATCH 26/26] refactor: address pr code-review comments --- docs/training/admin_guides.md | 37 ++++++++++++++----- .../management/commands/load_locations.py | 7 ++-- .../management/commands/refresh_locations.py | 37 +++++++++---------- 3 files changed, 48 insertions(+), 33 deletions(-) diff --git a/docs/training/admin_guides.md b/docs/training/admin_guides.md index 71e4ff29..60161508 100644 --- a/docs/training/admin_guides.md +++ b/docs/training/admin_guides.md @@ -12,7 +12,12 @@ as individuals described below. To set up VA Explorer for the Geographic Access mentioned in that section, you must load location data into the system. -Locations in VA Explorer follow an assumed three-level hierarchical structure by which each facility or hospital maps to an associated Level 2 ("District") and Level 1 ("Province) hierarchy. Each facility also has a corresponding `key`, which represents the XML option used in the dropdown list within ODK or Kobo, and a `status` which indicates if the Facility is actively producing VAs or not. +Locations in VA Explorer follow an assumed three-level hierarchical structure +by which each facility or hospital maps to an associated Level 2 ("District") +and Level 1 ("Province") hierarchy. Each facility also has a corresponding +`key`, which represents the XML option used in the dropdown list within ODK or +Kobo, and a `status` which indicates if the Facility is actively producing VAs +or not. The table below shows an example location hierarchy for States, Counties, and Cities in the United States. In this example, we have one state (California), two @@ -28,18 +33,20 @@ California,Los Angeles County,Los Angeles Hospital, los_angeles_hospital, Active ``` The input is similarly structured to support any number of geographic hierarchies -for VA Explorer users. With a {term}`CSV` file in hand, you can now supplement your initial -system set up with the `load_locations` management command. Full usage details -for this are provided in [Management Commands](#management-commands). The specification of the input CSV file is as follows: +for VA Explorer users. With a {term}`CSV` file in hand, you can now supplement +your initial system set up with the `load_locations` management command. Full +usage details for this are provided in [Management Commands](#management-commands). +The specification of the input CSV file is as follows: ```{csv-table} Expected columns for the location file :header-rows: 1 Column Name, Description, Specifics -Province, Level 1 Administrative Boundary Name, One of the `label::English` values as defined in the VA XLSForm -District, Level 2 Administrative Boundary Name, One of the `label::English` values as defined in the VA XLSForm +Province,Level 1 Administrative Boundary Name,One of the `label::English` values as defined in the VA XLSForm +District,Level 2 Administrative Boundary Name,One of the `label::English` values as defined in the VA XLSForm Name, Facility or Hospital Name, One of the `label::English` values as defined in the VA XLSForm -Key, Facility or Hospital XML Value, The choice name associated with the `label::English` defined in the previous column -Status, Whether the facility is still actively producing VAs, One of: 'Active' or 'Inactive' +Key, Facility or Hospital XML Value, The choice name associated with the +`label::English` defined in the previous column Status, Whether the facility is +still actively producing VAs, One of: 'Active' or 'Inactive' ``` Following this command, VA Explorer should support geographic restrictions to any @@ -51,7 +58,17 @@ Marin County, Los Angeles County, Sausalito, San Rafael, and Los Angeles. #### Updating locations in VA Explorer -When VAs are imported into VA Explorer, they are matched exactly on the locations loaded into the system in this step. If a VA does not have a valid location field, VA Explorer will track that mismatch as an error that either needs to be corrected in the VA Explorer locations file or in the underlying VA data. To add a location to VA Explorer, re-upload a revised location file following the `load_locations` management command. If a row is deleted from the locations file, it will also be kept in VA Explorer and marked inactive. To permanently delete locations in VA Explorer, re-upload a revised location file following the `load_locations` management command with the `--delete_previous` flag. Warning: doing so may delete all VAs in the database, so make sure to backup the system first. +When VAs are imported into VA Explorer, they are matched exactly on the +locations loaded into the system in this step. If a VA does not have a valid +location field, VA Explorer will track that mismatch as an error that either +needs to be corrected in the VA Explorer locations file or in the underlying +VA data. To add a location to VA Explorer, re-upload a revised location file +following the `load_locations` management command. If a row is deleted from +the locations file, it will also be kept in VA Explorer and marked inactive. +To permanently delete locations in VA Explorer, re-upload a revised location +file following the `load_locations` management command with `--delete_previous`. +Warning: doing so may delete all VAs in the database, so make sure to +backup the system first. ### Creating & Editing Users @@ -195,7 +212,7 @@ generally useful to admins. An even fuller list of these can be found under * - ``export_locations`` - ``--output_file`` - - Utility to obtainthe current list of locations in the VA + - Utility to obtain the current list of locations in the VA Explorer system in the CSV format with header fields corresponding to fields expected by the system. The intended use case for this utility is when administrators need to update the location file diff --git a/va_explorer/va_data_management/management/commands/load_locations.py b/va_explorer/va_data_management/management/commands/load_locations.py index ca99949d..042b4d98 100644 --- a/va_explorer/va_data_management/management/commands/load_locations.py +++ b/va_explorer/va_data_management/management/commands/load_locations.py @@ -30,15 +30,16 @@ class Command(BaseCommand): new tree. If False (default), attempts to update existing Locations table """ - help = "Loads initial location data into the database from a CSV file with \ - relevant info. Required Columns: Province, District, Key, Name, Status." + help = ( + "Loads initial location data into the database from a CSV file with" + "relevant info. Required Columns: Province, District, Key, Name, Status." + ) def add_arguments(self, parser): parser.add_argument("csv_file", type=argparse.FileType("r")) parser.add_argument("--delete_previous", type=bool, nargs="?", default=False) def handle(self, *args, **options): - print(options) csv_file = options["csv_file"] delete_previous = options["delete_previous"] diff --git a/va_explorer/va_data_management/management/commands/refresh_locations.py b/va_explorer/va_data_management/management/commands/refresh_locations.py index 582dbbe5..69b7021a 100644 --- a/va_explorer/va_data_management/management/commands/refresh_locations.py +++ b/va_explorer/va_data_management/management/commands/refresh_locations.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.core.management.base import BaseCommand from va_explorer.va_data_management.models import Location, VerbalAutopsy @@ -8,22 +9,18 @@ class Command(BaseCommand): help = "Reassigns locations based on most recent facility list" - # def add_arguments(self, parser): - # # parser.add_argument("csv_file", type=argparse.FileType("r")) - # # parser.add_argument("--random_locations", type=str, nargs="?", default=False) - def handle(self, *args, **options): - # verbal_autopsies = VerbalAutopsy.objects - count = VerbalAutopsy.objects.count() - print("Refreshing locations for all " + str(count) + " VAs in the database.") - - location_map = {} - - verbal_autopsies = list(VerbalAutopsy.objects.filter()[0:count]) + if settings.DEBUG: + count = VerbalAutopsy.objects.count() + print( + "Refreshing locations for all " + str(count) + " VAs in the database." + ) # build location mapper to map csv locations to known db locations - h = [va.hospital for va in verbal_autopsies] # using list comprehension to remove duplicated from list + location_map = {} + verbal_autopsies = list(VerbalAutopsy.objects.all()) + h = [va.hospital for va in verbal_autopsies] hospitals = [] [hospitals.append(x) for x in h if x not in hospitals] @@ -33,18 +30,18 @@ def handle(self, *args, **options): .only("name", "key") .values_list("key", "name") } - changedcount = 0 + changed_count = 0 for va in verbal_autopsies: - oldlocation = va.location - newva = assign_va_location(va, location_map) - newlocation = newva.location + old_location = va.location + new_va = assign_va_location(va, location_map) + new_location = new_va.location - if oldlocation != newlocation: - changedcount += 1 - va.location = newva.location + if old_location != new_location: + changed_count += 1 + va.location = new_va.location va.save_without_historical_record() validate_vas_for_dashboard(verbal_autopsies) - print(" changed locations for " + str(changedcount) + " VA(s).") + print(" changed locations for " + str(changed_count) + " VA(s).")