def transformStation(self, station, tsequence, context): bearing = 0 if context.nextStation: plon, plat = station.geometry['coordinates'] nlon, nlat = context.nextStation.geometry['coordinates'] diff = geomath.calculateDiffMeters([nlon, nlat], [plon, plat]) bearing = geomath.getBearingDegrees(diff) derivedInfo = station.derivedInfo durationSeconds = 0 #TODO calculate if derivedInfo: durationSeconds = derivedInfo['durationSeconds'] station.id = station.id[-(len(station.id) - station.id.rfind('_') - 1):] result = { 'id': station.id, 'name': station.name, 'type': settings.XGDS_PLANNER_STATION_MONIKER, 'commands': tsequence, 'geometry': self.getStationGeometry(station, context), 'notes': station.notes, 'tolerance': station.tolerance, 'durationSeconds': durationSeconds, 'bearing': bearing } if hasattr(station, 'heading'): result['heading'] = station.heading if hasattr(station, 'depth'): result['depth'] = station.depth return result
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 transformStation(self, station, tsequence, context): bearing = 0 if context.nextStation: plon, plat = station.geometry['coordinates'] nlon, nlat = context.nextStation.geometry['coordinates'] diff = geomath.calculateDiffMeters([nlon, nlat], [plon, plat]) bearing = geomath.getBearingDegrees(diff) derivedInfo = station.derivedInfo; durationSeconds = 0 #TODO calculate if derivedInfo: durationSeconds = derivedInfo['durationSeconds'] station.id = station.id[-(len(station.id)-station.id.rfind('_')-1):] return {'id': station.id, 'name': station.name, 'type': settings.XGDS_PLANNER2_STATION_MONIKER, 'commands': tsequence, 'geometry': station.geometry, 'notes': station.notes, 'tolerance': station.tolerance, 'userDuration': station.userDuration, 'durationSeconds': durationSeconds, 'bearing': bearing}
def getLocationCentroid(trackName, start, end): """ for a track, start time and end time get the centroid """ track = TRACK_MODEL.get().objects.get(name=trackName) if not track: return None # get all the lats and longs over duration and find average. positions = POSITION_MODEL.get().objects.filter(track=track, timestamp__gte=start, timestamp__lte=end) if not positions: return None # then figure out the distribution centroid = Centroid() # iterate through count = 1 totalLat = 0 totalLon = 0 for position in positions: totalLat += position.latitude totalLon += position.longitude count += 1 centroid.latitude = totalLat / count centroid.longitude = totalLon / count # now figure out the standard deviation distance = 0 for position in positions: distance += geomath.calculateDiffMeters([position.longitude, position.latitude], [centroid.longitude, centroid.latitude]) distance = distance / len(positions) centroid.distance = math.sqrt(distance) return centroid
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")