Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
COVID-19 Inzidenz-Widget für iOS innerhalb Deutschlands 🇩🇪 (Kreis/Stadt + Bundesland)
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: deep-gray; icon-glyph: magic;
// Licence: Robert Koch-Institut (RKI), dl-de/by-2-0
const apiUrl = (location) => `https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_Landkreisdaten/FeatureServer/0/query?where=1%3D1&outFields=GEN,cases7_per_100k,BL&geometry=${location.longitude.toFixed(3)}%2C${location.latitude.toFixed(3)}&geometryType=esriGeometryPoint&inSR=4326&spatialRel=esriSpatialRelWithin&returnGeometry=false&outSR=4326&f=json`
const apiUrlLand = (landname) => `https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/Coronaf%C3%A4lle_in_den_Bundesl%C3%A4ndern/FeatureServer/0/query?where=LAN_ew_GEN+%3D+%27${encodeURIComponent(landname)}%27&objectIds=&time=&geometry=&geometryType=esriGeometryEnvelope&inSR=&spatialRel=esriSpatialRelIntersects&resultType=none&distance=0.0&units=esriSRUnit_Meter&returnGeodetic=false&outFields=LAN_ew_GEN%2Cfaelle_100000_EW%2Ccases7_bl_per_100k&returnGeometry=false&returnCentroid=false&featureEncoding=esriDefault&multipatchOption=none&maxAllowableOffset=&geometryPrecision=&outSR=&datumTransformation=&applyVCSProjection=false&returnIdsOnly=false&returnUniqueIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&returnQueryGeometry=false&returnDistinctValues=false&cacheHint=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&having=&resultOffset=&resultRecordCount=&returnZ=false&returnM=false&returnExceededLimitFeatures=true&quantizationParameters=&sqlFormat=none&f=pjson&token=`
let widget = await createWidget()
if (!config.runsInWidget) {
await widget.presentSmall()
}
Script.setWidget(widget)
Script.complete()
async function createWidget(items) {
let location
if(args.widgetParameter) {
const fixedCoordinates = args.widgetParameter.split(",").map(parseFloat)
location = {
latitude: fixedCoordinates[0],
longitude: fixedCoordinates[1]
}
} else {
Location.setAccuracyToThreeKilometers()
location = await Location.current()
}
const data = await new Request(apiUrl(location)).loadJSON()
if(!data || !data.features || !data.features.length) {
const errorList = new ListWidget()
errorList.addText("Keine Ergebnisse für den aktuellen Ort gefunden.")
return errorList
}
const attr = data.features[0].attributes
const incidence = attr.cases7_per_100k.toFixed(1)
const cityName = attr.GEN
const list = new ListWidget()
let incidenceLand;
let landName;
if (!attr.BL) {
console.log('Kein Bundesland', attr);
} else {
const dataLand = await new Request(apiUrlLand(attr.BL)).loadJSON()
if(!dataLand || !dataLand.features || !dataLand.features.length) {
const errorList = new ListWidget()
errorList.addText("Keine Ergebnisse für den aktuellen Ort gefunden.")
return errorList
}
const attrLand = dataLand.features[0].attributes
incidenceLand = attrLand.cases7_bl_per_100k.toFixed(1)
landName = attrLand.LAN_ew_GEN
}
if(Device.isUsingDarkAppearance()){
const gradient = new LinearGradient()
gradient.locations = [0, 1]
gradient.colors = [
new Color("111111"),
new Color("222222")
]
list.backgroundGradient = gradient
}
const header = list.addText("🦠 Inzidenz".toUpperCase())
header.font = Font.mediumSystemFont(13)
list.addSpacer()
const label = list.addText(incidence+"")
label.font = Font.boldSystemFont(24)
label.textColor = Color.green()
if(incidence >= 50) {
label.textColor = Color.red()
} else if(incidence >= 35) {
label.textColor = Color.orange()
}
list.addText(cityName)
list.addSpacer()
let landLabel;
if (typeof landName !== 'undefined' && typeof incidenceLand !== 'undefined') {
landLabel = list.addText(incidenceLand + " " +landName)
} else {
landLabel = list.addText("Bundesland konnte nicht ermittelt werden.")
}
landLabel.font = Font.systemFont(12)
landLabel.textColor = Color.gray()
return list
}
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: deep-gray; icon-glyph: magic;
// Licence: Robert Koch-Institut (RKI), dl-de/by-2-0
//
// NEW: Save lat/lon to iCloud to prevent location error.
//
const apiUrl = (location) => `https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_Landkreisdaten/FeatureServer/0/query?where=1%3D1&outFields=GEN,cases7_per_100k,BL&geometry=${location.longitude.toFixed(3)}%2C${location.latitude.toFixed(3)}&geometryType=esriGeometryPoint&inSR=4326&spatialRel=esriSpatialRelWithin&returnGeometry=false&outSR=4326&f=json`
const apiUrlLand = (landname) => `https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/Coronaf%C3%A4lle_in_den_Bundesl%C3%A4ndern/FeatureServer/0/query?where=LAN_ew_GEN+%3D+%27${encodeURIComponent(landname)}%27&objectIds=&time=&geometry=&geometryType=esriGeometryEnvelope&inSR=&spatialRel=esriSpatialRelIntersects&resultType=none&distance=0.0&units=esriSRUnit_Meter&returnGeodetic=false&outFields=LAN_ew_GEN%2Cfaelle_100000_EW%2Ccases7_bl_per_100k&returnGeometry=false&returnCentroid=false&featureEncoding=esriDefault&multipatchOption=none&maxAllowableOffset=&geometryPrecision=&outSR=&datumTransformation=&applyVCSProjection=false&returnIdsOnly=false&returnUniqueIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&returnQueryGeometry=false&returnDistinctValues=false&cacheHint=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&having=&resultOffset=&resultRecordCount=&returnZ=false&returnM=false&returnExceededLimitFeatures=true&quantizationParameters=&sqlFormat=none&f=pjson&token=`
const saveIncidenceLatLon = (location) => {
let fm = FileManager.iCloud()
let path = fm.joinPath(fm.documentsDirectory(), "covid19latlon.json")
fm.writeString(path, JSON.stringify(location))
}
const getsavedIncidenceLatLon = () => {
let fm = FileManager.iCloud()
let path = fm.joinPath(fm.documentsDirectory(), "covid19latlon.json")
let data = fm.readString(path)
return JSON.parse(data)
}
let widget = await createWidget()
if (!config.runsInWidget) {
await widget.presentSmall()
}
Script.setWidget(widget)
Script.complete()
async function createWidget(items) {
let location
if(args.widgetParameter) {
console.log('get fixed lat/lon')
const fixedCoordinates = args.widgetParameter.split(",").map(parseFloat)
location = {
latitude: fixedCoordinates[0],
longitude: fixedCoordinates[1]
}
} else {
Location.setAccuracyToThreeKilometers()
try {
location = await Location.current()
console.log('get current lat/lon')
saveIncidenceLatLon(location)
} catch(e) {
console.log('using saved lat/lon')
location = getsavedIncidenceLatLon()
}
}
const data = await new Request(apiUrl(location)).loadJSON()
if(!data || !data.features || !data.features.length) {
const errorList = new ListWidget()
errorList.addText("Keine Ergebnisse für den aktuellen Ort gefunden.")
return errorList
}
const attr = data.features[0].attributes
const incidence = attr.cases7_per_100k.toFixed(1)
const cityName = attr.GEN
const list = new ListWidget()
let incidenceLand;
let landName;
if (!attr.BL) {
console.log('Kein Bundesland', attr);
} else {
const dataLand = await new Request(apiUrlLand(attr.BL)).loadJSON()
if(!dataLand || !dataLand.features || !dataLand.features.length) {
const errorList = new ListWidget()
errorList.addText("Keine Ergebnisse für den aktuellen Ort gefunden.")
return errorList
}
const attrLand = dataLand.features[0].attributes
incidenceLand = attrLand.cases7_bl_per_100k.toFixed(1)
landName = attrLand.LAN_ew_GEN
}
if(Device.isUsingDarkAppearance()){
const gradient = new LinearGradient()
gradient.locations = [0, 1]
gradient.colors = [
new Color("111111"),
new Color("222222")
]
list.backgroundGradient = gradient
}
const header = list.addText("🦠 Inzidenz".toUpperCase())
header.font = Font.mediumSystemFont(13)
list.addSpacer()
const label = list.addText(incidence+"")
label.font = Font.boldSystemFont(24)
label.textColor = Color.green()
if(incidence >= 50) {
label.textColor = Color.red()
} else if(incidence >= 35) {
label.textColor = Color.orange()
}
const citynameLabel = list.addText(cityName)
citynameLabel.font = Font.mediumSystemFont(14)
list.addSpacer()
let landLabel;
if (typeof landName !== 'undefined' && typeof incidenceLand !== 'undefined') {
landLabel = list.addText(incidenceLand + " " +landName)
} else {
landLabel = list.addText("Bundesland konnte nicht ermittelt werden.")
}
landLabel.font = Font.systemFont(12)
landLabel.textColor = Color.gray()
return list
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment