earths 0.0.4

High-fidelity Earth simulation engine — orbit, atmosphere, geology, hydrology, biosphere, terrain, lighting, rendering, satellites, and temporal systems with full scientific coupling
Documentation
#[derive(Debug, Clone)]
pub struct Region {
    pub name: String,
    pub regiontype: RegionType,
    pub boundary: Vec<[f64; 2]>,
    pub areakm2: f64,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum RegionType {
    Continent,
    Ocean,
    Sea,
    Country,
    Island,
}
pub struct RegionDatabase {
    pub regions: Vec<Region>,
}
impl RegionDatabase {
    pub fn continents() -> Self {
        Self {
            regions: vec![
                Region {
                    name: "Africa".into(),
                    regiontype: RegionType::Continent,
                    boundary: vec![
                        [35.8, -5.6],
                        [37.1, 10.5],
                        [33.0, 12.0],
                        [31.5, 25.1],
                        [31.5, 32.3],
                        [22.0, 36.5],
                        [12.5, 43.3],
                        [11.6, 51.0],
                        [-1.7, 41.9],
                        [-11.7, 40.4],
                        [-25.5, 35.0],
                        [-34.8, 20.0],
                        [-34.5, 18.5],
                        [-29.0, 16.5],
                        [-17.0, 11.7],
                        [-6.0, 12.3],
                        [4.0, 2.5],
                        [5.0, -3.5],
                        [4.7, -7.5],
                        [7.5, -13.0],
                        [12.0, -16.7],
                        [14.7, -17.5],
                        [21.4, -17.1],
                        [27.7, -13.1],
                        [35.8, -5.6],
                    ],
                    areakm2: 30370000.0,
                },
                Region {
                    name: "Antarctica".into(),
                    regiontype: RegionType::Continent,
                    boundary: vec![
                        [-65.0, -60.0],
                        [-68.0, -62.0],
                        [-72.0, -74.0],
                        [-72.5, -100.0],
                        [-71.5, -120.0],
                        [-73.0, -145.0],
                        [-71.0, -170.0],
                        [-77.0, 170.0],
                        [-72.0, 155.0],
                        [-67.0, 143.0],
                        [-66.5, 110.0],
                        [-69.0, 76.0],
                        [-69.5, 40.0],
                        [-70.0, 2.0],
                        [-71.0, -23.0],
                        [-65.0, -60.0],
                    ],
                    areakm2: 14200000.0,
                },
                Region {
                    name: "Asia".into(),
                    regiontype: RegionType::Continent,
                    boundary: vec![
                        [41.0, 28.8],
                        [42.0, 44.0],
                        [39.8, 53.4],
                        [37.4, 61.6],
                        [29.3, 66.4],
                        [23.7, 68.4],
                        [7.0, 80.2],
                        [1.3, 103.5],
                        [6.0, 106.6],
                        [18.0, 108.5],
                        [22.2, 114.2],
                        [32.0, 121.5],
                        [39.9, 124.4],
                        [43.0, 131.5],
                        [53.5, 141.0],
                        [59.0, 163.0],
                        [66.0, 170.0],
                        [71.0, -180.0],
                        [71.0, 180.0],
                        [69.0, 65.0],
                        [55.3, 28.0],
                        [44.4, 26.0],
                        [41.0, 28.8],
                    ],
                    areakm2: 44580000.0,
                },
                Region {
                    name: "Europe".into(),
                    regiontype: RegionType::Continent,
                    boundary: vec![
                        [36.0, -9.5],
                        [43.0, -9.3],
                        [47.5, -5.5],
                        [48.8, 2.3],
                        [51.5, -0.1],
                        [58.0, 5.3],
                        [64.0, 11.0],
                        [70.0, 26.0],
                        [69.0, 33.0],
                        [67.0, 41.0],
                        [55.7, 37.6],
                        [55.3, 28.0],
                        [44.4, 26.0],
                        [41.0, 28.8],
                        [39.6, 22.7],
                        [37.0, 15.0],
                        [36.0, -9.5],
                    ],
                    areakm2: 10180000.0,
                },
                Region {
                    name: "North America".into(),
                    regiontype: RegionType::Continent,
                    boundary: vec![
                        [71.0, -156.0],
                        [71.0, -95.0],
                        [63.0, -69.0],
                        [52.5, -55.7],
                        [47.0, -60.0],
                        [44.6, -66.9],
                        [30.0, -81.5],
                        [25.0, -80.0],
                        [18.5, -88.0],
                        [15.0, -84.0],
                        [8.0, -77.0],
                        [9.0, -79.5],
                        [14.5, -92.0],
                        [19.4, -99.1],
                        [22.9, -109.9],
                        [32.5, -117.1],
                        [48.5, -125.0],
                        [55.0, -133.0],
                        [60.0, -141.0],
                        [64.0, -166.0],
                        [71.0, -156.0],
                    ],
                    areakm2: 24710000.0,
                },
                Region {
                    name: "South America".into(),
                    regiontype: RegionType::Continent,
                    boundary: vec![
                        [12.5, -72.0],
                        [10.5, -61.9],
                        [6.8, -58.2],
                        [2.8, -51.0],
                        [-2.5, -44.3],
                        [-8.0, -34.9],
                        [-15.0, -39.0],
                        [-22.9, -43.2],
                        [-33.7, -53.4],
                        [-41.0, -65.0],
                        [-46.0, -67.5],
                        [-52.3, -70.0],
                        [-55.0, -68.0],
                        [-54.8, -65.0],
                        [-47.0, -75.5],
                        [-40.0, -73.5],
                        [-33.5, -71.6],
                        [-18.5, -70.4],
                        [-5.0, -81.0],
                        [1.0, -79.5],
                        [8.0, -77.0],
                        [12.5, -72.0],
                    ],
                    areakm2: 17840000.0,
                },
                Region {
                    name: "Oceania".into(),
                    regiontype: RegionType::Continent,
                    boundary: vec![
                        [-11.0, 131.0],
                        [-10.7, 142.0],
                        [-16.0, 145.7],
                        [-23.5, 150.0],
                        [-28.2, 153.5],
                        [-37.8, 150.0],
                        [-38.5, 146.0],
                        [-35.0, 136.0],
                        [-32.0, 133.5],
                        [-31.5, 131.0],
                        [-34.7, 116.0],
                        [-22.0, 114.0],
                        [-13.8, 126.8],
                        [-11.0, 131.0],
                    ],
                    areakm2: 8526000.0,
                },
            ],
        }
    }
    pub fn pointinregion(&self, lat: f64, lon: f64) -> Option<&Region> {
        self.regions
            .iter()
            .find(|region| pointinpolygon(lat, lon, &region.boundary))
    }
}
fn pointinpolygon(lat: f64, lon: f64, polygon: &[[f64; 2]]) -> bool {
    let n = polygon.len();
    if n < 3 {
        return false;
    }
    let mut inside = false;
    let mut j = n - 1;
    for i in 0..n {
        let (yi, xi) = (polygon[i][0], polygon[i][1]);
        let (yj, xj) = (polygon[j][0], polygon[j][1]);
        if ((yi > lat) != (yj > lat)) && (lon < (xj - xi) * (lat - yi) / (yj - yi) + xi) {
            inside = !inside;
        }
        j = i;
    }
    inside
}