Fetch binary chunk and draw on canvas
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
export const fetchJson = (url: string, options = {}) => {
|
||||
return fetch(url, options).then(async response => {
|
||||
let responseCode = ''
|
||||
if (!response.ok) {
|
||||
responseCode = `error ${response.status}`
|
||||
}
|
||||
|
||||
let data
|
||||
let responseMessage = ''
|
||||
try {
|
||||
data = await response.json()
|
||||
if (data.error) responseMessage = data.error
|
||||
} catch (err) {
|
||||
responseMessage = 'Invalid JSON response'
|
||||
}
|
||||
|
||||
if (responseCode) {
|
||||
if (responseMessage) throw new Error(`${responseCode}: ${responseMessage}`)
|
||||
else throw new Error(responseCode)
|
||||
} else if (responseMessage) {
|
||||
throw new Error(responseMessage)
|
||||
}
|
||||
|
||||
return data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export const fetchBuffer = (url: string, options = {}) => {
|
||||
return fetch(url, options).then(async response => {
|
||||
let responseCode = ''
|
||||
if (!response.ok) {
|
||||
responseCode = `error ${response.status}`
|
||||
}
|
||||
|
||||
let data
|
||||
try {
|
||||
data = await response.arrayBuffer()
|
||||
} catch (err) {
|
||||
throw new Error('Invalid ArrayBuffer response')
|
||||
}
|
||||
|
||||
if (responseCode) {
|
||||
throw new Error(responseCode)
|
||||
}
|
||||
|
||||
return data
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { ColorEntry } from '../grib/draw/constants'
|
||||
|
||||
type RGBu8 = [number, number, number]
|
||||
type RGBAu8 = [number, number, number, number]
|
||||
|
||||
export function interpolateColors(value: number, a: RGBu8, b: RGBu8): RGBAu8 {
|
||||
const color = a.slice(0).map((from, i) => {
|
||||
const to = b[i]
|
||||
const delta = (to - from) * (value/255)
|
||||
return from + delta
|
||||
})
|
||||
|
||||
return [...color, 255] as RGBAu8
|
||||
}
|
||||
|
||||
export function valueToColorThreshold(value: number, colorArr: ColorEntry[]): [number, number, number, number] {
|
||||
const entries = colorArr.filter(t => t.value <= value)
|
||||
|
||||
return entries.length === 0 ? colorArr[colorArr.length-1].color : entries[0].color
|
||||
}
|
||||
|
||||
export function valueToColorInterpolated(value: number, colorArr: ColorEntry[]): [number, number, number, number] {
|
||||
const minIdx = colorArr.length-1
|
||||
if (value >= colorArr[0].value) return colorArr[0].color
|
||||
if (value <= colorArr[minIdx].value) return colorArr[minIdx].color
|
||||
|
||||
let closeMax: ColorEntry = colorArr[0]
|
||||
let closeMin: ColorEntry = colorArr[minIdx]
|
||||
for (let i=0; i<colorArr.length; i++) {
|
||||
const currentDeg = colorArr[i].value
|
||||
if (currentDeg >= value && currentDeg < closeMax.value) {
|
||||
closeMax = colorArr[i]
|
||||
}
|
||||
|
||||
if (currentDeg <= value && currentDeg > closeMin.value) {
|
||||
closeMin = colorArr[i]
|
||||
}
|
||||
}
|
||||
|
||||
const maxDeg = closeMax.color.slice(0, 3) as [number, number, number]
|
||||
const minDeg = closeMin.color.slice(0, 3) as [number, number, number]
|
||||
const scale = Math.abs(closeMax.value - closeMin.value)
|
||||
const delta = 255*(value - closeMin.value)/scale
|
||||
const rgba = interpolateColors(delta, minDeg, maxDeg)
|
||||
|
||||
return rgba
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
export type U8bits = [boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean]
|
||||
|
||||
export function u8ToBits(dec: number): U8bits {
|
||||
const str = (dec >>> 0).toString(2)
|
||||
const str8 = leftPad(str)
|
||||
const arr: U8bits = [false, false, false, false, false, false, false, false]
|
||||
for (let i=0; i<8; i++) {
|
||||
arr[i] = str8[i] === '1' ? true : false
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
function leftPad(str: string): string {
|
||||
const padCount = 8 - str.length
|
||||
for(let i=0; i<padCount; i++) {
|
||||
str = '0' + str
|
||||
}
|
||||
return str
|
||||
}
|
||||
Reference in New Issue
Block a user