1

我的问题是关于在 windows phone 7 上使用 bing 地图。这是我需要做的总结

  • 每 x 秒轮询一次服务以检索一组坐标
  • 如果这是第一次轮询服务

    • 将这些坐标绘制为地图上的自定义图钉(我使用的是 Image 和 MapLayer)

      PinObject pin = new PinObject() //Custom object
                      {
                          Id = groupMember.Id,
                          PushPin = new Image()
                          {
                              Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("blackpin.png", UriKind.Relative)),
                              Opacity = 0.8,
                              Stretch = System.Windows.Media.Stretch.None
                          },
                          PinLocation = new GeoCoordinate(groupMember.Latitude, groupMember.Longitude)
                      }; 
      imageLayer.AddChild(pin.PushPin, pin.PinLocation); //Initialized in constructor
                      pinObjects.Add(pin);// Add pin object to a list to provide a handle to the objects
      
    • 自动设置地图缩放级别,以便所有绘制的点都可见(我假设使用 LocationRect.CreateLocationRect 应该这样做)

                  var coords = pinObjects.Select(p => p.PinLocation).ToList();                        
                  myMap.SetView(LocationRect.CreateLocationRect(coords));
      
    • 否则根据获得的新坐标,更新地图上每个图钉的位置 PinObject pObj = pinObjects.FirstOrDefault(p => p.Id == groupMember.Id);

       MapLayer.SetPosition(pObj.PushPin, new GeoCoordinate(groupMember.Latitude, groupMember.Longitude));
      

引脚加载正常,调用服务以获取他们的新位置也加载正常,问题是他们在地图上的位置永远不会更新,所以即使所有这些工作都在后台进行,他们基本上只是静止不动,我已经调试过,所以我知道它有效。如何重置图钉的位置,如果使用图像不起作用,我可以使用图钉对象吗?这将如何工作?

提前致谢。

4

3 回答 3

0

Here is an option similar to Dispatcher.BeginInvoke but it works better for me in some cases. When I really need to get off the current thread with some work I will use a private static class UICallbackTimer to offset execution just a slight amount. (typos and untested code, just pulling out pieces here you'll have to debug in your code)

UICallbackTimer is not my code but it's available on the Internet. You can get information on this class by searching "private static class UICallbackTimer"

Here is the code to execute it.

UICallbackTimer.DelayExecution(TimeSpan.FromSeconds(.01),
                                       () => (

MapLayer.SetPosition(pObj.PushPin, new GeoCoordinate(groupMember.Latitude, groupMember.Longitude))

);

and here is the class ( I place it inside the current object, so that it remains private to my class) Add using statement for System.Threading

private static class UICallbackTimer
    {
        private static bool _running = false;
        private static int runawayCounter = 0;

        public static bool running()
        {
            if (_running && runawayCounter++ < 10)
                return _running;

            runawayCounter = 0;
            _running = false;
            return _running;
        }

        public static void DelayExecution(TimeSpan delay, Action action)
        {
            _running = true;
            System.Threading.Timer timer = null;
            SynchronizationContext context = SynchronizationContext.Current;
            timer = new System.Threading.Timer(
                (ignore) =>
                {
                    timer.Dispose();
                    _running = false;
                    context.Post(ignore2 => action(), null);
                }, null, delay, TimeSpan.FromMilliseconds(-1));
        }
    }
于 2012-04-06T13:48:24.863 回答
0

我发现确保图钉得到更新的最佳方法是SetView()再次在地图上调用 call。您可以传入现有视图以基本上强制刷新。例如;MyMapControl.SetView(MyMapControl.BoundingRectangle);

于 2012-04-05T01:59:42.237 回答
0

好问题!

这是一些非常丑陋的代码,但至少它可以工作并且可以开始。

我从这里得到了主要结构。如果有人可以通过适当的绑定和更少的代码发布答案,我将不胜感激。

 <Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <!--RESOURCES-->
    <Grid.Resources>
        <DataTemplate x:Key="LogoTemplate">
            <maps:Pushpin Location="{Binding PinLocation}" />
        </DataTemplate>
        <maps:MapItemsControl x:Name="GroupAPins"
                    ItemTemplate="{StaticResource LogoTemplate}"
                    ItemsSource="{Binding PinsA}">
        </maps:MapItemsControl>
    </Grid.Resources>
    <Grid x:Name="ContentPanel" Grid.Row="0" Margin="12,0,12,0"/>
</Grid>

public partial class MapPage : PhoneApplicationPage
{
    private ObservableCollection<PinData> _pinsA = new ObservableCollection<PinData>();
    private Map MyMap;
    public ObservableCollection<PinData> PinsA { get { return this._pinsA; } }  

    public MapPage()
    {
        InitializeComponent();

        this.DataContext = this;
        //Create a map.
        MyMap = new Map();
        MyMap.CredentialsProvider = new ApplicationIdCredentialsProvider("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        //Remove the List of items from the resource and add it to the map
        this.LayoutRoot.Resources.Remove("GroupAPins");
        MyMap.Children.Add(GroupAPins);
        MyMap.Center = new GeoCoordinate(40.74569634433956, -73.96717071533204);
        MyMap.ZoomLevel = 5;
        //Add the map to the content panel.
        ContentPanel.Children.Add(MyMap);
        loadAPins_fromString();
    }

    //ADD PIN TO COLLECTION  
    private void addPin(String lat, String lon)
    {
        PinData tmpPin;
        tmpPin = new PinData()
        {
            PinLocation = new GeoCoordinate(System.Convert.ToDouble(lat), System.Convert.ToDouble(lon))
        };
        _pinsA.Add(tmpPin);

        var timer = new DispatcherTimer();
        timer.Interval = TimeSpan.FromSeconds(1);
        timer.Tick += delegate(object sender, EventArgs args)
                        {
                            PinsA.Remove(tmpPin);
                            tmpPin.PinLocation.Latitude += 1;
                            PinsA.Add(tmpPin);

                        };
        timer.Start();

    }

    //LOAD PINS ONE BY ONE  
    private string loadAPins_fromString()
    {
        //BAD  
        addPin("42.35960626034072", "-71.09212160110473");
        //addPin("51.388066116760086", "30.098590850830067");
        //addPin("48.17972265679143", "11.54910385608672");
        addPin("40.28802528051879", "-76.65668606758117");

        var coords = PinsA.Select(p => p.PinLocation).ToList();
        MyMap.SetView(LocationRect.CreateLocationRect(coords));

        return "A PINS LOADED - STRING";
    }
}

public class PinData 
{
    public GeoCoordinate PinLocation{get;set;}
} 
于 2012-04-12T21:54:44.313 回答