2

シナリオ:

ユーザーに地図と現在位置を見てもらいたい。次に、「開始」をクリックすると、ナビゲーションが開始され、位置が変化すると「ルート」が地図上に表示されます。これは、ランニング/ウォーキングをマップ化する一部のフィットネス アプリの動作と同様です。目標は、ユーザーの位置の変化に合わせてリアルタイムでこれを行うことです。

オプション:

私の見方では、2 つのオプションがあります。1)RouteQuery開始位置から次の位置 (位置が変更された場合) までを使用し、最後のMap.AddRoute位置を追跡し、常にその位置から新しい位置まで新しいものを描画します。、または 2) ユーザーの現在位置を、位置の変化に応じて移動するドットとして表示し、「停止」を押したときに、完全なルートを示すために位置ごとに を描画します。MapRoute MapRoute

ユーザーはルートの進行状況などを確認できるため、オプション #1 をお勧めします。

私が使用しているコードは次のとおりです。

XAML:

<maps:Map x:Name="MainMap" />
<Button x:Name="btnStart" Content="Start"/>
<Button x:Name="btnStop" Content="Stop" IsEnabled="False"/>

分離コード:

グローバル変数:

GeoCoordinateWatcher watcher;
List<GeoCoordinate> listCoordinates;
GeoCoordinate lastCoordinate;

btnStart.Tap():

private void btnStart_Tap(object sender, GestureEventArgs e)
{
   if (watcher == null)
   {
      watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
      watcher.MovementThreshold = 20;
      watcher.StatusChanged += watcher_StatusChanged;
      watcher.PositionChanged += watcher_PositionChanged;
   }
   watcher.Start();
}

ウォッチャー.StatusChanged():

private void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
   switch (e.Status)
   {
      case GeoPositionStatus.Initializing:
         btnStart.IsEnabled = false;
         btnStop.IsEnabled = true;
         break;

      case GeoPositionStatus.NoData:
         lblStatus.Text = "location data is not available.";
         break;

      case GeoPositionStatus.Ready:
         lblStatus.Text = "location data is available.";
         break;
   }
}

ウォッチャー.PositionChanged():

void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
   if (listCoordinates == null)
   {
      // first time through:
      listCoordinates = new List<GeoCoordinate>();
      listCoordinates.Add(e.Position.Location);
      lastCoordinate = e.Position.Location;
      return;
   } 
   else 
   {
      listCoordinates.Add(e.Position.Location);
      DrawRoute(e.Position.Location);
      lastCoordinate = e.Position.Location;
   }
}

DrawRoute 関数:

private void DrawRoute(GeoCoordinate newPosition)//
{
   RouteQuery query = new RouteQuery()
   {
      TravelMode = TravelMode.Driving,
      Waypoints = new List<GeoCoordinate>() { MainMap.Center, newPosition }
   };
   query.QueryCompleted += RouteQueryCompleted;
   query.QueryAsync();
   MainMap.Center = newPosition;
   lastCoordinate = newPosition;
}

最後に、RouteQueryCompleted():

void RouteQueryCompleted(object sender, QueryCompletedEventArgs<Route> e)
{
   mapRoute = new MapRoute(e.Result);
   MainMap.AddRoute(mapRoute);
}

何が起こるのですか:

運転を開始すると 1 秒間動作しているように見え、開始位置に短い線が引かれますが、その後約 10 秒で近くの通りにランダムに線が引かれます (おそらく 3 または 4 ブロックの長さに相当します)。それから脇道の別のブロックを下ります(その間ずっと、私は1ブロックも運転していませんでした.ターンすることは言うまでもありません!). それは非常に奇妙で、間違いなく正確ではありません。必要に応じて、スクリーンショットをアップロードして説明をわかりやすくすることができます。

私のコードで私が間違っていることを誰でも見ることができますか、それともこれを達成するためのより良い方法はありますか? これが最善の方法かどうかはわかりませんでしたが、そうでないことを示唆する例を見つけることができませんでした。

4

2 に答える 2

5

最後のものと新しいもののMapPolyLine間に線を引くために使用することになりました。GeoCoordinate

MapPolyline line = new MapPolyline();
line.StrokeColor = Colors.Blue;
line.StrokeThickness = 15;
line.Path.Add(lastCoordinate);
line.Path.Add(pos);
MainMap.MapElements.Add(line);
于 2013-09-11T00:23:47.953 に答える
2

なぜRouteQueryあなたの仕事に使用しているのかわかりません。一般に、これは、一連の座標を指定してマップ SDK にルートを決定させたい場合に使用します。ただし、あなたの場合、PositionChangedイベントを通じて自分がどこにいるかを常に知っています。移動しながら地図上に直接プロットする方が簡単です。

このようなもの

void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e) {
  Plot(e.Position.Location);
}

void Plot(GeoCoordinate pos) {
  var ellipse = new Ellipse();
  ellipse.Fill = new SolidColorBrush(System.Windows.Media.Colors.Blue);
  ellipse.Height = 15;
  ellipse.Width = 15;
  ellipse.Opacity = 25;

  var mapOverlay = new MapOverlay();
  mapOverlay.Content = ellipse;
  mapOverlay.PositionOrigin = new System.Windows.Point(0.5, 0.5);
  mapOverlay.GeoCoordinate = pos;

  var mapLayer = new MapLayer();
  mapLayer.Add(mapOverlay);

  MainMap.Layers.Add(mapLayer);
}
于 2013-09-06T02:14:29.023 に答える