Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Critical paths of the application to be tested by E2E tests using the user interface. Include all the steps in one go. If you can use the BDD type AS P, WHEN x, AND y, THEN z
dokku postgres:create wazimap-db \
-i kartoza/postgis \
-p <database user password> \
-r <root password> \
-I 11.0-2.5 \
-C "POSTGRES_MULTIPLE_EXTENSIONS=postgis,pg_trgm;POSTGRES_USER=postgres;POSTGRES_PASS=<database user password>"dokku redis:create wazimap-redisdokku apps:create wazimapdokku postgres:link wazimap-db wazimap
dokku redis:link wazimap-redis wazimapNEW_URL=$(dokku config:get wazimap DATABASE_URL | sed 's/^postgres/postgis/') dokku config:set wazimap DATABASE_URL=$NEW_URLdokku config:set wazimap \
AWS_ACCESS_KEY_ID=<access key id> \
AWS_S3_REGION_NAME=<region name> \
AWS_SECRET_ACCESS_KEY=<secret key> \
AWS_STORAGE_BUCKET_NAME=<storage bucket> \
DEFAULT_FILE_STORAGE=storages.backends.s3boto3.S3Boto3Storage \
DJANGO_CONFIGURATION=Production \
DJANGO_DEBUG=False \
DJANGO_SECRET_KEY=<django secret key>dokku domains:add wazimap wazimap.com
dokku letsencrypt:enable wazimap# Wazimap does not listen on port 5000 by default
echo dokku proxy:ports-add wazimap http:80:8000
dokku proxy:ports-add wazimap https:443:8000
dokku proxy:ports-remove wazimap http:80:5000
dokku proxy:ports-remove wazimap https:443:5000dokku nginx:set wazimap client-max-body-size 100m "filterable_fields": [
"campus"
] "filterable_fields": [
"campus", "random", "values", "facility type"
]"field_type": {
"more info": "html",
"report error": "text"
}{
Geography: ZA # Geography is actually stored in its own field and not in the JSON field.
Gender: Male,
Age: 20,
Count: 10
}Select
Geography,
Gender,
Sum(Count)
From
Dataset d
Where
d.id = XXX
Group by
Geography,
GenderSelect
Geography,
Age,
Sum(Count)
From
Dataset d
Where
d.id = XXX
Group by
Geography,
Age{
Geography: ZA,
subindicators: {
Male: 22,
Female: 28
}
... # other information is stored here and is described elsewhere in this manual.
}Select
Geography,
Age,
Sum(Count)
From
Dataset d
Where
d.id = XXX
and Gender = Female
Group by
Geography,
Age{
'Age Group__in': ['60-64', '65-69', '70-74', '75-79', '80-84', '85+']
}Dataset.objects.filter(**universe.filters) # pseudocodeThis page is a stub.
'groups': {'race': {'Other': [{'count': 14034.3619100001,
'region of birth': 'Other'},
{'count': 23014.7457499993, 'region of birth': 'Rest of africa'},
{'count': 34546.705719999, 'region of birth': 'Sadc'},
{'count': 33844.2467799998, 'region of birth': 'South africa'},
{'count': 8627.21382000001, 'region of birth': 'Unspecified'}],
'White': [{'count': 17755.8348600004, 'region of birth': 'Other'},
{'count': 1076.82088, 'region of birth': 'Rest of africa'},
{'count': 19345.9559600004, 'region of birth': 'Sadc'},
{'count': 1175191.32683901, 'region of birth': 'South africa'},
{'count': 9675.18685000005, 'region of birth': 'Unspecified'}],
'Coloured': [{'count': 1104.4229, 'region of birth': 'Other'},
{'count': 842.120029999999, 'region of birth': 'Rest of africa'},
{'count': 5666.85164000002, 'region of birth': 'Sadc'},
{'count': 1575281.6271999, 'region of birth': 'South africa'},
{'count': 1675.21038, 'region of birth': 'Unspecified'}],
'Black african': [{'count': 9463.15047999995, 'region of birth': 'Other'},
{'count': 68003.2315900028, 'region of birth': 'Rest of africa'},
{'count': 810647.802930328, 'region of birth': 'Sadc'},
{'count': 14739761.6385047, 'region of birth': 'South africa'},
{'count': 85310.3884700055, 'region of birth': 'Unspecified'}],
'Indian or asian': [{'count': 38132.814809999, 'region of birth': 'Other'},
{'count': 5076.67313999999, 'region of birth': 'Rest of africa'},
{'count': 2539.20952000001, 'region of birth': 'Sadc'},
{'count': 414713.136599942, 'region of birth': 'South africa'},
{'count': 5150.74462, 'region of birth': 'Unspecified'}]},
'gender': {'Male': [{'count': 55748.008589999, 'region of birth': 'Other'},
{'count': 72957.3858900018, 'region of birth': 'Rest of africa'},
{'count': 517617.920130245, 'region of birth': 'Sadc'},
{'count': 8727584.65349521, 'region of birth': 'South africa'},
{'count': 63433.5451700032, 'region of birth': 'Unspecified'}],
'Female': [{'count': 24742.5763700004, 'region of birth': 'Other'},
{'count': 25056.2055000003, 'region of birth': 'Rest of africa'},
{'count': 355128.605640082, 'region of birth': 'Sadc'},
{'count': 9211207.32242836, 'region of birth': 'South africa'},
{'count': 47005.1989700023, 'region of birth': 'Unspecified'}]},
'age group': {'15-19': [{'count': 6298.26723000001,
'region of birth': 'Other'},
{'count': 6312.14378000002, 'region of birth': 'Rest of africa'},
{'count': 68137.1359800096, 'region of birth': 'Sadc'},
{'count': 4775821.0196088, 'region of birth': 'South africa'},
{'count': 9359.01092000012, 'region of birth': 'Unspecified'}],
'20-24': [{'count': 16982.6305099999, 'region of birth': 'Other'},
{'count': 22846.8292099995, 'region of birth': 'Rest of africa'},
{'count': 229155.41202007, 'region of birth': 'Sadc'},
{'count': 4684128.15334481, 'region of birth': 'South africa'},
{'count': 27011.4452600009, 'region of birth': 'Unspecified'}],
'25-29': [{'count': 26769.6408399996, 'region of birth': 'Other'},
{'count': 34202.7678200008, 'region of birth': 'Rest of africa'},
{'count': 309901.929190191, 'region of birth': 'Sadc'},
{'count': 4354313.53260714, 'region of birth': 'South africa'},
{'count': 37417.0233700027, 'region of birth': 'Unspecified'}],
'30-35': [{'count': 30440.0463799999, 'region of birth': 'Other'},
{'count': 34651.8505800018, 'region of birth': 'Rest of africa'},
{'count': 265552.048580056, 'region of birth': 'Sadc'},
{'count': 4124529.27036281, 'region of birth': 'South africa'},
{'count': 36651.2645900019, 'region of birth': 'Unspecified'}]}},
'subindicators': {'Sadc': 872746.525770327,
'Other': 80490.5849599994,
'Unspecified': 110438.744140006,
'South africa': 17938791.9759236,
'Rest of africa': 98013.5913900021}}"preferred_children": {
"country": [
"province"
],
"district": [
"municipality",
"mainplace",
"ward"
],
"province": [
"district",
"municipality"
],
"mainplace": [
"subplace"
],
"municipality": [
"mainplace",
"ward"
]
}{
...
"results": [
{
"id": 2,
"name": "Vulekamali",
...
"configuration": {
"urls": [
"geo.vulekamali.gov.za"
],
...
}
},
{
"id": 3,
"name": "Cape Town Against Covid-19",
...
"configuration": {
"urls": [
"capetownagainstcovid19.openup.org.za"
],
...
}
},
...
}Instructions for merging new webflow exports
class DropDown extends Observable {
static EVENTS = {
selected: 'dropdown.selected'
}
constructor() {
super();
}
onElementSelected() {
let payload = ...
this.triggerEvent(DropDown.EVENTS.selected, payload)
}
}let dropdown = new DropDown();
dropdown.on(DropDown.EVENTS.selected, payload => alert('An element has been selected')class DropDown extends Component {
static EVENTS = {
selected: 'dropdown.selected'
}
constructor(parent) {
super(parent);
}
onElementSelected() {
...
}
}class Application extends Component {
constructor() {
super()
this._dropdown = new DropDown(this);
this.registerChild(this._dropdown);
}
}// This class implements the controller for the DropDown component.
export class DropDownComponent extends Component {
constructor(parent, container, values = [], defaultText = '') {
this._container = container
this._model = new DropDownModel(values, defaultText);
this.prepareDomElements();
this.prepareEvents();
}
get container() {
return this._container;
}
get model() {
return this._model;
}
prepareDomElements() {
this._textArea = $(this.container).find('.textArea')[0];
this._trigger = $(this.container).find('.trigger')[0];
this._optionContainer = $(this.container).find('.options')[0];
this._listItem = $(self._optionContainer).find('.list_item')[0]
}
prepareEvents() {
const self = this;
this._trigger.on('click', () => {
$(self._optionContainer).show();
})
this.model.on(DropDownModel.EVENTS.changeValue, model => {
self.updateText();
})
}
setOptions(values) {
const self = this;
this.model.options = values;
$(this._optionContainer).html('');
values.array.forEach((element, idx) => {
let li = self._listItem.clodeNode(true);
li.text(element);
$(self._optionContainer).html('');
let li = listItem.cloneNode(true);
li.on('click', () => {
self.model.currentIndex = idx;
})
$(self._optionContainer).append(li);
});
}
updateText() {
$(this._textArea).text(this.model.currentValue)
}
reset() {
this.model.reset();
}
}constructor(parent, container, values = [], defaultText = '')constructor(...) {
...
this.prepareDomElements();
...
}
...
prepareDomElements() {
this._textArea = $(this.container).find('.textArea')[0];
this._trigger = $(this.container).find('.trigger')[0];
this._optionContainer = $(this.container).find('.options')[0];
this._listItem = $(self._optionContainer).find('.list_item')[0]
}
...
constructor(...) {
...
this.prepareEvents();
}
prepareEvents() {
const self = this;
this._trigger.on('click', () => {
$(self._optionContainer).show();
})
this.model.on(DropdownModel.EVENTS.changeValue, model => {
self.updateText();
})
}setOptions(values) {
...
values.array.forEach((element, idx) => {
let li = self._listItem.clodeNode(true); // <-- Note that the li element is being cloned from an existing one.
li.text(element);
...
$(self._optionContainer).append(li); // <--- Note how the li element is inserted into the DOM.
});
}class DropDownModel extends Observable {
static EVENTS = {
changeValue: 'dropdown.model.changevalue'
}
constructor(options = [], defaultText = '') {
this._options = options
this._defaultText = defaultText;
this._currentIndex = null;
}
get options() {
return this._options;
}
set options(values) {
this._options = values;
this.reset();
}
get defaultText() {
return this._defaultText;
}
get currentIndex() {
return this._currentIndex;
}
set currentIndex(newIdx) {
if (newIdx != this._currentIndex) {
this._currentIndex = newIdx;
this.triggerEvent(DropDownModel.EVENTS.changeValue, this)
}
}
get currentValue() {
if (this.currentIndex == null)
return this.defaultText;
return this.options[this.currentIndex];
}
reset() {
this.currentIndex = null;
}
}
set currentIndex(newIdx) {
if (newIdx != this._currentIndex) {
this._currentIndex = newIdx;
this.triggerEvent(DropDownModel.EVENTS.changeValue, this)
}
}prepareEvents() {
...
this.model.on(DropDownModel.EVENTS.changeValue, model => {
self.updateText();
})
...
}updateText() {
$(this._textArea).text(this.model.currentValue)
}setOptions(values) {
...
li.on('click', () => {
self.model.currentIndex = idx;
})
...
}constructor(options = [], defaultText = '') {
this._options = options
this._defaultText = defaultText;
this._currentIndex = null;
}get options() {
return this._options;
}
set options(values) {
this._options = values;
this.reset();
}doSomething(data) {
console.log(data.key1.key2.value) // bad
}
doSomething(value) {
console.log(value);
}$ git checkout master
Switched to branch 'master'
Your branch is behind 'origin/master' by 28 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
$ git pull
Updating 5cb0775..d586c13
Fast-forward
...
src/index.html | 20 +-
...
$ git checkout feature-branch
Switched to branch 'feature-branch'
git merge master
Auto-merging src/index.html
CONFLICT (content): Merge conflict in src/index.html
Automatic merge failed; fix conflicts and then commit the result.
import-webflow ~/Downloads/wazimap-ng.webflow\ \(latest-export-10032022\).zip
Extracting to temporary directory /tmp/tmp-296926-8rNUgOwtcaJs
Copying css to src/css
Copying js to src/js
Copying images to src/images
Looking for files matching index.html in /tmp/tmp-296926-8rNUgOwtcaJs
Reading /tmp/tmp-296926-8rNUgOwtcaJs/index.html
Transforming using ./src/js/webflow/import.js
Looking for files matching {401,about}.html in /tmp/tmp-296926-8rNUgOwtcaJs
Reading /tmp/tmp-296926-8rNUgOwtcaJs/401.html
No DOM transformation provided
Writing src/401.html
Reading /tmp/tmp-296926-8rNUgOwtcaJs/about.html
No DOM transformation provided
Writing src/about.html
Writing src/index.html
Cleaning up temporary directory /tmp/tmp-296926-8rNUgOwtcaJs
$ git status
On branch no-style-tags-in-body
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Changes to be committed:
...
new file: __tests__/gui/...
...
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: src/401.html
modified: src/about.html
modified: src/css/wazimap-ng.webflow.css
modified: src/js/webflow.js
$ git add src/
$ git commit
[feature-branch 32ecbac] Merge branch 'master' into feature-branch.map-print.hidden.point-legend.profile-indicator__filter-buttons and .mapping-options__filter-buttons.profile-indicator__table_cell.facility-info__view-google-map as a child of .facility-info..map-print has a .hidden class by default which is removed when required.hover-menu__content_list-item.last.hidden to show.hidden to show@media print {
.page-break-before {
break-before: page;
}
body, .main, .rich-data, .rich-data-content, .rich-data-content .section, .profile-indicator{
float: none !important;
display: block !important;
}
.rich-data__print, .tab-notice{
display: none;
}
.rich-data[style*="display: none;"]{
display: none !important;
}
.facility-info[style*="display: none;"]{
display: none !important;
}
.facility-info[style*="display: flex;"]{
display: inline-table;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: #fff;
max-height: 100%;
max-width: 100%;
}
.facility-info__view-google-map, .facility-info__print, .facility-info__close{
display: none;
}
}.mapping-options__filter.disabled {
pointer-events: none;
} .profile-indicator__table_cell {
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}$ give me super-powers# Ain't no code for that yet, sorry
echo 'You got to trust me on this, I saved the world'





//sample config
translations: {
'en': {
'Point Mapper': 'Services'
}
},<!-- sample html -->
<div data-i18n="Point Mapper" id="test" class="i18n">Point Mapper</div><div id="test" class="i18n">Services</div>





heroku run python3 manage.py createsuperuser --app wazimap-pr-1234 if you want to create new supruser








A Wazimap-NG instance can be set to private, which means that a user will require credentials to login and view the data.





"preferred_children": {
"country": [
"province"
],
"province": [
"Districts and Metros",
"municipality"
],
"mainplace": [
"subplace"
],
"municipality": [
"mainplace",
"ward"
],
"Districts and Metros": [
"municipality",
"mainplace",
"ward"
]
}



{
"urls": [
"covid.openup.org.za"
]
}{
"urls": [
"beta.youthexplorer.org.za",
"localhost"
],
"preferred_children": {
"country": [
"province"
],
"district": [
"municipality",
"mainplace",
"ward"
],
"province": [
"district",
"municipality"
],
"mainplace": [
"subplace"
],
"municipality": [
"mainplace",
"ward"
]
}
}{
"types": {
"Value": {"formatting": "~s", "minX": 0, "maxX": 5000},
"Percentage": {"formatting": ".0%", "minX": 0, maxX: 100}
},
"disableToggle": false,
"defaultType": "Percentage",
"xTicks": 2,
"filter": {
"defaults": [
{
"name": "income sources",
"value": "Locally generated(%)"
}
]
},
}Authorization : Token yourtoken







"filter": {
"defaults": [
{
"name": "income sources",
"value": "Locally generated(%)"
}
]
}, "exclude": [
"data mapper"
]{
"types": {
"Value": {"formatting": ".1%"}
},
"disableToggle": true,
"defaultType": "Value"
}{
"types": {
"Value": {
"formatting": ",.0f"
}
}
}POST /api/v1/datasets/:id/upload/{
"id": 78,
"created": "2021-04-28T09:57:01+0000",
"updated": "2021-04-28T09:57:10+0000",
"name": "Cases",
"groups": [
"date"
],
"permission_type": "private",
"profile": 1,
"geography_hierarchy": 1,
"upload_task_id": "44ceb2d8acd04343bbcb7ca8f0468b6c",
}curl --location --request POST 'http://api.wazimap.com/api/v1/datasets/84/upload/' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Token yourtoken' \
--form 'file=@/covid_next.csv' \
--form 'update=True' \
--form 'overwrite=True'


{
"urls": [
"wazimap-ng.africa"
],
"choropleth": {
"zero_color": "#eeeeee",
"negative_color_range": [
"#0a3d62",
"#82ccdd"
],
"positive_color_range": [
"#fef0d9",
"#b30000"
],
"opacity": 0.7,
"opacity_over": 0.8
},
"watermark_enabled": true,
"tile_layers": [
{
"url": "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_only_labels/{z}/{x}/{y}.png",
"pane": "labelsPanel",
"zIndex": 650
},
{
"url": "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png",
"pane": "tilePane",
"zIndex": 200
}
],
"layer_styles": {
"selected": {
"out": {
"color": "#666666",
"weight": 1,
"opacity": 0.5,
"fillColor": "#cccccc",
"fillOpacity": 0.5
},
"over": {
"color": "#666666",
"fillColor": "#3BAD84",
"fillOpacity": 0.6
}
},
"hoverOnly": {
"out": {
"stroke": false,
"fillColor": "#ffffff"
},
"over": {
"fillColor": "3BAD84",
"fillOpacity": 0.5
}
}
},
"default_panel": "point_data",
"root_geography": "CPT",
"site_wide_filters_enabled": false,
"leaflet_options": {
"minZoom": 6
},
"chart_attribution": "See more at https://wazimap.ng"
}


"urls": [
"wazimap-ng.africa"
]"page_title": "This is a new title""choropleth": {
"positive_color_range": [
"#fef0d9",
"#b30000"
],
"zero_color": "#eeeeee",
"negative_color_range": [
"#0a3d62",
"#82ccdd"
],
"opacity": 0.7,
"opacity_over": 0.8
}"preferred_childre": {
"country": [
"province", "state"
],
"province": [
"district",
"metro"
],
"municipality": ["mainplace", "ward"],
...
}
{
"panels": {
"rich_data": {
"visible": true
},
"point_data": {
"visible": true
},
"data_explorer": {
"visible": false
},
},
"default_panel": "rich_data"
}"tutorial": [
{
"body": "This website was developed to enable you to easily find spatial information related to geographic areas. By clicking on the map or using the search bar, you can navigate to an area of interest and find relevant information about it.",
"image": "https://wazimap-ng.s3-eu-west-1.amazonaws.com/GCRO/Screenshot+1.jpg",
"title": "Introduction:"
},
{
"body": "To get started, first select a location on the map or use the search box to find the location you would like to analyse.",
"image": "https://wazimap-ng.s3-eu-west-1.amazonaws.com/GCRO/Screenshot+2.jpg",
"title": "Location Search:"
},
{
"body": "Basic information for your selected location can be found in the Location Panel. Use the buttons to navigate to parent locations.",
"image": "https://wazimap-ng.s3-eu-west-1.amazonaws.com/GCRO/Screenshot+3.jpg",
"title": "Location Panel:"
},
{
"body": "To view rich data specific to the location you selected, open the Rich Data panel in the left toolbar.",
"image": "https://wazimap-ng.s3-eu-west-1.amazonaws.com/GCRO/Screenshot+4.jpg",
"title": "Rich Data:"
},
{
"body": "To add point data to the map, use the Point Mapper to show different facilities in that area.",
"image": "https://wazimap-ng.s3-eu-west-1.amazonaws.com/GCRO/Screenshot+5.jpg",
"title": "Point Mapper:"
},
{
"body": "To overlay compatible datasets onto your location, open the Data Mapper and choose from the available indicators.",
"image": "https://wazimap-ng.s3-eu-west-1.amazonaws.com/GCRO/Screenshot+6.jpg",
"title": "Data Mapper:"
},
{
"body": "Once you've mapped a data-set (eg. gender), use the Data Filter to select a sub-indicator for that data-set (eg. male)",
"image": "https://wazimap-ng.s3-eu-west-1.amazonaws.com/GCRO/Screenshot+7.jpg",
"title": "Data Filtering:"
},
{
"body": "For more information on how to use specific features, look out for tutorial icons. For an in-depth guide on using this site, please see our user manual.",
"image": "https://wazimap-ng.s3-eu-west-1.amazonaws.com/GCRO/Screenshot+7.jpg",
"title": "Learn more:"
}
]"leafletOptions": {
"minZoom": 4
}"style": {
"location__search_input": [
{
"key": "background-color",
"value": "blue"
}
]
}//sample config
translations: {
'en': {
'Point Mapper': 'Services'
}
},
"point_markers": {
"clustering": {
"enabled": true
}
}, "watermark_enabled": true"cc_license_enabled": true"point_search_enabled": true"site_wide_filters_enabled": true "default_filters": [
{
"name": "language",
"value": "English"
},
{
"name": "gender",
"value": "Female"
}
] "restrict_values": {
"age": [
"15-35 (ZA)",
"15-24 (Intl)",
"30-35"
]
} "views": {
"youth": {
"url": "https://deploy-preview-735--wazimap-production.netlify.app/?dev-tools=true&view=children&profileView=%7B%22filters%22%3A%5B%5D%2C%22hiddenIndicators%22%3A%5B2198%2C2206%2C2201%2C2205%2C2319%2C2320%2C2321%2C2322%2C2323%2C2324%2C2325%2C2330%2C2407%2C2408%2C2411%5D%7D",
"label": "youth view",
"order": 4,
"default_filters": [
{
"name": "language",
"value": "English"
}
],
"restrict_values": {
"age": [
"15-35 (ZA)",
"15-24 (Intl)",
"30-35"
],
"race": [
"Coloured",
"Black African",
"Indian or Asian"
],
"language": [
"English",
"Afrikaans",
"Some other"
]
}
}
}{
"default_view_label": "Test view"
}{
"tabular_link_enabled": true
}


{
"count": 2,
"next": "https://api.wazimap.com/api/v1/profiles/?page=2",
"previous": null,
"results": [
{
"id": :profile_id,
"name": "Profile1",
"permission_type": "public",
"requires_authentication": false,
"geography_hierarchy": {
"id": 2,
"name": "2016 SA Boundaries",
"root_geography": {
"name": "South Africa",
"code": "ZA",
"level": "country",
"version": "2016 Boundaries"
},
"description": ""
},
"description": "",
"configuration": {}
},
{
"id": :profile_id,
"name": "Profile2",
"permission_type": "public",
"requires_authentication": false,
"geography_hierarchy": {
"id": 2,
"name": "2016 SA Boundaries",
"root_geography": {
"name": "South Africa",
"code": "ZA",
"level": "country",
"version": "2016 Boundaries"
},
"description": ""
},
"description": "",
"configuration": {}
},
]
}[
{
"id": :theme_id,
"categories": [
{
"id": :category_id,
"name": "Healthcare Facilities",
"description": "Representation of data gathered from various sources",
"theme": {
"id": :theme_id,
"name": "Health",
},
"metadata": {
"source": "",
"description": "",
"licence": null,
"icon": "local_hospital"
},
"color": "",
"visible_tooltip_attributes": []
}
],
"created": "2020-08-28T07:36:30+0000",
"updated": "2021-06-08T16:30:14+0000",
"name": "Health",
"icon": "local_hospital",
"order": 1 ,
"profile": :profile_id
},
][
{
"id": :category_id,
"name": "Healthcare Facilities",
"description": "Representation of data gathered from various sources",
"theme": {
"id": :theme_id,
"name": "Health",
"icon": "local_hospital"
},
"metadata": {
"source": "",
"description": "Representation of data gathered from various sources",
"licence": null
},
"color": "",
"visible_tooltip_attributes": []
}
]{
"type": "FeatureCollection",
"features": [
{
"id": :location_id,
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
26.643601,
-27.748028
]
},
"properties": {
"data": [],
"name": "ALLANRIDGE",
"url": null,
"image": null
}
},
{
"id": :location_id,
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
29.110443,
-22.680732
]
},
"properties": {...}
},
{
"id": :location_id,
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
28.131317,
-26.318641
]
},
"properties": {...}
}
]
}{
count: 2,
results: [
{
type: "FeatureCollection",
features: [
{
"id": :location_id,
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
26.643601,
-27.748028
]
},
"properties": {...}
},
],
category: "Post Office service points"
},
{
type: "FeatureCollection",
features: [...],
category: "SASSA Pay Points"
}
]
}{
"type": "FeatureCollection",
"features": [
{
"id": :location_id,
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
27.877098,
-25.800849
]
},
"properties": {
"data": [],
"name": "BROEDERSTROOM",
"url": null,
"image": null
}
},
{
"id": :location_id,
"type": "Feature",
"geometry":{...},
"properties": {...}
},
{
"id": :location_id,
"type": "Feature",
"geometry":{...},
"properties": {...}
}
]
}




































































































