/* -*-c++-*- */ /* osgEarth - Geospatial SDK for OpenSceneGraph * Copyright 2020 Pelican Mapping * http://osgearth.org * * osgEarth is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see */ #ifndef OSGEARTH_LOCATORS_H #define OSGEARTH_LOCATORS_H 1 #include #include #include namespace osgEarth { namespace Util { /** * Object that facilitates the conversion between map or world coordinates * and a local unit coordinate space defined by a geospatial extent. */ class /* header only */ GeoLocator { public: //! Construct with an extent that defines the unit [0..1] space GeoLocator(const GeoExtent& extent) { _extent = extent; _srs = extent.getSRS(); _transform.set( extent.width(), 0.0, 0.0, 0.0, 0.0, extent.height(), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, extent.xMin(), extent.yMin(), 0.0, 1.0); _inverse.invert(_transform); } //! Convert world coordinates to unit space inline void worldToUnit(const osg::Vec3d& world, osg::Vec3d& unit) const { if (_srs->isGeographic()) unit = _srs->getEllipsoid().geocentricToGeodetic(world) * _inverse; else unit = world * _inverse; } //! Convert unit coordinates to world space inline void unitToWorld(const osg::Vec3d& unit, osg::Vec3d& world) const { world = unit * _transform; if (_srs->isGeographic()) world = _srs->getEllipsoid().geodeticToGeocentric(world); } GeoExtent _extent; osg::Matrixd _transform; osg::Matrixd _inverse; double _x0, _y0, _x1, _y1; osg::ref_ptr _srs; }; } } #endif // OSGEARTH_LOCATORS_H