Skip to content

Commit

Permalink
Add African Union regions (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
ebrelsford authored Nov 13, 2023
1 parent 736d408 commit 2df70f4
Show file tree
Hide file tree
Showing 8 changed files with 314 additions and 0 deletions.
41 changes: 41 additions & 0 deletions vacs-map-app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions vacs-map-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"format": "prettier --write src/"
},
"dependencies": {
"@turf/bbox": "^6.5.0",
"@turf/helpers": "^6.5.0",
"autoprefixer": "^10.4.16",
"d3": "^7.8.5",
Expand Down
12 changes: 12 additions & 0 deletions vacs-map-app/public/data/african-union-regions.geojson

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions vacs-map-app/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import MapContainerColor from '@/components/MapContainerColor.vue';
import MapContainerColorRadius from '@/components/MapContainerColorRadius.vue';
import MapContainerNotFilled from '@/components/MapContainerNotFilled.vue';
import MapContainerNotFilledTwoLayers from '@/components/MapContainerNotFilledTwoLayers.vue';
import MapContainerColorAfricanUnion from '@/components/MapContainerColorAfricanUnion.vue';
import Filters from '@/components/Filters.vue';
const availableMaps = [
Expand All @@ -39,6 +40,11 @@ const availableMaps = [
name: 'circles not filled, two layers',
component: MapContainerNotFilledTwoLayers,
},
{
id: 'african-union',
name: 'circles + african union regions',
component: MapContainerColorAfricanUnion,
},
];
const selectedMap = ref(availableMaps[0].id);
const selectedMapComponent = computed(() => {
Expand Down
91 changes: 91 additions & 0 deletions vacs-map-app/src/components/AfricanUnionRegionsLayer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<template></template>

<script setup>
import * as d3 from 'd3';
import bbox from '@turf/bbox';
import { computed, toRefs, watch } from 'vue';
import { storeToRefs } from 'pinia';
import { useAfricanUnionRegionsStore } from '@/stores/africanUnionRegions';
const props = defineProps({
id: {
type: String,
default: '',
},
map: {
type: Object,
default: null,
},
mapReady: {
type: Boolean,
default: false,
},
sourceId: {
type: String,
default: '',
},
zoomOnClick: {
type: Boolean,
default: true,
},
});
const {
id,
map,
mapReady,
sourceId,
zoomOnClick,
} = toRefs(props);
const africanUnionRegionsStore = useAfricanUnionRegionsStore();
const { data: regionsData } = storeToRefs(africanUnionRegionsStore);
const addLayer = () => {
if (!map.value || !mapReady.value || map.value.getLayer(id.value)) return;
const linesLayerId = `${id.value}-lines`;
map.value.addLayer({
id: id.value,
source: sourceId.value,
type: 'fill',
paint: {
'fill-color': 'transparent',
}
}, 'country-label-filter');
map.value.addLayer({
id: linesLayerId,
source: sourceId.value,
type: 'line',
paint: {
'line-color': 'black',
}
}, 'country-label-filter');
if (zoomOnClick) {
map.value.on('click', [id.value, linesLayerId], (e) => {
if (!e.features?.[0]) return;
const feature = regionsData.value.features
.find(({ id }) => id === e.features[0].id);
const [minX, minY, maxX, maxY] = bbox(feature);
map.value.fitBounds([[minX, minY], [maxX, maxY]]);
});
}
};
watch(map, () => {
addLayer();
});
watch(mapReady, () => {
addLayer();
});
</script>
<style scoped></style>
55 changes: 55 additions & 0 deletions vacs-map-app/src/components/AfricanUnionRegionsSource.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<template></template>

<script setup>
import { computed, onMounted, toRefs, watch } from 'vue';
import { storeToRefs } from 'pinia';
import { useAfricanUnionRegionsStore } from '@/stores/africanUnionRegions';
const props = defineProps({
id: {
type: String,
default: '',
},
map: {
type: Object,
default: null,
},
mapReady: {
type: Boolean,
default: false,
},
});
const { id, map, mapReady } = toRefs(props);
const africanUnionRegionsStore = useAfricanUnionRegionsStore();
const { data } = storeToRefs(africanUnionRegionsStore);
onMounted(() => {
africanUnionRegionsStore.load();
});
const addSource = (geoJson) => {
if (!map.value || !mapReady.value || map.value.getSource(id)) return;
map.value.addSource(id.value, {
type: 'geojson',
data: geoJson,
});
};
watch(mapReady, () => {
if (!data.value) return;
addSource(data.value);
});
watch(data, () => {
if (!data.value) return;
addSource(data.value);
});
</script>

<style></style>
75 changes: 75 additions & 0 deletions vacs-map-app/src/components/MapContainerColorAfricanUnion.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<template>
<BaseMap>
<template v-slot="{ map, mapReady }">
<GridSource :id="sourceId" :map="map" :mapReady="mapReady" />
<AfricanUnionRegionsSource
:id="africanUnionRegionsSourceId"
:map="map"
:mapReady="mapReady"
/>
<AfricanUnionRegionsLayer
id="africanUnionRegionsLayer"
:sourceId="africanUnionRegionsSourceId"
:map="map"
:mapReady="mapReady"
/>
<GridOverlay
id="grid-layer-1"
:color-column="selectedColumn"
:color-column-extent="selectedColumnExtent"
:color-column-quintiles="selectedColumnQuintiles"
:color-diverging="false"
:sourceId="sourceId"
:map="map"
:mapReady="mapReady"
/>
</template>
</BaseMap>
</template>

<script setup>
import { computed } from 'vue';
import { storeToRefs } from 'pinia';
import BaseMap from '@/components/BaseMap.vue';
import { useFiltersStore } from '@/stores/filters';
import { useCropYieldsStore } from '@/stores/cropYields';
import GridSource from './GridSource.vue';
import GridOverlay from './GridOverlay.vue';
import AfricanUnionRegionsSource from './AfricanUnionRegionsSource.vue';
import AfricanUnionRegionsLayer from './AfricanUnionRegionsLayer.vue';
const sourceId = 'cropGrid';
const africanUnionRegionsSourceId = 'africanUnionRegions';
const cropYieldsStore = useCropYieldsStore();
const filtersStore = useFiltersStore();
const {
selectedCrop,
selectedMetric,
selectedModel
} = storeToRefs(filtersStore);
const selectedColumn = computed(() => {
if (!selectedMetric.value || !selectedCrop.value || !selectedModel.value) {
return null;
}
return [
selectedMetric.value,
selectedCrop.value,
selectedModel.value,
].join('_');
});
const selectedColumnExtent = computed(() => {
if (!selectedColumn.value) return null;
return cropYieldsStore.getExtent(selectedColumn.value);
});
const selectedColumnQuintiles = computed(() => {
if (!selectedColumn.value) return null;
return cropYieldsStore.getQuintiles(selectedColumn.value);
});
</script>

<style scoped></style>
33 changes: 33 additions & 0 deletions vacs-map-app/src/stores/africanUnionRegions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as d3 from 'd3';
import { ref } from 'vue';
import { defineStore } from 'pinia';
import { getDataUrl } from '@/constants/data-load';

export const useAfricanUnionRegionsStore = defineStore('africanUnionRegions', () => {
const data = ref(null);
const loading = ref(false);

const load = async () => {
if (loading.value || data.value) return false;
loading.value = true;

const response = await fetch(getDataUrl('african-union-regions.geojson'));
let geojson = await response.json();

geojson = {
...geojson,
features: geojson.features.map((f, i) => ({
...f,
id: i,
})),
};

data.value = Object.freeze(geojson);
}

return {
data,
loading,
load,
};
});

0 comments on commit 2df70f4

Please sign in to comment.