def buildTimeCoords(self, downsample=False): currentPositions = self.getPositions(downsample) if currentPositions.count() < 2: return if self.coordGroups: return coords = [] times = [] lastPos = None breakDist = settings.GEOCAM_TRACK_START_NEW_LINE_DISTANCE_METERS for pos in currentPositions: if lastPos and breakDist is not None: diff = geomath.calculateDiffMeters( [lastPos.longitude, lastPos.latitude], [pos.longitude, pos.latitude]) dist = geomath.getLength(diff) if dist > breakDist: # start new line string if coords: self.coordGroups.append(coords) coords = [] self.timesGroups.append(times) times = [] coords.append(pos.coords_array) times.append(pos.timestamp) lastPos = pos self.coordGroups.append(coords) self.timesGroups.append(times)
def transformSegment(self, segment, tsequence, context): derivedInfo = segment.derivedInfo if derivedInfo: distanceMeters = derivedInfo['distanceMeters'] durationSeconds = derivedInfo['durationSeconds'] else: plon, plat = context.prevStation.geometry['coordinates'] nlon, nlat = context.nextStation.geometry['coordinates'] distanceMeters = geomath.getLength( geomath.calculateDiffMeters([plon, plat], [nlon, nlat])) speed = context.plan._objDict['defaultSpeed'] try: speed = segment._objDict['hintedSpeed'] except: pass durationSeconds = (distanceMeters / speed) segment.id = segment.id[-(len(segment.id) - segment.id.rfind('_') - 1):] return { 'id': segment.id, 'name': segment.name, 'type': settings.XGDS_PLANNER_SEGMENT_MONIKER, 'commands': tsequence, 'notes': segment.notes, 'distanceMeters': distanceMeters, 'durationSeconds': durationSeconds }
def buildTimeCoords(self, downsample=False): currentPositions = self.getPositions(downsample) if currentPositions.count() < 2: return if self.coordGroups: return coords = [] times = [] lastPos = None breakDist = settings.GEOCAM_TRACK_START_NEW_LINE_DISTANCE_METERS for pos in currentPositions: if lastPos and breakDist is not None: diff = geomath.calculateDiffMeters([lastPos.longitude, lastPos.latitude], [pos.longitude, pos.latitude]) dist = geomath.getLength(diff) if dist > breakDist: # start new line string if coords: self.coordGroups.append(coords) coords = [] self.timesGroups.append(times) times = [] coords.append(pos.coords_array) times.append(pos.timestamp) lastPos = pos self.coordGroups.append(coords) self.timesGroups.append(times)
def transformSegment(self, segment, tsequence, context): plon, plat = context.prevStation.geometry['coordinates'] nlon, nlat = context.nextStation.geometry['coordinates'] meters = getLength(calculateDiffMeters([plon, plat], [nlon, nlat])) speed = context.plan._objDict['defaultSpeed'] try: speed = segment._objDict['hintedSpeed'] except: pass segmentDuration = self.DRIVE_TIME_MULTIPLIER * ( meters / speed) + self.ROTATION_ADDITION name = "Segment %02d%s" % (self.segmentCounter, '' if segment.name is None else ' ' + segment.name) notes = segment.notes if notes: notes = '"' + notes + '"' activity = self.makeActivity("Segment", segment.id, name, segmentDuration, notes, 'ffa300') self.startTime = self.startTime + datetime.timedelta( seconds=segmentDuration) self.segmentCounter = self.segmentCounter + 1 return activity
def getTrackCsv(request, trackName, fname=None): if not trackName: return HttpResponseBadRequest('trackName is required') if not fname: fname = trackName + '.csv' track = TRACK_MODEL.get().objects.get(name=trackName) positions = PAST_POSITION_MODEL.get().objects.filter(track=track). \ order_by('timestamp') startTimeEpoch = request.GET.get('start') if startTimeEpoch: startTime = datetime.datetime.utcfromtimestamp(float(startTimeEpoch)) positions = positions.filter(timestamp__gte=startTime) endTimeEpoch = request.GET.get('end') if endTimeEpoch: endTime = datetime.datetime.utcfromtimestamp(float(endTimeEpoch)) positions = positions.filter(timestamp__lte=endTime) hasHeading = issubclass(PAST_POSITION_MODEL.get(), HeadingMixin) out = StringIO() topRow = '"epoch timestamp","timestamp","latitude","longitude","distance (m)","capped distance (m)","cumulative distance (m)"\n' if hasHeading: topRow = '"epoch timestamp","timestamp","latitude","longitude","heading","distance (m)","capped distance (m)","cumulative distance (m)"\n' out.write(topRow) prevPos = None cumDist = 0 for pos in positions: epoch = calendar.timegm(pos.timestamp.timetuple()) timestamp = pos.timestamp.isoformat() + 'Z' if prevPos: diff = geomath.calculateDiffMeters([pos.longitude, pos.latitude], [prevPos.longitude, prevPos.latitude]) dist = geomath.getLength(diff) else: dist = 0 if (settings.GEOCAM_TRACK_START_NEW_LINE_DISTANCE_METERS and dist > settings.GEOCAM_TRACK_START_NEW_LINE_DISTANCE_METERS): cappedDist = 0 else: cappedDist = dist cumDist += cappedDist if hasHeading: if not pos.heading: out.write('%d,"%s",%.6f,%.6f,%s,%.2f,%.2f,%.2f\n' % (epoch, timestamp, pos.latitude, pos.longitude, '', dist, cappedDist, cumDist)) else: out.write('%d,"%s",%.6f,%.6f,%.2f,%.2f,%.2f,%.2f\n' % (epoch, timestamp, pos.latitude, pos.longitude, pos.heading, dist, cappedDist, cumDist)) else: out.write('%d,"%s",%.6f,%.6f,%.2f,%.2f,%.2f\n' % (epoch, timestamp, pos.latitude, pos.longitude, dist, cappedDist, cumDist)) prevPos = pos response = HttpResponse(out.getvalue(), content_type='text/csv') response['Content-disposition'] = 'attachment; filename=%s' % fname return response
def transformSegment(self, segment, tsequence, context): plon, plat = context.prevStation.geometry['coordinates'] nlon, nlat = context.nextStation.geometry['coordinates'] meters = getLength(calculateDiffMeters([plon, plat], [nlon, nlat])) speed = context.plan._objDict['defaultSpeed'] try: speed = segment._objDict['hintedSpeed'] except: pass segmentDuration = self.DRIVE_TIME_MULTIPLIER * (meters / speed) + self.ROTATION_ADDITION name = "Segment %02d%s" % (self.segmentCounter, '' if segment.name is None else ' ' + segment.name) notes = segment.notes if notes: notes = '"' + notes + '"' activity = self.makeActivity("Segment", segment.id, name, segmentDuration, notes, 'ffa300') self.startTime = self.startTime + datetime.timedelta(seconds=segmentDuration) self.segmentCounter = self.segmentCounter + 1 return activity
def transformSegment(self, segment, tsequence, context): derivedInfo = segment.derivedInfo; if derivedInfo: distanceMeters = derivedInfo['distanceMeters'] durationSeconds = derivedInfo['durationSeconds'] else: plon, plat = context.prevStation.geometry['coordinates'] nlon, nlat = context.nextStation.geometry['coordinates'] distanceMeters = geomath.getLength(geomath.calculateDiffMeters([plon, plat], [nlon, nlat])) speed = context.plan._objDict['defaultSpeed'] try: speed = segment._objDict['hintedSpeed'] except: pass durationSeconds = (distanceMeters / speed) segment.id = segment.id[-(len(segment.id)-segment.id.rfind('_')-1):] return {'id': segment.id, 'name': segment.name, 'type': settings.XGDS_PLANNER2_SEGMENT_MONIKER, 'commands': tsequence, 'notes': segment.notes, 'distanceMeters': distanceMeters, 'durationSeconds': durationSeconds}
def getDistance(self, pos): diff = geomath.calculateDiffMeters([self.longitude, self.latitude], [pos.longitude, pos.latitude]) return geomath.getLength(diff)
def writeTrackKml(self, out, positions=None, lineStyle=None, urlFn=None, animated=False): if positions is None: positions = self.getPositions() if lineStyle is None: lineStyle = self.lineStyle n = positions.count() if n == 0: return if n < 2: # kml LineString requires 2 or more positions return out.write("<Folder>\n") out.write(""" <Placemark> <name>%(name)s path</name> """ % dict(name=self.name)) if lineStyle: out.write("<Style>") lineStyle.writeKml(out, urlFn=urlFn, color=self.getLineColor()) out.write("</Style>") if animated: if self.iconStyle: out.write("<Style id=\"%s\">\n" % self.iconStyle.pk) self.iconStyle.writeKml(out, 0, urlFn=urlFn, color=self.getLineColor()) out.write("</Style>\n") out.write(""" <MultiGeometry> <LineString> <tessellate>1</tessellate> <coordinates> """) lastPos = None breakDist = settings.GEOCAM_TRACK_START_NEW_LINE_DISTANCE_METERS for pos in positions: if lastPos and breakDist is not None: diff = geomath.calculateDiffMeters( [lastPos.longitude, lastPos.latitude], [pos.longitude, pos.latitude]) dist = geomath.getLength(diff) if dist > breakDist: # start new line string out.write(""" </coordinates> </LineString> <LineString> <tessellate>1</tessellate> <coordinates> """) pos.writeCoordinatesKml(out) lastPos = pos out.write(""" </coordinates> </LineString> </MultiGeometry> </Placemark> """) if animated: self.writeAnimatedPlacemarks(out, list(positions)) out.write("</Folder>\n")
def writeTrackKml(self, out, positions=None, lineStyle=None, urlFn=None, animated=False): if positions is None: positions = self.getPositions() if lineStyle is None: lineStyle = self.lineStyle n = positions.count() if n == 0: return if n < 2: # kml LineString requires 2 or more positions return out.write("<Folder>\n") out.write(""" <Placemark> <name>%(name)s path</name> """ % dict(name=self.name)) if lineStyle: out.write("<Style>") lineStyle.writeKml(out, urlFn=urlFn, color=self.getLineColor()) out.write("</Style>") if animated: if self.iconStyle: out.write("<Style id=\"%s\">\n" % self.iconStyle.pk) self.iconStyle.writeKml(out, 0, urlFn=urlFn, color=self.getLineColor()) out.write("</Style>\n") out.write(""" <MultiGeometry> <LineString> <tessellate>1</tessellate> <coordinates> """) lastPos = None breakDist = settings.GEOCAM_TRACK_START_NEW_LINE_DISTANCE_METERS for pos in positions: if lastPos and breakDist is not None: diff = geomath.calculateDiffMeters([lastPos.longitude, lastPos.latitude], [pos.longitude, pos.latitude]) dist = geomath.getLength(diff) if dist > breakDist: # start new line string out.write(""" </coordinates> </LineString> <LineString> <tessellate>1</tessellate> <coordinates> """) pos.writeCoordinatesKml(out) lastPos = pos out.write(""" </coordinates> </LineString> </MultiGeometry> </Placemark> """) if animated: self.writeAnimatedPlacemarks(out, list(positions)) out.write("</Folder>\n")