I am working on developing support in Xamarin.Forms. I have basic functionality working, but I'm working on figuring out some Nutiteq SDK behavior that is unrelated to working with Forms. So, I'm hesitant to release code yet, because it just isn't a completely working example.
But I'll share the approach that I have taken so far. First of all, what I want to support in my app, at least in the short term are:
a) offline use
b) draw lines to locations over time using lat/lon info that I pull from a database.
c) showing dots or markers in locations where certain events have occurred
d) downloading multiple regions to present accurate depictions of the US East Coastline
I can do the first three items - I am still working on how to do multiple regions efficiently (i.e. without downloading a dozen large state files)
My approach so far:
1) I created a class in my XF app that inherits from View and create a number of BindableProperty objects for different properties of the map:
public class xNutiteqMapView : View
{
public xNutiteqMapView ( )
{ }
// Location
public static readonly BindableProperty LocationPathProperty = BindableProperty.Create<xNutiteqMapView, List<Point>>( p => p.LocationPath, new List<Point>() );
public List<Point> LocationPath
{
get { return GetValue( LocationPathProperty ) as List<Point>; }
set { SetValue( LocationPathProperty, value ); }
}
// Location Path Color
public static readonly BindableProperty LocationPathColorProperty = BindableProperty.Create<xNutiteqMapView, Color>( p => p.LocationPathColor, Color.Red );
public Color LocationPathColor
{
get { return (Color)GetValue( LocationPathColorProperty ); }
set { SetValue( LocationPathColorProperty, value ); }
}
2) I then create a Custom Renderer on each platform that gets values from the BindableProperty properties to configure the map. It also handles the PropertyChanged event to modify the map after it has been created.
protected override void OnElementPropertyChanged ( object sender,
System.ComponentModel.PropertyChangedEventArgs e )
{
base.OnElementPropertyChanged( sender, e );
xNutiteqMapView parentUiObj = sender as xNutiteqMapView;
if ( e.PropertyName == "CurrentLocation" ||
e.PropertyName == "MapRotation" ||
e.PropertyName == "Tilt" )
{
SetCurrentLocation( parentUiObj );
}
else if ( e.PropertyName == "Zoom" )
{
SetZoom( parentUiObj );
}
else if ( e.PropertyName == "LocationPath" ||
e.PropertyName == "LocationPathColor" ||
e.PropertyName == "LocationPathWidth" )
{
DrawLocationPath( parentUiObj );
}
else if ( e.PropertyName == "CatchLocations" ||
e.PropertyName == "CatchLocationColor" ||
e.PropertyName == "CatchLocationSize" )
{
DrawCatchLocations( parentUiObj );
}
else if ( e.PropertyName == "MapPackageId" )
{
UpdateDownloadedMaps( parentUiObj );
}
else if ( e.PropertyName == "MapStyle" )
{
ConfigureMapStyle( parentUiObj );
}
}
The functions call in the OnElementPropertyChanged event go off and work with the Nutiteq SDK functions. You can get those details from their documentation.
I don't know how far I can go in terms of implementing everything I might need in the future, and its still not working 100%, so there's still some work to do, but I figured I'd offer this up to start the discussion.
-Bill
1) I have created