def test_haversine_distance(self): loc1 = mod_geo.Location(1, 2) loc2 = mod_geo.Location(2, 3) self.assertEqual( loc1.distance_2d(loc2), mod_geo.distance(loc1.latitude, loc1.longitude, None, loc2.latitude, loc2.longitude, None)) loc1 = mod_geo.Location(1, 2) loc2 = mod_geo.Location(3, 4) self.assertEqual( loc1.distance_2d(loc2), mod_geo.distance(loc1.latitude, loc1.longitude, None, loc2.latitude, loc2.longitude, None)) loc1 = mod_geo.Location(1, 2) loc2 = mod_geo.Location(3.1, 4) self.assertEqual( loc1.distance_2d(loc2), mod_geo.haversine_distance(loc1.latitude, loc1.longitude, loc2.latitude, loc2.longitude)) loc1 = mod_geo.Location(1, 2) loc2 = mod_geo.Location(2, 4.1) self.assertEqual( loc1.distance_2d(loc2), mod_geo.haversine_distance(loc1.latitude, loc1.longitude, loc2.latitude, loc2.longitude))
def cluster(csv2read, outFileName): print "generating culster information" ptscsv = pd.read_csv(csv2read, index_col=0) unqSegIDs = ptscsv.sid.unique() result = pd.DataFrame() oldgrp = None for unqSID in unqSegIDs: meanCol = [] grp = ptscsv[ptscsv['sid'] == unqSID] grp.is_copy = False # supress copy warning while assignment mean = grp.mean().lat, grp.mean().lon grp['mlat'] = mean[0] grp['mlon'] = mean[1] if oldgrp is not None: grp['dir'] = mod_geo.get_bearing( mod_geo.Location(oldgrp[0], oldgrp[1]), mod_geo.Location(mean[0], mean[1])) else: grp['dir'] = None result = result.append(grp, ignore_index=True) oldgrp = mean[0], mean[1] devList = [] distList = [] oldID = None oldRow = None for i, r in result.iterrows(): if not pd.isnull(r.dir): dist = mod_geo.distance(r.mlat, r.mlon, None, r.lat, r.lon, None) dirTgt = mod_geo.get_bearing( mod_geo.Location(oldID.mlat, oldID.mlon), mod_geo.Location(r.lat, r.lon)) dir90 = mod_geo.get_bearing(mod_geo.Location(r.mlat, r.mlon), mod_geo.Location(r.lat, r.lon)) if (r.dir > dirTgt): dist = dist * (-1) distList.append(dist) devList.append(cartDist(r.lat, r.lon, r.mlat, r.mlon)) else: distList.append( mod_geo.distance(r.mlat, r.mlon, None, r.lat, r.lon, None)) devList.append(cartDist(r.lat, r.lon, r.mlat, r.mlon)) if oldID is None: oldID = r else: if (oldRow.dir != r.dir) and (not pd.isnull(r.dir)): oldID = oldRow oldRow = r result['dev'] = devList result['dist'] = distList result.to_csv(outFileName) print "written : " + outFileName return outFileName
def weightedK(x, y, **kwargs): ''' x and y expect data in the following format ------------------------------------------- lat lon acc ''' # check point's accuracy includes the center if (mod_geo.distance(x[0], x[1], None, y[0], y[1], None) <= x[2]): return 0 else: return (mod_geo.distance(x[0], x[1], None, y[0], y[1], None) - x[2])
def distance(lat, lon, ele): distance = 0 if not ele == None: for i in range(len(lat) - 1): d = mod_geo.distance(lat[i], lon[i], ele[i], lat[i + 1], lon[i + 1], ele[i + 1]) distance = distance + d else: for i in range(len(lat) - 1): d = mod_geo.distance(lat[i], lon[i], None, lat[i + 1], lon[i + 1], None) distance = distance + d return distance
def get_geo_from_exif(self, filename, time_offset=0): try: geo_data, exif_time, bearing = exif_fields(filename) if self is not None and self.gpx_data: offset_time = self.gpx_data[-1].offset elif self is None: offset_time = time_offset else: offset_time = 0 t = exif_time - \ datetime.timedelta(seconds=offset_time) lat = geo_data["latitude"] lon = geo_data["longitude"] elevation = geo_data["altitude"] speed = None slope = None if self is not None and self.gpx_data: last = self.gpx_data[-1] seconds = (t - last.datetime).total_seconds() length = geo.distance(last.lat, last.lon, last.elevation, lat, lon, elevation) speed = length / float(seconds) slope = round((elevation - last.elevation) / length * 100) return GPSData(lat, lon, bearing, elevation, speed, None, t, None, slope, None) except KeyError as e: print("No latitude in {}".format(filename)) raise e except ValueError as e: print("Skipping {0}: {1}".format(filename, e))
def kcsvToKML(inFile, outFile): kml = simplekml.Kml() f = pd.read_csv(inFile) f['ts'] = pd.to_datetime(f.ts, unit='s') kml = simplekml.Kml() c2add = [] oldr = None for ii, r in f.iterrows(): if oldr is not None: dist = mod_geo.distance(r.lat, r.lon, None, oldr.lat, oldr.lon, None) ''' tdel = (oldr.ts - r.ts).seconds diffTrip = False if dist > 10 or tdel > 90: diffTrip = True ''' if (ii % 40000 == 0 or dist > 10): ls = kml.newlinestring(name=str(ii)) ls.coords = c2add ls.extrude = 1 ls.altitudemode = simplekml.AltitudeMode.relativetoground ls.style.linestyle.width = 1 ls.style.linestyle.color = simplekml.Color.yellow c2add = [] ############ order changed due to KML specifications, add altitude for good display pt = r['lon'], r['lat'], 1 c2add.append(pt) oldr = r kml.save(outFile) print "Written : " + outFile return outFile
def calc_pdist_matrix(self, X): spots = np.union1d(X['start_spot'].values, X['end_spot'].values) dist_matrix = list() for spot1 in spots: inner_matrix = list() if len(X[X['start_spot'] == spot1]) > 0: p1_ex = X[X['start_spot'] == spot1].iloc[0] p1_lat = float(p1_ex.start_lat) p1_lon = float(p1_ex.start_lon) else: p1_ex = X[X['end_spot'] == spot1].iloc[0] p1_lat = float(p1_ex.end_lat) p1_lon = float(p1_ex.end_lon) for spot2 in spots: if len(X[X['start_spot'] == spot2]) > 0: p2_ex = X[X['start_spot'] == spot2].iloc[0] p2_lat = float(p2_ex.start_lat) p2_lon = float(p2_ex.start_lon) else: p2_ex = X[X['end_spot'] == spot2].iloc[0] p2_lat = float(p2_ex.end_lat) p2_lon = float(p2_ex.end_lon) dist = geo.distance(p1_lat, p1_lon, None, p2_lat, p2_lon, None) inner_matrix.append(dist) dist_matrix.append(inner_matrix) return spots.tolist(), dist_matrix
def test_bearing(): p1 = Location(52.3710, 4.9006) p2 = Location(51.8448, 5.8631) d = distance(p1.latitude, p1.longitude, None, p2.latitude, p2.longitude, None) eq_(int(d), 88000) bearing = geo.bearing(p1, p2) eq_(bearing, 131.292906976903)
def chkDist(id): load() setDevice(id) t = [] for i in range(0,10000): x,y = addErr(10,10) dist = mod_geo.distance(10,10,None, x,y,None) dt = {'x':x,'y':y,'dist':dist} t.append(dt) nf = pd.DataFrame(t) plt.hist(nf.dist, bins=20, normed=True) plt.show()
def csv2gpx(pathToCSV, outFile): ''' pathToCSV: input csvFile outFile: output gpx file name input file must have lat and lon columns Converts simulation csv to gpx file for easy viewing ''' gpxOpTmp = gpxpy.gpx.GPX() gpx_track = gpxpy.gpx.GPXTrack() gpxOpTmp.tracks.append(gpx_track) gpx_segment = gpxpy.gpx.GPXTrackSegment() gpx_track.segments.append(gpx_segment) f = pd.read_csv(pathToCSV) # custom fence: f = f[f['lat'] > fence[0]] f = f[f['lat'] < fence[2]] f = f[f['lon'] > fence[1]] f = f[f['lon'] < fence[3]] f = f[f['accuracy'] <= accThreashold] #f = f.dropna() f['sts'] = pd.to_datetime(f['date'] + " " + f['hour'], format="%d.%m.%Y %H:%M:%S:%f") startDate = datetime.strptime('2016-08-01', '%Y-%m-%d') # YYYY-MM-DD format endDate = datetime.strptime('2016-09-01', '%Y-%m-%d') # YYYY-MM-DD format f = f.ix[(f['sts'] >= startDate) & (f['sts'] <= endDate)] f = f.sort_values(['vid', 'sts']) f = f.reset_index(drop=True) veh = f.vid.unique() print "no. of individual vehicles : ", len(veh) print "no. of day(s) there was data : ", len(f.date.unique()) print "frames: ", len(f) oldVeh = f.iloc[0] for i, r in f.iterrows(): if ((oldVeh.vid == r.vid) and (mod_geo.distance( oldVeh.lat, oldVeh.lon, None, r.lat, r.lon, None) < 1200)): gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(r.lat, r.lon)) else: gpx_track = gpxpy.gpx.GPXTrack() gpxOpTmp.tracks.append(gpx_track) gpx_segment = gpxpy.gpx.GPXTrackSegment() gpx_track.segments.append(gpx_segment) oldVeh = r outFile = outFile.split('.')[0] + str(startDate.month) + str( startDate.day) + "-" + str(endDate.month) + str(endDate.day) + ".gpx" outfile = open(outFile, 'w') outfile.write(gpxOpTmp.to_xml()) print "Written : " + outFile
def chk(): mdl.setDevice("n1") sampleSize = 1000 # enter coordinates here initLoc = [40, 8] initLoc = np.zeros((sampleSize, 2)) + initLoc errCords, errDist = [], [] for i in range(0, sampleSize): e = mdl.addErr(initLoc[i][0], initLoc[i][1]) errCords.append(e) d = mdl_geo.distance(initLoc[i][0], initLoc[i][1],None, e[0], e[1], None) errDist.append(d) plt.hist(errDist) plt.show()
def test_haversine_distance(self): loc1 = mod_geo.Location(1, 2) loc2 = mod_geo.Location(2, 3) self.assertEqual(loc1.distance_2d(loc2), mod_geo.distance(loc1.latitude, loc1.longitude, None, loc2.latitude, loc2.longitude, None)) loc1 = mod_geo.Location(1, 2) loc2 = mod_geo.Location(3, 4) self.assertEqual(loc1.distance_2d(loc2), mod_geo.distance(loc1.latitude, loc1.longitude, None, loc2.latitude, loc2.longitude, None)) loc1 = mod_geo.Location(1, 2) loc2 = mod_geo.Location(3.1, 4) self.assertEqual(loc1.distance_2d(loc2), mod_geo.haversine_distance(loc1.latitude, loc1.longitude, loc2.latitude, loc2.longitude)) loc1 = mod_geo.Location(1, 2) loc2 = mod_geo.Location(2, 4.1) self.assertEqual(loc1.distance_2d(loc2), mod_geo.haversine_distance(loc1.latitude, loc1.longitude, loc2.latitude, loc2.longitude))
def estCenters(c): # c is an array of points on the sampling segment. mc = c.mean(axis=0) percentToMove = 1.5 for i in range(len(c)): dir = mod_geo.get_bearing(mod_geo.Location(c[i][0], c[i][1]), mod_geo.Location(mc[0], mc[1])) distBet = mod_geo.distance(c[i][0], c[i][1], None, mc[0], mc[1], None) if (distBet >= c[i][2]): mDist = c[i][2] * percentToMove updatedPoint = mod_geo.point_from_distance_bearing( mod_geo.Location(c[i][0], c[i][1]), mDist, dir) else: updatedPoint = mod_geo.Location(mc[0], mc[1]) c[i][0], c[i][1] = updatedPoint.latitude, updatedPoint.longitude return c.mean(axis=0)
def crossSection(): ''' performs a cross section along a given track at minimum distance of every cxInt meters width of section is cxWidth points output are in right to left direction ''' gpx_file = open('..\..\samples\A67lt.gpx', "r") gpx = gpxpy.parse(gpx_file) gpxOpTmp = gpxpy.gpx.GPX() for tracks in gpx.tracks: gpx_track = gpxpy.gpx.GPXTrack() gpxOpTmp.tracks.append(gpx_track) for segment in tracks.segments: oldPoint = [] for point in segment.points: currPt = [point.latitude, point.longitude] if (oldPoint == []): oldPoint = currPt else: dist = mod_geo.distance(oldPoint[0], oldPoint[1], None, currPt[0], currPt[1], None, True) direction = mod_geo.get_bearing( mod_geo.Location(oldPoint[0], oldPoint[1]), mod_geo.Location(currPt[0], currPt[1])) # code to take cross section at regular distance [global] if (dist < cxInt): midpt = mod_geo.midpoint_cartesian(oldPoint, currPt) addCx(midpt, direction, gpx_track) else: ctr = 1 while True: if (ctr * cxInt > dist): break # breaks the while loop else: tgtPt = mod_geo.point_from_distance_bearing( mod_geo.Location(oldPoint[0], oldPoint[1]), ctr * cxInt, direction) addCx(tgtPt, direction, gpx_track) ctr = ctr + 1 oldPoint = currPt gpx_file.close() outfile = open('crossSection.gpx', 'w') outfile.write(gpxOpTmp.to_xml())
def is_break(self, index, seconds_from_start, next_image_start, effect_length, speedup_factor): """Checks if this image is last in recording break. Recording break is last image when we stopped recording and we moved more then 10 meters to next image. And takes more then 2*effect_length+2 time. 2 times effect_length is for zooming in/out map 2 seconds is for showing the map. Time is for actual time not recording time. """ gpx_start, index_start = self.get_geo_at(index, seconds_from_start) gpx_end, index_end = self.get_geo_at(index, next_image_start) distance = geo.distance(gpx_start.lat, gpx_start.lon, gpx_start.elevation, gpx_end.lat, gpx_end.lon, gpx_end.elevation) return (next_image_start - seconds_from_start) / speedup_factor > ( 2 * effect_length + 2) and distance > 10
def create_route_json(points, start_time, sample_rate, user_id, route_id): sample_rate_delta = datetime.timedelta(seconds=sample_rate) route_points = [] for i, j in zip(range(0, len(points) - 1), range(1, len(points))): data_id = i lat = points[i][0] lon = points[i][1] timey = start_time + (sample_rate_delta * i) timey = int(time.mktime(timey.timetuple())) * 1000 head = calc_heading(points[i], points[j]) dist_to_next = geo.distance(points[i][0], points[i][1], None, points[j][0], points[j][1], None) x = { "dataID": data_id, "latitude": lat, "longitude": lon, "time": timey, "userID": user_id, "routeID": route_id, "head": head, "speed": dist_to_next / sample_rate, "distanceToNextPoint": dist_to_next, "timediffToNextPoint": (sample_rate * 1000), "leadsTo": 0, "mappedToSpot": False, "spot": None, "closestSpotInfo": None, "pointInfoDBSAN": None, "processedDBSCAN": False, "clusterDBSCAN": None } route_points.append(x) trajectory = {"trajectory": [point for point in route_points]} return json.dumps(trajectory) \ .replace("False", "false") \ .replace("None", "null") \ .replace("]}", '],"user":'******',"routeID": ' + str(route_id)+', "spotProcessed":false}')
def get_pdist_matrix(results=None): query = """ MATCH (n:Spot) RETURN n.latitude AS latitude, n.longitude AS longitude, n.spotID as spotID """ if not results: results = query_neo4j(query) distances = dict() for i in results: distance_to_i = dict() p1_lat = i['latitude'] p1_lon = i['longitude'] for j in results: p2_lat = j['latitude'] p2_lon = j['longitude'] distance = geo.distance(p1_lat, p1_lon, None, p2_lat, p2_lon, None) distance_to_i[j['spotID']] = distance distances[i['spotID']] = distance_to_i return distances
def writeTrace(gpx, fno, fname, optype): ''' writes a blurred gpx output(s) input gpx : parsed gpx file fno : file number fname : file name optype: gpx|csv output blurred gpx output(s) ''' # device distribution here gen = num_gen([('d1', 0.01),('n1', 0.99)]) devName = gen.next() # set local device model here d = mdl.load() mdl.setDevice(devName) if (optype == "gpx"): # output file gpxOp = gpxpy.gpx.GPX() recTrack,recSeg,recPt = 0,0,0 log.write("reading trace") for track in gpx.tracks: gpx_track = gpxpy.gpx.GPXTrack() gpx_track.description = devName gpxOp.tracks.append(gpx_track) recTrack+=1 log.write("completed "+ str(round(recTrack * 100/gpx.tracks.__len__(), 2)) + "% of tracks\tfile: " + str(fno+1)) for segment in track.segments: gpx_segment = gpxpy.gpx.GPXTrackSegment() gpx_track.segments.append(gpx_segment) recSeg+=1 xo, yo = 0, 0 for point in segment.points: x, y = mdl.addErr(point.latitude, point.longitude) xe, ye = x - point.latitude, y - point.longitude xe, ye = ( xo * oec ) + (xe * (1 - oec)), ( yo * oec ) + (ye * (1 - oec)) x, y = xe + point.latitude, ye + point.longitude gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(x, y)) recPt+=1 xo, yo = xe, ye log.write("trace reading done") log.write("Tracks: " + str(recTrack) + "\tSegments: " + str(recSeg) + "\tPoints: " + str(recPt)) # write output # this can be threaded to increase speed # approx 1 - 1.5 sec requried to write depending on the size log.write("writing new trace") outfile = open('output/output_' + fname.replace('.gpx','') + '_' + str(fno) +'.gpx', 'w') outfile.write(gpxOp.to_xml()) outfile.close() log.write("new trace written") if (optype == "csv"): # get unique vehicles vehicles = gpx.vid.unique() withGPXFile = True gpxOp = gpxpy.gpx.GPX() for veh in vehicles: trace = gpx[gpx['vid']==veh] # sort according to sts trace = trace.sort_values(['sts']) xo, yo = 0, 0 log.write('vehicle: '+str(veh)) if withGPXFile: gpx_track = gpxpy.gpx.GPXTrack() gpx_track.description = 'v'+ str(veh) gpxOp.tracks.append(gpx_track) gpx_segment = gpxpy.gpx.GPXTrackSegment() gpx_track.segments.append(gpx_segment) for i, r in trace.iterrows(): lat, lon = trace.loc[i, "lat"], trace.loc[i, "lon"] x, y = mdl.addErr(lat, lon) xe, ye = x - lat, y - lon xe, ye = ( xo * oec ) + (xe * (1 - oec)), ( yo * oec ) + (ye * (1 - oec)) x, y = xe + lat, ye + lon acc = round(mdl_geo.distance(x, y, None, lat, lon, None) * 1.33) acc = 3 if acc <=3 else acc gpx.loc[i, "lat"] = x gpx.loc[i, "lon"] = y gpx.loc[i, "accuracy"] = acc if withGPXFile: gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(x, y)) xo, yo = xe, ye log.write("writing new trace") gpx.to_csv('output/' + fname.replace('.csv','') + '_' + str(fno) +'.csv', sep=',', index=False) if withGPXFile: outfile = open('output/output_' + fname.replace('.csv','') + '_' + str(fno) +'.gpx', 'w') outfile.write(gpxOp.to_xml()) outfile.close() log.write("new trace written") exeEndTime = time.time() exeTime = exeEndTime - exeStartTime log.write("Program execution time "+ "{0:.3f}".format(exeTime) + " sec")
def gpx_run(): gpx_file = open(dirName + fileList[fileName], 'r') gpx = gpxpy.parse(gpx_file) length = gpx.length_3d() print('Distance: %s' % length) # this is simly removing all points with no change in 3m gpx.reduce_points(2000, min_distance=3) # smoothin both gpx.smooth(vertical=True, horizontal=True) # and again smoothing just vertical gpx.smooth(vertical=True, horizontal=False) # Variables for power calculation mRider = 80 # mass in kg of the rider mBike = 7 # mass in kg of the bike M = mBike + mRider # mass in kg of the bike + rider h = 1.92 # hight in m of rider A = 0.0276 * h**0.725 * mRider**0.425 + 0.1647 # cross sectional area of the rider, bike and wheels Crr = 0.3386 / M # coefficient of rolling resistance # v = gear * RPM # velocity in m/s # Constants g = 9.8067 # acceleration in m/s^2 due to gravity p = 1.225 # air density in kg/m^3 at 15°C at sea level CD = 0.725 # coefficient of drag E = 1 # drive chain efficiency # datafild for calculation and plotting df = pd.DataFrame( columns=['lon', 'lat', 'alt', 'time', 'dist', 'ele', 'grad', 'pow']) for track in gpx.tracks: for segment in track.segments: for point_no, point in enumerate(segment.points): # print the current point information from GPX file # print('Point at ({0},{1}) -> {2} -> {3}' # .format(point.latitude, # point.longitude, # point.elevation, # point.time)) # calculate the distance between two point in 3D distance = mod_geo.distance( point.latitude, point.longitude, point.elevation, segment.points[point_no - 1].latitude, segment.points[point_no - 1].longitude, segment.points[point_no - 1].elevation) # calculate the elevation between points elevation = point.elevation - segment.points[point_no - 1].elevation # avoid division by 0 if distance == 0: gradient = 0 else: # calculate gradient between points gradient = elevation / distance * 100 """ the simulation is close to the calculator found here: https://www.gribble.org/cycling/power_v_speed.html gpx.py: Gradient: 3.00 % Power: 194.46 W gribble.org: Gradient: 3.00 % Power: 194.82 W """ # load gpx information into a datafild for # calculation and plotting df = df.append( { 'lon': point.longitude, 'lat': point.latitude, 'alt': point.elevation, 'time': point.time, 'dist': distance, 'ele': elevation, 'grad': gradient }, ignore_index=True) for index, row in df.iterrows(): # define cylce in 10th of wait cycle = 10 # recalculation of dynamic sleep time based on # the refreshed velocity for i in range(0, 10): # test with simulated velocity of 20km/h == 5.55 m/s v = 5.55 G = row['grad'] / 100 # output of power calculation P = E * (M * g * v * math.cos(math.atan(G)) * Crr + M * g * v * math.sin(math.atan(G)) + 1 / 2 * p * CD * A * v**3) print("Gradient: ", f"{row['grad']:4.2f}", "%", "Power: ", f"{P:4.2f}", "W") wait = row['dist'] / v / cycle print("Wait: ", f"{wait:4.2f}", "s") time.sleep(wait)
def test_distance(self): distance = mod_geo.distance(48.56806,21.43467, None, 48.599214,21.430878, None) print(distance) self.assertTrue(distance > 3450 and distance < 3500)
def distance_from(self, point: "Point") -> float: return geo.distance(point.latitude, point.longitude, None, self.latitude, self.longitude, None)
def gpx_run(): gpx_file = open(dirName + fileList[fileName], 'r') gpx = gpxpy.parse(gpx_file) length = gpx.length_3d() print('Distance: %s' % length) # this is simly removing all points with no change in 3m gpx.reduce_points(2000, min_distance=3) # smoothin both gpx.smooth(vertical=True, horizontal=True) # and again smoothing just vertical gpx.smooth(vertical=True, horizontal=False) # Variables for power calculation mRider = 80 # mass in kg of the rider mBike = 7 # mass in kg of the bike M = mBike + mRider # mass in kg of the bike + rider h = 1.92 # hight in m of rider A = 0.0276 * h**0.725 * mRider**0.425 + 0.1647 # cross sectional area of the rider, bike and wheels Crr = 0.3386 / M # coefficient of rolling resistance # v = gear * RPM # velocity in m/s # Constants g = 9.8067 # acceleration in m/s^2 due to gravity p = 1.225 # air density in kg/m^3 at 15°C at sea level CD = 0.725 # coefficient of drag E = 1 # drive chain efficiency # datafild for calculation and plotting df = pd.DataFrame(columns=['lon', 'lat', 'alt', 'time', 'dist', 'ele', 'grad', 'pow']) for track in gpx.tracks: for segment in track.segments: for point_no, point in enumerate(segment.points): # print the current point information from GPX file # print('Point at ({0},{1}) -> {2} -> {3}' # .format(point.latitude, # point.longitude, # point.elevation, # point.time)) # calculate the distance between two point in 3D distance = mod_geo.distance(point.latitude, point.longitude, point.elevation, segment.points[point_no - 1].latitude, segment.points[point_no - 1].longitude, segment.points[point_no - 1].elevation) # calculate the elevation between points elevation = point.elevation - segment.points[point_no - 1].elevation # avoid division by 0 if distance == 0: gradient = 0 else: # calculate gradient between points gradient = elevation / distance * 100 # test with simulated velocity of 20km/h == 5.55 m/s v = 5.55 # inputs for power calculation G = gradient/100 # output of power calculation P = E * (M * g * v * math.cos(math.atan(G)) * Crr + M * g * v * math.sin(math.atan(G)) + 1/2*p * CD * A * v**3) """ the simulation is close to the calculator found here: https://www.gribble.org/cycling/power_v_speed.html gpx.py: Gradient: 3.00 % Power: 194.46 W gribble.org: Gradient: 3.00 % Power: 194.82 W """ # this is the procesing time for each point to point (segment) # but what if the speed (RPM) changes in between this time? # this will not work, but good for simulation with constant speed # another for loop will be neccesarry with a sleep of 1sec for # recalculation of dynamic sleep time based on # the refreshed velocity # load gpx information into a datafild for calculation and plotting df = df.append({'lon': point.longitude, 'lat': point.latitude, 'alt': point.elevation, 'time': point.time, 'dist': distance, 'ele': elevation, 'grad': gradient, 'pow': P}, ignore_index=True) # time.sleep(wait) # start of plotting def make_patch_spines_invisible(ax): ax.set_frame_on(True) ax.patch.set_visible(False) for sp in ax.spines.values(): sp.set_visible(False) fig, host = plt.subplots() fig.subplots_adjust(right=0.75) par1 = host.twinx() par2 = host.twinx() # Offset the right spine of par2. The ticks and label have already been # placed on the right by twinx above. par2.spines["right"].set_position(("axes", 1.2)) # Having been created by twinx, par2 has its frame off, so the line of its # detached spine is invisible. First, activate the frame but make the patch # and spines invisible. make_patch_spines_invisible(par2) # Second, show the right spine. par2.spines["right"].set_visible(True) p1, = host.plot(df['time'], df['alt'], "b-", label="Altitude") p2, = par1.plot(df['time'], df['ele'], "r-", label="Elevation") p3, = par2.plot(df['time'], df['pow'], "g-", label="Power") # host.set_xlim(0, 2) # host.set_ylim(0, 2) # par1.set_ylim(0, 4) # par2.set_ylim(1, 65) host.set_xlabel("Time") host.set_ylabel("Altitude") par1.set_ylabel("Elevation") par2.set_ylabel("Power") host.yaxis.label.set_color(p1.get_color()) par1.yaxis.label.set_color(p2.get_color()) par2.yaxis.label.set_color(p3.get_color()) tkw = dict(size=4, width=1.5) host.tick_params(axis='y', colors=p1.get_color(), **tkw) par1.tick_params(axis='y', colors=p2.get_color(), **tkw) par2.tick_params(axis='y', colors=p3.get_color(), **tkw) host.tick_params(axis='x', **tkw) lines = [p1, p2, p3] host.legend(lines, [l.get_label() for l in lines]) plt.show() for index, row in df.iterrows(): print("Gradient: ", f"{row['grad']:4.2f}", "%", "Power: ", f"{row['pow']:4.2f}", "W") wait = row['dist'] / v print("Wait: ", f"{wait:4.2f}", "s") time.sleep(wait)
def test_distance(self): distance = mod_geo.distance(48.56806, 21.43467, None, 48.599214, 21.430878, None) print(distance) self.assertTrue(distance > 3450 and distance < 3500)
def segments(pathToCSV, outFileName): ''' takes simulation converted csv finds and writes crossSections into csv ''' print "generating segments" maxDist = 50 # meters f = pd.read_csv(pathToCSV) f['sts'] = pd.to_datetime(f.sts) f = f.sort_values(['vid', 'sts']) f = f.reset_index(drop=True) # to reindex the sorted values] f = f[f['lat'] > fence[0]] f = f[f['lat'] < fence[2]] f = f[f['lon'] > fence[1]] f = f[f['lon'] < fence[3]] # fence attached f = f.reset_index(drop=True) flen = len(f) traces = [] traceVal = 0 prevRow = None print "\nassigning trip ids\n" for i, r in f.iterrows(): sys.stdout.write("\r%d of %d %d%%" % (i, flen, ((i + 1) * 100 / flen))) sys.stdout.flush() if prevRow is not None: if (prevRow.vid == r.vid and not np.isnan(r.vid)): diff = r.sts - prevRow.sts if (diff.days != 0 or diff.seconds > timeThreshold): traceVal = traceVal + 1 elif (np.isnan(r.vid)): traces.append(-1) else: traceVal = traceVal + 1 if (not np.isnan(r.vid)): traces.append(traceVal) else: traces.append(traceVal) prevRow = r print '\n' f['tripID'] = traces #f = f.dropna() f.to_csv("int.csv", index=False) tr = (f.tripID.unique()).tolist() try: tr.remove(-1) except ValueError: "All valid traces" # use 0 for RU to DA # use 5 for DA to RU initVidTrace = f[f['tripID'] == 0] #random.choice(tr)] oldPt = None cx = pd.DataFrame() for i, r in initVidTrace.iterrows(): if oldPt is not None: direction = mod_geo.get_bearing( mod_geo.Location(oldPt.lat, oldPt.lon), mod_geo.Location(r.lat, r.lon)) if (direction != None): if ((r.lat > fence[0]) and (r.lat < fence[2]) and (r.lon > fence[1]) and (r.lon < fence[3])): dist = mod_geo.distance(oldPt.lat, oldPt.lon, None, r.lat, r.lon, None) if dist > maxDist: for t in range(0, int(dist / maxDist) + 1): midPt = mod_geo.point_from_distance_bearing( mod_geo.Location(oldPt.lat, oldPt.lon), maxDist * t, direction) lp, rp = mod_geo.point_from_distance_bearing( midPt, cxWidthBaseLine[0], direction + 90), mod_geo.point_from_distance_bearing( midPt, cxWidthBaseLine[1], direction - 90) cx = cx.append( { 'llat': lp.latitude, 'llon': lp.longitude, 'rlat': rp.latitude, 'rlon': rp.longitude, 'dir': direction, 'sid': len(cx) }, ignore_index=True) else: midPt = [ (oldPt.lat + r.lat) / 2, (oldPt.lon + r.lon) / 2 ] #simple cartesian midpoint lp, rp = mod_geo.point_from_distance_bearing( mod_geo.Location(midPt[0], midPt[1]), cxWidthBaseLine[0], direction + 90), mod_geo.point_from_distance_bearing( mod_geo.Location(midPt[0], midPt[1]), cxWidthBaseLine[1], direction - 90) cx = cx.append( { 'llat': lp.latitude, 'llon': lp.longitude, 'rlat': rp.latitude, 'rlon': rp.longitude, 'dir': direction, 'sid': len(cx) }, ignore_index=True) oldPt = r cx.to_csv(outFileName) print "written : " + outFileName return outFileName
df = pd.DataFrame( columns=['lon', 'lat', 'alt', 'time', 'dist', 'ele', 'grad', 'pow']) for track in gpx.tracks: for segment in track.segments: for point_no, point in enumerate(segment.points): # print the current point information from GPX file # print('Point at ({0},{1}) -> {2} -> {3}' # .format(point.latitude, # point.longitude, # point.elevation, # point.time)) # calculate the distance between two point in 3D distance = mod_geo.distance(point.latitude, point.longitude, point.elevation, segment.points[point_no - 1].latitude, segment.points[point_no - 1].longitude, segment.points[point_no - 1].elevation) # calculate the elevation between points elevation = point.elevation - segment.points[point_no - 1].elevation # avoid division by 0 if distance == 0: gradient = 0 else: # calculate gradient between points gradient = elevation / distance * 100 # test with simulated velocity of 20km/h == 5.55 m/s
def smoothengpx(gpx_file_smooth_data, algo, return_dict=None): infile = tempfile.NamedTemporaryFile('w', 1) infile.write(gpx_file_smooth_data) tempfilename = infile.name tempf = open(tempfilename, 'r') temp = tempf.read() lat, lon, ele, times = functions.getarraysfile(gpx_file_smooth_data) latsmooth = list(lat) lonsmooth = list(lon) elesmooth = list(ele) # this is the smoothening algorithm nsection = 7 for sectionstart in range(0, len(lon) - 1 - nsection): centslice = int(sectionstart + (nsection - 1) / 2) lonslice = lon[sectionstart:sectionstart + nsection] latslice = lat[sectionstart:sectionstart + nsection] eleslice = ele[sectionstart:sectionstart + nsection] timesslice = times[sectionstart:sectionstart + nsection] if int(algo) == 0: import numpy as np z = np.polyfit(lonslice, latslice, 1) p = np.poly1d(z) xp = np.linspace(lonslice[0], lonslice[nsection - 1], nsection) stepsize = (lonslice[nsection - 1] - lonslice[0]) / 100 dmin = 1000 for i in range(1, 100): d = mod_geo.distance(lonslice[0] + stepsize * i, p(lonslice[0] + stepsize * i), None, lonslice[(nsection - 1) / 2], latslice[(nsection - 1) / 2], None) if d < dmin: dmin = d lonsmooth[centslice] = lonslice[0] + stepsize * i latsmooth[centslice] = p(lonslice[0] + stepsize * i) if int(algo) == 1: lonsmooth[centslice] = sum(lonslice) / len(lonslice) latsmooth[centslice] = sum(latslice) / len(latslice) elesmooth[centslice] = sum(eleslice) / len(eleslice) # time limit on point average if int(algo) == 2: midstamp = datetime.strptime(timesslice[int((nsection - 1) / 2)], "%Y-%m-%dT%H:%M:%SZ") i = -1 while i < len(latslice) - 1: i = i + 1 thisstamp = datetime.strptime(timesslice[i], "%Y-%m-%dT%H:%M:%SZ") delta = thisstamp - midstamp delta = abs(delta) if delta.seconds > 6: latslice = latslice[:i] + latslice[i + 1:] lonslice = lonslice[:i] + lonslice[i + 1:] eleslice = eleslice[:i] + eleslice[i + 1:] timesslice = timesslice[:i] + timesslice[i + 1:] i = i - 1 lonsmooth[centslice] = sum(lonslice) / len(lonslice) latsmooth[centslice] = sum(latslice) / len(latslice) elesmooth[centslice] = sum(eleslice) / len(eleslice) distance = 0 pos = 0 i = -1 while i < len(lat) - 1: i = i + 1 tempf.seek(pos) line = tempf.readline() pos = tempf.tell() line = line + tempf.readline() linevalues = re.findall("\d+\.\d+", line) if (len(linevalues) == 3): thislat = float(linevalues[0]) thislon = float(linevalues[1]) newline = ' <trkpt lat="{0:.7f}" lon="{1:.7f}">\n <ele>{2:.1f}</ele>\n'.format( latsmooth[i], lonsmooth[i], elesmooth[i]) gpx_file_smooth_data = gpx_file_smooth_data.replace(line, newline) else: i = i - 1 # print(line,thislat,thislon) # if thislat == lat[i]: # if thislon == lon[i]: # if i > 0 : # distance = distance + mod_geo.distance(latsmooth[i],lonsmooth[i],elesmooth[i],latsmooth[i-1],lonsmooth[i-1],elesmooth[i-1]) # newline = ' <trkpt lat="{0:.7f}" lon="{1:.7f}">\n <ele>{2:.1f}</ele>\n'.format(latsmooth[i],lonsmooth[i],elesmooth[i]) # #newline = ' <trkpt lat="{0:.7f}" lon="{1:.7f}">\n <ele>{2:.1f}</ele>\n <extensions>\n <distance>{3:.2f}</distance>\n </extensions>\n'.format(latsmooth[i],lonsmooth[i],elesmooth[i],distance) # gpx_file_smooth_data = gpx_file_smooth_data.replace(line,newline) # break if return_dict == None: return gpx_file_smooth_data, lat, lon, ele, latsmooth, lonsmooth, elesmooth return_dict[0] = gpx_file_smooth_data return_dict[1] = lat return_dict[2] = lon return_dict[3] = ele return_dict[4] = latsmooth return_dict[5] = lonsmooth return_dict[6] = elesmooth
def create_gps_points(points, speed, sampling_rate, wrong_order, starttime): new_points = [] tdsr = datetime.timedelta(seconds=sampling_rate) timecounter = starttime for p1, p2 in zip(points[:-1], points[1:]): if not wrong_order: p1_lat = p1.point.latitude p1_lon = p1.point.longitude p2_lat = p2.point.latitude p2_lon = p2.point.longitude else: p1_lat = p1.point.longitude p1_lon = p1.point.latitude p2_lat = p2.point.longitude p2_lon = p2.point.latitude distance = geo.distance(p1_lat, p1_lon, None, p2_lat, p2_lon, None) numb_of_points = int(distance / (speed * sampling_rate)) new_points.append(Point(p1_lat, p1_lon, timecounter)) if numb_of_points == 0: timecounter = timecounter + tdsr continue if p1_lat > p2_lat: if p1_lon > p2_lon: diff_lat = abs(p1_lat - p2_lat) diff_lon = abs(p1_lon - p2_lon) for i in range(numb_of_points + 1): part_lat = (diff_lat / numb_of_points) * i new_lat = p1_lat - part_lat part_lon = (diff_lon / numb_of_points) * i new_lon = p1_lon - part_lon new_points.append(Point(new_lat, new_lon, timecounter)) timecounter = timecounter + tdsr else: diff_lat = abs(p1_lat - p2_lat) diff_lon = abs(p2_lon - p1_lon) for i in range(numb_of_points + 1): part_lat = (diff_lat / numb_of_points) * i new_lat = p1_lat - part_lat part_lon = (diff_lon / numb_of_points) * i new_lon = p1_lon + part_lon new_points.append(Point(new_lat, new_lon, timecounter)) timecounter = timecounter + tdsr else: if p1_lon > p2_lon: diff_lat = abs(p2_lat - p1_lat) diff_lon = abs(p1_lon - p2_lon) for i in range(numb_of_points + 1): part_lat = (diff_lat / numb_of_points) * i new_lat = p1_lat + part_lat part_lon = (diff_lon / numb_of_points) * i new_lon = p1_lon - part_lon new_points.append(Point(new_lat, new_lon, timecounter)) timecounter = timecounter + tdsr else: diff_lat = abs(p2_lat - p1_lat) diff_lon = abs(p2_lon - p1_lon) for i in range(numb_of_points + 1): part_lat = (diff_lat / numb_of_points) * i new_lat = p1_lat + part_lat part_lon = (diff_lon / numb_of_points) * i new_lon = p1_lon + part_lon new_points.append(Point(new_lat, new_lon, timecounter)) timecounter = timecounter + tdsr timecounter = timecounter + tdsr return new_points
def compareCenter(baseCL, inpCL, outFileName): base = pd.read_csv(baseCL) inpd = pd.read_csv(inpCL) op = pd.DataFrame() cxWidthBaseLine = [30, 30] oldR = None for ii, ir in inpd.iterrows(): if oldR is not None: midPt = mod_geo.Location((oldR.clat + ir.clat) / 2, (oldR.clon + ir.clon) / 2) direction = mod_geo.get_bearing( mod_geo.Location(oldR.clat, oldR.clon), mod_geo.Location(ir.clat, ir.clon)) lp, rp = mod_geo.point_from_distance_bearing( midPt, cxWidthBaseLine[0], direction - 90), mod_geo.point_from_distance_bearing( midPt, cxWidthBaseLine[1], direction + 90) A, B = Point(lp.latitude, lp.longitude), Point(rp.latitude, rp.longitude) C = None, None for bi, br in base.iterrows(): D = Point(br.clat, br.clon) if (C != (None, None)): poi = intersectionPoint(A, B, C, D) if poi != (None, None): dirMid = mod_geo.get_bearing( mod_geo.Location(oldR.clat, oldR.clon), mod_geo.Location(midPt.latitude, midPt.longitude)) dirTgt = mod_geo.get_bearing( mod_geo.Location(oldR.clat, oldR.clon), mod_geo.Location(poi[0], poi[1])) deltaDist = mod_geo.distance(midPt.latitude, midPt.longitude, None, poi[0], poi[1], None) if ((dirMid < dirTgt) or (abs(dirMid - dirTgt) > 180)): deltaDist = (-1) * deltaDist rowData = { 'sid': ir.sid, 'deltaDist': deltaDist, 'blat': br.clat, 'blon': br.clon, 'tlat': ir.clat, 'tlon': ir.clon, 'llat': lp.latitude, 'llon': lp.longitude, 'rlat': rp.latitude, 'rlon': rp.longitude, 'mlat': midPt.latitude, 'mlon': midPt.longitude, 'plat': poi[0], 'plon': poi[1] } op = op.append(rowData, ignore_index=True) C = D oldR = ir op.to_csv(outFileName) print "Written : " + outFileName plt.hist(op.deltaDist, bins=20) plt.savefig("__" + outFileName.replace("csv", "jpg")) plt.show() return outFileName
def clusterTypes(inFile, outFile, clusteringMethod): ''' clusteringMethod : in (kmeans, mbKMeans, meanshift, wkmeans) ''' f = pd.read_csv(inFile) # custom filter #f = f[f['sid']==108] f = f.dropna() sids = f.sid.unique() laneCenters = [] nlanes = 2 for sid in sids: sel = f[f['sid'] == sid] # change paramters for weighting... # dt = np.column_stack((sel.lat, sel.lon, sel.accuracy)) dt = np.column_stack((sel.lat, sel.lon, sel.accuracy**2)) # dt = np.column_stack((sel.lat, sel.lon)) # perform mandatory check to avoid unnecessary errors if len(dt) >= nlanes: if clusteringMethod.lower() == "kmeans": c = s.KMeans(n_clusters=nlanes) c.fit(dt) if clusteringMethod.lower() == "mbkmeans": c = s.MiniBatchKMeans(n_clusters=nlanes) with warnings.catch_warnings(): warnings.simplefilter("ignore") c.fit_predict(dt) if clusteringMethod.lower() == "meanshift": c = s.MeanShift() c.fit(dt) if clusteringMethod.lower() == "wkmeans": c = ck.Kmeans(dt, nlanes, metric=ck.weightedK, iterno=sid) centroids = c.cluster_centers_[:, [0, 1]] laneCenters.append([centroids, sid]) else: print "Not enough data yet across all sections!!!" sys.exit() oldCenterRd = f.lat.mean(), f.lon.mean() tmp = [] offsetList = [] for i in laneCenters: sel = f[f['sid'] == i[1]] # since its a pair centroids, sid currCenter = sel.lat.mean(), sel.lon.mean() dir = mod_geo.get_bearing( mod_geo.Location(oldCenterRd[0], oldCenterRd[1]), mod_geo.Location(currCenter[0], currCenter[1])) dt = i[0].ravel() for indx, irow in sel.iterrows(): offset = 0 if oldCenterRd is not None: ndir = mod_geo.get_bearing( mod_geo.Location(oldCenterRd[0], oldCenterRd[1]), mod_geo.Location(irow.lat, irow.lon)) offset = mod_geo.distance(currCenter[0], currCenter[1], None, irow.lat, irow.lon, None) if ndir < dir: offset = offset * (-1) offsetList.append(offset) for j in range(0, nlanes): ll = dt[j * 2], dt[(j * 2) + 1] dirPt = mod_geo.get_bearing( mod_geo.Location(oldCenterRd[0], oldCenterRd[1]), mod_geo.Location(ll[0], ll[1])) dist = mod_geo.distance(ll[0], ll[1], None, currCenter[0], currCenter[1], None) direction = dirPt - dir tmp.append({ 'lat': ll[0], 'lon': ll[1], 'lane': direction, 'sid': sel.sid.unique()[0] }) oldCenterRd = currCenter f['offset'] = offsetList #f.to_csv("offsets.csv",index=False) k = pd.DataFrame(tmp) k = k.sort_values(['sid']) #k.to_csv(inFile.split('.')[0]+"__k.csv") sids = k.sid.unique() result = pd.DataFrame() tmpDict = {} for sid in sids: sel = k[k['sid'] == sid] sel = sel.sort_values(['lane']) sel = sel.reset_index(drop=True) prevLane = None for i, r in sel.iterrows(): tmpDict['c' + str(i) + '_lat'] = r.lat tmpDict['c' + str(i) + '_lon'] = r.lon if prevLane is not None: delta = mod_geo.distance(prevLane.lat, prevLane.lon, None, r.lat, r.lon, None) tmpDict['del_' + str(i - 1) + str(i)] = delta prevLane = r selDet = f[f['sid'] == sid] tmpDict['_sid'] = sid tmpDict['var'] = selDet.offset.var() tmpDict['std'] = selDet.offset.std() tmpDict['mean'] = np.abs(selDet).offset.mean() result = result.append(tmpDict, ignore_index=True) result.to_csv(outFile, index=False) print "Written : " + outFile return outFile