-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathGeo.cs
More file actions
67 lines (54 loc) · 2.34 KB
/
Geo.cs
File metadata and controls
67 lines (54 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// This file contains logic and math for working with latitude and longitude
// values. Bing Maps uses lat/lon for many of their parameters, and these
// aren't always intuitive or simple to draw them on screen in 3D. So these
// functions are largely just converting values to and from 2D grids of
// meters.
using BingMapsRESTToolkit;
using StereoKit;
using System;
static class Geo
{
public const double EarthCircumference = 40075040.0;
public const float EarthTallest = 8848.0f; // Mount everest is 8,848m tall
///////////////////////////////////////////
public static double DistLatitude(double a, double b)
=> (EarthCircumference * (a-b)) / 360.0;
///////////////////////////////////////////
public static double DistLongitude(double a, double b, double latitudeY)
=> ((a-b) * EarthCircumference * Math.Cos(latitudeY*Units.deg2rad)) / 360.0;
///////////////////////////////////////////
public static BoundingBox LatLonBounds(double latitudeY, double longitudeX, double radiusM)
{
double radiusY = (radiusM * 360) / EarthCircumference;
double radiusX = (radiusM * 360) / (EarthCircumference * Math.Cos(latitudeY * Units.deg2rad));
// In order of South, West, North, East
return new BoundingBox(new double[]{
latitudeY -radiusY,
longitudeX-radiusX,
latitudeY +radiusY,
longitudeX+radiusX });
}
///////////////////////////////////////////
public static Vec2 BoundsSize(BoundingBox bounds)
{
return new Vec2(
(float)DistLongitude(bounds.EastLongitude, bounds.WestLongitude, (bounds.NorthLatitude + bounds.SouthLatitude) / 2),
(float)DistLatitude (bounds.NorthLatitude, bounds.SouthLatitude));
}
///////////////////////////////////////////
public static void BoundsToWorld(BoundingBox queryBox, BoundingBox givenBox, out Vec3 size, out Vec2 offset)
{
Vec2 queryCenter = new Vec2(
(float)(queryBox.WestLongitude + queryBox.EastLongitude) / 2.0f,
(float)(queryBox.NorthLatitude + queryBox.SouthLatitude) / 2.0f);
Vec2 givenCenter = new Vec2(
(float)(givenBox.WestLongitude + givenBox.EastLongitude) / 2.0f,
(float)(givenBox.NorthLatitude + givenBox.SouthLatitude) / 2.0f);
offset = new Vec2(
(float)DistLongitude(givenCenter.x, queryCenter.x, queryCenter.y),
(float)DistLatitude (givenCenter.y, queryCenter.y));
size = Vec3.Zero;
size.XZ = BoundsSize(givenBox);
size.y = EarthTallest;
}
}