From 9e40c944d88da4c2deb44ea56df74d90fb1e4752 Mon Sep 17 00:00:00 2001 From: harry093 Date: Fri, 1 May 2020 13:37:24 +1000 Subject: [PATCH] Removed deprecated functions and refactored --- api/app.py | 20 ++-- geodepy/convert.py | 179 +++++++++++----------------------- geodepy/inputoutput.py | 19 ++-- geodepy/tests/test_convert.py | 36 +++---- 4 files changed, 97 insertions(+), 157 deletions(-) diff --git a/api/app.py b/api/app.py index e058d12..70f72ba 100644 --- a/api/app.py +++ b/api/app.py @@ -4,26 +4,27 @@ from flask import url_for from geodepy.geodesy import vincdir from geodepy.geodesy import vincinv -from geodepy.convert import dms2dd -from geodepy.convert import dd2dms +from geodepy.convert import hp2dec +from geodepy.convert import dec2hp app = Flask(__name__) angle_type_to_dd = { 'dd': lambda x: x, - 'dms': dms2dd, + 'dms': hp2dec, } dd_to_angle_type = { 'dd': lambda x: x, - 'dms': dd2dms, + 'dms': dec2hp, } @app.route('/') def list_routes(): - return str(tuple(url_for(rule.endpoint) for rule in app.url_map.iter_rules() if rule.endpoint != 'static')) + return str(tuple(url_for(rule.endpoint) for rule in + app.url_map.iter_rules() if rule.endpoint != 'static')) @app.route('/vincinv') @@ -38,7 +39,8 @@ def handle_vincinv(): dd = angle_type_to_dd[from_angle_type] lat1_dd, lon1_dd, lat2_dd, lon2_dd = dd(lat1), dd(lon1), dd(lat2), dd(lon2) - ell_dist, azimuth1to2_dd, azimuth2to1_dd = vincinv(lat1_dd, lon1_dd, lat2_dd, lon2_dd) + ell_dist, azimuth1to2_dd, azimuth2to1_dd = vincinv(lat1_dd, lon1_dd, + lat2_dd, lon2_dd) angle = dd_to_angle_type[to_angle_type] azimuth1to2, azimuth2to1 = angle(azimuth1to2_dd), angle(azimuth2to1_dd) @@ -62,10 +64,12 @@ def handle_vincdir(): dd = angle_type_to_dd[from_angle_type] lat1_dd, lon1_dd, azimuth1to2_dd = dd(lat1), dd(lon1), dd(azimuth1to2) - lat2_dd, lon2_dd, azimuth2to1_dd = vincdir(lat1_dd, lon1_dd, azimuth1to2_dd, ell_dist) + lat2_dd, lon2_dd, azimuth2to1_dd = vincdir(lat1_dd, lon1_dd, + azimuth1to2_dd, ell_dist) angle_type = dd_to_angle_type[to_angle_type] - lat2, lon2, azimuth2to1 = angle_type(lat2_dd), angle_type(lon2_dd), angle_type(azimuth2to1_dd) + lat2, lon2, azimuth2to1 = angle_type(lat2_dd), angle_type(lon2_dd),\ + angle_type(azimuth2to1_dd) return jsonify({ 'lat2': lat2, diff --git a/geodepy/convert.py b/geodepy/convert.py index 5688844..582d1c8 100644 --- a/geodepy/convert.py +++ b/geodepy/convert.py @@ -5,21 +5,7 @@ Convert Module """ -from math import modf, sin, cos, atan2, radians, degrees, sqrt - - -def dec2hp(dec): - minute, second = divmod(abs(dec) * 3600, 60) - degree, minute = divmod(minute, 60) - hp = degree + (minute / 100) + (second / 10000) - return hp if dec >= 0 else -hp - - -def hp2dec(hp): - degmin, second = divmod(abs(hp) * 1000, 10) - degree, minute = divmod(degmin, 100) - dec = degree + (minute / 60) + (second / 360) - return dec if hp >= 0 else -dec +from math import sin, cos, atan2, radians, degrees, sqrt class DMSAngle(object): @@ -49,49 +35,57 @@ def __repr__(self): signsymbol = '+' else: signsymbol = 'error' - return '{DMSAngle: ' + signsymbol + str(self.degree) + 'd ' + str(self.minute) + 'm ' + str(self.second) + 's}' + return '{DMSAngle: ' + signsymbol + str(self.degree) + 'd ' +\ + str(self.minute) + 'm ' + str(self.second) + 's}' def __add__(self, other): try: return dec2dms(self.dec() + other.dec()) except AttributeError: - raise TypeError('Can only add DMSAngle and/or DDMAngle objects together') + raise TypeError('Can only add DMSAngle and/or DDMAngle objects ' + 'together') def __radd__(self, other): try: return dec2dms(other.dec() + self.dec()) except AttributeError: - raise TypeError('Can only add DMSAngle and/or DDMAngle objects together') + raise TypeError('Can only add DMSAngle and/or DDMAngle objects ' + 'together') def __sub__(self, other): try: return dec2dms(self.dec() - other.dec()) except AttributeError: - raise TypeError('Can only subtract DMSAngle and/or DDMAngle objects together') + raise TypeError('Can only subtract DMSAngle and/or DDMAngle ' + 'objects together') def __rsub__(self, other): try: return dec2dms(other.dec() - self.dec()) except AttributeError: - raise TypeError('Can only subtract DMSAngle and/or DDMAngle objects together') + raise TypeError('Can only subtract DMSAngle and/or DDMAngle ' + 'objects together') def __mul__(self, other): try: return dec2dms(self.dec() * other) except TypeError: - raise TypeError('Multiply only defined between DMSAngle Object and Int or Float') + raise TypeError('Multiply only defined between DMSAngle Object ' + 'and Int or Float') def __rmul__(self, other): try: return dec2dms(other * self.dec()) except TypeError: - raise TypeError('Multiply only defined between DMSAngle Object and Int or Float') + raise TypeError('Multiply only defined between DMSAngle Object ' + 'and Int or Float') def __truediv__(self, other): try: return dec2dms(self.dec() / other) except TypeError: - raise TypeError('Division only defined between DMSAngle Object and Int or Float') + raise TypeError('Division only defined between DMSAngle Object ' + 'and Int or Float') def __abs__(self): return DMSAngle(self.degree, self.minute, self.second) @@ -115,10 +109,12 @@ def __gt__(self, other): return self.dec() > other.dec() def dec(self): - return self.sign * (self.degree + (self.minute / 60) + (self.second / 3600)) + return self.sign * (self.degree + (self.minute / 60) + + (self.second / 3600)) def hp(self): - return self.sign * (self.degree + (self.minute / 100) + (self.second / 10000)) + return self.sign * (self.degree + (self.minute / 100) + + (self.second / 10000)) def ddm(self): if self.sign == 1: @@ -151,49 +147,57 @@ def __repr__(self): signsymbol = '+' else: signsymbol = 'error' - return '{DDMAngle: ' + signsymbol + str(self.degree) + 'd ' + str(self.minute) + 'm}' + return '{DDMAngle: ' + signsymbol + str(self.degree) + 'd ' + \ + str(self.minute) + 'm}' def __add__(self, other): try: return dec2ddm(self.dec() + other.dec()) except AttributeError: - raise TypeError('Can only add DMSAngle and/or DDMAngle objects together') + raise TypeError('Can only add DMSAngle and/or DDMAngle objects ' + 'together') def __radd__(self, other): try: return dec2ddm(other.dec() + self.dec()) except AttributeError: - raise TypeError('Can only add DMSAngle and/or DDMAngle objects together') + raise TypeError('Can only add DMSAngle and/or DDMAngle objects ' + 'together') def __sub__(self, other): try: return dec2ddm(self.dec() - other.dec()) except AttributeError: - raise TypeError('Can only add DMSAngle and/or DDMAngle objects together') + raise TypeError('Can only add DMSAngle and/or DDMAngle objects ' + 'together') def __rsub__(self, other): try: return dec2ddm(other.dec() - self.dec()) except AttributeError: - raise TypeError('Can only add DMSAngle and/or DDMAngle objects together') + raise TypeError('Can only add DMSAngle and/or DDMAngle objects ' + 'together') def __mul__(self, other): try: return dec2ddm(self.dec() * other) except TypeError: - raise TypeError('Multiply only defined between DMSAngle Object and Int or Float') + raise TypeError('Multiply only defined between DMSAngle Object ' + 'and Int or Float') def __rmul__(self, other): try: return dec2ddm(other * self.dec()) except TypeError: - raise TypeError('Multiply only defined between DMSAngle Object and Int or Float') + raise TypeError('Multiply only defined between DMSAngle Object ' + 'and Int or Float') def __truediv__(self, other): try: return dec2ddm(self.dec() / other) except TypeError: - raise TypeError('Division only defined between DMSAngle Object and Int or Float') + raise TypeError('Division only defined between DMSAngle Object ' + 'and Int or Float') def __abs__(self): return DDMAngle(self.degree, self.minute) @@ -221,17 +225,33 @@ def dec(self): def hp(self): minute_int, second = divmod(self.minute, 1) - return self.sign * (self.degree + (minute_int / 100) + (second * 0.006)) + return self.sign * (self.degree + (minute_int / 100) + + (second * 0.006)) def dms(self): minute_int, second = divmod(self.minute, 1) return self.sign * DMSAngle(self.degree, minute_int, second * 60) +def dec2hp(dec): + minute, second = divmod(abs(dec) * 3600, 60) + degree, minute = divmod(minute, 60) + hp = degree + (minute / 100) + (second / 10000) + return hp if dec >= 0 else -hp + + +def hp2dec(hp): + degmin, second = divmod(abs(hp) * 1000, 10) + degree, minute = divmod(degmin, 100) + dec = degree + (minute / 60) + (second / 360) + return dec if hp >= 0 else -dec + + def dec2dms(dec): minute, second = divmod(abs(dec) * 3600, 60) degree, minute = divmod(minute, 60) - return DMSAngle(degree, minute, second) if dec >= 0 else DMSAngle(-degree, minute, second) + return DMSAngle(degree, minute, second) if dec >= 0 \ + else DMSAngle(-degree, minute, second) def dec2ddm(dec): @@ -244,7 +264,8 @@ def dec2ddm(dec): def hp2dms(hp): degmin, second = divmod(abs(hp) * 1000, 10) degree, minute = divmod(degmin, 100) - return DMSAngle(degree, minute, second * 10) if hp >= 0 else DMSAngle(-degree, minute, second * 10) + return DMSAngle(degree, minute, second * 10) if hp >= 0 \ + else DMSAngle(-degree, minute, second * 10) def hp2ddm(hp): @@ -275,89 +296,3 @@ def dd2sec(dd): degrees, minutes = divmod(minutes, 60) sec = (degrees * 3600) + (minutes * 60) + seconds return sec if dd >= 0 else -sec - - -# ---------------- -# Legacy Functions -# dd2dms refactored as dec2hp -def dd2dms(dd): - minutes, seconds = divmod(abs(dd) * 3600, 60) - degrees, minutes = divmod(minutes, 60) - dms = degrees + (minutes / 100) + (seconds / 10000) - return dms if dd >= 0 else -dms - - -# dms2dd refactored as hp2dec -def dms2dd(dms): - degmin, seconds = divmod(abs(dms) * 1000, 10) - degrees, minutes = divmod(degmin, 100) - dd = degrees + (minutes / 60) + (seconds / 360) - return dd if dms >= 0 else -dd - - -def dd2dms_v(dd): - minutes, seconds = divmod(abs(dd) * 3600, 60) - degrees, minutes = divmod(minutes, 60) - dms = degrees + (minutes / 100) + (seconds / 10000) - dms[dd <= 0] = -dms[dd <= 0] - return dms - - -def dms2dd_v(dms): - degmin, seconds = divmod(abs(dms) * 1000, 10) - degrees, minutes = divmod(degmin, 100) - dd = degrees + (minutes / 60) + (seconds / 360) - dd[dms <= 0] = -dd[dms <= 0] - return dd - - -class DNACoord(object): - def __init__(self, pointid, const, easting, northing, zone, lat, - long, ortho_ht, ell_ht, x, y, z, x_sd, y_sd, z_sd, desc): - self.pointid = pointid - self.const = const - self.easting = easting - self.northing = northing - self.zone = zone - self.lat = lat - self.long = long - self.ortho_ht = ortho_ht - self.ell_ht = ell_ht - self.x = x - self.y = y - self.z = z - self.x_sd = x_sd - self.y_sd = y_sd - self.z_sd = z_sd - self.desc = desc - - def converthptodd(self): - self.lat = hp2dec(self.lat) - self.long = hp2dec(self.long) - - -def read_dnacoord(fn): - coord_list = [] - with open(fn, 'r') as file: - dnadata = file.readlines() - for line in dnadata: - pointid = line[0:20] - const = line[21:25] - easting = float(line[28:40]) - northing = float(line[41:58]) - zone = int(line[60:63]) - lat = float(line[63:78]) - long = float(line[78:92]) - ortho_ht = float(line[93:103]) - ell_ht = float(line[103:114]) - x = float(line[115:129]) - y = float(line[130:144]) - z = float(line[145:159]) - x_sd = float(line[160:171]) - y_sd = float(line[172:181]) - z_sd = float(line[182:191]) - desc = line[192:-1] - record = DNACoord(pointid.strip(), const.strip(), easting, northing, zone, lat, - long, ortho_ht, ell_ht, x, y, z, x_sd, y_sd, z_sd, desc.strip()) - coord_list.append(record) - return coord_list diff --git a/geodepy/inputoutput.py b/geodepy/inputoutput.py index c47484c..14cbd45 100644 --- a/geodepy/inputoutput.py +++ b/geodepy/inputoutput.py @@ -8,9 +8,10 @@ import geodepy.constants as cs ''' -The inputoutput module acts as the backend for the GUI and manages the calls to the GeodePy functions. The functions -are rewritten from the transform module but use pandas to improve efficiency. Functions placed here to not overcrowd -the transform module. +The inputoutput module acts as the backend for the GUI and manages the calls +to the GeodePy functions. The functions are rewritten from the transform +module but use pandas to improve efficiency. Functions placed here to not +overcrowd the transform module. ''' @@ -46,8 +47,8 @@ def grid2geoio(fn, fn_out, easting, northing, utmzone, geotypeout): # Convert tuple returned to DafaFrame resultdf = pd.DataFrame(list(returned), columns=['Latitude', 'Longitude', 'Point Scale Factor', 'Grid Convergence']) if geotypeout == 'DMS': - resultdf['Latitude'] = resultdf['Latitude'].apply(cv.dd2dms) - resultdf['Longitude'] = resultdf['Longitude'].apply(cv.dd2dms) + resultdf['Latitude'] = resultdf['Latitude'].apply(cv.dec2hp) + resultdf['Longitude'] = resultdf['Longitude'].apply(cv.dec2hp) # Adds the results to the original dataframe from the csv csvdf = pd.concat([csvdf, resultdf], axis=1) # Writes the dataframe to a csv @@ -83,8 +84,8 @@ def geo2gridio(fn, fn_out, latitude, longitude, geotypein): # Converts DMS lat and long to Decimal Degrees if required if geotypein == 'DMS': - csvdf['LatitudeDD'] = csvdf[latitude].apply(cv.dms2dd) - csvdf['LongitudeDD'] = csvdf[longitude].apply(cv.dms2dd) + csvdf['LatitudeDD'] = csvdf[latitude].apply(cv.hp2dec) + csvdf['LongitudeDD'] = csvdf[longitude].apply(cv.hp2dec) latitude = 'LatitudeDD' longitude = 'LongitudeDD' @@ -159,8 +160,8 @@ def gdatrans7(fn, fn_out, latitude, longitude, ellht, gdageotypein, direction): if gdageotypein == 'DMS': csvdf['LatitudeDMS'] = csvdf[latitude] csvdf['LongitudeDMS'] = csvdf[longitude] - csvdf['Latitude'] = csvdf[latitude].apply(cv.dms2dd) - csvdf['Longitude'] = csvdf[longitude].apply(cv.dms2dd) + csvdf['Latitude'] = csvdf[latitude].apply(cv.hp2dec) + csvdf['Longitude'] = csvdf[longitude].apply(cv.hp2dec) # Converts Lat, Long & ElipHt XYZ returned = csvdf.apply(lambda x: tf.llh2xyz(x[latitude], x[longitude], x[ellht]), axis=1) diff --git a/geodepy/tests/test_convert.py b/geodepy/tests/test_convert.py index 8f0591c..309a97d 100644 --- a/geodepy/tests/test_convert.py +++ b/geodepy/tests/test_convert.py @@ -1,6 +1,6 @@ import unittest -from geodepy.convert import dec2hp, hp2dec, DMSAngle, DDMAngle, dec2dms, dec2ddm, hp2dms,\ - hp2ddm, dd2dms, dms2dd +from geodepy.convert import dec2hp, hp2dec, DMSAngle, DDMAngle, dec2dms,\ + dec2ddm, hp2dms, hp2ddm dec_ex = 123.74875 dec_ex2 = 12.575 @@ -35,7 +35,8 @@ def test_dec2hp(self): def test_hp2dec(self): self.assertAlmostEqual(dec_ex, hp2dec(hp_ex), 13) self.assertAlmostEqual(-dec_ex, hp2dec(-hp_ex), 13) - self.assertAlmostEqual(hp2dec(hp_ex) + hp2dec(hp_ex2), dec_ex + dec_ex2, 13) + self.assertAlmostEqual(hp2dec(hp_ex) + + hp2dec(hp_ex2), dec_ex + dec_ex2, 13) def test_DMSAngle(self): # Test DMSAngle Methods @@ -47,10 +48,14 @@ def test_DMSAngle(self): self.assertEqual(ddm_ex3, dms_ex3.ddm()) # Test DMSAngle Sign Conventions - self.assertEqual(-dec_ex, DMSAngle(-dms_ex.degree, dms_ex.minute, dms_ex.second).dec()) - self.assertEqual(dec_ex, DMSAngle(dms_ex.degree, -dms_ex.minute, -dms_ex.second).dec()) - self.assertAlmostEqual(-dec_ex4, DMSAngle(0, -dms_ex4.minute, dms_ex4.second).dec(), 9) - self.assertAlmostEqual(dec_ex4, DMSAngle(0, dms_ex4.minute, dms_ex4.second).dec(), 9) + self.assertEqual(-dec_ex, DMSAngle(-dms_ex.degree, dms_ex.minute, + dms_ex.second).dec()) + self.assertEqual(dec_ex, DMSAngle(dms_ex.degree, -dms_ex.minute, + -dms_ex.second).dec()) + self.assertAlmostEqual(-dec_ex4, DMSAngle(0, -dms_ex4.minute, + dms_ex4.second).dec(), 9) + self.assertAlmostEqual(dec_ex4, DMSAngle(0, dms_ex4.minute, + dms_ex4.second).dec(), 9) self.assertEqual(-dec_ex5, DMSAngle(0, 0, -dms_ex5.second).dec()) self.assertEqual(dec_ex5, DMSAngle(0, 0, dms_ex5.second).dec()) self.assertEqual(-dms_ex3, DMSAngle(12, 34, -30)) @@ -107,9 +112,11 @@ def test_DMSAngle(self): # Test Class Interoperability self.assertEqual(DMSAngle(1, 2, 3) + DDMAngle(2, 3), DMSAngle(3, 5, 3)) - self.assertEqual(DMSAngle(3, 2, 0) - DDMAngle(2, 2.5), DMSAngle(0, 59, 30)) + self.assertEqual(DMSAngle(3, 2, 0) - DDMAngle(2, 2.5), + DMSAngle(0, 59, 30)) self.assertEqual(DDMAngle(2, 3) + DMSAngle(1, 2, 3), DDMAngle(3, 5.05)) - self.assertEqual(DDMAngle(3, 2) - DMSAngle(2, 2, 30), DDMAngle(0, 59.5)) + self.assertEqual(DDMAngle(3, 2) - DMSAngle(2, 2, 30), + DDMAngle(0, 59.5)) def test_DDMAngle(self): # Test DDMAngle Methods @@ -119,7 +126,8 @@ def test_DDMAngle(self): self.assertEqual(hp_ex3, ddm_ex3.hp()) # Test DMSAngle Sign Conventions - self.assertEqual(-dec_ex, DDMAngle(-dms_ex.degree, ddm_ex.minute).dec()) + self.assertEqual(-dec_ex, DDMAngle(-dms_ex.degree, + ddm_ex.minute).dec()) self.assertEqual(dec_ex, DDMAngle(dms_ex.degree, -ddm_ex.minute).dec()) self.assertAlmostEqual(-dec_ex4, DDMAngle(0, -ddm_ex4.minute).dec(), 9) self.assertAlmostEqual(dec_ex4, DDMAngle(0, ddm_ex4.minute).dec(), 9) @@ -196,14 +204,6 @@ def test_hp2ddm(self): self.assertEqual(ddm_ex, hp2ddm(hp_ex)) self.assertEqual(-ddm_ex, hp2ddm(-hp_ex)) - def test_dd2dms(self): - self.assertEqual(hp_ex, dd2dms(dec_ex)) - self.assertEqual(-hp_ex, dd2dms(-dec_ex)) - - def test_dms2dd(self): - self.assertAlmostEqual(dec_ex, dms2dd(hp_ex), 9) - self.assertAlmostEqual(-dec_ex, dms2dd(-hp_ex), 9) - if __name__ == '__main__': unittest.main()