⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datum.py

📁 gps pygarmin-0[1].6.tgz
💻 PY
字号:
"""   Datums and other conversions.   This is meant to be pretty and understandable rather than fast.   Geodetic datums are models of the shape of the earth. The earth is   rather irregular and attempts to simplify it by assuming that it is   basically an ellipsoid, for example, tend to be reasonably accurate   only for a local area. This is why so many datums are in use.   The most common datum for international purposes is WGS84, and the   parameters of the other ones are usually quoted as differences from   WGS84.  In this module. a Datum object represents a datum and   converts lat/lon points in that datum to and from WGS84.      A reference datum consists of a particular shape of ellipsoid and   an x, y, z offset.  The ellipsoid is defined by its semi-major-axis   'a' (in this case, the equatorial radius) and its semi-minor-axis   'b' (the polar radius).  In most cases, rather than using 'b'   directly, we are interested in the difference between the two - the   degree to which the earth is considered to be 'flattened' at the   poles. So the flattening, f, is given by (a-b)/a.   An example use:     import datum     osd = datum.DatumFromName ('Ordnance Survey of Great Britain 36')     print osd.toWGS84deg(12.3,54.3)    (c) Quentin Stafford-Fraser <quentin@uk.research.att.com>       AT&T Laboratories Cambridge 2001   Partly derived from some python code by Joseph Newman   which in turn came from C code by Alan Jones"""import mathimport refdatum# These are for convenience:def DEG_TO_RAD(angle): return angle*0.0174532925199def RAD_TO_DEG(angle): return angle/0.0174532925199# First we define an ellipsoidclass Ellipsoid:    def __init__(self, a, invf):        """        Create an ellipsoid.  Flattenings tend to be incoveniently        small numbers (typically 0.0033), so they are often quoted        as their reciprocal.  The invf parameter expected here is 1/f.        The value es is the first eccentricity squared, which is        useful later.        """        self.a = a        self.f = 1.0/invf        self.es = 2 * self.f  -  self.f * self.fdef EllipsoidFromName(name):    """    Create a standard ellipsoid from the parameters in    refdatum.py    """    re =  refdatum.Ellipsoids[name]    return Ellipsoid(re[0], re[1])class Datum:    def __init__(self, ellipsoid, dx, dy, dz):        """          All parameters give the WGS84 values relative to this datum.          So dx is the WGS84 X value minus the local datum X value, etc.          dx, dy, dz are the X,Y,Z offsets.        """        global WGS84Datum        self.dx = dx        self.dy = dy        self.dz = dz        # self.ell = ellipsoid        self.a = ellipsoid.a        self.f = ellipsoid.f        self.wgse = EllipsoidFromName("WGS 84")        self.da = self.wgse.a - self.a        self.df = self.wgse.f - self.f    def fromWGS84rad(self, lat, lon, alt=0.0):        return self.molodensky(lat, lon, alt,                               -self.dx, -self.dy, -self.dz,                               self.wgse.a, self.wgse.f,                               -self.da, -self.df)    def fromWGS84deg(self, lat, lon, alt=0.0):        latrad = DEG_TO_RAD(lat)        lonrad = DEG_TO_RAD(lon)        newlat, newlon, newalt = self.fromWGS84rad(latrad, lonrad, alt)        return (RAD_TO_DEG(newlat), RAD_TO_DEG(newlon), newalt)    def toWGS84rad(self, lat, lon, alt=0.0):        return self.molodensky(lat, lon, alt,                               self.dx, self.dy, self.dz,                               self.a, self.f,                               self.da, self.df)    def toWGS84deg(self, lat, lon, alt=0.0):        latrad = DEG_TO_RAD(lat)        lonrad = DEG_TO_RAD(lon)        newlat, newlon, newalt = self.toWGS84rad(latrad, lonrad, alt)        return (RAD_TO_DEG(newlat), RAD_TO_DEG(newlon), newalt)    # everything in radians here    def molodensky(self, lat, lon,  alt, dx, dy, dz, from_a, from_f, da, df):        sinlat = math.sin (lat)        coslat = math.cos (lat)        sinlon = math.sin (lon)        coslon = math.cos (lon)        sin1 = math.sin (math.pi / (3600.0 * 180.0))        bdiva = 1.0 - from_f        esq = (2.0 - from_f)*from_f        exp = 1.0 - esq*sinlat*sinlat        sqrtexp = math.sqrt (exp)        rn = from_a / sqrtexp        rm = from_a * (1.0 - esq) / (exp*sqrtexp)        dlat = (- dx*sinlat*coslon - dy*sinlat*sinlon + dz*coslat +                da*(rn*esq*sinlat*coslat)/from_a +                df*(rm/bdiva + rn*bdiva)*sinlat*coslat) / (rm + alt)        dlon = (-dx*sinlon +dy*coslon)/((rn+alt)*coslat)        dh = (dx*coslat*coslon +              dy*coslat*sinlon +              dz*sinlat-              da*from_a/rn +              df*bdiva*rn*sinlat*sinlat)        newlat = lat + dlat        newlon = lon + dlon        newalt = alt + dh        return (newlat, newlon, newalt)# Then we use the ellipsoids to define datumsdef DatumFromName(name):    rd = refdatum.Datums[name]    e = EllipsoidFromName(rd[0])    return Datum(e, rd[1], rd[2], rd[3])# A simple test routinedef test():     osd = DatumFromName ('Ordnance Survey of Great Britain 36')     nad = DatumFromName ('North America 1927 mean')     wlat, wlon, walt    = (12.3, 45.6, 78)     print "lat, lon, alt =", wlat, wlon, walt     olat, olon, oalt    = osd.fromWGS84deg(wlat,wlon,walt)     wlat2, wlon2, walt2 = osd.toWGS84deg(olat, olon, oalt)     print "Under OSGB datum =", olat, olon, oalt     print "errors after conversion back = ",     print wlat2-wlat, wlon2-wlon, walt2-waltif __name__ == '__main__':    test()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -