Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
808 changes: 574 additions & 234 deletions package-lock.json

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,26 @@
"@fontsource/poppins": "^5.2.7",
"@jop-software/astro-cookieconsent": "^3.0.1",
"@tailwindcss/vite": "^4.1.17",
"astro": "^5.15.5",
"astro": "^5.16.4",
"astro-icon": "^1.1.5",
"astro-pagefind": "^1.8.5",
"maplibre-gl": "^5.14.0",
"preline": "^3.2.3",
"sass": "^1.94.0",
"sass": "^1.95.0",
"scrollama": "^3.2.0",
"tailwindcss": "^4.1.17",
"vanilla-cookieconsent": "^3.1.0"
},
"devDependencies": {
"@iconify-json/gis": "^1.2.5",
"@iconify-json/mdi": "^1.2.3",
"@typescript-eslint/eslint-plugin": "^8.46.4",
"@typescript-eslint/parser": "^8.46.4",
"@typescript-eslint/eslint-plugin": "^8.49.0",
"@typescript-eslint/parser": "^8.49.0",
"eslint": "^9.39.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-astro": "^1.5.0",
"prettier": "^3.6.2",
"prettier": "^3.7.4",
"prettier-plugin-astro": "^0.14.1",
"prettier-plugin-tailwindcss": "^0.7.1"
"prettier-plugin-tailwindcss": "^0.7.2"
}
}
6 changes: 3 additions & 3 deletions src/components/Data.astro
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Layout from '../layouts/Layout.astro';
import Section from '../components/Section.astro';
import {useLocalePages, useTranslations, type LocaleString} from '../i18n/utils';
import type {DataEntryMap} from 'astro:content';
import {mdExcerpt} from './utils';
import {mdExcerpt, pictureWidths} from './utils';

interface Props {
datum: DataEntryMap['data'];
Expand Down Expand Up @@ -43,7 +43,7 @@ const t = useTranslations(lang);

<Layout title={datum.title} description={mdExcerpt(pageBody, 200)}>
<Section>
<Picture class="w-full rounded-xl object-cover" src={datum.exampleImage} alt={datum.title} />
<Picture class="w-full rounded-xl object-cover" src={datum.exampleImage} alt={datum.title} widths={pictureWidths()} />
<div class="text-lg"><slot /></div>
</Section>
<Section bg="green" box>
Expand All @@ -68,7 +68,7 @@ const t = useTranslations(lang);
<p>{datum.method}</p>
<h4 class="mt-4 text-lg font-semibold">{t('data.quality')}</h4>
<p>{datum.quality}</p>
{datum.qualityImage && <Picture src={datum.qualityImage} alt={t('data.quality')} />}
{datum.qualityImage && <Picture src={datum.qualityImage} alt={t('data.quality')} widths={pictureWidths()} />}
<div class="mt-4">
<h4 class="text-lg font-semibold">{t('data.properties')}</h4>
<table class="border-main-lightgreen mt-4 w-full border-2">
Expand Down
3 changes: 2 additions & 1 deletion src/components/Logos.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
import type {ImageMetadata} from 'astro';
import {Picture} from 'astro:assets';
import {pictureWidths} from './utils';

const _logos = import.meta.glob<{default: ImageMetadata}>('/src/images/logos/*.{jpeg,jpg,png,gif}');
const logos: Array<{src: ImageMetadata; alt: string}> = await Promise.all(
Expand Down Expand Up @@ -35,7 +36,7 @@ const logos: Array<{src: ImageMetadata; alt: string}> = await Promise.all(
{
logos.map((logo) => (
<div class="flex w-full items-center justify-center">
<Picture src={logo.src} alt={logo.alt} class="h-auto w-full object-contain" />
<Picture src={logo.src} alt={logo.alt} class="h-auto w-full object-contain" widths={pictureWidths()} />
</div>
))
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/News.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import {getCollection} from 'astro:content';
import {asLocale, slugToPostLink, useTranslations} from '../i18n/utils';
import {Image} from 'astro:assets';
import {mdExcerpt} from './utils';
import {mdExcerpt, pictureWidths} from './utils';

const pageLang = Astro.currentLocale;
const t = useTranslations(pageLang);
Expand Down Expand Up @@ -68,7 +68,7 @@ const newsItems: Array<{
class="group flex h-full flex-col rounded-xl border border-gray-200 p-5 transition duration-300 hover:border-transparent hover:shadow-lg focus:border-transparent focus:shadow-lg focus:outline-hidden dark:border-neutral-700 dark:hover:border-transparent dark:hover:shadow-black/40 dark:focus:border-transparent dark:focus:shadow-black/40"
href={news.link}
>
<Image class="aspect-video w-full rounded-xl object-cover" src={news.image} alt={news.title} />
<Image class="aspect-video w-full rounded-xl object-cover" src={news.image} alt={news.title} widths={pictureWidths()} />
<div class="my-6">
<h3 class="text-xl font-semibold text-gray-800 dark:text-neutral-300 dark:group-hover:text-white">{news.title}</h3>
<p class="mt-5 text-gray-600 dark:text-neutral-400">{news.abstract}</p>
Expand Down
3 changes: 2 additions & 1 deletion src/components/team/person.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
import {Icon} from 'astro-icon/components';
import {Image} from 'astro:assets';
import {pictureWidths} from '../utils';

interface Props {
name: string;
Expand All @@ -15,7 +16,7 @@ const {name, title, image, linkedin, twitter, website} = Astro.props;
---

<div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-4">
<Image class="size-20 rounded-lg" src={image} alt={name} />
<Image class="size-20 rounded-lg" src={image} alt={name} widths={pictureWidths()} />

<div class="grow">
<div>
Expand Down
7 changes: 7 additions & 0 deletions src/components/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,10 @@ export function mdExcerpt(text: string, length: number) {

return trimmedText.substring(0, length) + '…';
}

/**
* @returns an array of picture widths used for responsive and optimized images in <Image /> and <Picture /> components.
*
* Note: This is a function because Astro requires sizes to be mutable.
*/
export const pictureWidths = (): number[] => [768, 1024, 1280, 1536] as const;
22 changes: 22 additions & 0 deletions src/content.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,34 @@ const data = defineCollection({
}),
});

const scroller = defineCollection({
type: 'data',
schema: ({image}) =>
z.array(
z.object({
id: z.string().nonempty().max(100),
title: z.string().nonempty().max(100),
image: image(),
description: z.object({
de: z.string().nonempty(),
en: z.string().nonempty(),
}),
location: z.object({
center: z.array(z.number().finite()).length(2),
zoom: z.number().finite().positive(),
pitch: z.number().int().positive(),
bearing: z.number().int(),
}),
}),
),
});
// 4. Export a single `collections` object to register your collection(s)
export const collections = {
data,
cookies,
posts,
publications,
references,
scroller,
services,
};
131 changes: 131 additions & 0 deletions src/content/scroller/2025.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
[
{
"id": "ai4wildlive",
"title": "AI4WildLIVE Phase II",
"image": "../../images/retrospective/2025/AI4WildLIVE.png",
"description": {
"de": "Wir haben mit der Entwicklung des WildLIVE-GIS in Phase II von AI4WildLIVE begonnen. Ein zentrales Ziel ist die Etablierung eines Analyse-Tools, das das WildLIVE-Portal von Senckenberg mit der Geo Engine verbindet.",
"en": "We started developing the WildLIVE-GIS in Phase II of AI4WildLIVE. A central goal is establishing an analysis tool that connects the Senckenberg WildLIVE portal with the Geo Engine."
},
"location": {
"center": [8.6821, 50.1109],
"zoom": 10,
"pitch": 30,
"bearing": 15
},
"date": "Januar 2025"
},
{
"id": "circular-valley",
"title": "Circular Valley Convention 2025",
"image": "../../images/posts/circular-valley-2025.jpg",
"description": {
"de": "Bei der Circular Valley Convention 2025 haben wir unsere Lösungen für datengetriebene Entscheidungen vorgestellt und diskutiert, wie man Nachhaltigkeit und Effizienz vereinen kann.",
"en": "At the Circular Valley Convention 2025, we presented our solutions for data-driven decisions and discussed how to combine sustainability and efficiency."
},
"location": {
"center": [6.7735, 51.2277],
"zoom": 11,
"pitch": 50,
"bearing": 45
},
"date": "März 2025"
},
{
"id": "ad-astra",
"title": "Ad Astra Summit",
"image": "../../images/retrospective/2025/Ad Astra Summit.jpg",
"description": {
"de": "Beim Ad Astra Summit haben wir gezeigt, wie sich Geodaten effizient für ESG-Reporting und automatisierte Analyseprozesse nutzen lassen. ",
"en": "At the Ad Astra Summit, we demonstrated how geodata can be used efficiently for ESG reporting and automated analysis processes."
},
"location": {
"center": [8.6512, 49.8728],
"zoom": 13,
"pitch": 20,
"bearing": 90
},
"date": "April 2025"
},
{
"id": "living-planet",
"title": "Living Planet Symposium (LPS)",
"image": "../../images/retrospective/2025/Living Planet Symposium.jpg",
"description": {
"de": "Beim Living Planet Symposium (LPS) haben wir unsere neuesten Arbeiten in zwei Vorträgen vorgestellt: zum einen über die deutsche EnMap-Mission und das CropHype-Projekt zur Feldfruchterkennung, zum anderen darüber, wie wir Machine-Learning-Modelle mit der Geo Engine operationalisieren. ",
"en": "At the Living Planet Symposium (LPS), we presented our latest work in two talks: one on the German EnMap mission and the CropHype project for crop detection, and the other on how we operationalize machine learning models with the Geo Engine."
},
"location": {
"center": [16.4138, 48.2163],
"zoom": 14,
"pitch": 60,
"bearing": 120
},
"date": "Juni 2025"
},
{
"id": "baumarten",
"title": "Dominant Tree Types in Germany",
"image": "../../images/posts/dominant-tree-types/image0.png",
"description": {
"de": "Mit der Baumarten-Klassifikation haben wir ein neues Datenprodukt veröffentlicht, das präzise Einblicke in die Waldzusammensetzung in Deutschland bietet.<br><br><a href=\"/posts/dominant-tree-types/\" target=\"_blank\">Zum Artikel</a>",
"en": "With the tree species classification, we released a new data product offering precise insights into forest composition in Germany.<br><br><a href=\"/en/posts/dominant-tree-types/\" target=\"_blank\">Read the article</a>"
},
"location": {
"center": [8.7562, 50.809],
"zoom": 12,
"pitch": 35,
"bearing": 75
},
"date": "13. Juni 2025"
},
{
"id": "gfoe-wuerzburg",
"title": "GfÖ-Jahrestagung 2025",
"image": "../../images/retrospective/2025/GfÖ.png",
"description": {
"de": "Bei der GfÖ-Jahrestagung 2025 in Würzburg veranstalteten wir einen Hands-on-Workshop (\"VAT & Geo Engine 4 ML\") zur Kombination von Biodiversitätsdaten mit Fernerkundung und maschinellem Lernen, bei dem wir Machine-Learning-Workflows im Rahmen von NFDI4Biodiversity gezeigt haben.",
"en": "At the GfÖ Annual Meeting 2025 in Würzburg, we hosted a hands-on workshop (\"VAT & Geo Engine 4 ML\") on combining biodiversity data with remote sensing and machine learning, showcasing machine learning workflows within the NFDI4Biodiversity framework."
},
"location": {
"center": [9.9534, 49.7913],
"zoom": 10,
"pitch": 45,
"bearing": 30
},
"date": "September 2025"
},
{
"id": "push-hessen",
"title": "push! Hessen",
"image": "../../images/retrospective/2025/push.png",
"description": {
"de": "Wir haben eine Förderung im push!-Hessen-Programm gewonnen und freuen uns, unsere Lösungen voranzubringen und Unternehmen bei ihren Nachhaltigkeitsberichtspflichten im Bereich Biodiversität zu unterstützen.",
"en": "We won funding in the push! Hessen program and look forward to advancing our solutions and supporting companies with their sustainability reporting obligations in the field of biodiversity."
},
"location": {
"center": [8.2398, 50.0782],
"zoom": 11,
"pitch": 25,
"bearing": 60
},
"date": "September 2025"
},
{
"id": "esa-bic",
"title": "ESA BIC Incubation",
"image": "../../images/posts/esa-bic-2025.png",
"description": {
"de": "Bei ESA BIC haben wir unsere Inkubationszeit erfolgreich abgeschlossen und dadurch neue Bausteine in unserer Infrastruktur geschaffen: eine Random-Forest-Pipeline, einen flexiblen ML-Operator und Modell-Blaupausen.<br><br><a href=\"https://youtu.be/1186CBUKm8Y\" target=\"_blank\" rel=\"noopener noreferrer\">Zum Video</a>",
"en": "We successfully completed our incubation period at ESA BIC, creating new building blocks in our infrastructure: a Random Forest pipeline, a flexible ML operator, and model blueprints.<br><br><a href=\"https://youtu.be/1186CBUKm8Y\" target=\"_blank\" rel=\"noopener noreferrer\">Watch the video</a>"
},
"video": "https://youtu.be/1186CBUKm8Y",
"location": {
"center": [8.6209, 49.8722],
"zoom": 14,
"pitch": 50,
"bearing": 150
},
"date": "15. Oktober 2025"
}
]
2 changes: 2 additions & 0 deletions src/i18n/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export const translations = {
'data.time': 'Zeit',
'data.spatialResolution': 'Räumliche Auflösung',
'data.spatialValidity': 'Räumliche Gültigkeit',
retrospective: 'Retrospektive',
},
en: {
'nav.contact': 'Contact',
Expand Down Expand Up @@ -169,6 +170,7 @@ export const translations = {
'data.time': 'Time',
'data.spatialResolution': 'Spatial Resolution',
'data.spatialValidity': 'Spatial Validity',
retrospective: 'Retrospective',
},
} as const;

Expand Down
Binary file added src/images/retrospective/2025/AI4WildLIVE.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/retrospective/2025/GfÖ.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/retrospective/2025/push.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 11 additions & 5 deletions src/layouts/Layout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import {useTranslations} from '../i18n/utils';
interface Props {
title: string;
description?: string;
noNav?: boolean;
noHeader?: boolean;
noFooter?: boolean;
}

const currentLocale = Astro.currentLocale;
const t = useTranslations(currentLocale);

const {title, description = t('header.slogan'), noHeader = false} = Astro.props;
const {title, description = t('header.slogan'), noHeader = false, noFooter = false, noNav = false} = Astro.props;

const pageTitle = `${title} - Geo Engine`;
---
Expand All @@ -31,12 +33,16 @@ const pageTitle = `${title} - Geo Engine`;
</head>

<body>
<NavBar />
{!noNav && <NavBar />}
{!noHeader && <PageHeader>{title}</PageHeader>}
<slot />
<div class="bg-black">
<Footer />
</div>
{
!noFooter && (
<div class="bg-black">
<Footer />
</div>
)
}
<!-- Preline UI -->
<script>
import 'preline/dist/preline.js';
Expand Down
Loading