-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
138 create 2 2d map component tracking a single satellite (#231)
* feat(ide): ✨ Add zustand and store.ts * feat(backend): ✨ Add fetch of satellite data based on name * example usage * semi-working country finder * prettier * lint * simple styling for component * feat(backend): ✨ Refactor code of zustand store to enable multiple satellite showings * small fixes * eslint and prettier * testing setup * geomercator * feat(frontend): add new map projection * feat(frontend): ✨ Add better map projection and add live data for satellite * show to pradipta * small change to test code * feat(frontend): Finish map, fix styling, add turf to check country Fixed general styling of the map, can be changed later based on new designs. Added turf to check country to fix bugs with the previous method. * lint and prettier * add 2dmap to satdatatable * lint and prettier
- Loading branch information
Lukas Thrane
authored and
GitHub
committed
Apr 7, 2024
1 parent
6928f11
commit 7ad0821
Showing
9 changed files
with
29,728 additions
and
183 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| "use client"; | ||
| /* eslint-disable react/jsx-handler-names */ | ||
| import React from "react"; | ||
| import * as topojson from "topojson-client"; | ||
| import { CustomProjection } from "@visx/geo"; | ||
| import { geoNaturalEarth1 } from "@visx/vendor/d3-geo"; | ||
| import topology from "./world-topo.json"; | ||
|
|
||
| export type GeoCustomProps = { | ||
| width: number; | ||
| height: number; | ||
| satLatitude?: number; | ||
| satLongitude?: number; | ||
| }; | ||
|
|
||
| interface FeatureShape { | ||
| type: "Feature"; | ||
| id: string; | ||
| geometry: { coordinates: [number, number][][]; type: "Polygon" }; | ||
| 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({ | ||
| width, | ||
| height, | ||
| satLatitude, | ||
| satLongitude, | ||
| }: 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 : ( | ||
| <> | ||
| <div className="relative"> | ||
| <svg width={width} height={height}> | ||
| <rect | ||
| x={0} | ||
| y={0} | ||
| width={width} | ||
| height={height} | ||
| fill={background} | ||
| rx={14} | ||
| /> | ||
| <CustomProjection<FeatureShape> | ||
| projection={geoNaturalEarth1} | ||
| data={world.features} | ||
| scale={scale} | ||
| translate={[centerX, centerY]} | ||
| > | ||
| {(customProjection) => ( | ||
| <g> | ||
| {customProjection.features.map( | ||
| ({ path }, i) => ( | ||
| <path | ||
| key={`map-feature-${i}`} | ||
| d={path || ""} | ||
| fill={"#d3d3d3"} | ||
| stroke={"#000"} | ||
| strokeWidth={0.5} | ||
| /> | ||
| ), | ||
| )} | ||
| {satPoint && ( | ||
| <circle | ||
| cx={satPoint[0]} | ||
| cy={satPoint[1]} | ||
| r="6" | ||
| fill="red" | ||
| stroke="black" | ||
| strokeWidth="1" | ||
| /> | ||
| )} | ||
| </g> | ||
| )} | ||
| </CustomProjection> | ||
| </svg> | ||
| </div> | ||
| </> | ||
| ); | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| "use client"; | ||
| import GeoCustom from "./2dMapProjection"; | ||
| import { useSatelliteStore } from "@/lib/store"; | ||
| import React, { useState, useEffect } from "react"; | ||
| import { SatelliteInfo, convertSatrec } from "@/lib/convertSatrec"; | ||
|
|
||
| const updateInterval = 10; | ||
|
|
||
| export default function Map2d({ satName }: { satName: string }) { | ||
| const { satelliteData, fetchAndSetSatelliteData } = useSatelliteStore(); | ||
| const [satelliteInfo, setSatelliteInfo] = useState<SatelliteInfo | null>( | ||
| null, | ||
| ); | ||
|
|
||
| // Fetch satellite data on component mount | ||
| useEffect(() => { | ||
| fetchAndSetSatelliteData(satName); | ||
| }, [fetchAndSetSatelliteData, satName]); | ||
|
|
||
| // Update satellite info every `updateInterval` ms | ||
| useEffect(() => { | ||
| const intervalId = setInterval(() => { | ||
| // Access satellite data by name | ||
| const satData = satelliteData[satName]; | ||
| if (satData) { | ||
| const updatedInfo = convertSatrec(satData.satrec, satData.name); | ||
| setSatelliteInfo(updatedInfo); | ||
| } | ||
| }, updateInterval); | ||
|
|
||
| // Clear interval on component unmount | ||
| return () => clearInterval(intervalId); | ||
| }, [satelliteData, satName]); | ||
|
|
||
| // Convert string values to numbers | ||
| const satLatitude = satelliteInfo | ||
| ? parseFloat(satelliteInfo.latitudeDeg) | ||
| : undefined; | ||
| const satLongitude = satelliteInfo | ||
| ? parseFloat(satelliteInfo.longitudeDeg) | ||
| : undefined; | ||
|
|
||
| const width = 960; | ||
| const height = width / 2; | ||
|
|
||
| return ( | ||
| <div className=""> | ||
| <GeoCustom | ||
| width={width} | ||
| height={height} | ||
| satLatitude={satLatitude} | ||
| satLongitude={satLongitude} | ||
| /> | ||
| </div> | ||
| ); | ||
| } |
Oops, something went wrong.