Initial 1.3.x rework
This commit is contained in:
+128
-76
@@ -1,85 +1,137 @@
|
||||
import type React from 'react';
|
||||
import { useState } from 'react';
|
||||
import type React from "react";
|
||||
import { useEffect, useMemo, useRef } from "react";
|
||||
|
||||
import mapboxgl from 'mapbox-gl';
|
||||
import { FiMapPin } from 'react-icons/fi';
|
||||
import { RiRoadMapLine } from 'react-icons/ri';
|
||||
import { Pane } from "evergreen-ui";
|
||||
|
||||
import { Layout } from '@components/layout';
|
||||
import { MapboxProvider } from '@components/MapBox/MapboxProvider';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import type { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
import { MapContainer } from '@pages/Map/MapContainer';
|
||||
import { Marker } from '@pages/Map/Marker';
|
||||
import { NodeCard } from '@pages/Nodes/NodeCard';
|
||||
import { useDevice } from "@app/core/stores/deviceStore.js";
|
||||
import Point from "@arcgis/core/geometry/Point";
|
||||
import Graphic from "@arcgis/core/Graphic";
|
||||
import FeatureLayer from "@arcgis/core/layers/FeatureLayer";
|
||||
import LabelClass from "@arcgis/core/layers/support/LabelClass";
|
||||
import Map from "@arcgis/core/Map";
|
||||
import LineCallout3D from "@arcgis/core/symbols/callouts/LineCallout3D";
|
||||
import LabelSymbol3D from "@arcgis/core/symbols/LabelSymbol3D";
|
||||
import TextSymbol3DLayer from "@arcgis/core/symbols/TextSymbol3DLayer";
|
||||
import SceneView from "@arcgis/core/views/SceneView";
|
||||
|
||||
export const Map = (): JSX.Element => {
|
||||
const [selectedNode, setSelectedNode] = useState<Protobuf.NodeInfo>();
|
||||
export const MapPage = (): JSX.Element => {
|
||||
const { nodes } = useDevice();
|
||||
|
||||
const nodes = useAppSelector((state) => state.meshtastic.nodes);
|
||||
const myNodeNum = useAppSelector(
|
||||
(state) => state.meshtastic.radio.hardware.myNodeNum,
|
||||
const nodesWithPosition = nodes.filter((node) => node.data.position);
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
console.log(nodesWithPosition);
|
||||
}, [nodesWithPosition]);
|
||||
|
||||
const labelClass = useMemo(
|
||||
() =>
|
||||
new LabelClass({
|
||||
labelExpressionInfo: {
|
||||
expression: "$feature.name",
|
||||
},
|
||||
symbol: new LabelSymbol3D({
|
||||
symbolLayers: [
|
||||
new TextSymbol3DLayer({
|
||||
text: "{name}",
|
||||
material: {
|
||||
color: "black",
|
||||
},
|
||||
halo: {
|
||||
color: [255, 255, 255, 0.7],
|
||||
size: 2,
|
||||
},
|
||||
font: {
|
||||
size: 12,
|
||||
weight: "bold",
|
||||
},
|
||||
size: 10,
|
||||
}),
|
||||
],
|
||||
verticalOffset: {
|
||||
screenLength: 150,
|
||||
maxWorldLength: 2000,
|
||||
minWorldLength: 30,
|
||||
},
|
||||
callout: new LineCallout3D({
|
||||
size: 0.5,
|
||||
color: [0, 0, 0],
|
||||
border: {
|
||||
color: [255, 255, 255],
|
||||
},
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<MapboxProvider>
|
||||
{nodes.map((node) => {
|
||||
return (
|
||||
node.data.position && (
|
||||
<Marker
|
||||
key={node.data.num}
|
||||
center={
|
||||
new mapboxgl.LngLat(
|
||||
node.data.position.longitudeI / 1e7,
|
||||
node.data.position.latitudeI / 1e7,
|
||||
)
|
||||
const points: Graphic[] = nodesWithPosition.map(
|
||||
(node, index) =>
|
||||
node.data.position
|
||||
? new Graphic({
|
||||
geometry: new Point({
|
||||
latitude: node.data.position.latitudeI / 1e7,
|
||||
longitude: node.data.position.longitudeI / 1e7,
|
||||
}),
|
||||
attributes: {
|
||||
ObjectID: index,
|
||||
name: node.data.user?.longName,
|
||||
},
|
||||
})
|
||||
: new Graphic() //should be undefined/removed from array
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
const layer = new FeatureLayer({
|
||||
labelsVisible: true,
|
||||
labelingInfo: [labelClass],
|
||||
source: points,
|
||||
fields: [
|
||||
{
|
||||
name: "ObjectID",
|
||||
alias: "ObjectID",
|
||||
type: "oid",
|
||||
},
|
||||
{
|
||||
name: "name",
|
||||
alias: "Name",
|
||||
type: "string",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
basemap: "satellite",
|
||||
ground: "world-elevation",
|
||||
layers: [layer],
|
||||
});
|
||||
|
||||
const scene = new SceneView({
|
||||
container: ref.current,
|
||||
map: map,
|
||||
camera: {
|
||||
position: nodesWithPosition[0]
|
||||
? {
|
||||
x: nodesWithPosition[0].data.position?.longitudeI ?? 0 / 1e7,
|
||||
y: nodesWithPosition[0].data.position?.latitudeI ?? 0 / 1e7,
|
||||
z: nodesWithPosition[0].data.position?.altitude ?? 0 / 1e7,
|
||||
}
|
||||
>
|
||||
<div
|
||||
onClick={(): void => {
|
||||
setSelectedNode(node.data);
|
||||
}}
|
||||
className={`z-50 rounded-full border-2 bg-opacity-30 ${
|
||||
node.data.num === selectedNode?.num
|
||||
? 'border-green-500 bg-green-500'
|
||||
: 'border-blue-500 bg-blue-500'
|
||||
}`}
|
||||
>
|
||||
<div className="m-4 ">
|
||||
<FiMapPin className="h-5 w-5" />
|
||||
</div>
|
||||
</div>
|
||||
</Marker>
|
||||
)
|
||||
);
|
||||
})}
|
||||
<Layout
|
||||
title="Nodes"
|
||||
icon={<RiRoadMapLine />}
|
||||
sidebarContents={
|
||||
<div className="flex flex-col gap-2">
|
||||
{!nodes.length && (
|
||||
<span className="p-4 text-sm text-gray-400 dark:text-gray-600">
|
||||
No nodes found.
|
||||
</span>
|
||||
)}
|
||||
: {
|
||||
y: -35.59, //Longitude
|
||||
x: 148, //Latitude
|
||||
z: 200, //Meters
|
||||
},
|
||||
tilt: 75,
|
||||
},
|
||||
});
|
||||
scene.on("click", (event) => {
|
||||
void scene.hitTest(event).then((point) => {
|
||||
console.log(point);
|
||||
});
|
||||
});
|
||||
}
|
||||
}, [labelClass, points]);
|
||||
|
||||
{nodes.map((node) => (
|
||||
<NodeCard
|
||||
key={node.data.num}
|
||||
node={node.data}
|
||||
isMyNode={node.data.num === myNodeNum}
|
||||
selected={selectedNode?.num === node.data.num}
|
||||
setSelected={(): void => {
|
||||
setSelectedNode(node.data);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<MapContainer />
|
||||
</Layout>
|
||||
</MapboxProvider>
|
||||
);
|
||||
return <Pane width="100%" height="100%" ref={ref} />;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user