def testViennaFromDMS(self): """ The convertLatLong must return the expected value when passed the location of Vienna with degrees, minutes, and seconds. """ lat, lon = convertLatLong('48°12\'30.0"N 16°6\'15.5"E') self.assertAlmostEqual(lat, 48.208333333) self.assertAlmostEqual(lon, 16.104305555)
def testRandom(self): """ Test a random value obtained from https://www.fcc.gov/media/radio/dms-decimal """ lat, lon = convertLatLong('22°22\'22"N 33°33\'33"E') self.assertAlmostEqual(lat, 22.37277777) self.assertAlmostEqual(lon, 33.55916666)
def testViennaFromDM(self): """ The convertLatLong must return the expected value when passed the location of Vienna with only degrees and minutes (no seconds). """ lat, lon = convertLatLong('48°12\'N 16°22\'E') self.assertAlmostEqual(lat, 48.2) self.assertAlmostEqual(lon, 16.366666666666)
def testTwoFloatsLeadingAndTrailingWhitespace(self): """ The convertLatLong must return the expected value when passed two floats separated by a space with leading and trailing whitespace. """ lat, lon = convertLatLong(' 27.0 35.3 ') self.assertAlmostEqual(lat, 27.0) self.assertAlmostEqual(lon, 35.3)
def testTwoFloatsSpace(self): """ The convertLatLong must return the expected value when passed two floats separated by a space. """ lat, lon = convertLatLong('27.0 35.3') self.assertAlmostEqual(lat, 27.0) self.assertAlmostEqual(lon, 35.3)
def testTwoFloatsCommaNoSpace(self): """ The convertLatLong must return the expected value when passed two floats separated by a comma but with no intervening space. """ lat, lon = convertLatLong('27.0,35.3') self.assertAlmostEqual(lat, 27.0) self.assertAlmostEqual(lon, 35.3)
def main(): data = [] idsSeen = {} # Key is int id, value is first record completeRecords = 0 for lineNumber, record in enumerate(reader(sys.stdin), start=1): if lineNumber == 1: if record != headers: raise RuntimeError( 'CSV headers have changed!\nExpected %r\nSaw %r\n' % (headers, record)) continue [name, strId, editBy, lastEditBy, country1, country1Place, country2, country2Place, otherNames, coords, active, hours, crossingType, bikeCrossing, tcr4Survey, notes] = record try: intId = int(strId) except ValueError: raise ValueError( 'Could not convert id %r to int on line %d.\nRecord %r' % (strId, lineNumber, record)) if intId in idsSeen: raise(ValueError, 'Place id %r occurs more than once (on lines %d and %d)' % (idsSeen[intId], lineNumber)) else: idsSeen[intId] = lineNumber if not coords: print('Skipped record %d due to missing coords.' % lineNumber, file=sys.stderr) continue try: lat, lon = convertLatLong(coords) except ValueError: print('Could not convert coords %r on line %d' % (coords, lineNumber), file=sys.stderr) continue # Round latitude & longitude to 5 decimals. This provides for # accuracy down to 1.1 meters. I don't keep all the decimal places # for display purposes (we have some coords that have many places # and these look odd in the UI). lat = round(lat, 5) lon = round(lon, 5) if not (country1 and country2): print('Skipped record %d due to missing country.' % lineNumber, file=sys.stderr) continue for country in country1, country2: if country not in countries: raise ValueError('Unknown country %r found on line %d' % (country, lineNumber)) if active.lower() != 'yes': print('Skipped record %d due to inactive (value %r).' % (lineNumber, active), file=sys.stderr) continue data.append({ 'active': active, 'bikeCrossing': bikeCrossing, 'countryTo': country1, 'countryToPlace': country1Place, 'countryFrom': country2, 'countryFromPlace': country2Place, 'crossingType': crossingType, 'hours': hours, 'id': intId, 'latitude': lat, 'longitude': lon, 'name': name, 'notes': notes, 'otherNames': otherNames.split() if otherNames else [], 'tcr4Survey': tcr4Survey, }) completeRecords += 1 print(dumps({ 'date': ctime(mktime(gmtime())), 'crossings': data, }, indent=4, sort_keys=True)) print('Found %d complete records in %d lines of input.' % (completeRecords, lineNumber), file=sys.stderr)