コード例 #1
0
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);
}
コード例 #2
0
ファイル: Task.cpp プロジェクト: Adrien81/XCSoar
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);
}
コード例 #3
0
ファイル: RouteComputer.cpp プロジェクト: rjsikarwar/XCSoar
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;
}
コード例 #4
0
ファイル: Airspaces.cpp プロジェクト: galippi/xcsoar
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
}
コード例 #5
0
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));
}
コード例 #6
0
ファイル: TestWaypoints.cpp プロジェクト: kwtskran/XCSoar
static void
AddSpiralWaypoints(Waypoints &waypoints,
                   const GeoPoint &center = 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();
}
コード例 #7
0
ファイル: Builder.cpp プロジェクト: rkohel/XCSoar
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));
}
コード例 #8
0
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);
}
コード例 #9
0
ファイル: AirspaceCircle.cpp プロジェクト: Plantain/XCSoar
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();
}
コード例 #10
0
ファイル: AirspacePolygon.cpp プロジェクト: Plantain/XCSoar
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();
}
コード例 #11
0
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;
}
コード例 #12
0
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;
}
コード例 #13
0
 void SetInvalid() {
   vec.SetInvalid();
   start.SetInvalid();
 }
コード例 #14
0
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;
}
コード例 #15
0
ファイル: Task.cpp プロジェクト: Advi42/XCSoar
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;
}