Skip to content

Commit

Permalink
232 move 2d map to individual satellite page and integrate so specifi…
Browse files Browse the repository at this point in the history
…c satellite is shown (#253)

* feat(frontend): add 2d map to individual satellite page

* feat(frontend): Add 2d map to individual satellite page, add position prediction, style page

* styling

* prettier and lint
  • Loading branch information
Lukas Thrane authored and GitHub committed Apr 10, 2024
1 parent 7e5fba6 commit 7c53414
Show file tree
Hide file tree
Showing 13 changed files with 387 additions and 63 deletions.
2 changes: 1 addition & 1 deletion frontend/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const nextConfig = {
{
protocol: "http",
hostname: "web.hypso.ies.ntnu.no",
port: '1337'
port: "1337",
},
{
protocol: "http",
Expand Down
57 changes: 52 additions & 5 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@turf/turf": "^6.5.0",
"@visx/geo": "^3.5.0",
"@visx/scale": "^3.5.0",
"@visx/shape": "^3.5.0",
"add": "^2.0.6",
"chart.js": "^4.4.1",
"chartjs-adapter-luxon": "^1.3.1",
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { ApolloWrapper } from "@/components/wrappers/ApolloWrapper";
const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
title: "NTNU SmallSat Lab",
description: "NTNU Small Satellite Lab",
};

import ErrorBoundaryNavigation from "@/components/ErrorBoundaryNavigation";
Expand Down
80 changes: 55 additions & 25 deletions frontend/src/app/satellites/[satelliteSlug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import BlockRendererClient from "@/components/BlockRendererClient";
import fetchSatelliteInfo from "@/lib/data/fetchSatelliteInfo";
import { BlocksContent } from "@strapi/blocks-react-renderer";
import RelatedProjectsAndSatellites from "@/components/RelatedProjectsAndSatellites";
import SatelliteDataHome from "@/components/satelliteData/SatelliteDataHome";
import Map2d from "@/components/2dmap/Map2d";
import { useSatelliteStore } from "@/lib/store";
import SolarDataComponent from "@/components/SolarActivity/SolarData";
import SatelliteDataHome from "@/components/satelliteData/SatelliteDataHome";

function setSelectedSatelliteSlug(satelliteSlug: string) {
const setSelectedSatellite =
useSatelliteStore.getState().setSelectedSatellite;
Expand Down Expand Up @@ -39,31 +40,60 @@ export default async function SatelliteInfoPage({
if (!satelliteInfo) return <div>Loading...</div>;

return (
<>
<SolarDataComponent></SolarDataComponent>
<div className="my-12 flex min-h-screen items-center justify-center">
<div className="flex w-2/3 flex-col">
<div className="flex w-full flex-col items-center border-2 border-gray-600 bg-black p-4">
{/* Container for satname, stats and sat image */}
<div className="flex w-full flex-col bg-gray-600 p-0.5 xl:flex-row">
{/* Stats Container */}
<div className="z-10 flex w-full flex-col">
<div className="bg-black p-5">
<h1 className="text-xl font-bold tracking-wide">
{satelliteInfo.name}
</h1>
</div>
<div className="mt-0.5">
<SatelliteDataHome />
</div>
</div>

{/* Image container */}
<div className="z-0 ml-0.5 w-full">
<div className="flex h-full w-full items-center justify-center bg-black">
<h1>Satellite Image</h1>
</div>
</div>
</div>

{/* Container for map */}
<div className="mt-6 w-full">
<Map2d satName={satelliteInfo.name} />
</div>

{/* Container for body content */}
<div className="mt-6">
<BlockRendererClient content={satelliteInfo.content} />
</div>
</div>

{/* Related projects */}
<div className="mt-8 flex w-full flex-col items-center border-2 border-gray-600 bg-black p-4">
{satelliteInfo.relatedProjects?.length != 0 ? (
<h1 className="text-xl font-bold">Related Projects</h1>
) : null}

<div className="flex flex-col items-center">
<h1 className="mt-4 text-2xl font-bold">
{satelliteInfo.name}
</h1>
<SatelliteDataHome />
<BlockRendererClient content={satelliteInfo.content} />
{satelliteInfo.relatedProjects?.length ? (
<h1 className="mb-2 mt-2 text-xl font-bold">
Related Projects
</h1>
) : null}
<div className="mx-10 mt-4 flex flex-wrap justify-center gap-4 md:justify-start">
{satelliteInfo.relatedProjects?.map(
(project: ProjectOrSatellite) => (
<RelatedProjectsAndSatellites
project={project}
key={project.id}
/>
),
)}
<div className="mx-10 mt-4 flex flex-wrap justify-center gap-4 md:justify-start">
{satelliteInfo.relatedProjects?.map(
(project: ProjectOrSatellite) => (
<RelatedProjectsAndSatellites
project={project}
key={project.id}
/>
),
)}
</div>
</div>
</div>
</>
</div>
);
}
53 changes: 40 additions & 13 deletions frontend/src/components/2dmap/2dMapProjection.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use client";
/* eslint-disable react/jsx-handler-names */
import React from "react";
import * as topojson from "topojson-client";
// @ts-ignore
import { CustomProjection } from "@visx/geo";
import { geoNaturalEarth1 } from "@visx/vendor/d3-geo";
import topology from "./world-topo.json";
Expand All @@ -11,6 +10,7 @@ export type GeoCustomProps = {
height: number;
satLatitude?: number;
satLongitude?: number;
futurePositions?: [number, number][];
};

interface FeatureShape {
Expand All @@ -20,35 +20,44 @@ interface FeatureShape {
properties: { name: string };
}

export const background = "";

// @ts-expect-error
const world = topojson.feature(topology, topology.objects.units) as {
type: "FeatureCollection";
features: FeatureShape[];
};

export default function GeoCustom({
export default function Map2dNaturalProjection({
width,
height,
satLatitude,
satLongitude,
futurePositions,
}: GeoCustomProps) {
const centerX = width / 2;
const centerY = height / 2;
const scale = (width / 630) * 100;

// This function projects lat/long to the SVG coordinate system
const projection = geoNaturalEarth1()
.scale(scale)
.translate([centerX, centerY]);

// Check if both satLatitude and satLongitude are defined
let satPoint: [number, number] | undefined;
if (typeof satLatitude === "number" && typeof satLongitude === "number") {
satPoint = projection([satLongitude, satLatitude]) || undefined;
}
return width < 10 ? null : (

// Function to interpolate the green color based on the index
const interPolateColor = (index: number, total: number) => {
const startColor = { r: 40, g: 96, b: 241 };
const endColor = { r: 241, g: 0, b: 20 };
const ratio = index / total;
const r = Math.round((1 - ratio) * startColor.r + ratio * endColor.r);
const g = Math.round((1 - ratio) * startColor.g + ratio * endColor.g);
const b = Math.round((1 - ratio) * startColor.b + ratio * endColor.b);
return `rgb(${r}, ${g}, ${b})`;
};

return (
<>
<div className="relative">
<svg width={width} height={height}>
Expand All @@ -57,8 +66,7 @@ export default function GeoCustom({
y={0}
width={width}
height={height}
fill={background}
rx={14}
fill={"#000"}
/>
<CustomProjection<FeatureShape>
projection={geoNaturalEarth1}
Expand All @@ -73,18 +81,37 @@ export default function GeoCustom({
<path
key={`map-feature-${i}`}
d={path || ""}
fill={"#d3d3d3"}
fill={"#FFFFFF"}
stroke={"#000"}
strokeWidth={0.5}
/>
),
)}
{futurePositions &&
futurePositions.map(([lng, lat], i) => {
const point = projection([lng, lat]);
return (
point && (
<circle
key={`future-position-${i}`}
cx={point[0]}
cy={point[1]}
r="3"
fill={interPolateColor(
i,
futurePositions.length -
1,
)}
/>
)
);
})}
{satPoint && (
<circle
cx={satPoint[0]}
cy={satPoint[1]}
r="6"
fill="red"
r="8"
fill={interPolateColor(0, 1)}
stroke="black"
strokeWidth="1"
/>
Expand Down
Loading

0 comments on commit 7c53414

Please sign in to comment.