Skip to content

Commit

Permalink
AntPath and other map stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
OlliV committed Oct 27, 2023
1 parent 3d7adf2 commit dac5eb9
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 39 deletions.
30 changes: 30 additions & 0 deletions components/map/AntPath.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { LayerProps, createLayerComponent } from "@react-leaflet/core";
import { antPath } from "leaflet-ant-path";

export interface AntPathProps extends LayerProps {
positions: [number, number][];
options?: {
paused?: boolean;
reverse?: boolean;
hardwareAccelerated?: true;
pulseColor?: string;
delay?: string;
dashArray?: [number, number] | string;
};
}

export default createLayerComponent<antPath,AntPathProps>(
function createAntPath({positions, options}, ctx) {
const instance = antPath(positions, options);
return {
instance,
context: { ...ctx, overlayContainer: instance } };
},
function updateAntPath(layer, props, prevProps) {
if (props.positions !== prevProps.positions) {
layer.setLatLngs(props.positions);
}
// TODO
//layer.setStyle({ ...prevProps.options, ...props.options });
}
);
28 changes: 20 additions & 8 deletions components/map/Course.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import { useEffect, useMemo, useState } from 'react';
import { Polyline } from 'react-leaflet';
import {CourseData} from '../../lib/gpx_parser';
import { useEffect, useMemo } from 'react';
import { CircleMarker, Polyline } from 'react-leaflet';
import AntPath from '../../components/map/AntPath';
import { CourseData } from '../../lib/gpx_parser';

export default function MapCourse({ map, course }: {map: any, course: CourseData}) {
const { trackpoints } = course?.tracks[0]?.segments[0] || {trackpoints: []};
const polyline = useMemo(() => trackpoints.map(({lat, lon}) => [lat, lon]), [trackpoints]);
export default function MapCourse({ map, course }: { map: any; course: CourseData }) {
const { trackpoints } = course?.tracks[0]?.segments[0] || { trackpoints: [] };
const polyline = useMemo<[number, number][]>(() => trackpoints.map(({ lat, lon }) => [lat, lon]), [trackpoints]);
const first = polyline[0];
const last = polyline[polyline.length - 1];

useEffect(() => {
if (map && polyline.length > 0) {
map.flyTo(polyline[0], map.getZoom());
}
}, [,map, polyline]);
}, [map, polyline]);

return <Polyline pathOptions={{ color: 'black' }} positions={polyline} />;
return (
<>
{/* @ts-ignore*/}
{first ? <CircleMarker center={first} radius={20} pathOptions={{ color: 'blue' }} /> : null}
{/* @ts-ignore */}
{last ? <CircleMarker center={last} radius={20} pathOptions={{ color: 'red' }} /> : null}
<AntPath positions={polyline} options={{ hardwareAccelerated: true, delay: '1200' }}/>
</>
);
}
//<Polyline pathOptions={{ color: 'black' }} positions={polyline} />
15 changes: 3 additions & 12 deletions components/map/Marker.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
'use client';
import L from 'leaflet';
import { Marker, Popup } from 'react-leaflet';
import { useEffect } from 'react';
import MarkerIcon from '../../node_modules/leaflet/dist/images/marker-icon.png';
import MarkerShadow from '../../node_modules/leaflet/dist/images/marker-shadow.png';
import { ReactNode } from 'react';

export default function MapMarker({ map, position }) {
useEffect(() => {
if (map) {
map.flyTo(position, map.getZoom());
}
}, [map, position]);

export default function MapMarker({ position, children }: { position: [number, number]; children?: ReactNode }) {
return (
<Marker
position={position}
Expand All @@ -28,10 +22,7 @@ export default function MapMarker({ map, position }) {
})
}
>
<Popup>
You are here.
{`${position}`}
</Popup>
<Popup>{children}</Popup>
</Marker>
);
}
8 changes: 4 additions & 4 deletions lib/gpx_parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ type Segment = {
type Track = {
name?: string;
segments: Segment[];
}
};
type Routepoint = Coord;
type Waypoint = Coord;
export type CourseData = {
tracks: Track[];
routePoints: Routepoint[],
routePoints: Routepoint[];
waypoints: Waypoint[];
};

Expand Down Expand Up @@ -85,8 +85,8 @@ export function gpxDocument2obj(doc: Document): CourseData {
export function getMapBounds(obj: CourseData) {
// TODO support all tracks and segments
const points = [...obj.tracks[0].segments[0].trackpoints, ...obj.routePoints, ...obj.waypoints];
const lats = points.map(({lat}) => lat);
const lons = points.map(({lon}) => lon);
const lats = points.map(({ lat }) => lat);
const lons = points.map(({ lon }) => lon);
return {
minlat: Math.min(...lats),
maxlat: Math.max(...lats),
Expand Down
8 changes: 7 additions & 1 deletion package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
"@mui/icons-material": "5.14.15",
"@mui/material": "5.14.15",
"@nivo/line": "0.80.0",
"leaflet-ant-path": "1.3.0",
"next": "13.5.6",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hooks-global-state": "2.1.0",
"react-leaflet": "^4.2.1",
"react-leaflet": "4.2.1",
"sharp": "0.31.2"
},
"devDependencies": {
Expand Down
24 changes: 11 additions & 13 deletions pages/ride/map/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,24 @@ function MyLocationButton({ setPosition }) {
);
}

function Courses({ map, courses }: { map: any, courses: CourseData[] }) {
return (
<>
{courses.map((course: CourseData, i: number) => {
})}
</>
);
function Courses({ map, courses }: { map: any; courses: CourseData[] }) {
return <>{courses.map((course: CourseData, i: number) => {})}</>;
}

export default function RideMap() {
const [map, setMap] = useState(null);
const [coord, setCoord] = useState([51.505, -0.09]);
const [coord, setCoord] = useState<[number, number]>([51.505, -0.09]);
const [course, setCourse] = useState<CourseData>();
const bounds = useMemo(() => course && getMapBounds(course), [course]);

useEffect(() => {
if (bounds) {
map.fitBounds([[bounds.minlat, bounds.minlon], [bounds.maxlat, bounds.maxlon]]);
if (map && bounds) {
map.fitBounds([
[bounds.minlat, bounds.minlon],
[bounds.maxlat, bounds.maxlon],
]);
}
}, [bounds]);
}, [map, bounds]);

const importGpx = (file: File) => {
parseGpxFile2Document(file)
Expand Down Expand Up @@ -95,8 +93,8 @@ export default function RideMap() {
</Stack>

<DynamicMap center={coord} setMap={setMap}>
<DynamicMapMarker map={map} position={coord} />
{ course ? <DynamicCourse map={map} course={course} /> : <></> }
<DynamicMapMarker position={coord}>You are here.</DynamicMapMarker>
{course ? <DynamicCourse map={map} course={course} /> : <></>}
</DynamicMap>

<Grid container direction="row" alignItems="center" spacing={2}></Grid>
Expand Down

1 comment on commit dac5eb9

@vercel
Copy link

@vercel vercel bot commented on dac5eb9 Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

bfree – ./

bfree.vercel.app
bfree-git-master-olliv.vercel.app
bfree-olliv.vercel.app

Please sign in to comment.