diff options
author | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 13:02:25 -0700 |
---|---|---|
committer | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 16:13:41 -0700 |
commit | 17fdde66d94155fc62a034fa6658995bef6fd6e5 (patch) | |
tree | b5e5073a2a7b15cdbe826faa5c763e270a505729 /Xamarin.Forms.Maps.WinRT.Tablet | |
download | xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.gz xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.bz2 xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.zip |
Initial import
Diffstat (limited to 'Xamarin.Forms.Maps.WinRT.Tablet')
4 files changed, 484 insertions, 0 deletions
diff --git a/Xamarin.Forms.Maps.WinRT.Tablet/GeocoderBackend.cs b/Xamarin.Forms.Maps.WinRT.Tablet/GeocoderBackend.cs new file mode 100644 index 00000000..565182d4 --- /dev/null +++ b/Xamarin.Forms.Maps.WinRT.Tablet/GeocoderBackend.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Bing.Maps; +using Bing.Maps.Search; + +namespace Xamarin.Forms.Maps.WinRT +{ + internal class GeocoderBackend + { + public static void Register() + { + Geocoder.GetPositionsForAddressAsyncFunc = GetPositionsForAddress; + Geocoder.GetAddressesForPositionFuncAsync = GetAddressesForPositionAsync; + } + + static async Task<IEnumerable<string>> GetAddressesForPositionAsync(Position position) + { + var results = new List<string>(); + var source = new TaskCompletionSource<IEnumerable<string>>(); + var requestOptions = new ReverseGeocodeRequestOptions(new Location(position.Latitude, position.Longitude)); + var response = + await + new Bing.Maps.Map { Credentials = FormsMaps.AuthenticationToken }.SearchManager.ReverseGeocodeAsync(requestOptions); + if (!response.HasError) + { + foreach (var address in response.LocationData) + results.Add(address.Address.FormattedAddress); + } + + return results; + } + + static async Task<IEnumerable<Position>> GetPositionsForAddress(string s) + { + var results = new List<Position>(); + + if (string.IsNullOrEmpty(s)) + return results; + + var requestOptions = new GeocodeRequestOptions(s); + var response = + await new Bing.Maps.Map { Credentials = FormsMaps.AuthenticationToken }.SearchManager.GeocodeAsync(requestOptions); + if (!response.HasError) + { + foreach (var address in response.LocationData) + results.Add(new Position(address.Location.Latitude, address.Location.Longitude)); + } + return results; + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Maps.WinRT.Tablet/MapRenderer.cs b/Xamarin.Forms.Maps.WinRT.Tablet/MapRenderer.cs new file mode 100644 index 00000000..b3eba8ac --- /dev/null +++ b/Xamarin.Forms.Maps.WinRT.Tablet/MapRenderer.cs @@ -0,0 +1,249 @@ +using System; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Linq; +using System.Threading.Tasks; +using Windows.Devices.Geolocation; +using Windows.UI; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Shapes; +using Bing.Maps; +using Xamarin.Forms.Platform.WinRT; + +namespace Xamarin.Forms.Maps.WinRT +{ + public class MapRenderer : ViewRenderer<Map, Bing.Maps.Map> + { + bool _disposed; + bool _firstZoomLevelChangeFired; + Ellipse _userPositionCircle; + + protected override async void OnElementChanged(ElementChangedEventArgs<Map> e) + { + base.OnElementChanged(e); + + if (e.OldElement != null) + { + var mapModel = e.OldElement; + MessagingCenter.Unsubscribe<Map, MapSpan>(this, "MapMoveToRegion"); + ((ObservableCollection<Pin>)mapModel.Pins).CollectionChanged -= OnCollectionChanged; + } + + if (e.NewElement != null) + { + var mapModel = e.NewElement; + + if (Control == null) + { + SetNativeControl(new Bing.Maps.Map()); + Control.Credentials = FormsMaps.AuthenticationToken; + Control.ViewChanged += (s, a) => UpdateVisibleRegion(); + } + + MessagingCenter.Subscribe<Map, MapSpan>(this, "MapMoveToRegion", (s, a) => MoveToRegion(a), mapModel); + + UpdateMapType(); + UpdateHasScrollEnabled(); + UpdateHasZoomEnabled(); + + ((ObservableCollection<Pin>)mapModel.Pins).CollectionChanged += OnCollectionChanged; + + if (mapModel.Pins.Any()) + LoadPins(); + + await UpdateIsShowingUser(); + } + } + + protected override async void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) + { + base.OnElementPropertyChanged(sender, e); + + if (e.PropertyName == Map.MapTypeProperty.PropertyName) + UpdateMapType(); + else if (e.PropertyName == Map.IsShowingUserProperty.PropertyName) + await UpdateIsShowingUser(); + else if (e.PropertyName == Map.HasScrollEnabledProperty.PropertyName) + UpdateHasScrollEnabled(); + else if (e.PropertyName == Map.HasZoomEnabledProperty.PropertyName) + UpdateHasZoomEnabled(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && !_disposed) + { + _disposed = true; + + MessagingCenter.Unsubscribe<Map, MapSpan>(this, "MapMoveToRegion"); + + if (Element != null) + ((ObservableCollection<Pin>)Element.Pins).CollectionChanged -= OnCollectionChanged; + } + base.Dispose(disposing); + } + + async Task UpdateIsShowingUser() + { + if (Element.IsShowingUser) + { + var myGeolocator = new Geolocator(); + if (myGeolocator.LocationStatus != PositionStatus.NotAvailable && + myGeolocator.LocationStatus != PositionStatus.Disabled) + { + var userPosition = await myGeolocator.GetGeopositionAsync(); + if (userPosition?.Coordinate != null) + LoadUserPosition(userPosition.Coordinate, true); + } + } + else if (_userPositionCircle != null && Control.Children.Contains(_userPositionCircle)) + Control.Children.Remove(_userPositionCircle); + } + + void LoadPins() + { + foreach (var pin in Element.Pins) + LoadPin(pin); + } + + void ClearPins() + { + Control.Children.Clear(); + UpdateIsShowingUser(); + } + + void RemovePin(Pin pinToRemove) + { + var pushPin = Control.Children.FirstOrDefault(c => + { + var pin = (c as Pushpin); + return (pin != null && pin.DataContext.Equals(pinToRemove)); + }); + + if (pushPin != null) + Control.Children.Remove(pushPin); + } + + void LoadPin(Pin pin) + { + var pushPin = new Pushpin { Text = pin.Label, DataContext = pin }; + MapLayer.SetPosition(pushPin, new Location(pin.Position.Latitude, pin.Position.Longitude)); + pushPin.Tapped += (s, e) => ((s as Pushpin)?.DataContext as Pin)?.SendTap(); + Control.Children.Add(pushPin); + } + + void UpdateMapType() + { + switch (Element.MapType) + { + case MapType.Street: + Control.MapType = Bing.Maps.MapType.Road; + break; + case MapType.Satellite: + Control.MapType = Bing.Maps.MapType.Aerial; + break; + case MapType.Hybrid: + Control.MapType = Bing.Maps.MapType.Birdseye; + break; + } + } + + void MoveToRegion(MapSpan span) + { + var center = new Location(span.Center.Latitude, span.Center.Longitude); + var location = new LocationRect(center, span.LongitudeDegrees, span.LatitudeDegrees); + Control.SetView(location); + } + + void UpdateVisibleRegion() + { + if (Control == null || Element == null) + return; + + if (!_firstZoomLevelChangeFired) + { + MoveToRegion(Element.LastMoveToRegion); + _firstZoomLevelChangeFired = true; + return; + } + + var center = new Position(Control.Center.Latitude, Control.Center.Longitude); + + var boundingRegion = Control.Bounds; + var result = new MapSpan(center, boundingRegion.Height, boundingRegion.Width); + Element.VisibleRegion = result; + } + + void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (Pin pin in e.NewItems) + LoadPin(pin); + break; + case NotifyCollectionChangedAction.Move: + // no matter + break; + case NotifyCollectionChangedAction.Remove: + foreach (Pin pin in e.OldItems) + RemovePin(pin); + break; + case NotifyCollectionChangedAction.Replace: + foreach (Pin pin in e.OldItems) + RemovePin(pin); + foreach (Pin pin in e.NewItems) + LoadPin(pin); + break; + case NotifyCollectionChangedAction.Reset: + ClearPins(); + break; + } + } + + void LoadUserPosition(Geocoordinate userCoordinate, bool center) + { + var userPosition = new Location + { + Latitude = userCoordinate.Point.Position.Latitude, + Longitude = userCoordinate.Point.Position.Longitude + }; + + if (_userPositionCircle == null) + { + _userPositionCircle = new Ellipse + { + Stroke = new SolidColorBrush(Colors.White), + Fill = new SolidColorBrush(Colors.Blue), + StrokeThickness = 2, + Height = 20, + Width = 20, + Opacity = 50 + }; + } + + if (Control.Children.Contains(_userPositionCircle)) + Control.Children.Remove(_userPositionCircle); + + MapLayer.SetPosition(_userPositionCircle, userPosition); + MapLayer.SetPositionAnchor(_userPositionCircle, new Windows.Foundation.Point(0.5, 0.5)); + + Control.Children.Add(_userPositionCircle); + + if (center) + { + Control.Center = userPosition; + Control.ZoomLevel = 13; + } + } + + void UpdateHasZoomEnabled() + { + } + + void UpdateHasScrollEnabled() + { + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Maps.WinRT.Tablet/Properties/AssemblyInfo.cs b/Xamarin.Forms.Maps.WinRT.Tablet/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..74cc63dc --- /dev/null +++ b/Xamarin.Forms.Maps.WinRT.Tablet/Properties/AssemblyInfo.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using Xamarin.Forms.Maps; +using Xamarin.Forms.Maps.WinRT; +using Xamarin.Forms.Platform.WinRT; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly: AssemblyTitle("Xamarin.Forms.Maps.WinRT.Tablet")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Xamarin.Forms.Maps.WinRT.Tablet")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] + +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] +[assembly: ExportRenderer(typeof (Map), typeof (MapRenderer))]
\ No newline at end of file diff --git a/Xamarin.Forms.Maps.WinRT.Tablet/Xamarin.Forms.Maps.WinRT.Tablet.csproj b/Xamarin.Forms.Maps.WinRT.Tablet/Xamarin.Forms.Maps.WinRT.Tablet.csproj new file mode 100644 index 00000000..8251abb0 --- /dev/null +++ b/Xamarin.Forms.Maps.WinRT.Tablet/Xamarin.Forms.Maps.WinRT.Tablet.csproj @@ -0,0 +1,149 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.30703</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{E5C4698D-FB57-4EEC-98C0-89E620F6920A}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Xamarin.Forms.Maps.WinRT</RootNamespace> + <AssemblyName>Xamarin.Forms.Maps.WinRT.Tablet</AssemblyName> + <DefaultLanguage>en-US</DefaultLanguage> + <TargetPlatformVersion>8.1</TargetPlatformVersion> + <MinimumVisualStudioVersion>12</MinimumVisualStudioVersion> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'"> + <DebugSymbols>true</DebugSymbols> + <OutputPath>bin\ARM\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants> + <NoWarn>;2008</NoWarn> + <DebugType>full</DebugType> + <PlatformTarget>ARM</PlatformTarget> + <UseVSHostingProcess>false</UseVSHostingProcess> + <ErrorReport>prompt</ErrorReport> + <Prefer32Bit>true</Prefer32Bit> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'"> + <OutputPath>bin\ARM\Release\</OutputPath> + <DefineConstants>TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants> + <Optimize>true</Optimize> + <NoWarn>;2008</NoWarn> + <DebugType>pdbonly</DebugType> + <PlatformTarget>ARM</PlatformTarget> + <UseVSHostingProcess>false</UseVSHostingProcess> + <ErrorReport>prompt</ErrorReport> + <Prefer32Bit>true</Prefer32Bit> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> + <DebugSymbols>true</DebugSymbols> + <OutputPath>bin\x64\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants> + <NoWarn>;2008</NoWarn> + <DebugType>full</DebugType> + <PlatformTarget>x64</PlatformTarget> + <UseVSHostingProcess>false</UseVSHostingProcess> + <ErrorReport>prompt</ErrorReport> + <Prefer32Bit>true</Prefer32Bit> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> + <OutputPath>bin\x64\Release\</OutputPath> + <DefineConstants>TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants> + <Optimize>true</Optimize> + <NoWarn>;2008</NoWarn> + <DebugType>pdbonly</DebugType> + <PlatformTarget>x64</PlatformTarget> + <UseVSHostingProcess>false</UseVSHostingProcess> + <ErrorReport>prompt</ErrorReport> + <Prefer32Bit>true</Prefer32Bit> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'"> + <DebugSymbols>true</DebugSymbols> + <OutputPath>bin\x86\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants> + <NoWarn>;2008</NoWarn> + <DebugType>full</DebugType> + <PlatformTarget>x86</PlatformTarget> + <UseVSHostingProcess>false</UseVSHostingProcess> + <ErrorReport>prompt</ErrorReport> + <Prefer32Bit>true</Prefer32Bit> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'"> + <OutputPath>bin\x86\Release\</OutputPath> + <DefineConstants>TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants> + <Optimize>true</Optimize> + <NoWarn>;2008</NoWarn> + <DebugType>pdbonly</DebugType> + <PlatformTarget>x86</PlatformTarget> + <UseVSHostingProcess>false</UseVSHostingProcess> + <ErrorReport>prompt</ErrorReport> + <Prefer32Bit>true</Prefer32Bit> + </PropertyGroup> + <ItemGroup> + <!-- A reference to the entire .Net Framework and Windows SDK are automatically included --> + <ProjectReference Include="..\Xamarin.Forms.Core\Xamarin.Forms.Core.csproj"> + <Project>{57b8b73d-c3b5-4c42-869e-7b2f17d354ac}</Project> + <Name>Xamarin.Forms.Core</Name> + </ProjectReference> + <ProjectReference Include="..\Xamarin.Forms.Maps\Xamarin.Forms.Maps.csproj"> + <Project>{7d13bac2-c6a4-416a-b07e-c169b199e52b}</Project> + <Name>Xamarin.Forms.Maps</Name> + </ProjectReference> + <ProjectReference Include="..\Xamarin.Forms.Platform.WinRT.Tablet\Xamarin.Forms.Platform.WinRT.Tablet.csproj"> + <Project>{d3f9265a-30ac-43e8-a3eb-59bb76d2d0bf}</Project> + <Name>Xamarin.Forms.Platform.WinRT.Tablet</Name> + </ProjectReference> + <ProjectReference Include="..\Xamarin.Forms.Platform.WinRT\Xamarin.Forms.Platform.WinRT.csproj"> + <Project>{f3fdd7ac-8899-4e41-bfd7-ec83403e736d}</Project> + <Name>Xamarin.Forms.Platform.WinRT</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Compile Include="..\Xamarin.Forms.Maps.UWP\FormsMaps.cs"> + <Link>FormsMaps.cs</Link> + </Compile> + <Compile Include="GeocoderBackend.cs" /> + <Compile Include="MapRenderer.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <SDKReference Include="Bing.Maps.Xaml, Version=1.313.0825.0"> + <Name>Bing Maps for C#, C++, or Visual Basic</Name> + </SDKReference> + <SDKReference Include="Microsoft.VCLibs, version=12.0"> + <Name>Microsoft Visual C++ 2013 Runtime Package for Windows</Name> + </SDKReference> + </ItemGroup> + <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' "> + <VisualStudioVersion>12.0</VisualStudioVersion> + </PropertyGroup> + <Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file |