Skip to main content

dioxus_maplibre/
types.rs

1//! Core geographic types for dioxus-maplibre
2
3use serde::{Deserialize, Serialize};
4
5/// A geographic coordinate (latitude/longitude pair)
6#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Default)]
7pub struct LatLng {
8    /// Latitude in degrees (-90 to 90)
9    pub lat: f64,
10    /// Longitude in degrees (-180 to 180)
11    pub lng: f64,
12}
13
14impl LatLng {
15    /// Create a new coordinate
16    pub fn new(lat: f64, lng: f64) -> Self {
17        Self { lat, lng }
18    }
19
20    /// Helsinki, Finland - example default location
21    pub fn helsinki() -> Self {
22        Self::new(60.1699, 24.9384)
23    }
24
25    /// Convert to [lng, lat] array format used by MapLibre
26    pub fn to_array(&self) -> [f64; 2] {
27        [self.lng, self.lat]
28    }
29
30    /// Create from [lng, lat] array format used by MapLibre
31    pub fn from_array(arr: [f64; 2]) -> Self {
32        Self {
33            lng: arr[0],
34            lat: arr[1],
35        }
36    }
37}
38
39/// Map position (center + zoom)
40#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
41pub struct MapPosition {
42    /// Center coordinate
43    pub center: LatLng,
44    /// Zoom level (0-22)
45    pub zoom: f64,
46}
47
48impl MapPosition {
49    pub fn new(center: LatLng, zoom: f64) -> Self {
50        Self { center, zoom }
51    }
52}
53
54impl Default for MapPosition {
55    fn default() -> Self {
56        Self {
57            center: LatLng::helsinki(),
58            zoom: 10.0,
59        }
60    }
61}
62
63/// A bounding box defined by southwest and northeast corners
64#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
65pub struct Bounds {
66    /// Southwest corner (min lat, min lng)
67    pub sw: LatLng,
68    /// Northeast corner (max lat, max lng)
69    pub ne: LatLng,
70}
71
72impl Bounds {
73    pub fn new(sw: LatLng, ne: LatLng) -> Self {
74        Self { sw, ne }
75    }
76
77    /// Check if a point is within these bounds
78    pub fn contains(&self, point: &LatLng) -> bool {
79        point.lat >= self.sw.lat
80            && point.lat <= self.ne.lat
81            && point.lng >= self.sw.lng
82            && point.lng <= self.ne.lng
83    }
84
85    /// Get the center of the bounds
86    pub fn center(&self) -> LatLng {
87        LatLng {
88            lat: f64::midpoint(self.sw.lat, self.ne.lat),
89            lng: f64::midpoint(self.sw.lng, self.ne.lng),
90        }
91    }
92}
93
94/// A feature returned by query methods (`queryRenderedFeatures`, `querySourceFeatures`)
95#[derive(Debug, Clone, Serialize, Deserialize)]
96#[serde(rename_all = "camelCase")]
97pub struct QueryFeature {
98    /// Feature ID (numeric, if present)
99    #[serde(default)]
100    pub id: Option<i64>,
101    /// GeoJSON geometry
102    pub geometry: serde_json::Value,
103    /// Feature properties
104    pub properties: serde_json::Value,
105    /// Source ID
106    pub source: String,
107    /// Source layer (for vector tile sources)
108    #[serde(default)]
109    pub source_layer: Option<String>,
110}
111
112/// A point in screen pixel coordinates
113#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Default)]
114pub struct Point {
115    /// X coordinate in pixels from left edge
116    pub x: f64,
117    /// Y coordinate in pixels from top edge
118    pub y: f64,
119}
120
121impl Point {
122    pub fn new(x: f64, y: f64) -> Self {
123        Self { x, y }
124    }
125}