//TODO: C Code. static functions are not good if we plan to have a test for them. static bool merge_locations_into_dives(void) { int i, nr = 0, changed = 0; struct dive *gpsfix, *last_named_fix = NULL, *dive; sort_table(&gps_location_table); for_each_gps_location (i, gpsfix) { if (is_automatic_fix(gpsfix)) { dive = find_dive_including(gpsfix->when); if (dive && !dive_has_gps_location(dive)) { #if DEBUG_WEBSERVICE struct tm tm; utc_mkdate(gpsfix->when, &tm); printf("found dive named %s @ %04d-%02d-%02d %02d:%02d:%02d\n", gpsfix->location, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); #endif changed++; copy_gps_location(gpsfix, dive); } } else { if (last_named_fix && dive_within_time_range(last_named_fix, gpsfix->when, SAME_GROUP)) { nr++; } else { nr = 1; last_named_fix = gpsfix; } dive = find_dive_n_near(gpsfix->when, nr, SAME_GROUP); if (dive) { if (!dive_has_gps_location(dive)) { copy_gps_location(gpsfix, dive); changed++; } if (!dive->location) { dive->location = strdup(gpsfix->location); changed++; } } else { struct tm tm; utc_mkdate(gpsfix->when, &tm); #if DEBUG_WEBSERVICE printf("didn't find dive matching gps fix named %s @ %04d-%02d-%02d %02d:%02d:%02d\n", gpsfix->location, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); #endif } } } return changed > 0; }
//TODO: C Code. static functions are not good if we plan to have a test for them. static bool merge_locations_into_dives(void) { int i, j, tracer=0, changed=0; struct dive *gpsfix, *nextgpsfix, *dive; sort_table(&gps_location_table); for_each_dive (i, dive) { if (!dive_has_gps_location(dive)) { for (j = tracer; (gpsfix = get_gps_location(j, &gps_location_table)) !=NULL; j++) { if (dive_within_time_range (dive, gpsfix->when, SAME_GROUP)) { /* * If position is fixed during dive. This is the good one. * Asign and mark position, and end gps_location loop */ if ((dive->when <= gpsfix->when && gpsfix->when <= dive->when + dive->duration.seconds)) { copy_gps_location(gpsfix,dive); changed++; tracer = j; break; } else { /* * If it is not, check if there are more position fixes in SAME_GROUP range */ if ((nextgpsfix = get_gps_location(j+1,&gps_location_table)) && dive_within_time_range (dive, nextgpsfix->when, SAME_GROUP)) { /* * If distance from gpsfix to end of dive is shorter than distance between * gpsfix and nextgpsfix, gpsfix is the good one. Asign, mark and end loop. * If not, simply fail and nextgpsfix will be evaluated in next iteration. */ if ((dive->when + dive->duration.seconds - gpsfix->when) < (nextgpsfix->when - gpsfix->when)) { copy_gps_location(gpsfix,dive); tracer = j; break; } /* * If no more positions in range, the actual is the one. Asign, mark and end loop. */ } else { copy_gps_location(gpsfix,dive); changed++; tracer = j; break; } } } else { /* If position is out of SAME_GROUP range and in the future, mark position for * next dive iteration and end the gps_location loop */ if (gpsfix->when >= dive->when + dive->duration.seconds + SAME_GROUP) { tracer = j; break; } } } } } return changed > 0; }
void GlobeGPS::mouseClicked(qreal lon, qreal lat, GeoDataCoordinates::Unit unit) { GeoDataCoordinates here(lon, lat, unit); long lon_udeg = rint(1000000 * here.longitude(GeoDataCoordinates::Degree)); long lat_udeg = rint(1000000 * here.latitude(GeoDataCoordinates::Degree)); // distance() is in km above the map. // We're going to use that to decide how // approximate the dives have to be. // // Totally arbitrarily I say that 1km // distance means that we can resolve // to about 100m. Which in turn is about // 1000 udeg. // // Trigonometry is hard, but sin x == x // for small x, so let's just do this as // a linear thing. long resolve = rint(distance() * 1000); int idx; struct dive *dive; bool clear = !(QApplication::keyboardModifiers() && Qt::ControlModifier); bool toggle = !clear; bool first = true; for_each_dive(idx, dive) { long lat_diff, lon_diff; if (!dive_has_gps_location(dive)) continue; lat_diff = labs(dive->latitude.udeg - lat_udeg); lon_diff = labs(dive->longitude.udeg - lon_udeg); if (lat_diff > 180000000) lat_diff = 360000000 - lat_diff; if (lon_diff > 180000000) lon_diff = 180000000 - lon_diff; if (lat_diff > resolve || lon_diff > resolve) continue; if (clear) { mainWindow()->dive_list()->unselectDives(); clear = false; } mainWindow()->dive_list()->selectDive(dive, first, toggle); first = false; }
//TODO: C Code. static functions are not good if we plan to have a test for them. static bool merge_locations_into_dives(void) { int i, j, tracer=0, changed=0; struct dive *gpsfix, *nextgpsfix, *dive; sort_table(&gps_location_table); for_each_dive (i, dive) { if (!dive_has_gps_location(dive)) { for (j = tracer; (gpsfix = get_dive_from_table(j, &gps_location_table)) !=NULL; j++) { if (time_during_dive_with_offset(dive, gpsfix->when, SAME_GROUP)) { qDebug() << "processing gpsfix @" << get_dive_date_string(gpsfix->when) << "which is withing six hours of dive from" << get_dive_date_string(dive->when) << "until" << get_dive_date_string(dive->when + dive->duration.seconds); /* * If position is fixed during dive. This is the good one. * Asign and mark position, and end gps_location loop */ if (time_during_dive_with_offset(dive, gpsfix->when, 0)) { qDebug() << "gpsfix is during the dive, pick that one"; copy_gps_location(gpsfix, dive); changed++; tracer = j; break; } else { /* * If it is not, check if there are more position fixes in SAME_GROUP range */ if ((nextgpsfix = get_dive_from_table(j + 1, &gps_location_table)) && time_during_dive_with_offset(dive, nextgpsfix->when, SAME_GROUP)) { qDebug() << "look at the next gps fix @" << get_dive_date_string(nextgpsfix->when); /* first let's test if this one is during the dive */ if (time_during_dive_with_offset(dive, nextgpsfix->when, 0)) { qDebug() << "which is during the dive, pick that one"; copy_gps_location(nextgpsfix, dive); changed++; tracer = j + 1; break; } /* we know the gps fixes are sorted; if they are both before the dive, ignore the first, * if theay are both after the dive, take the first, * if the first is before and the second is after, take the closer one */ if (nextgpsfix->when < dive->when) { qDebug() << "which is closer to the start of the dive, do continue with that"; continue; } else if (gpsfix->when > dive->when + dive->duration.seconds) { qDebug() << "which is even later after the end of the dive, so pick the previous one"; copy_gps_location(gpsfix, dive); changed++; tracer = j; break; } else { /* ok, gpsfix is before, nextgpsfix is after */ if (dive->when - gpsfix->when <= nextgpsfix->when - (dive->when + dive->duration.seconds)) { qDebug() << "pick the one before as it's closer to the start"; copy_gps_location(gpsfix, dive); changed++; tracer = j; break; } else { qDebug() << "pick the one after as it's closer to the start"; copy_gps_location(nextgpsfix, dive); changed++; tracer = j + 1; break; } } /* * If no more positions in range, the actual is the one. Asign, mark and end loop. */ } else { qDebug() << "which seems to be the best one for this dive, so pick it"; copy_gps_location(gpsfix, dive); changed++; tracer = j; break; } } } else { /* If position is out of SAME_GROUP range and in the future, mark position for * next dive iteration and end the gps_location loop */ if (gpsfix->when >= dive->when + dive->duration.seconds + SAME_GROUP) { tracer = j; break; } } } } } return changed > 0; }
QVariant DiveItem::data(int column, int role) const { QVariant retVal; struct dive *dive = get_dive_by_uniq_id(diveId); if (!dive) return QVariant(); switch (role) { case Qt::TextAlignmentRole: retVal = dive_table_alignment(column); break; case DiveTripModel::SORT_ROLE: Q_ASSERT(dive != NULL); switch (column) { case NR: retVal = (qulonglong)dive->when; break; case DATE: retVal = (qulonglong)dive->when; break; case RATING: retVal = dive->rating; break; case DEPTH: retVal = dive->maxdepth.mm; break; case DURATION: retVal = dive->duration.seconds; break; case TEMPERATURE: retVal = dive->watertemp.mkelvin; break; case TOTALWEIGHT: retVal = total_weight(dive); break; case SUIT: retVal = QString(dive->suit); break; case CYLINDER: retVal = QString(dive->cylinder[0].type.description); break; case GAS: retVal = nitrox_sort_value(dive); break; case SAC: retVal = dive->sac; break; case OTU: retVal = dive->otu; break; case MAXCNS: retVal = dive->maxcns; break; case LOCATION: retVal = QString(get_dive_location(dive)); break; } break; case Qt::DisplayRole: Q_ASSERT(dive != NULL); switch (column) { case NR: retVal = dive->number; break; case DATE: retVal = displayDate(); break; case DEPTH: retVal = displayDepth(); break; case DURATION: retVal = displayDuration(); break; case TEMPERATURE: retVal = displayTemperature(); break; case TOTALWEIGHT: retVal = displayWeight(); break; case SUIT: retVal = QString(dive->suit); break; case CYLINDER: retVal = QString(dive->cylinder[0].type.description); break; case SAC: retVal = displaySac(); break; case OTU: retVal = dive->otu; break; case MAXCNS: retVal = dive->maxcns; break; case LOCATION: retVal = QString(get_dive_location(dive)); break; case GAS: const char *gas_string = get_dive_gas_string(dive); retVal = QString(gas_string); free((void*)gas_string); break; } break; case Qt::DecorationRole: if (column == LOCATION) if (dive_has_gps_location(dive)) { IconMetrics im = defaultIconMetrics(); retVal = QIcon(":satellite").pixmap(im.sz_small, im.sz_small); } break; case Qt::ToolTipRole: switch (column) { case NR: retVal = tr("#"); break; case DATE: retVal = tr("Date"); break; case RATING: retVal = tr("Rating"); break; case DEPTH: retVal = tr("Depth(%1)").arg((get_units()->length == units::METERS) ? tr("m") : tr("ft")); break; case DURATION: retVal = tr("Duration"); break; case TEMPERATURE: retVal = tr("Temp(%1%2)").arg(UTF8_DEGREE).arg((get_units()->temperature == units::CELSIUS) ? "C" : "F"); break; case TOTALWEIGHT: retVal = tr("Weight(%1)").arg((get_units()->weight == units::KG) ? tr("kg") : tr("lbs")); break; case SUIT: retVal = tr("Suit"); break; case CYLINDER: retVal = tr("Cyl"); break; case GAS: retVal = tr("Gas"); break; case SAC: const char *unit; get_volume_units(0, NULL, &unit); retVal = tr("SAC(%1)").arg(QString(unit).append(tr("/min"))); break; case OTU: retVal = tr("OTU"); break; case MAXCNS: retVal = tr("Max CNS"); break; case LOCATION: retVal = tr("Location"); break; } break; } if (role == DiveTripModel::STAR_ROLE) { Q_ASSERT(dive != NULL); retVal = dive->rating; } if (role == DiveTripModel::DIVE_ROLE) { retVal = QVariant::fromValue<void *>(dive); } if (role == DiveTripModel::DIVE_IDX) { Q_ASSERT(dive != NULL); retVal = get_divenr(dive); } return retVal; }
bool GpsLocation::applyLocations() { int i; bool changed = false; int last = 0; int cnt = m_trackers.count(); if (cnt == 0) return false; // create a table with the GPS information QList<struct gpsTracker> gpsTable = m_trackers.values(); // now walk the dive table and see if we can fill in missing gps data struct dive *d; for_each_dive(i, d) { if (dive_has_gps_location(d)) continue; for (int j = last; j < cnt; j++) { if (time_during_dive_with_offset(d, gpsTable[j].when, SAME_GROUP)) { if (verbose) qDebug() << "processing gpsFix @" << get_dive_date_string(gpsTable[j].when) << "which is withing six hours of dive from" << get_dive_date_string(d->when) << "until" << get_dive_date_string(dive_endtime(d)); /* * If position is fixed during dive. This is the good one. * Asign and mark position, and end gps_location loop */ if (time_during_dive_with_offset(d, gpsTable[j].when, 0)) { if (verbose) qDebug() << "gpsFix is during the dive, pick that one"; SET_LOCATION(d, gpsTable[j], j); break; } else { /* * If it is not, check if there are more position fixes in SAME_GROUP range */ if (j + 1 < cnt && time_during_dive_with_offset(d, gpsTable[j+1].when, SAME_GROUP)) { if (verbose) qDebug() << "look at the next gps fix @" << get_dive_date_string(gpsTable[j+1].when); /* we know the gps fixes are sorted; if they are both before the dive, ignore the first, * if theay are both after the dive, take the first, * if the first is before and the second is after, take the closer one */ if (gpsTable[j+1].when < d->when) { if (verbose) qDebug() << "which is closer to the start of the dive, do continue with that"; continue; } else if (gpsTable[j].when > dive_endtime(d)) { if (verbose) qDebug() << "which is even later after the end of the dive, so pick the previous one"; SET_LOCATION(d, gpsTable[j], j); break; } else { /* ok, gpsFix is before, nextgpsFix is after */ if (d->when - gpsTable[j].when <= gpsTable[j+1].when - dive_endtime(d)) { if (verbose) qDebug() << "pick the one before as it's closer to the start"; SET_LOCATION(d, gpsTable[j], j); break; } else { if (verbose) qDebug() << "pick the one after as it's closer to the start"; SET_LOCATION(d, gpsTable[j + 1], j + 1); break; } } /* * If no more positions in range, the actual is the one. Asign, mark and end loop. */ } else { if (verbose) qDebug() << "which seems to be the best one for this dive, so pick it"; SET_LOCATION(d, gpsTable[j], j); break; } } } else { /* If position is out of SAME_GROUP range and in the future, mark position for * next dive iteration and end the gps_location loop */ if (gpsTable[j].when >= dive_endtime(d) + SAME_GROUP) { last = j; break; } } } } if (changed) mark_divelist_changed(true); return changed; }