Skip to content

Commit

Permalink
feat: BasicLocationPulsingCircleExample (#35)
Browse files Browse the repository at this point in the history
* - use `is null` expression

* - fix(android): move mapready event invocation to MapboxViewFragment.OnViewCreated

* - fix(android): AddREmoveAnnotations - move MapboxStyle setup to MapReady

* - initial setup for location component on Android

* - Toggle Map Style

* - add menu items on Android

* - add iOS implementation (draft)

* - Use bottomsheet instead of toolbar items (not work for iOS)
- Correct iOS impl

* - add CameraForCoordinates

* - iOS impl

* - update nuget package

* - check and fix iOS binding
  • Loading branch information
tuyen-vuduc authored Aug 14, 2024
1 parent 68456b9 commit f558ca6
Show file tree
Hide file tree
Showing 25 changed files with 849 additions and 70 deletions.
18 changes: 18 additions & 0 deletions src/libs/Mapbox.Maui/IMapboxView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using System.Windows.Input;
using MapboxMaui.Annotations;
using MapboxMaui.Locations;
using MapboxMaui.Query;
using MapboxMaui.Styles;
using MapboxMaui.Viewport;
Expand Down Expand Up @@ -35,6 +36,8 @@ public partial interface IMapboxView : IView
IMapFeatureQueryable QueryManager { get; }

IViewportPlugin Viewport { get; }

ILocationComponentPlugin LocationComponent { get; }
}

partial interface IMapboxView
Expand Down Expand Up @@ -83,6 +86,21 @@ public interface IMapboxController
IPosition GetMapPosition(ScreenPosition position);
CoordinateBounds GetCoordinateBoundsForCamera(CameraOptions cameraOptions);
ScreenPosition GetScreenPosition(IPosition position);
CameraOptions? CameraForCoordinates(
IEnumerable<IPosition> coordinates,
CameraOptions? cameraOptions = default,
Thickness? coordinatesPadding = default,
double? maxZoom = default,
ScreenPosition? offset = default
);
void CameraForCoordinates(
IEnumerable<IPosition> coordinates,
Action<CameraOptions?> completion,
CameraOptions? cameraOptions = default,
Thickness? coordinatesPadding = default,
double? maxZoom = default,
ScreenPosition? offset = default
);
}

public class MapTappedEventArgs : EventArgs
Expand Down
10 changes: 8 additions & 2 deletions src/libs/Mapbox.Maui/Mapbox.Maui.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,27 @@
<RepositoryUrl>https://github.com/tuyen-vuduc/mapbox-maui</RepositoryUrl>
<PackageProjectUrl>https://mapbox.tuyen-vuduc.tech</PackageProjectUrl>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageVersion>11.5.1-alpha02</PackageVersion>
<PackageVersion>11.5.1-alpha03</PackageVersion>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageIcon>tv-mapbox.png</PackageIcon>
</PropertyGroup>
<PropertyGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
<CreatePackage>false</CreatePackage>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Platforms\Android\MapboxViewHandler.Location.cs" />
<Compile Remove="Platforms\iOS\MapboxViewHandler.Location.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="Models\Gestures\" />
</ItemGroup>
<ItemGroup>
<None Include="../../../assets/tv-mapbox.png" Pack="True" PackagePath="tv-mapbox.png" />
<None Include="../../../LICENSE" Pack="True" PackagePath="" />
<None Include="../../../README.md" Pack="True" PackagePath="README.md" />
<None Include="Platforms\Android\MapboxViewHandler.Location.cs" />
<None Include="Platforms\iOS\MapboxViewHandler.Location.cs" />

<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="Xamarin.Build.Download" Version="0.11.4" />
Expand All @@ -94,7 +100,7 @@
<PackageReference Include="Xamarin.AndroidX.Annotation" Version="1.8.0.1" />
</ItemGroup>
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
<PackageReference Include="MapboxMapsObjC.iOS" Version="11.5.2.3" />
<PackageReference Include="MapboxMapsObjC.iOS" Version="11.5.2.6" />
<PackageReference Include="MapboxMaps.iOS" Version="11.5.2" />
</ItemGroup>
<ItemGroup>
Expand Down
2 changes: 2 additions & 0 deletions src/libs/Mapbox.Maui/MapboxView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using MapboxMaui.Annotations;
using MapboxMaui.Camera;
using MapboxMaui.Locations;
using MapboxMaui.Styles;
using MapboxMaui.Viewport;

Expand Down Expand Up @@ -237,4 +238,5 @@ public MapboxStyle MapboxStyle
public IMapboxController MapboxController { get; internal set; }
public ICameraPlugin CameraController { get; internal set; }
public IViewportPlugin Viewport { get; internal set; }
public ILocationComponentPlugin LocationComponent { get; internal set; }
}
8 changes: 6 additions & 2 deletions src/libs/Mapbox.Maui/MapboxViewHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public partial class MapboxViewHandler : ViewHandler<IMapboxView, PlatformView>
{
internal static string ACCESS_TOKEN;

public static IPropertyMapper<IMapboxView, MapboxViewHandler> PropertyMapper
public static IPropertyMapper<IMapboxView, MapboxViewHandler> Mapper
= new PropertyMapper<IMapboxView, MapboxViewHandler>(ViewHandler.ViewMapper)
{
[nameof(MapboxView.CameraOptions)] = HandleCameraOptionsChanged,
Expand All @@ -28,8 +28,12 @@ public static IPropertyMapper<IMapboxView, MapboxViewHandler> PropertyMapper
[nameof(MapboxView.Terrain)] = HandleTerrainChanged,
[nameof(MapboxView.Light)] = HandleLightChanged
};
public static CommandMapper<IMapboxView, MapboxViewHandler> CommandMapper
= new (ViewHandler.ViewCommandMapper)
{
};

public MapboxViewHandler() : base(PropertyMapper)
public MapboxViewHandler() : base(Mapper, CommandMapper)
{

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace MapboxMaui.Locations;

public interface ILocationComponentPlugin
{
bool Enabled { get; set; }
bool PulsingEnabled { get; set; }
bool ShowAccuracyRing { get; set; }
float PulsingMaxRadius { get; set; }
}
104 changes: 104 additions & 0 deletions src/libs/Mapbox.Maui/Models/Locations/ILocationPuck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
namespace MapboxMaui.Locations;

public interface ILocationPuck { }

public record LocationPuck2D(
/**
* Name of image in sprite to use as the top of the location indicator.
*/
ResolvedImage TopImage = null,
/**
* Name of image in sprite to use as the middle of the location indicator.
*/
ResolvedImage BearingImage = null,
/**
* Name of image in sprite to use as the background of the location indicator.
*/
ResolvedImage ShadowImage = null,
/**
* The scale expression of the images. If defined, it will be applied to all the three images.
*/
string ScaleExpression = null,
/**
* The opacity of the entire location puck
*/
float Opacity = 1f
) : ILocationPuck
{ }

/**
* Definition of a location_puck_3_d.
*/
public record LocationPuck3D(
/**
* An URL for the model file in gltf format.
*/
string ModelUri,
/**
* The position of the model.
*/
float[] Position = default,
/**
* The opacity of the model.
*/
float ModelOpacity = 1f,
/**
* The scale of the model.
*/
float[] ModelScale = default,
/**
* The scale expression of the model, which will overwrite the default scale expression that keeps the model size constant during zoom.
*/
string ModelScaleExpression = null,
/**
* The translation of the model [lon, lat, z]
*/
float[] ModelTranslation = default,
/**
* The rotation of the model.
*/
float[] ModelRotation = default,
/**
* Enable/Disable shadow casting for the 3D location puck.
*/
bool ModelCastShadows = true,
/**
* Enable/Disable shadow receiving for the 3D location puck.
*/
bool ModelReceiveShadows = true,
/**
* Defines scaling mode. Only applies to location-indicator type layers.
*/
ModelScaleMode modelScaleMode = ModelScaleMode.Viewport,
/**
* Strength of the emission. There is no emission for value 0. For value 1.0, only emissive component (no shading) is displayed and values above 1.0 produce light contribution to surrounding area, for some of the parts (e.g. doors).
*/
float modelEmissiveStrength = 1f,
/**
* Strength of the emission as Expression string, note that when [modelEmissiveStrengthExpression] is specified, it will overwrite the [modelEmissiveStrength] property. There is no emission for value 0. For value 1.0, only emissive component (no shading) is displayed and values above 1.0 produce light contribution to surrounding area, for some of the parts (e.g. doors).
*/
string modelEmissiveStrengthExpression = default
) : ILocationPuck
{
public float[] Position { get; init; } = Position ?? [0, 0];
public float[] ModelScale { get; init; } = ModelScale ?? [1, 1, 1];
public float[] ModelTranslation { get; init; } = ModelTranslation ?? [0, 0, 0];
public float[] ModelRotation { get; init; } = ModelRotation ?? [0, 0, 90];
}

/**
* Defines scaling mode. Only applies to location-indicator type layers.
*
* @param value String value of this property
*/
public enum ModelScaleMode
{
/**
* Model is scaled so that it's always the same size relative to other map features. The property model-scale specifies how many meters each unit in the model file should cover.
*/
Map,
/**
* Model is scaled so that it's always the same size on the screen. The property model-scale specifies how many pixels each unit in model file should cover.
*/
Viewport,
}
66 changes: 66 additions & 0 deletions src/libs/Mapbox.Maui/Models/Locations/LocationComponentSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Microsoft.VisualBasic;

namespace MapboxMaui.Locations;

/**
* Shows a location puck on the map.
*/
public record LocationComponentSettings(
/**
* Whether the user location is visible on the map.
*/
bool Enabled,
/**
* Whether the location puck is pulsing on the map. Works for 2D location puck only.
*/
bool PulsingEnabled,
/**
* The color of the pulsing circle. Works for 2D location puck only.
*/
int PulsingColor,
/**
* The maximum radius of the pulsing circle. Works for 2D location puck only. Note: Setting
* [pulsingMaxRadius] to LocationComponentConstants.PULSING_MAX_RADIUS_FOLLOW_ACCURACY will set the
* pulsing circle's maximum radius to follow location accuracy circle. This property is specified in
* pixels.
*/
float PulsingMaxRadius,
/**
* Whether show accuracy ring with location puck. Works for 2D location puck only.
*/
bool ShowAccuracyRing,
/**
* The color of the accuracy ring. Works for 2D location puck only.
*/
int AccuracyRingColor,
/**
* The color of the accuracy ring border. Works for 2D location puck only.
*/
int AccuracyRingBorderColor,
/**
* Sets the id of the layer that's added above to when placing the component on the map.
*/
string LayerAbove,
/**
* Sets the id of the layer that's added below to when placing the component on the map.
*/
string LayerBelow,
/**
* Whether the puck rotates to track the bearing source.
*/
bool PuckBearingEnabled,
/**
* The enum controls how the puck is oriented
*/
PuckBearing puckBearing,
/**
* The slot this layer is assigned to. If specified, and a slot with that name exists, it will be
* placed at that position in the layer order.
*/
string Slot,
/**
* Defines what the customised look of the location puck. Note that direct changes to the puck
* variables won't have any effect, a new puck needs to be set every time.
*/
ILocationPuck LocationPuck
);
7 changes: 7 additions & 0 deletions src/libs/Mapbox.Maui/Models/Locations/PuckBearing.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace MapboxMaui.Locations;

public enum PuckBearing
{
Heading,
Course,
}
6 changes: 5 additions & 1 deletion src/libs/Mapbox.Maui/Platforms/Android/MapboxFragment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public partial class MapboxFragment : Fragment
public event Action<MapView> MapLoaded;
public event Action<MapView> MapLoadingError;
public event Action<MapTappedPosition> MapLongClicked;
public event Action<MapView> MapReady;
public event Action<MapView> StyleLoaded;
public event Action<ViewportStatusChangedEventArgs> ViewportStatusChanged;
public event Action<RotatingEventArgs> Rotating;
Expand Down Expand Up @@ -57,7 +58,10 @@ public override View OnCreateView(LayoutInflater inflater, ViewGroup container,
MapboxOptions.AccessToken = MapboxViewHandler.ACCESS_TOKEN;
}

return MapView = new MapView(Context);
MapView = new MapView(Context);

MapReady?.Invoke(MapView);
return MapView;
}

public override void OnViewCreated(View view, Bundle savedInstanceState)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Android.Animation;
using Android.App;
using Com.Mapbox.Functions;
using Com.Mapbox.Maps.Plugins.Animation;
using MapboxMaui.Camera;

Expand All @@ -12,7 +14,7 @@ public CameraOptions CameraState
{
var mapView = mapboxFragment?.MapView;

if (mapView == null) return default;
if (mapView is null) return default;

return mapView.MapboxMap.CameraState.ToX();
}
Expand All @@ -22,7 +24,7 @@ public void EaseTo(CameraOptions cameraOptions, AnimationOptions animationOption
{
var mapView = mapboxFragment?.MapView;

if (mapView == null) return;
if (mapView is null) return;

var xcameraOptions = cameraOptions.ToNative();
var xanimationOptions = animationOptions?.ToNative();
Expand All @@ -41,7 +43,7 @@ public void FlyTo(CameraOptions cameraOptions, AnimationOptions animationOptions
{
var mapView = mapboxFragment?.MapView;

if (mapView == null) return;
if (mapView is null) return;

var xcameraOptions = cameraOptions.ToNative();
var xanimationOptions = animationOptions?.ToNative();
Expand Down
Loading

0 comments on commit f558ca6

Please sign in to comment.