Working on passing bounds to database airports query
This commit is contained in:
@@ -40,8 +40,20 @@ pub struct Airports {
|
|||||||
pub longitude: f64,
|
pub longitude: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Bounds {
|
||||||
|
pub north_east: LatLng,
|
||||||
|
pub south_west: LatLng,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct LatLng {
|
||||||
|
pub lat: f32,
|
||||||
|
pub lon: f32
|
||||||
|
}
|
||||||
|
|
||||||
impl Airports {
|
impl Airports {
|
||||||
pub fn find_all(limit: i32, page: i32) -> Result<Vec<Self>, CustomError> {
|
pub fn find_all(bounds: Bounds, limit: i32, page: i32) -> Result<Vec<Self>, CustomError> {
|
||||||
let conn = db::connection()?;
|
let conn = db::connection()?;
|
||||||
let airports = airports::table
|
let airports = airports::table
|
||||||
.limit(limit as i64)
|
.limit(limit as i64)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::airports::{Airport, Airports};
|
use crate::airports::{Airport, Airports, Bounds, LatLng};
|
||||||
use actix_web::{delete, get, post, put, web, HttpResponse, HttpRequest};
|
use actix_web::{delete, get, post, put, web, HttpResponse, HttpRequest};
|
||||||
use log::error;
|
use log::error;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
@@ -6,14 +6,24 @@ use serde_json::json;
|
|||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
struct FindAllParams {
|
struct FindAllParams {
|
||||||
|
ne_lat: f32,
|
||||||
|
ne_lon: f32,
|
||||||
|
sw_lat: f32,
|
||||||
|
sw_lon: f32,
|
||||||
limit: i32,
|
limit: i32,
|
||||||
page: i32
|
page: i32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[get("/airports")]
|
#[get("/airports")]
|
||||||
async fn find_all(req: HttpRequest) -> HttpResponse {
|
async fn find_all(req: HttpRequest) -> HttpResponse {
|
||||||
let params = web::Query::<FindAllParams>::from_query(req.query_string()).unwrap();
|
let params = web::Query::<FindAllParams>::from_query(req.query_string()).unwrap();
|
||||||
match web::block(move || Airports::find_all(params.limit, params.page)).await.unwrap() {
|
let bounds = Bounds {
|
||||||
|
north_east: LatLng { lat: params.ne_lat, lon: params.ne_lon },
|
||||||
|
south_west: LatLng { lat: params.sw_lat, lon: params.sw_lon }
|
||||||
|
};
|
||||||
|
match web::block(move || Airports::find_all(bounds, params.limit, params.page)).await.unwrap() {
|
||||||
Ok(a) => HttpResponse::Ok().json(a),
|
Ok(a) => HttpResponse::Ok().json(a),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("{}", err);
|
error!("{}", err);
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
import { Airport } from '@/js/api/airport.types';
|
|
||||||
import { getAirports } from '@/js/api/airport';
|
|
||||||
import { Metar } from '@/js/api/metar.types';
|
import { Metar } from '@/js/api/metar.types';
|
||||||
import { getMetars } from '@/js/api/metar';
|
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
|
||||||
export default async function Metar() {
|
export default async function Metar() {
|
||||||
@@ -16,16 +13,5 @@ export default async function Metar() {
|
|||||||
ssr: false
|
ssr: false
|
||||||
});
|
});
|
||||||
|
|
||||||
let airports: Airport[] = [];
|
return <Map />;
|
||||||
|
|
||||||
async function update() {
|
|
||||||
airports = await getAirports({ limit: 10, page: 1 });
|
|
||||||
const metars = await getMetars(airports);
|
|
||||||
for (let i = 0; i < metars.length; i++) {
|
|
||||||
airports[i].metar = metars[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await update();
|
|
||||||
|
|
||||||
return <Map airportString={JSON.stringify(airports)} />;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
import { getAirports } from '@/js/api/airport';
|
||||||
import { Airport } from '@/js/api/airport.types';
|
import { Airport } from '@/js/api/airport.types';
|
||||||
|
import { getMetars } from '@/js/api/metar';
|
||||||
import { Metar } from '@/js/api/metar.types';
|
import { Metar } from '@/js/api/metar.types';
|
||||||
import { faArrowsSpin, faLocationArrow, faLocationPin } from '@fortawesome/free-solid-svg-icons';
|
import { faArrowsSpin, faLocationArrow, faLocationPin } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { DivIcon } from 'leaflet';
|
import { DivIcon, LatLngBounds } from 'leaflet';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import ReactDOMServer from 'react-dom/server';
|
import ReactDOMServer from 'react-dom/server';
|
||||||
import { MapContainer, Marker, Popup, TileLayer, Tooltip, useMapEvents } from 'react-leaflet';
|
import { MapContainer, Marker, Popup, TileLayer, Tooltip, useMap, useMapEvents } from 'react-leaflet';
|
||||||
|
|
||||||
export default function Map({ airportString }: { airportString: string }) {
|
|
||||||
const [airports] = useState<Airport[]>(JSON.parse(airportString));
|
|
||||||
|
|
||||||
|
export default function Map() {
|
||||||
return (
|
return (
|
||||||
<MapContainer
|
<MapContainer
|
||||||
center={[38.7209, -77.5133]}
|
center={[38.7209, -77.5133]}
|
||||||
@@ -23,27 +23,48 @@ export default function Map({ airportString }: { airportString: string }) {
|
|||||||
className='overflow-y-hidden overflow-x-hidden'
|
className='overflow-y-hidden overflow-x-hidden'
|
||||||
attributionControl={false}
|
attributionControl={false}
|
||||||
>
|
>
|
||||||
<MapTiles airports={airports} />
|
<MapTiles />
|
||||||
</MapContainer>
|
</MapContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function MapTiles({ airports }: { airports: Airport[] }) {
|
function MapTiles() {
|
||||||
|
const [airports, setAirports] = useState<Airport[]>([]);
|
||||||
const [zoomLevel, setZoomLevel] = useState(8);
|
const [zoomLevel, setZoomLevel] = useState(8);
|
||||||
// const [dragging, setDragging] = useState(false);
|
// const [dragging, setDragging] = useState(false);
|
||||||
// const [center, setCenter] = useState([50, 10.5]);
|
const map = useMap();
|
||||||
|
|
||||||
const mapEvents = useMapEvents({
|
const mapEvents = useMapEvents({
|
||||||
zoomend: () => {
|
zoomend: () => {
|
||||||
setZoomLevel(mapEvents.getZoom());
|
setZoomLevel(mapEvents.getZoom());
|
||||||
},
|
},
|
||||||
moveend: () => {
|
movestart: () => {
|
||||||
console.log(mapEvents.getBounds());
|
// setDragging(true);
|
||||||
|
},
|
||||||
|
moveend: async () => {
|
||||||
|
// setDragging(false);
|
||||||
|
await updateAirports(mapEvents.getBounds());
|
||||||
}
|
}
|
||||||
// mouseup: () => {
|
|
||||||
// setCenter([mapEvents.getCenter().lat, mapEvents.getCenter().lng]);
|
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function updateAirports(bounds: LatLngBounds) {
|
||||||
|
const ne = bounds.getNorthEast();
|
||||||
|
const sw = bounds.getSouthWest();
|
||||||
|
const _airports = await getAirports({
|
||||||
|
ne_lat: ne.lat,
|
||||||
|
ne_lon: ne.lng,
|
||||||
|
sw_lat: sw.lat,
|
||||||
|
sw_lon: sw.lng,
|
||||||
|
limit: 10,
|
||||||
|
page: 1
|
||||||
|
});
|
||||||
|
const metars = await getMetars(_airports);
|
||||||
|
for (let i = 0; i < metars.length; i++) {
|
||||||
|
_airports[i].metar = metars[i];
|
||||||
|
}
|
||||||
|
setAirports(_airports);
|
||||||
|
}
|
||||||
|
|
||||||
function metarBGColor(metar: Metar | undefined) {
|
function metarBGColor(metar: Metar | undefined) {
|
||||||
if (metar?.flight_category == 'VFR') {
|
if (metar?.flight_category == 'VFR') {
|
||||||
return 'bg-emerald-600';
|
return 'bg-emerald-600';
|
||||||
@@ -109,6 +130,10 @@ function MapTiles({ airports }: { airports: Airport[] }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
updateAirports(map.getBounds());
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TileLayer
|
<TileLayer
|
||||||
@@ -116,7 +141,6 @@ function MapTiles({ airports }: { airports: Airport[] }) {
|
|||||||
url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
|
url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
|
||||||
/>
|
/>
|
||||||
{airports.map((airport) => (
|
{airports.map((airport) => (
|
||||||
<>
|
|
||||||
<Marker key={airport.icao} position={[airport.latitude, airport.longitude]} icon={icon(airport)}>
|
<Marker key={airport.icao} position={[airport.latitude, airport.longitude]} icon={icon(airport)}>
|
||||||
<Tooltip className='metar-tooltip' direction='top' offset={[5, -5]} opacity={1}>
|
<Tooltip className='metar-tooltip' direction='top' offset={[5, -5]} opacity={1}>
|
||||||
{airport.icao}
|
{airport.icao}
|
||||||
@@ -163,7 +187,6 @@ function MapTiles({ airports }: { airports: Airport[] }) {
|
|||||||
</div>
|
</div>
|
||||||
</Popup>
|
</Popup>
|
||||||
</Marker>
|
</Marker>
|
||||||
</>
|
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,8 +2,12 @@ import axios from 'axios';
|
|||||||
import { Airport } from './airport.types';
|
import { Airport } from './airport.types';
|
||||||
|
|
||||||
interface GetAirportsProps {
|
interface GetAirportsProps {
|
||||||
page: number;
|
ne_lat: number;
|
||||||
limit: number;
|
ne_lon: number;
|
||||||
|
sw_lat: number;
|
||||||
|
sw_lon: number;
|
||||||
|
page?: number;
|
||||||
|
limit?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GetAirportProps {
|
interface GetAirportProps {
|
||||||
@@ -15,9 +19,16 @@ export async function getAirport({ icao }: GetAirportProps) {
|
|||||||
return response?.data;
|
return response?.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAirports({ limit = 10, page = 1 }: GetAirportsProps): Promise<Airport[]> {
|
export async function getAirports({
|
||||||
|
ne_lat,
|
||||||
|
ne_lon,
|
||||||
|
sw_lat,
|
||||||
|
sw_lon,
|
||||||
|
limit = 10,
|
||||||
|
page = 1
|
||||||
|
}: GetAirportsProps): Promise<Airport[]> {
|
||||||
const response = await axios
|
const response = await axios
|
||||||
.get(`http://localhost:5000/airports`, { params: { page: page, limit: limit } })
|
.get(`http://localhost:5000/airports`, { params: { ne_lat, ne_lon, sw_lat, sw_lon, page, limit } })
|
||||||
.catch((error) => console.error(error));
|
.catch((error) => console.error(error));
|
||||||
return response?.data;
|
return response?.data;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user