initial geo location conversion using pyproj
This commit is contained in:
parent
ceb3d072da
commit
95c32ddd28
6 changed files with 435 additions and 276 deletions
|
@ -1128,7 +1128,6 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
self.session.location.refgeo,
|
||||
self.session.location.refscale,
|
||||
)
|
||||
logging.info("location configured: UTM%s", self.session.location.refutm)
|
||||
|
||||
def handle_config_metadata(self, message_type, config_data):
|
||||
replies = []
|
||||
|
|
|
@ -37,8 +37,8 @@ from core.emulator.emudata import (
|
|||
from core.emulator.enumerations import EventTypes, ExceptionLevels, LinkTypes, NodeTypes
|
||||
from core.emulator.sessionconfig import SessionConfig
|
||||
from core.errors import CoreError
|
||||
from core.location.corelocation import CoreLocation
|
||||
from core.location.event import EventLoop
|
||||
from core.location.geo import GeoLocation
|
||||
from core.location.mobility import BasicRangeModel, MobilityManager
|
||||
from core.nodes.base import CoreNetworkBase, CoreNode, CoreNodeBase, NodeBase
|
||||
from core.nodes.docker import DockerNode
|
||||
|
@ -146,7 +146,7 @@ class Session:
|
|||
self.distributed = DistributedController(self)
|
||||
|
||||
# initialize session feature helpers
|
||||
self.location = CoreLocation()
|
||||
self.location = GeoLocation()
|
||||
self.mobility = MobilityManager(session=self)
|
||||
self.services = CoreServices(session=self)
|
||||
self.emane = EmaneManager(session=self)
|
||||
|
|
119
daemon/core/location/geo.py
Normal file
119
daemon/core/location/geo.py
Normal file
|
@ -0,0 +1,119 @@
|
|||
"""
|
||||
Provides conversions from x,y,z to lon,lat,alt.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Tuple
|
||||
|
||||
import pyproj
|
||||
|
||||
from core.emulator.enumerations import RegisterTlvs
|
||||
|
||||
SCALE_FACTOR = 100.0
|
||||
|
||||
|
||||
class GeoLocation:
|
||||
"""
|
||||
Provides logic to convert x,y,z coordinates to lon,lat,alt using
|
||||
defined projections.
|
||||
"""
|
||||
|
||||
name = "location"
|
||||
config_type = RegisterTlvs.UTILITY.value
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""
|
||||
Creates a GeoLocation instance.
|
||||
"""
|
||||
self.projection = pyproj.Proj("epsg:3857")
|
||||
self.refproj = (0.0, 0.0)
|
||||
self.refgeo = (0.0, 0.0, 0.0)
|
||||
self.refxyz = (0.0, 0.0, 0.0)
|
||||
self.refscale = 1.0
|
||||
|
||||
def setrefgeo(self, lat: float, lon: float, alt: float) -> None:
|
||||
"""
|
||||
Set the geospatial reference point.
|
||||
|
||||
:param lat: latitude reference
|
||||
:param lon: longitude reference
|
||||
:param alt: altitude reference
|
||||
:return: nothing
|
||||
"""
|
||||
self.refgeo = (lat, lon, alt)
|
||||
px, py = self.projection(lon, lat)
|
||||
self.refproj = (px, py, alt)
|
||||
|
||||
def reset(self) -> None:
|
||||
"""
|
||||
Reset reference data to default values.
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.refxyz = (0.0, 0.0, 0.0)
|
||||
self.refgeo = (0.0, 0.0, 0.0)
|
||||
self.refscale = 1.0
|
||||
self.refproj = self.projection(self.refgeo[0], self.refgeo[1])
|
||||
|
||||
def pixels2meters(self, value: float) -> float:
|
||||
"""
|
||||
Provides conversion from pixels to meters.
|
||||
|
||||
:param value: pixels value
|
||||
:return: pixels value in meters
|
||||
"""
|
||||
return (value / SCALE_FACTOR) * self.refscale
|
||||
|
||||
def meters2pixels(self, value: float) -> float:
|
||||
"""
|
||||
Provides conversion from meters to pixels.
|
||||
|
||||
:param value: meters value
|
||||
:return: meters value in pixels
|
||||
"""
|
||||
if self.refscale == 0.0:
|
||||
return 0.0
|
||||
return SCALE_FACTOR * (value / self.refscale)
|
||||
|
||||
def getxyz(self, lat: float, lon: float, alt: float) -> Tuple[float, float, float]:
|
||||
"""
|
||||
Convert provided lon,lat,alt to x,y,z.
|
||||
|
||||
:param lat: latitude value
|
||||
:param lon: longitude value
|
||||
:param alt: altitude value
|
||||
:return: x,y,z representation of provided values
|
||||
"""
|
||||
logging.debug("input lon,lat,alt(%s, %s, %s)", lon, lat, alt)
|
||||
px, py = self.projection(lon, lat)
|
||||
px -= self.refproj[0]
|
||||
py -= self.refproj[1]
|
||||
pz = alt - self.refproj[2]
|
||||
x = self.meters2pixels(px) + self.refxyz[0]
|
||||
y = -(self.meters2pixels(py) + self.refxyz[1])
|
||||
z = self.meters2pixels(pz) + self.refxyz[2]
|
||||
logging.debug("result x,y,z(%s, %s, %s)", x, y, z)
|
||||
return x, y, z
|
||||
|
||||
def getgeo(self, x: float, y: float, z: float) -> Tuple[float, float, float]:
|
||||
"""
|
||||
Convert provided x,y,z to lon,lat,alt.
|
||||
|
||||
:param x: x value
|
||||
:param y: y value
|
||||
:param z: z value
|
||||
:return: lat,lon,alt representation of provided values
|
||||
"""
|
||||
logging.debug("input x,y(%s, %s)", x, y)
|
||||
x -= self.refxyz[0]
|
||||
y = -(y - self.refxyz[1])
|
||||
if z is None:
|
||||
z = self.refxyz[2]
|
||||
else:
|
||||
z -= self.refxyz[2]
|
||||
px = self.refproj[0] + self.pixels2meters(x)
|
||||
py = self.refproj[1] + self.pixels2meters(y)
|
||||
lon, lat = self.projection(px, py, inverse=True)
|
||||
alt = self.refgeo[2] + self.pixels2meters(z)
|
||||
logging.debug("result lon,lat(%s, %s)", lon, lat)
|
||||
return lat, lon, alt
|
Loading…
Add table
Add a link
Reference in a new issue