inline void GlideComputerAirData::NextLegEqThermal(const NMEAInfo &basic, DerivedInfo &calculated, const ComputerSettings &settings) { const GeoVector vector_remaining = calculated.task_stats.current_leg.vector_remaining; const GeoVector next_leg_vector = calculated.task_stats.current_leg.next_leg_vector; if(!next_leg_vector.IsValid() || !vector_remaining.IsValid() || !calculated.wind_available) { // Assign a negative value to invalidate the result calculated.next_leg_eq_thermal = fixed(-1); return; } // Calculate wind component on current and next legs const fixed wind_comp = calculated.wind.norm * (calculated.wind.bearing - vector_remaining.bearing).fastcosine(); const fixed next_comp = calculated.wind.norm * (calculated.wind.bearing - next_leg_vector.bearing).fastcosine(); calculated.next_leg_eq_thermal = settings.polar.glide_polar_task.GetNextLegEqThermal(wind_comp, next_comp); }
void UpdateInfoBoxNextDistanceNominal(InfoBoxData &data) { const Waypoint* way_point = protected_task_manager != NULL ? protected_task_manager->GetActiveWaypoint() : NULL; if (!way_point) { data.SetInvalid(); return; } const NMEAInfo &basic = CommonInterface::Basic(); const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!task_stats.task_valid || !basic.location_available) { data.SetInvalid(); return; } const GeoVector vector(basic.location, way_point->location); if (!vector.IsValid()) { data.SetInvalid(); return; } // Set Value data.SetValueFromDistance(vector.distance); data.SetValueColor(task_stats.inside_oz ? 3 : 0); data.SetComment(vector.bearing); }
inline void RouteComputer::TerrainWarning(const MoreData &basic, DerivedInfo &calculated, const RoutePlannerConfig &config) { const AircraftState as = ToAircraftState(basic, calculated); const GlideResult& sol = calculated.task_stats.current_leg.solution_remaining; if (!sol.IsDefined()) { calculated.terrain_warning = false; return; } const AGeoPoint start (as.location, as.altitude); const RoughAltitude h_ceiling(std::max((int)basic.nav_altitude+500, (int)calculated.thermal_band.working_band_ceiling)); // allow at least 500m of climb above current altitude as ceiling, in case // there are no actual working band stats. GeoVector v = sol.vector; if (v.distance > fixed(200000)) /* limit to reasonable distances (200km max.) to avoid overflow in GeoVector::EndPoint() */ v.distance = fixed(200000); if (terrain) { if (sol.IsDefined()) { const AGeoPoint dest(v.EndPoint(start), sol.min_arrival_altitude); bool dirty = route_clock.CheckAdvance(basic.time); if (!dirty) { dirty = calculated.common_stats.active_taskpoint_index != last_active_tp || calculated.common_stats.task_type != last_task_type; if (dirty) { // restart clock route_clock.CheckAdvance(basic.time); route_clock.Reset(); } } last_task_type = calculated.common_stats.task_type; last_active_tp = calculated.common_stats.active_taskpoint_index; if (dirty) { protected_route_planner.SolveRoute(dest, start, config, h_ceiling); calculated.planned_route = route_planner.GetSolution(); calculated.terrain_warning = route_planner.Intersection(start, dest, calculated.terrain_warning_location); } return; } else { protected_route_planner.SolveRoute(start, start, config, h_ceiling); calculated.planned_route = route_planner.GetSolution(); } } calculated.terrain_warning = false; }
void Airspaces::visit_intersecting(const GeoPoint &loc, const GeoVector &vec, AirspaceIntersectionVisitor& visitor) const { FlatRay ray(task_projection.project(loc), task_projection.project(vec.end_point(loc))); GeoPoint c = vec.mid_point(loc); Airspace bb_target(c, task_projection); int mrange = task_projection.project_range(c, vec.Distance / 2); IntersectingAirspaceVisitorAdapter adapter(loc, vec, ray, visitor); airspace_tree.visit_within_range(bb_target, -mrange, adapter); #ifdef INSTRUMENT_TASK n_queries++; #endif }
void MapItemListBuilder::AddLocation(const NMEAInfo &basic, const RasterTerrain *terrain) { GeoVector vector; if (basic.location_available) vector = basic.location.DistanceBearing(location); else vector.SetInvalid(); short elevation; if (terrain != NULL) elevation = terrain->GetTerrainHeight(location); else elevation = RasterBuffer::TERRAIN_INVALID; list.checked_append(new LocationMapItem(vector, elevation)); }
static void AddSpiralWaypoints(Waypoints &waypoints, const GeoPoint ¢er = GeoPoint(Angle::Degrees(51.4), Angle::Degrees(7.85)), Angle angle_start = Angle::Degrees(0), Angle angle_step = Angle::Degrees(15), fixed distance_start = fixed(0), fixed distance_step = fixed(1000), fixed distance_max = fixed(150000)) { assert(positive(distance_step)); for (unsigned i = 0;; ++i) { GeoVector vector; vector.distance = distance_start + distance_step * i; if (vector.distance > distance_max) break; vector.bearing = angle_start + angle_step * i; Waypoint waypoint; waypoint.location = vector.EndPoint(center); waypoint.original_id = i; waypoint.elevation = fixed(i * 10 - 500); StaticString<256> buffer; if (i % 7 == 0) { buffer = _T("Airfield"); waypoint.type = Waypoint::Type::AIRFIELD; } else if (i % 3 == 0) { buffer = _T("Field"); waypoint.type = Waypoint::Type::OUTLANDING; } else buffer = _T("Waypoint"); buffer.AppendFormat(_T(" #%d"), i + 1); waypoint.name = buffer; waypoints.Append(std::move(waypoint)); } waypoints.Optimise(); }
void MapItemListBuilder::AddLocation(const NMEAInfo &basic, const RasterTerrain *terrain) { if (list.full()) return; GeoVector vector; if (basic.location_available) vector = basic.location.DistanceBearing(location); else vector.SetInvalid(); double elevation = LocationMapItem::UNKNOWN_ELEVATION; if (terrain != nullptr) elevation = terrain->GetTerrainHeight(location) .ToDouble(LocationMapItem::UNKNOWN_ELEVATION); list.append(new LocationMapItem(vector, elevation)); }
void AirspaceXSRenderer::Draw(Canvas &canvas, const ChartRenderer &chart, const Airspaces &database, const GeoPoint &start, const GeoVector &vec, const AircraftState &state) const { canvas.Select(*look.name_font); // Create IntersectionVisitor to render to the canvas AirspaceIntersectionVisitorSlice ivisitor( canvas, chart, settings, look, start, state); // Call visitor with intersecting airspaces database.VisitIntersecting(start, vec.EndPoint(start), ivisitor); }
AirspaceIntersectionVector AirspaceCircle::intersects(const GeoPoint& start, const GeoVector &vec) const { const GeoPoint end = vec.end_point(start); AirspaceIntersectSort sorter(start, end, *this); const fixed f_radius = m_task_projection->fproject_range(m_center, m_radius); const FlatPoint f_center = m_task_projection->fproject(m_center); const FlatPoint f_start = m_task_projection->fproject(start); const FlatPoint f_end = m_task_projection->fproject(end); const FlatLine line(f_start, f_end); if (inside(start)) sorter.add(fixed_zero, start); FlatPoint f_p1, f_p2; if (line.intersect_circle(f_radius, f_center, f_p1, f_p2)) { const fixed mag = line.mag_sq(); if (positive(mag)) { fixed inv_mag = -fixed_one; const fixed t1 = FlatLine(f_start, f_p1).dot(line); const fixed t2 = (f_p1 == f_p2) ? -fixed_one : FlatLine(f_start, f_p2).dot(line); const bool in_range = (t1 < mag) || (t2 < mag); // if at least one point is within range, capture both points if ((t1 >= fixed_zero) && in_range) { if (negative(inv_mag)) inv_mag = fixed_one / mag; sorter.add(t1 * inv_mag, m_task_projection->funproject(f_p1)); } if ((t2 >= fixed_zero) && in_range) { if (negative(inv_mag)) inv_mag = fixed_one / mag; sorter.add(t2 * inv_mag, m_task_projection->funproject(f_p2)); } } } return sorter.all(); }
AirspaceIntersectionVector AirspacePolygon::intersects(const GeoPoint& start, const GeoVector &vec) const { const GeoPoint end = vec.end_point(start); const FlatRay ray(m_task_projection->project(start), m_task_projection->project(end)); AirspaceIntersectSort sorter(start, end, *this); for (SearchPointVector::const_iterator it= m_border.begin(); it+1 != m_border.end(); ++it) { const FlatRay r_seg(it->get_flatLocation(), (it+1)->get_flatLocation()); const fixed t = ray.intersects(r_seg); if (t>=fixed_zero) { sorter.add(t, m_task_projection->unproject(ray.parametric(t))); } } return sorter.all(); }
bool ShpReader::SetupVectorScaling(VectorMapModelPtr vectorMapModel, ProgressDlgPtr progressDlg) { double minX,minY,maxX,maxY; double aspect,width,height,scaleFactor; if ( App::Inst().GetLayerTreeController()->GetNumMapLayers() >0 ) { MapControllerPtr mapController= App::Inst().GetLayerTreeController()->GetLayerTreeModel()->GetStudy(0)->GetMapLayer(0)->GetMapController(); FileHeader* header=mapController->GetMapModel()->GetHeader(); minX=header->projExtents.x; maxX=header->projExtents.dx; minY=header->projExtents.y; maxY=header->projExtents.dy; aspect = header->projExtents.Height() / header->projExtents.Width(); width = 2.0; height = 2.0*aspect; scaleFactor = 2.0 / header->projExtents.Width(); } else{ minX=vectorMapModel->GetVectorBoundary_MinX(); minY=vectorMapModel->GetVectorBoundary_MinY(); maxX=vectorMapModel->GetVectorBoundary_MaxX(); maxY=vectorMapModel->GetVectorBoundary_MaxY(); aspect = fabs((maxY-minY) / (maxX-minX)); width = 2.0; height = 2.0*aspect; scaleFactor = 2.0 / fabs(maxX-minX); } double scaledextent_minX= -1.0f + 2*((vectorMapModel->GetVectorBoundary_MinX() - minX) / fabs(maxX-minX)); double scaledextent_minY = (1.0f + -2*((vectorMapModel->GetVectorBoundary_MinY() - minY) / fabs(maxY-minY)))*aspect; double scaledextent_maxX= -1.0f + 2*((vectorMapModel->GetVectorBoundary_MaxX() - minX) / fabs(maxX-minX)); double scaledextent_maxY = (1.0f + -2*((vectorMapModel->GetVectorBoundary_MaxY() - minY) / fabs(maxY-minY)))*aspect; vectorMapModel->SetAspect(aspect); vectorMapModel->SetVectorBoundary_ScaledMinX(scaledextent_minX); vectorMapModel->SetVectorBoundary_ScaledMinY(scaledextent_minY); vectorMapModel->SetVectorBoundary_ScaledMaxX(scaledextent_maxX); vectorMapModel->SetVectorBoundary_ScaledMaxY(scaledextent_maxY); for ( unsigned int currGeometry = 0; currGeometry < vectorMapModel->GetNumberOfGeometries(); currGeometry++ ) { GeoVector* GeoVector = vectorMapModel->GetGeoVector( currGeometry ); for ( unsigned int currPoint = 0; currPoint < GeoVector->GetNumberOfPoints(); currPoint++ ) { GeoVector->pointX[currPoint] = -1.0f + 2*((GeoVector->pointX[currPoint] - minX) / fabs(maxX-minX)); GeoVector->pointY[currPoint] = (1.0f + -2*((GeoVector->pointY[currPoint] - minY) / fabs(maxY-minY)))*aspect; } if(progressDlg) { if(!progressDlg->Update(int(50 + (float(currGeometry)/vectorMapModel->GetNumberOfGeometries())*50))) return false; } } return true; }
bool ShpReader::Open(std::wstring fullPath, StudyControllerPtr studyController, VectorMapControllerPtr vectorMapController, ProgressDlgPtr progressDlg) { // Registers all format drivers built into GDAL/OGR. OGRRegisterAll(); OGRDataSource *OGRDataset; // Open vector file path std::string tempStr( fullPath.begin(), fullPath.end() ); OGRDataset = OGRSFDriverRegistrar::Open( tempStr.c_str(), FALSE ); // Return if no vector files are found if( OGRDataset == NULL ) { Log::Inst().Warning("(Warning) Failed to open file at " + tempStr + "."); return false; } if ( App::Inst().GetLayerTreeController()->GetNumMapLayers() >0 ) MapControllerPtr mapController= App::Inst().GetLayerTreeController()->GetLayerTreeModel()->GetStudy(0)->GetMapLayer(0)->GetMapController(); // It appears that shapefiles (*.SHP) only support up to one layer per file // This will need to be further investigated for other vector filetypes (e.g., KML) // For now just grab layer at position 0 OGRLayer *poLayer = OGRDataset->GetLayer( 0 ); // Determine the XY boundaries for the entire vector dataset OGREnvelope psEnvelope; VectorMapModelPtr vectorMapModel = vectorMapController->GetVectorMapModel(); poLayer->GetExtent( &psEnvelope ); vectorMapModel->SetVectorBoundary(psEnvelope); if(!SetupVectorProjection(OGRDataset,studyController,poLayer,vectorMapController )) { OGRDataset->DestroyDataSource(OGRDataset); return false; } if(progressDlg) { if(!progressDlg->Update(0, _T("Reading Vector Map Information..."))) { OGRDataset->DestroyDataSource(OGRDataset); return false; } } GLdouble minX, minY, maxX, maxY; minX = minY = std::numeric_limits<float>::max(); maxX = maxY = -std::numeric_limits<float>::max(); // Retrieve features from the dataset OGRFeature *poFeature; poLayer->ResetReading(); int numFeatures = poLayer->GetFeatureCount(); int count=0; //Log::Inst().Write("Loading shapefile with the following meta data:"); while ( ( poFeature = poLayer->GetNextFeature() ) != NULL ) { ///////////////////////////////////////////////// // PHASE 1: Retrieve METADATA from the dataset // ///////////////////////////////////////////////// OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn(); int iField; for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ ) { OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn( iField ); //if( poFieldDefn->GetType() == OFTInteger ) // printf( "%d,", poFeature->GetFieldAsInteger( iField ) ); //else if( poFieldDefn->GetType() == OFTReal ) // printf( "%.3f,", poFeature->GetFieldAsDouble(iField) ); //else if( poFieldDefn->GetType() == OFTString ) // printf( "%s,", poFeature->GetFieldAsString(iField) ); //else // printf( "%s,", poFeature->GetFieldAsString(iField) ); //ofs << poFeature->GetFieldAsString(iField) << ","; std::string metaData = poFeature->GetFieldAsString(iField); // do something with the meta data... //Log::Inst().Write(metaData); } count++; if(progressDlg) { if(!progressDlg->Update(int(50 + (float(count)/numFeatures)*50))) return false; } /////////////////////////////////////////////////// // PHASE 2: Retrieve GEOMETRIES from the dataset // /////////////////////////////////////////////////// OGRGeometry *poGeometry; poGeometry = poFeature->GetGeometryRef(); // Move to the next feature in the set if no geometry present if( poGeometry == NULL ) { OGRFeature::DestroyFeature( poFeature ); continue; } OGRwkbGeometryType whatisit = poGeometry->getGeometryType(); // Handle POINTS if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbPoint ) { GeoVector* geoVector = new GeoVector(); OGRPoint *poPoint = (OGRPoint *) poGeometry; geoVector->SetGeometryType( wkbPoint ); geoVector->SetNumberOfPoints( 1 ); if(needProjection) { double x,y; x= poPoint->getX(); y= poPoint->getY(); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[0] = x; geoVector->pointY[0] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[0] = poPoint->getX(); geoVector->pointY[0] = poPoint->getY(); } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } //Handle MultiPoint else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiPoint ) { OGRMultiPoint *poMultiPoint = (OGRMultiPoint *) poGeometry; for ( int currGeometry = 0; currGeometry < poMultiPoint->getNumGeometries(); currGeometry++ ) { GeoVector* geoVector = new GeoVector(); OGRPoint *poPoint = ( OGRPoint* )poMultiPoint->getGeometryRef( currGeometry ); geoVector->SetGeometryType( wkbPoint ); geoVector->SetNumberOfPoints( 1 ); if(needProjection) { double x,y; x= poPoint->getX(); y= poPoint->getY(); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[0] = x; geoVector->pointY[0] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[0] = poPoint->getX(); geoVector->pointY[0] = poPoint->getY(); } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } } //Handle Polylines else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbLineString ) { GeoVector* geoVector = new GeoVector(); OGRLineString *poLine = (OGRLineString *) poGeometry; geoVector->SetGeometryType( wkbLineString ); geoVector->SetNumberOfPoints( poLine->getNumPoints() ); // Convert and store the points for ( int currentPoint = 0; currentPoint < poLine->getNumPoints(); currentPoint++ ) { // Convert and store the points if(needProjection) { double x,y; x= poLine->getX( currentPoint ); y= poLine->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLine->getX( currentPoint ); geoVector->pointY[currentPoint] = poLine->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } // Handle MultiPolyLine else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiLineString ) { OGRMultiLineString *poMultiLine = (OGRMultiLineString *) poGeometry; for ( int currGeometry = 0; currGeometry < poMultiLine->getNumGeometries(); currGeometry++ ) { GeoVector* geoVector = new GeoVector(); OGRLineString *poLine = ( OGRLineString* )poMultiLine->getGeometryRef( currGeometry ); geoVector->SetGeometryType( wkbLineString ); geoVector->SetNumberOfPoints( poLine->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLine ->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLine->getX( currentPoint ); y= poLine->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLine->getX( currentPoint ); geoVector->pointY[currentPoint] = poLine->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } } // Handle POLYGONS else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbPolygon ) { GeoVector* geoVector = new GeoVector(); OGRPolygon *poPolygon = ( OGRPolygon* )poGeometry; OGRLinearRing *poLinearRing = poPolygon->getExteriorRing(); geoVector->SetGeometryType( wkbLinearRing ); geoVector->SetNumberOfPoints( poLinearRing->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLinearRing->getX( currentPoint ); y= poLinearRing->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLinearRing->getX( currentPoint ); geoVector->pointY[currentPoint] = poLinearRing->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } // Handle MULTIPOLYGONS else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiPolygon ) { OGRMultiPolygon *poMultiPolygon = (OGRMultiPolygon *) poGeometry; for ( int currGeometry = 0; currGeometry < poMultiPolygon->getNumGeometries(); currGeometry++ ) { GeoVector* geoVector = new GeoVector(); // OGRPolygon http://www.gdal.org/ogr/classOGRPolygon.html OGRPolygon *poPolygon = ( OGRPolygon* )poMultiPolygon->getGeometryRef( currGeometry ); // Retrieve the EXTERNAL ring of the multipolygon OGRLinearRing *poLinearRing = poPolygon->getExteriorRing(); geoVector->SetGeometryType( wkbLinearRing ); geoVector->SetNumberOfPoints( poLinearRing->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLinearRing->getX( currentPoint ); y= poLinearRing->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLinearRing->getX( currentPoint ); geoVector->pointY[currentPoint] = poLinearRing->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); // Retrieve all the INTERNAL rings of the multipolygon for ( int currentRing = 0; currentRing < poPolygon->getNumInteriorRings(); currentRing++ ) { GeoVector* geoVector2 = new GeoVector(); poLinearRing = poPolygon->getInteriorRing( currentRing ); geoVector2->SetGeometryType( wkbLinearRing ); geoVector2->SetNumberOfPoints( poLinearRing->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLinearRing->getX( currentPoint ); y= poLinearRing->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector2->pointX[currentPoint] = x; geoVector2->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector2->pointX[currentPoint] = poLinearRing->getX( currentPoint ); geoVector2->pointY[currentPoint] = poLinearRing->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector2 ); } } } // Report a warning message for unhandled geometries else { Log::Inst().Warning("(Warning) Could not load vector data: unsupported geometry."); } OGRFeature::DestroyFeature( poFeature ); } if (float(minX) == float(maxX) && float(minY) == float(maxY)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } if(needProjection) { vectorMapModel->SetVectorBoundary_MinX(minX); vectorMapModel->SetVectorBoundary_MaxX(maxX); vectorMapModel->SetVectorBoundary_MinY(minY); vectorMapModel->SetVectorBoundary_MaxY(maxY); } if(!SetupVectorScaling(vectorMapModel,progressDlg)) { OGRDataset->DestroyDataSource(OGRDataset); return false; } VectorMetaDataInfo(OGRDataset, studyController, vectorMapController); OGRDataSource::DestroyDataSource( OGRDataset ); return true; }
void SetInvalid() { vec.SetInvalid(); start.SetInvalid(); }
static int ShowMapItemListDialog(SingleWindow &parent) { unsigned num_items = list->size(); UPixelScalar item_height = Fonts::map_bold.GetHeight() + Layout::Scale(6) + Fonts::map_label.GetHeight(); assert(num_items <= 0x7fffffff); assert(item_height > 0); wf = LoadDialog(CallBackTable, parent, Layout::landscape ? _T("IDR_XML_MAPITEMLIST_L") : _T("IDR_XML_MAPITEMLIST")); assert(wf != NULL); details_button = (WndButton *)wf->FindByName(_T("cmdDetails")); assert(details_button); WndListFrame *list_control = (WndListFrame *)wf->FindByName(_T("frmComboPopupList")); assert(list_control != NULL); list_control->SetItemHeight(item_height); list_control->SetLength(num_items); list_control->SetCursorIndex(0); list_control->SetActivateCallback(OnComboPopupListEnter); list_control->SetPaintItemCallback(PaintListItem); list_control->SetCursorCallback(OnListIndexChange); OnListIndexChange(0); WndFrame *info_label = (WndFrame *)wf->FindByName(_T("lblInfo")); assert(info_label); info_label->SetAlignCenter(); info_label->SetVAlignCenter(); TCHAR info_buffer[256], distance_buffer[32], direction_buffer[32]; if (vector.IsValid()) { Units::FormatUserDistance(vector.distance, distance_buffer, 32); FormatBearing(direction_buffer, ARRAY_SIZE(direction_buffer), vector.bearing, _T("T")); _stprintf(info_buffer, _T("%s: %s - %s: %s"), _("Distance"), distance_buffer, _("Direction"), direction_buffer); } else { _stprintf(info_buffer, _T("%s: %s - %s: %s"), _("Distance"), _T("???"), _("Direction"), _T("???")); } TCHAR elevation_buffer[32]; if (elevation != RasterBuffer::TERRAIN_INVALID) { Units::FormatUserAltitude(fixed(elevation), elevation_buffer, 32); _stprintf(info_buffer + _tcslen(info_buffer), _T(" - %s: %s"), _("Elevation"), elevation_buffer); } AnyCanvas canvas; canvas.Select(info_label->GetFont()); UPixelScalar text_width = canvas.CalcTextWidth(info_buffer); if (text_width > info_label->get_width()) { if (vector.IsValid()) _stprintf(info_buffer, _T("%s - %s"), distance_buffer, direction_buffer); else _stprintf(info_buffer, _T("%s - %s"), _T("???"), _T("???")); if (elevation != RasterBuffer::TERRAIN_INVALID) _stprintf(info_buffer + _tcslen(info_buffer), _T(" - %s"), elevation_buffer); } info_label->SetCaption(info_buffer); int result = wf->ShowModal() == mrOK ? (int)list_control->GetCursorIndex() : -1; delete wf; return result; }
static int l_task_index(lua_State *L) { const char *name = lua_tostring(L, 2); if (name == nullptr) return 0; else if (StringIsEqual(name, "bearing")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; const GeoVector &vector_remaining = task_stats.current_leg.vector_remaining; if (!task_stats.task_valid || !vector_remaining.IsValid() || vector_remaining.distance <= 10) { return 0; } Lua::Push(L, vector_remaining.bearing); } else if (StringIsEqual(name, "bearing_diff")) { const NMEAInfo &basic = CommonInterface::Basic(); const TaskStats &task_stats = CommonInterface::Calculated().task_stats; const GeoVector &vector_remaining = task_stats.current_leg.vector_remaining; if (!basic.track_available || !task_stats.task_valid || !vector_remaining.IsValid() || vector_remaining.distance <= 10) { return 0; } Lua::Push(L, vector_remaining.bearing - basic.track); } else if (StringIsEqual(name, "radial")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; const GeoVector &vector_remaining = task_stats.current_leg.vector_remaining; if (!task_stats.task_valid || !vector_remaining.IsValid() || vector_remaining.distance <= 10) { return 0; } Lua::Push(L, vector_remaining.bearing.Reciprocal()); } else if (StringIsEqual(name, "next_distance")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; const GeoVector &vector_remaining = task_stats.current_leg.vector_remaining; if (!task_stats.task_valid || !vector_remaining.IsValid()) return 0; Lua::Push(L, vector_remaining.distance); } else if (StringIsEqual(name, "next_distance_nominal")) { const auto way_point = protected_task_manager != nullptr ? protected_task_manager->GetActiveWaypoint() : NULL; if (!way_point) return 0; const NMEAInfo &basic = CommonInterface::Basic(); const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!task_stats.task_valid || !basic.location_available) return 0; const GeoVector vector(basic.location, way_point->location); if (!vector.IsValid()) return 0; Lua::Push(L, vector.distance); } else if (StringIsEqual(name, "next_ete")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!task_stats.task_valid || !task_stats.current_leg.IsAchievable()) return 0; assert(task_stats.current_leg.time_remaining_now >= 0); Lua::Push(L, task_stats.current_leg.time_remaining_now); } else if (StringIsEqual(name, "next_eta")) { const auto &task_stats = CommonInterface::Calculated().task_stats; const BrokenTime &now_local = CommonInterface::Calculated().date_time_local; if (!task_stats.task_valid || !task_stats.current_leg.IsAchievable() || !now_local.IsPlausible()) { return 0; } const BrokenTime t = now_local + unsigned(task_stats.current_leg.solution_remaining.time_elapsed); float time = t.hour + (float)(t.second/60); Lua::Push(L, time); } else if (StringIsEqual(name, "next_altitude_diff")) { const auto &task_stats = CommonInterface::Calculated().task_stats; const auto &next_solution = task_stats.current_leg.solution_remaining; if (!task_stats.task_valid || !next_solution.IsAchievable()) return 0; const auto &settings = CommonInterface::GetComputerSettings(); auto altitude_difference = next_solution.SelectAltitudeDifference(settings.task.glide); Lua::Push(L, altitude_difference); } else if (StringIsEqual(name, "nextmc0_altitude_diff")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!task_stats.task_valid || !task_stats.current_leg.solution_mc0.IsAchievable()) return 0; const auto &settings = CommonInterface::GetComputerSettings(); auto altitude_difference = task_stats.current_leg.solution_mc0.SelectAltitudeDifference(settings.task.glide); Lua::Push(L, altitude_difference); } else if (StringIsEqual(name, "next_altitude_require")) { const auto &task_stats = CommonInterface::Calculated().task_stats; const auto &next_solution = task_stats.current_leg.solution_remaining; if (!task_stats.task_valid || !next_solution.IsAchievable()) return 0; Lua::Push(L, next_solution.GetRequiredAltitude()); } else if (StringIsEqual(name, "next_altitude_arrival")) { const auto &basic = CommonInterface::Basic(); const auto &task_stats = CommonInterface::Calculated().task_stats; const auto next_solution = task_stats.current_leg.solution_remaining; if (!basic.NavAltitudeAvailable() || !task_stats.task_valid || !next_solution.IsAchievable()) { return 0; } Lua::Push(L, next_solution.GetArrivalAltitude(basic.nav_altitude)); } else if (StringIsEqual(name, "next_gr")) { if (!CommonInterface::Calculated().task_stats.task_valid) return 0; auto gradient = CommonInterface::Calculated().task_stats.current_leg.gradient; if (gradient <= 0) return 0; if (::GradientValid(gradient)) Lua::Push(L, gradient); else return 0; } else if (StringIsEqual(name, "final_distance")) { const auto &calculated = CommonInterface::Calculated(); const TaskStats &task_stats = calculated.task_stats; if (!task_stats.task_valid || !task_stats.current_leg.vector_remaining.IsValid() || !task_stats.total.remaining.IsDefined()) { return 0; } Lua::Push(L, task_stats.total.remaining.GetDistance()); } else if (StringIsEqual(name, "final_ete")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!task_stats.task_valid || !task_stats.total.IsAchievable()) return 0; assert(task_stats.total.time_remaining_now >= 0); Lua::Push(L, task_stats.total.time_remaining_now); } else if (StringIsEqual(name, "final_eta")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; const BrokenTime &now_local = CommonInterface::Calculated().date_time_local; if (!task_stats.task_valid || !task_stats.total.IsAchievable() || !now_local.IsPlausible()) return 0; const BrokenTime t = now_local + unsigned(task_stats.total.solution_remaining.time_elapsed); float time = t.hour + (float)(t.minute/60); Lua::Push(L, time); } else if (StringIsEqual(name, "final_altitude_diff")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; const auto &settings = CommonInterface::GetComputerSettings(); if (!task_stats.task_valid || !task_stats.total.solution_remaining.IsAchievable()) return 0; auto altitude_difference = task_stats.total.solution_remaining.SelectAltitudeDifference(settings.task.glide); Lua::Push(L, altitude_difference); } else if (StringIsEqual(name, "finalmc0_altitude_diff")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; const auto &settings = CommonInterface::GetComputerSettings(); if (!task_stats.task_valid || !task_stats.total.solution_mc0.IsAchievable()) return 0; auto altitude_difference = task_stats.total.solution_mc0.SelectAltitudeDifference(settings.task.glide); Lua::Push(L, altitude_difference); } else if (StringIsEqual(name, "final_altitude_require")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!task_stats.task_valid || !task_stats.total.solution_remaining.IsOk()) { return 0; } Lua::Push(L, task_stats.total.solution_remaining.GetRequiredAltitude()); } else if (StringIsEqual(name, "task_speed")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!task_stats.task_valid || !task_stats.total.travelled.IsDefined()) return 0; Lua::Push(L, task_stats.total.travelled.GetSpeed()); } else if (StringIsEqual(name, "task_speed_achieved")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!task_stats.task_valid || !task_stats.total.remaining_effective.IsDefined()) return 0; Lua::Push(L, task_stats.total.remaining_effective.GetSpeed()); } else if (StringIsEqual(name, "task_speed_instant")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!task_stats.task_valid) return -1; Lua::Push(L, task_stats.inst_speed_fast); } else if (StringIsEqual(name, "task_speed_hour")) { const WindowStats &window = CommonInterface::Calculated().task_stats.last_hour; if (window.duration < 0) return 0; Lua::Push(L, window.speed); } else if (StringIsEqual(name, "final_gr")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!task_stats.task_valid) return 0; auto gradient = task_stats.total.gradient; if (gradient <= 0) return 0; if (::GradientValid(gradient)) Lua::Push(L, gradient); else return 0; } else if (StringIsEqual(name, "aat_time")) { const auto &calculated = CommonInterface::Calculated(); const TaskStats &task_stats = calculated.ordered_task_stats; const CommonStats &common_stats = calculated.common_stats; if (!task_stats.has_targets || !task_stats.total.IsAchievable()) return 0; Lua::Push(L, common_stats.aat_time_remaining); } else if (StringIsEqual(name, "aat_time_delta")) { const auto &calculated = CommonInterface::Calculated(); const TaskStats &task_stats = calculated.ordered_task_stats; const CommonStats &common_stats = calculated.common_stats; if (!task_stats.has_targets || !task_stats.total.IsAchievable()) return 0; assert(task_stats.total.time_remaining_start >= 0); auto diff = task_stats.total.time_remaining_start - common_stats.aat_time_remaining; Lua::Push(L, diff); } else if (StringIsEqual(name, "aat_distance")) { const auto &calculated = CommonInterface::Calculated(); const TaskStats &task_stats = calculated.ordered_task_stats; if (!task_stats.has_targets || !task_stats.total.planned.IsDefined()) return 0; Lua::Push(L, task_stats.total.planned.GetDistance()); } else if (StringIsEqual(name, "aat_distance_max")) { const auto &calculated = CommonInterface::Calculated(); const TaskStats &task_stats = calculated.ordered_task_stats; if (!task_stats.has_targets) return 0; Lua::Push(L, task_stats.distance_max); } else if (StringIsEqual(name, "aat_distance_min")) { const auto &calculated = CommonInterface::Calculated(); const TaskStats &task_stats = calculated.ordered_task_stats; if (!task_stats.has_targets) return 0; Lua::Push(L, task_stats.distance_min); } else if (StringIsEqual(name, "aat_speed")) { const auto &calculated = CommonInterface::Calculated(); const TaskStats &task_stats = calculated.ordered_task_stats; const CommonStats &common_stats = calculated.common_stats; if (!task_stats.has_targets || common_stats.aat_speed_target <= 0) return 0; Lua::Push(L, common_stats.aat_speed_target); } else if (StringIsEqual(name, "aat_speed_max")) { const auto &calculated = CommonInterface::Calculated(); const TaskStats &task_stats = calculated.ordered_task_stats; const CommonStats &common_stats = calculated.common_stats; if (!task_stats.has_targets || common_stats.aat_speed_max <= 0) return 0; Lua::Push(L, common_stats.aat_speed_max); } else if (StringIsEqual(name, "aat_speed_min")) { const auto &calculated = CommonInterface::Calculated(); const TaskStats &task_stats = calculated.ordered_task_stats; const CommonStats &common_stats = calculated.common_stats; if (!task_stats.has_targets || !task_stats.task_valid || common_stats.aat_speed_min <= 0) return 0; Lua::Push(L, common_stats.aat_speed_min); } else if (StringIsEqual(name, "time_under_max_height")) { const auto &calculated = CommonInterface::Calculated(); const auto &task_stats = calculated.ordered_task_stats; const auto &common_stats = calculated.common_stats; const double maxheight = protected_task_manager->GetOrderedTaskSettings().start_constraints.max_height; if (!task_stats.task_valid || maxheight <= 0 || !protected_task_manager || common_stats.TimeUnderStartMaxHeight <= 0) { return 0; } const int time = (int)(CommonInterface::Basic().time - common_stats.TimeUnderStartMaxHeight); Lua::Push(L, time); } else if (StringIsEqual(name, "next_etevmg")) { const NMEAInfo &basic = CommonInterface::Basic(); const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!basic.ground_speed_available || !task_stats.task_valid || !task_stats.current_leg.remaining.IsDefined()) { return 0; } const auto d = task_stats.current_leg.remaining.GetDistance(); const auto v = basic.ground_speed; if (!task_stats.task_valid || d <= 0 || v <= 0) { return 0; } Lua::Push(L, d/v); } else if (StringIsEqual(name, "final_etevmg")) { const NMEAInfo &basic = CommonInterface::Basic(); const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!basic.ground_speed_available || !task_stats.task_valid || !task_stats.total.remaining.IsDefined()) { return 0; } const auto d = task_stats.total.remaining.GetDistance(); const auto v = basic.ground_speed; if (!task_stats.task_valid || d <= 0 || v <= 0) { return 0; } Lua::Push(L, d/v); } else if (StringIsEqual(name, "cruise_efficiency")) { const TaskStats &task_stats = CommonInterface::Calculated().task_stats; if (!task_stats.task_valid || !task_stats.start.task_started) return 0; Lua::Push(L, task_stats.cruise_efficiency); } else return 0; return 1; }