import api, { getAPIV3Pooling } from '@/api'
import * as ramda from 'ramda'
import Ajv from 'ajv'
const latLngScaleFactor = 100000
const ajv = new Ajv({
allErrors: true,
})
ajv.addKeyword('$isNotEmpty', {
type: 'string',
validate: function (schema, data) {
return typeof data === 'string' && data.trim() !== ''
},
errors: false,
})
const predefinedViewCreateSchema = {
type: 'object',
properties: {
id: { type: 'number' },
name: { type: 'string', $isNotEmpty: true },
xMin: { type: 'number' },
xMax: { type: 'number' },
yMin: { type: 'number' },
yMax: { type: 'number' },
default: { type: 'number' },
//clientId: { type: 'number' },
//userId: { type: 'number' },
},
required: ['name', 'xMin', 'xMax', 'yMin', 'yMax'],
}
export async function removePredefinedView(id) {
if (!id) {
throw new Error('id is required')
}
return (
await api.v3.delete(
`${api.APIUrls.APIV3_GET_GEORED_CLIENT_USER_MAP_VIEWS}/${id}`
)
).data
}
/**
* API stores Lat/Lng as integer (multiply by latLngScaleFactor and remove decimals)
*/
function getNormalizedLatLngValueForAPI(value) {
//return Math.round(value * latLngScaleFactor)
//return parseInt(value * latLngScaleFactor)
//return parseInt(parseFloat(value * latLngScaleFactor).toFixed(0))
value = parseFloat(value.toFixed(4)) //i.g 3 decimals is enough precision to target a parking lot
//Similar to PHP intval
return parseInt(value * latLngScaleFactor, 10)
}
export async function savePredefinedViewDefault(id) {
const validateParams = ajv.compile({
type: 'object',
properties: {
id: { type: 'number' },
},
required: ['id'],
})
const payload = {
id,
default: 1,
}
if (!validateParams(payload)) {
//throw new Error(ajv.errorsText(validateParams.errors))
console.error(ajv.errorsText(validateParams.errors))
return false
}
return savePredefinedView(payload, {
disableValidations: true,
disableLatLngNormalization: true,
})
}
export async function savePredefinedView(values, options = {}) {
const validatePayload = ajv.compile(predefinedViewCreateSchema)
const isValid = options.disableValidations === true || validatePayload(values)
if (!isValid) {
console.error({
errors: ajv.errorsText(validatePayload.errors),
})
throw new Error(ajv.errorsText(validatePayload.errors))
return false
}
if (options.disableLatLngNormalization !== true) {
values = {
...values,
xMin: getNormalizedLatLngValueForAPI(values.xMin),
yMin: getNormalizedLatLngValueForAPI(values.yMin),
xMax: getNormalizedLatLngValueForAPI(values.xMax),
yMax: getNormalizedLatLngValueForAPI(values.yMax),
}
}
let data
if (values.id) {
data = (
await api.v3.patch(
`${api.APIUrls.APIV3_GET_GEORED_CLIENT_USER_MAP_VIEWS}/${values.id}}`,
values
)
).data
} else {
data = (await api.v3.post(
api.APIUrls.APIV3_GET_GEORED_CLIENT_USER_MAP_VIEWS,
values
),
values).data
}
return true
}
export async function getCenterLatLngFromPredefinedViewId(id) {
if (!id) {
return false
}
let res = await api.v3.get(
api.APIUrls.APIV3_GET_GEORED_CLIENT_USER_MAP_VIEWS + '/' + id
)
let item = res.data
if (item.id) {
return getLatLngFromRectangle({
topLeft: {
lat: item.yMin / latLngScaleFactor,
lng: item.xMin / latLngScaleFactor,
},
bottomRight: {
lat: item.yMax / latLngScaleFactor,
lng: item.xMax / latLngScaleFactor,
},
})
} else {
return false
}
}
function getLatLngFromRectangle(rectangle) {
const { topLeft, bottomRight } = rectangle
const latDiff = topLeft.lat - bottomRight.lat
const lngDiff = topLeft.lng - bottomRight.lng
const midpointLat = topLeft.lat - latDiff / 2
const midpointLng = topLeft.lng - lngDiff / 2
return { lat: midpointLat, lng: midpointLng }
}
export async function fetchPredefinedViews(options = {}) {
//return (await api.v3.get(api.APIUrls.APIV3_GET_GEORED_CLIENT_USER_MAP_VIEWS)).data
return await getAPIV3Pooling({
uri: `${api.APIUrls.APIV3_GET_GEORED_CLIENT_USER_MAP_VIEWS}?page=1&itemsPerPage=500`,
transform:
options.transform !== undefined
? options.transform
: function normalizePredefinedViewItem(item) {
return {
...ramda.pick(['id', 'userId', 'clientId', 'name'], item),
xMin: item.xMin / latLngScaleFactor,
xMax: item.xMax / latLngScaleFactor,
yMin: item.yMin / latLngScaleFactor,
yMax: item.yMax / latLngScaleFactor,
}
},
payload: {
properties: options.properties || [
'id',
'userId',
'clientId',
'name',
'xMin',
'yMin',
'xMax',
'yMax',
],
},
forcePayload: true,
})
}
export async function fetchDefaultPredefinedView() {
let views = await fetchPredefinedViews({
transform: null,
properties: ['id', 'default'],
})
return (
views.find((v) => v.default === 1 || v.default === true || !!v.default)
?.id || null
)
}
Source