Skip to content

Commit

Permalink
Update distribution endpoints, add aggregate type
Browse files Browse the repository at this point in the history
  • Loading branch information
jlpereira committed May 31, 2023
1 parent ef3d8e0 commit ee6f86f
Show file tree
Hide file tree
Showing 14 changed files with 163 additions and 64 deletions.
1 change: 1 addition & 0 deletions src/assets/css/vars.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
--color-base-content: 0, 0, 0;

--color-map-georeference: 239, 68, 68;
--color-map-aggregate: 249, 115, 22;
--color-map-asserted: 249, 115, 22;
--color-map-type-material: 51, 136, 255;
--color-map-collection-object: 239, 68, 68;
Expand Down
7 changes: 7 additions & 0 deletions src/components/Map/shapes/Aggregate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const Aggregate = {
color: 'rgb(var(--color-map-aggregate))',
weight: 1,
dashArray: '3',
dashOffset: '3',
fillOpacity: 0.25
}
1 change: 1 addition & 0 deletions src/components/Map/shapes/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './Aggregate'
export * from './AssertedDistribution'
export * from './CollectionObject'
export * from './TypeMaterial'
3 changes: 2 additions & 1 deletion src/components/Map/utils/geojsonOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ const TYPES = [
'TypeMaterial',
'CollectionObject',
'AssertedDistribution',
'Georeference'
'Georeference',
'Aggregate'
]

const DEFAULT_OPTIONS = {
Expand Down
79 changes: 21 additions & 58 deletions src/modules/otus/components/Panel/PanelMap/PanelMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class="h-96 max-h-96"
dragging
:zoom="zoom"
:geojson="geojson"
:geojson="store.distribution.geojson"
@geojson:ready="() => (isLoading = false)"
/>
</ClientOnly>
Expand All @@ -22,23 +22,23 @@
<OtuSearch
v-if="isOtuSearchVisible"
:otu="otu"
:shapes="geojson"
:shapes="store.distribution.geojson"
@close="() => (isOtuSearchVisible = false)"
/>
</ClientOnly>
</div>
<div
v-if="errorMessage"
v-if="store.distribution.errorMessage"
class="flex flex-row p-2 text-xs italic"
>
* {{ errorMessage }}
* {{ store.distribution.errorMessage }}
</div>
<div
class="flex flex-row p-2 gap-2 text-xs"
v-if="currentShapeTypes.length"
v-if="store.distribution.currentShapeTypes.length"
>
<div
v-for="type in currentShapeTypes"
v-for="type in store.distribution.currentShapeTypes"
:key="type"
class="flex flex-row items-center"
>
Expand All @@ -54,7 +54,7 @@

<script setup>
import { ref, watch } from 'vue'
import TaxonWorks from '../../../services/TaxonWorks'
import { useOtuStore } from '@/modules/otus/store/store'
import OtuSearch from '../../Search/OtuSearch.vue'
const props = defineProps({
Expand All @@ -66,15 +66,18 @@ const props = defineProps({
otu: {
type: Object,
required: true
},
taxon: {
type: Object,
required: true
}
})
const zoom = 2
const geojson = ref(undefined)
const isLoading = ref(true)
const isOtuSearchVisible = ref(false)
const currentShapeTypes = ref([])
const errorMessage = ref(null)
const store = useOtuStore()
const LEGEND = {
AssertedDistribution: {
Expand All @@ -92,6 +95,10 @@ const LEGEND = {
CollectionObject: {
label: 'Collection object',
background: 'bg-map-collection-object'
},
Aggregate: {
label: 'Aggregate (Asserted distribution & Georeference)',
background: 'bg-map-aggregate'
}
}
Expand All @@ -101,55 +108,11 @@ watch(
if (newId === oldId) return
isLoading.value = true
const { data } = await TaxonWorks.getOtuDistribution(props.otuId)
if (data.request_too_large) {
geojson.value = null
errorMessage.value = data.message
} else {
geojson.value = {
...data,
features: removeDuplicateShapes(data)
}
}
store.loadDistribution({
otuId: props.otuId,
rankString: props.taxon.rank_string
})
},
{ immediate: true }
)
function removeDuplicateShapes(data) {
const features = []
data.features.forEach((feature) => {
const shapeId = feature.properties.shape.id
const shapeType = feature.properties.shape.type
if (!currentShapeTypes.value.includes(feature.properties.base.type)) {
currentShapeTypes.value.push(feature.properties.base.type)
}
const index = features.findIndex(
(item) =>
item.properties.shape.id === shapeId &&
item.properties.shape.type === shapeType
)
if (index > -1) {
const currentFeature = features[index]
currentFeature.properties.base.push(feature.properties.base)
currentFeature.properties.target.push(feature.properties.target)
} else {
const item = structuredClone(feature)
item.properties.base = [item.properties.base]
item.properties.target = [item.properties.target]
features.push(item)
}
})
currentShapeTypes.value.sort()
return features
}
</script>
6 changes: 5 additions & 1 deletion src/modules/otus/services/TaxonWorks.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ export default class TaxonWorks {
}

static getOtuDistribution(otuId) {
return makeAPIRequest.get(`/otus/${otuId}/inventory/distribution`)
return makeAPIRequest.get(`/otus/${otuId}/inventory/distribution.json`)
}

static getOtuGeoJSONDistribution(otuId) {
return makeAPIRequest.get(`/otus/${otuId}/inventory/distribution.geojson`)
}

static getOtuContent(otuId) {
Expand Down
1 change: 1 addition & 0 deletions src/modules/otus/store/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './loadDistribution'
51 changes: 51 additions & 0 deletions src/modules/otus/store/actions/loadDistribution.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {
isRankGrpup,
removeDuplicateShapes,
makeGeoJSONFeature
} from '../../utils'
import TaxonWorks from '../../services/TaxonWorks'

export const actionLoadDistribution = {
async loadDistribution({ otuId, rankString }) {
const isSpeciesGroup = isRankGrpup('SpeciesGroup', rankString)

const getAggregateShape = async (otuId) => {
TaxonWorks.getOtuDistribution(otuId)
.then(({ data }) => {
const geojson = JSON.parse(data.cached_map.geo_json)

this.distribution.currentShapeTypes = ['Aggregate']
this.distribution.geojson = {
features: [makeGeoJSONFeature(geojson, 'Aggregate')]
}
})
.catch((e) => {
this.distribution.errorMessage = e.response.data.error
this.distribution.currentShapeTypes = []
this.distribution.geojson = []
})
}

if (isSpeciesGroup) {
TaxonWorks.getOtuGeoJSONDistribution(otuId)
.then(({ data }) => {
if (data.request_too_large) {
this.distribution.geojson = null
this.distribution.errorMessage = data.message
} else {
const { features, shapeTypes } = removeDuplicateShapes(data)

this.distribution.currentShapeTypes = shapeTypes
this.distribution.geojson = {
features
}
}
})
.catch((e) => {
getAggregateShape(otuId)
})
} else {
getAggregateShape(otuId)
}
}
}
16 changes: 12 additions & 4 deletions src/modules/otus/store/store.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { defineStore } from 'pinia'
import TaxonWorks from '../services/TaxonWorks'
import { actionLoadDistribution } from './actions'

export const useOtuStore = defineStore('otuStore', {
state: () => {
return {
otu: null,
taxon: null,
images: null
images: null,
distribution: {
geojson: null,
errorMessage: null,
currentShapeTypes: []
}
}
},
actions: {
Expand Down Expand Up @@ -36,6 +42,8 @@ export const useOtuStore = defineStore('otuStore', {
}

this.images = (await TaxonWorks.getOtuImages(otuId, params)).data
}
},
})
},

...actionLoadDistribution
}
})
3 changes: 3 additions & 0 deletions src/modules/otus/utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './isRankGroup'
export * from './makeGeoJSONFeature'
export * from './removeDuplicateShapes'
5 changes: 5 additions & 0 deletions src/modules/otus/utils/isRankGroup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function isRankGrpup(compareRank, rank) {
const rankGroup = rank.split('::').at(2)

return rankGroup === compareRank
}
13 changes: 13 additions & 0 deletions src/modules/otus/utils/makeGeoJSONFeature.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export function makeGeoJSONFeature(geometry, type) {
return {
type: 'Feature',
geometry,
properties: {
base: [
{
type
}
]
}
}
}
40 changes: 40 additions & 0 deletions src/modules/otus/utils/removeDuplicateShapes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
export function removeDuplicateShapes(data) {
const features = []
const shapeTypes = []

data.features.forEach((feature) => {
const shapeId = feature.properties.shape.id
const shapeType = feature.properties.shape.type

if (!shapeTypes.includes(feature.properties.base.type)) {
shapeTypes.push(feature.properties.base.type)
}

const index = features.findIndex(
(item) =>
item.properties.shape.id === shapeId &&
item.properties.shape.type === shapeType
)

if (index > -1) {
const currentFeature = features[index]

currentFeature.properties.base.push(feature.properties.base)
currentFeature.properties.target.push(feature.properties.target)
} else {
const item = structuredClone(feature)

item.properties.base = [item.properties.base]
item.properties.target = [item.properties.target]

features.push(item)
}
})

shapeTypes.sort()

return {
shapeTypes,
features
}
}
1 change: 1 addition & 0 deletions tailwind.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module.exports = {

map: {
georeference: withOpacity('--color-map-georeference'),
aggregate: withOpacity('--color-map-aggregate'),
asserted: withOpacity('--color-map-asserted'),
'type-material': withOpacity('--color-map-type-material'),
'collection-object': withOpacity('--color-map-collection-object')
Expand Down

0 comments on commit ee6f86f

Please sign in to comment.