diff --git a/src/ArcGIS.AllSampleViewers.sln b/src/ArcGIS.AllSampleViewers.sln
index 11f4ec9732..759eefb4c7 100644
--- a/src/ArcGIS.AllSampleViewers.sln
+++ b/src/ArcGIS.AllSampleViewers.sln
@@ -11,8 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArcGIS.WPF.Viewer.Net", "WP
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArcGIS.WinUI.Viewer", "WinUI\ArcGIS.WinUI.Viewer\ArcGIS.WinUI.Viewer.csproj", "{F39D6B3E-4E1D-4211-B152-59F8F71C8544}"
EndProject
-Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "ArcGIS.WinUI.Viewer (Package)", "WinUI\ArcGIS.WinUI.Viewer (Package)\ArcGIS.WinUI.Viewer (Package).wapproj", "{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MAUI", "MAUI", "{5EA55853-597D-4ED0-BAF9-6B737EBC5AC1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArcGIS.Samples.Maui", "MAUI\Maui.Samples\ArcGIS.Samples.Maui.csproj", "{7F7B3255-9EA0-4296-B690-14BE9E2204F3}"
@@ -21,49 +19,19 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ArcGIS.Samples.Shared", "Sa
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
- Ad-Hoc|ARM64 = Ad-Hoc|ARM64
- Ad-Hoc|iPhone = Ad-Hoc|iPhone
- Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
- Ad-Hoc|x64 = Ad-Hoc|x64
- Ad-Hoc|x86 = Ad-Hoc|x86
- AppStore|Any CPU = AppStore|Any CPU
- AppStore|ARM64 = AppStore|ARM64
- AppStore|iPhone = AppStore|iPhone
- AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
- AppStore|x64 = AppStore|x64
- AppStore|x86 = AppStore|x86
Debug|Any CPU = Debug|Any CPU
Debug|ARM64 = Debug|ARM64
- Debug|iPhone = Debug|iPhone
- Debug|iPhoneSimulator = Debug|iPhoneSimulator
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM64 = Release|ARM64
- Release|iPhone = Release|iPhone
- Release|iPhoneSimulator = Release|iPhoneSimulator
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Ad-Hoc|ARM64.ActiveCfg = Release|Any CPU
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Ad-Hoc|x64.ActiveCfg = Release|x64
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Ad-Hoc|x86.ActiveCfg = Release|x86
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.AppStore|ARM64.ActiveCfg = Release|Any CPU
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.AppStore|iPhone.ActiveCfg = Release|Any CPU
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.AppStore|x64.ActiveCfg = Release|x64
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.AppStore|x86.ActiveCfg = Release|x86
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Debug|ARM64.ActiveCfg = Debug|Any CPU
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Debug|x64.ActiveCfg = Debug|x64
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Debug|x64.Build.0 = Debug|x64
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Debug|x86.ActiveCfg = Debug|x86
@@ -71,102 +39,30 @@ Global
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Release|Any CPU.Build.0 = Release|Any CPU
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Release|ARM64.ActiveCfg = Release|Any CPU
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Release|iPhone.ActiveCfg = Release|Any CPU
- {FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Release|x64.ActiveCfg = Release|x64
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Release|x64.Build.0 = Release|x64
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Release|x86.ActiveCfg = Release|x86
{FE1B81E3-59BE-4632-A1EB-12FF19F4B59A}.Release|x86.Build.0 = Release|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Ad-Hoc|Any CPU.ActiveCfg = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Ad-Hoc|Any CPU.Build.0 = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Ad-Hoc|ARM64.ActiveCfg = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Ad-Hoc|ARM64.Build.0 = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Ad-Hoc|iPhone.ActiveCfg = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Ad-Hoc|iPhone.Build.0 = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Ad-Hoc|x64.ActiveCfg = Debug|x64
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Ad-Hoc|x64.Build.0 = Debug|x64
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Ad-Hoc|x86.ActiveCfg = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Ad-Hoc|x86.Build.0 = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.AppStore|Any CPU.ActiveCfg = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.AppStore|Any CPU.Build.0 = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.AppStore|ARM64.ActiveCfg = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.AppStore|ARM64.Build.0 = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.AppStore|iPhone.ActiveCfg = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.AppStore|iPhone.Build.0 = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.AppStore|iPhoneSimulator.ActiveCfg = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.AppStore|iPhoneSimulator.Build.0 = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.AppStore|x64.ActiveCfg = Debug|x64
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.AppStore|x64.Build.0 = Debug|x64
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.AppStore|x86.ActiveCfg = Debug|x86
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.AppStore|x86.Build.0 = Debug|x86
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Debug|Any CPU.ActiveCfg = Debug|x64
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Debug|ARM64.ActiveCfg = Debug|x64
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Debug|iPhone.ActiveCfg = Debug|x64
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Debug|iPhoneSimulator.ActiveCfg = Debug|x64
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Debug|x64.ActiveCfg = Debug|x64
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Debug|x64.Build.0 = Debug|x64
+ {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Debug|x64.Deploy.0 = Debug|x64
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Debug|x86.ActiveCfg = Debug|x86
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Debug|x86.Build.0 = Debug|x86
+ {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Debug|x86.Deploy.0 = Debug|x86
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Release|Any CPU.ActiveCfg = Release|x64
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Release|Any CPU.Build.0 = Release|x64
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Release|ARM64.ActiveCfg = Release|x64
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Release|ARM64.Build.0 = Release|x64
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Release|iPhone.ActiveCfg = Release|x64
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Release|iPhone.Build.0 = Release|x64
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Release|iPhoneSimulator.ActiveCfg = Release|x64
- {F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Release|iPhoneSimulator.Build.0 = Release|x64
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Release|x64.ActiveCfg = Release|x64
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Release|x64.Build.0 = Release|x64
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Release|x86.ActiveCfg = Release|x86
{F39D6B3E-4E1D-4211-B152-59F8F71C8544}.Release|x86.Build.0 = Release|x86
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|Any CPU.ActiveCfg = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|Any CPU.Build.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|Any CPU.Deploy.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|ARM64.ActiveCfg = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|ARM64.Build.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|ARM64.Deploy.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|iPhone.ActiveCfg = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|iPhone.Build.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|iPhone.Deploy.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|x64.ActiveCfg = Debug|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|x64.Build.0 = Debug|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|x64.Deploy.0 = Debug|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|x86.ActiveCfg = Debug|x86
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|x86.Build.0 = Debug|x86
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Ad-Hoc|x86.Deploy.0 = Debug|x86
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|Any CPU.ActiveCfg = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|Any CPU.Build.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|Any CPU.Deploy.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|ARM64.ActiveCfg = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|ARM64.Build.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|ARM64.Deploy.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|iPhone.ActiveCfg = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|iPhone.Build.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|iPhone.Deploy.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|iPhoneSimulator.ActiveCfg = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|iPhoneSimulator.Build.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|iPhoneSimulator.Deploy.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|x64.ActiveCfg = Debug|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|x64.Build.0 = Debug|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|x64.Deploy.0 = Debug|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|x86.ActiveCfg = Debug|x86
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|x86.Build.0 = Debug|x86
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.AppStore|x86.Deploy.0 = Debug|x86
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|Any CPU.ActiveCfg = Debug|x64
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|ARM64.ActiveCfg = Debug|arm64
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|ARM64.Build.0 = Debug|arm64
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|ARM64.Deploy.0 = Debug|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|iPhone.ActiveCfg = Debug|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|iPhone.Build.0 = Debug|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|iPhone.Deploy.0 = Debug|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|iPhoneSimulator.ActiveCfg = Debug|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|iPhoneSimulator.Build.0 = Debug|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|iPhoneSimulator.Deploy.0 = Debug|x64
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|x64.ActiveCfg = Debug|x64
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|x64.Build.0 = Debug|x64
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Debug|x64.Deploy.0 = Debug|x64
@@ -179,64 +75,16 @@ Global
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|ARM64.ActiveCfg = Release|arm64
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|ARM64.Build.0 = Release|arm64
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|ARM64.Deploy.0 = Release|arm64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|iPhone.ActiveCfg = Release|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|iPhone.Build.0 = Release|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|iPhone.Deploy.0 = Release|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|iPhoneSimulator.ActiveCfg = Release|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|iPhoneSimulator.Build.0 = Release|x64
- {BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|iPhoneSimulator.Deploy.0 = Release|x64
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|x64.ActiveCfg = Release|x64
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|x64.Build.0 = Release|x64
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|x64.Deploy.0 = Release|x64
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|x86.ActiveCfg = Release|x86
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|x86.Build.0 = Release|x86
{BA503BD0-660A-4EA6-AB0E-11823F9BAD96}.Release|x86.Deploy.0 = Release|x86
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|Any CPU.Deploy.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|ARM64.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|ARM64.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|ARM64.Deploy.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|iPhone.Deploy.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|x64.Deploy.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Ad-Hoc|x86.Deploy.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|Any CPU.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|Any CPU.Deploy.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|ARM64.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|ARM64.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|ARM64.Deploy.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|iPhone.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|iPhone.Deploy.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|iPhoneSimulator.Deploy.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|x64.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|x64.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|x64.Deploy.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|x86.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|x86.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.AppStore|x86.Deploy.0 = Debug|Any CPU
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Debug|ARM64.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Debug|iPhone.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Debug|iPhone.Deploy.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Debug|x64.ActiveCfg = Debug|Any CPU
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Debug|x86.ActiveCfg = Debug|Any CPU
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -245,12 +93,6 @@ Global
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|ARM64.ActiveCfg = Release|Any CPU
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|ARM64.Build.0 = Release|Any CPU
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|ARM64.Deploy.0 = Release|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|iPhone.ActiveCfg = Release|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|iPhone.Build.0 = Release|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|iPhone.Deploy.0 = Release|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|x64.ActiveCfg = Release|Any CPU
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|x64.Build.0 = Release|Any CPU
{7F7B3255-9EA0-4296-B690-14BE9E2204F3}.Release|x64.Deploy.0 = Release|Any CPU
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
new file mode 100644
index 0000000000..9bba7baacf
--- /dev/null
+++ b/src/Directory.Packages.props
@@ -0,0 +1,36 @@
+
+
+ true
+ 200.2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/ArcGIS.Samples.Maui.csproj b/src/MAUI/Maui.Samples/ArcGIS.Samples.Maui.csproj
index a6489d8a92..ef8cf2a6d7 100644
--- a/src/MAUI/Maui.Samples/ArcGIS.Samples.Maui.csproj
+++ b/src/MAUI/Maui.Samples/ArcGIS.Samples.Maui.csproj
@@ -128,24 +128,22 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
- 1.5.1.1
-
+
diff --git a/src/MAUI/Maui.Samples/Converters/ItemToImageSourceConverter.cs b/src/MAUI/Maui.Samples/Converters/ItemToImageSourceConverter.cs
deleted file mode 100644
index bfef3eb382..0000000000
--- a/src/MAUI/Maui.Samples/Converters/ItemToImageSourceConverter.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using Esri.ArcGISRuntime;
-using Esri.ArcGISRuntime.Portal;
-using System.Globalization;
-
-namespace ArcGIS.Converters
-{
- internal class ItemToImageSourceConverter : IValueConverter
- {
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- Item mapItem = value as Item;
- if (mapItem != null)
- {
- if (mapItem.ThumbnailUri != null)
- {
- // Sometimes image URIs have a . appended to them...
- return ImageSource.FromUri(new Uri(mapItem.ThumbnailUri.OriginalString.TrimEnd('.')));
- }
-
- if (mapItem.Thumbnail != null &&
- mapItem.Thumbnail.LoadStatus == LoadStatus.Loaded &&
- mapItem.Thumbnail.Width > 0)
- {
- return ImageSource.FromStream(() => mapItem.Thumbnail.GetEncodedBufferAsync().Result);
- }
- }
-
- return null;
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- throw new NotImplementedException();
- }
- }
-}
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Helpers/SampleLoader.cs b/src/MAUI/Maui.Samples/Helpers/SampleLoader.cs
index b1a025fff4..b372d85963 100644
--- a/src/MAUI/Maui.Samples/Helpers/SampleLoader.cs
+++ b/src/MAUI/Maui.Samples/Helpers/SampleLoader.cs
@@ -50,7 +50,7 @@ public static async Task LoadSample(SampleInfo sampleInfo)
AuthenticationManager.Current.ChallengeHandler = null;
// Load offline data before showing the sample.
- if (sampleInfo.OfflineDataItems != null)
+ if (sampleInfo.OfflineDataItems != null && !await DataManager.HasSampleDataPresent(sampleInfo))
{
CancellationTokenSource cancellationSource = new CancellationTokenSource();
diff --git a/src/MAUI/Maui.Samples/MauiProgram.cs b/src/MAUI/Maui.Samples/MauiProgram.cs
index 58dfb74dc1..a968af007c 100644
--- a/src/MAUI/Maui.Samples/MauiProgram.cs
+++ b/src/MAUI/Maui.Samples/MauiProgram.cs
@@ -1,12 +1,15 @@
namespace ArcGIS.Samples.Maui;
-using Esri.ArcGISRuntime.Maui;
using CommunityToolkit.Maui;
+using Esri.ArcGISRuntime.Maui;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
+#if __ANDROID__
+ Esri.ArcGISRuntime.UI.Controls.SceneView.MemoryLimit = 2 * 1073741824L; // 2Gb
+#endif
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp()
diff --git a/src/MAUI/Maui.Samples/SamplePage.xaml b/src/MAUI/Maui.Samples/SamplePage.xaml
index 770148f828..bd8f1e28a8 100644
--- a/src/MAUI/Maui.Samples/SamplePage.xaml
+++ b/src/MAUI/Maui.Samples/SamplePage.xaml
@@ -19,7 +19,6 @@
-
@@ -34,7 +33,7 @@
Text=""
VerticalOptions="Center" />
-
+ SourceFiles { get; } = new ObservableCollection();
@@ -41,13 +45,6 @@ public SamplePage()
public SamplePage(ContentPage sample, SampleInfo sampleInfo) : this()
{
- this.NavigatedFrom += NavigatedFromEvent;
-
-#if IOS || MACCATALYST
- // iOS / MacCatalyst lifecycle works differently, so we need to use the main page changing instead of the NavigatedFrom event for this.
- Application.Current.MainPage.PropertyChanged += MainPagePropertyChanged;
-#endif
-
// Set the sample variable.
_sample = sample;
@@ -83,6 +80,50 @@ public SamplePage(ContentPage sample, SampleInfo sampleInfo) : this()
LoadSampleData(sampleInfo);
}
+ protected override void OnNavigatedTo(NavigatedToEventArgs args)
+ {
+ base.OnNavigatedTo(args);
+ SampleDetailPage.Content = DescriptionView;
+ SourceCodeViewContainer.Content = SourceCodeView;
+ DescriptionView.Navigating += Webview_Navigating;
+ SourceCodeView.Navigating += Webview_Navigating;
+ }
+
+ protected override void OnNavigatingFrom(NavigatingFromEventArgs args)
+ {
+ SampleDetailPage.Content = null;
+ SourceCodeViewContainer.Content = null;
+ DescriptionView.Navigating -= Webview_Navigating;
+ SourceCodeView.Navigating -= Webview_Navigating;
+ base.OnNavigatingFrom(args);
+ }
+
+ protected override void OnNavigatedFrom(NavigatedFromEventArgs args)
+ {
+ base.OnNavigatedFrom(args);
+
+ // Check that the navigation is backward from the sample and not forward into another page in the sample.
+ if (!Application.Current.MainPage.Navigation.NavigationStack.OfType().Any())
+ {
+ // Explicit cleanup of the Map and SceneView instead of waiting for garbage collector can help when
+ // lots of geoviews are being opened and closed
+ foreach (var geoView in TreeWalker(_sample))
+ {
+ if (geoView is MapView mapView)
+ {
+ mapView.Map = null;
+ if (mapView.LocationDisplay != null) mapView.LocationDisplay.IsEnabled = false;
+ }
+ else if (geoView is SceneView sceneView) sceneView.Scene = null;
+
+ geoView.Handler?.DisconnectHandler();
+ }
+
+ if (_sample is IDisposable disposableSample) disposableSample.Dispose();
+ if (_sample is IARSample ARSample) ARSample.StopAugmentedReality();
+ }
+ }
+
private async void LoadSampleData(SampleInfo sampleInfo)
{
// Set up the description page.
@@ -93,7 +134,6 @@ private async void LoadSampleData(SampleInfo sampleInfo)
{
Html = htmlString
};
- DescriptionView.Navigating += Webview_Navigating;
}
catch (Exception ex)
{
@@ -104,7 +144,6 @@ private async void LoadSampleData(SampleInfo sampleInfo)
{
LoadSourceCode(sampleInfo);
- SourceCodeView.Navigating += Webview_Navigating;
}
catch (Exception ex)
{
@@ -112,36 +151,6 @@ private async void LoadSampleData(SampleInfo sampleInfo)
}
}
- private void MainPagePropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == "CurrentPage")
- {
- TryDispose();
- }
- }
-
- private void NavigatedFromEvent(object sender, NavigatedFromEventArgs e)
- {
- TryDispose();
- }
-
- private void TryDispose()
- {
- // Check that the navigation is backward from the sample and not forward into another page in the sample.
- if (!Application.Current.MainPage.Navigation.NavigationStack.OfType().Any())
- {
- // Explicit cleanup of the Map and SceneView instead of waiting for garbage collector can help when
- // lots of geoviews are being opened and closed
- foreach (var geoview in TreeWalker(_sample))
- {
- geoview.Handler?.DisconnectHandler();
- }
-
- if (_sample is IDisposable disposableSample) disposableSample.Dispose();
- if (_sample is IARSample ARSample) ARSample.StopAugmentedReality();
- }
- }
-
private static IEnumerable TreeWalker(VisualElement root)
{
if (root is not null)
diff --git a/src/MAUI/Maui.Samples/Samples/Analysis/DistanceMeasurement/DistanceMeasurement.xaml b/src/MAUI/Maui.Samples/Samples/Analysis/DistanceMeasurement/DistanceMeasurement.xaml
index 6fc7ca4dd2..95efe73be1 100644
--- a/src/MAUI/Maui.Samples/Samples/Analysis/DistanceMeasurement/DistanceMeasurement.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Analysis/DistanceMeasurement/DistanceMeasurement.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Analysis/LineOfSightGeoElement/LineOfSightGeoElement.xaml b/src/MAUI/Maui.Samples/Samples/Analysis/LineOfSightGeoElement/LineOfSightGeoElement.xaml
index fac02c3962..890eef999d 100644
--- a/src/MAUI/Maui.Samples/Samples/Analysis/LineOfSightGeoElement/LineOfSightGeoElement.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Analysis/LineOfSightGeoElement/LineOfSightGeoElement.xaml
@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui"
xmlns:sampleViewer="clr-namespace:ArcGIS.Resources">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Analysis/QueryFeatureCountAndExtent/QueryFeatureCountAndExtent.xaml b/src/MAUI/Maui.Samples/Samples/Analysis/QueryFeatureCountAndExtent/QueryFeatureCountAndExtent.xaml
index 7d43a752a1..021121e9cd 100644
--- a/src/MAUI/Maui.Samples/Samples/Analysis/QueryFeatureCountAndExtent/QueryFeatureCountAndExtent.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Analysis/QueryFeatureCountAndExtent/QueryFeatureCountAndExtent.xaml
@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui"
xmlns:sampleViewer="clr-namespace:ArcGIS.Resources">
-
+
-
+
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Data/EditAndSyncFeatures/EditAndSyncFeatures.xaml b/src/MAUI/Maui.Samples/Samples/Data/EditAndSyncFeatures/EditAndSyncFeatures.xaml
index 48c065020b..04211e619f 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/EditAndSyncFeatures/EditAndSyncFeatures.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/EditAndSyncFeatures/EditAndSyncFeatures.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Data/EditBranchVersioning/EditBranchVersioning.xaml b/src/MAUI/Maui.Samples/Samples/Data/EditBranchVersioning/EditBranchVersioning.xaml
index 559a1d72fa..1797c2e5b1 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/EditBranchVersioning/EditBranchVersioning.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/EditBranchVersioning/EditBranchVersioning.xaml
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Data/EditFeatureAttachments/EditFeatureAttachments.xaml b/src/MAUI/Maui.Samples/Samples/Data/EditFeatureAttachments/EditFeatureAttachments.xaml
index 085dadeb13..90a1aaded1 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/EditFeatureAttachments/EditFeatureAttachments.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/EditFeatureAttachments/EditFeatureAttachments.xaml
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Data/EditFeatureLinkedAnnotation/EditFeatureLinkedAnnotation.xaml b/src/MAUI/Maui.Samples/Samples/Data/EditFeatureLinkedAnnotation/EditFeatureLinkedAnnotation.xaml
index 1b3b557205..3df6b5d947 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/EditFeatureLinkedAnnotation/EditFeatureLinkedAnnotation.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/EditFeatureLinkedAnnotation/EditFeatureLinkedAnnotation.xaml
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Data/FeatureLayerQuery/FeatureLayerQuery.xaml b/src/MAUI/Maui.Samples/Samples/Data/FeatureLayerQuery/FeatureLayerQuery.xaml
index bccc0f7a25..c0cc113133 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/FeatureLayerQuery/FeatureLayerQuery.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/FeatureLayerQuery/FeatureLayerQuery.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Data/GenerateGeodatabaseReplica/GenerateGeodatabaseReplica.xaml b/src/MAUI/Maui.Samples/Samples/Data/GenerateGeodatabaseReplica/GenerateGeodatabaseReplica.xaml
index 9984a96b38..1787216c83 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/GenerateGeodatabaseReplica/GenerateGeodatabaseReplica.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/GenerateGeodatabaseReplica/GenerateGeodatabaseReplica.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Data/GeodatabaseTransactions/GeodatabaseTransactions.xaml b/src/MAUI/Maui.Samples/Samples/Data/GeodatabaseTransactions/GeodatabaseTransactions.xaml
index ff9ea20e91..3f496a0c85 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/GeodatabaseTransactions/GeodatabaseTransactions.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/GeodatabaseTransactions/GeodatabaseTransactions.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
{
- // Call a function (and await it) to get the local geodatabase (or generate it from the feature service)
+ // Call a function (and await it) to get the local geodatabase (or generate it from the feature service).
await GetLocalGeodatabase();
- // Once the local geodatabase is available, load the tables as layers to the map
+ // Once the local geodatabase is available, load the tables as layers to the map.
await LoadLocalGeodatabaseTables();
};
- // Create a new map with the oceans basemap and add it to the map view
+ // Create a new map with the oceans basemap and add it to the map view.
Map map = new Map(BasemapStyle.ArcGISOceans);
MyMapView.Map = map;
}
private async Task GetLocalGeodatabase()
{
- // Get the path to the local geodatabase for this platform (temp directory, for example)
+ // Get the path to the local geodatabase for this platform (temp directory, for example).
string localGeodatabasePath = GetGdbPath();
try
{
- // See if the geodatabase file is already present
+ // See if the geodatabase file is already present.
if (File.Exists(localGeodatabasePath))
{
- // If the geodatabase is already available, open it, hide the progress control, and update the message
+ // If the geodatabase is already available, open it, hide the progress control, and update the message.
_localGeodatabase = await Geodatabase.OpenAsync(localGeodatabasePath);
LoadingProgressBar.IsVisible = false;
MessageTextBlock.Text = "Using local geodatabase from '" + _localGeodatabase.Path + "'";
}
else
{
- // Create a new GeodatabaseSyncTask with the uri of the feature server to pull from
+ // Create a new GeodatabaseSyncTask with the uri of the feature server to pull from.
Uri uri = new Uri(SyncServiceUrl);
GeodatabaseSyncTask gdbTask = await GeodatabaseSyncTask.CreateAsync(uri);
- // Create parameters for the task: layers and extent to include, out spatial reference, and sync model
+ // Create parameters for the task: layers and extent to include, out spatial reference, and sync model.
GenerateGeodatabaseParameters gdbParams = await gdbTask.CreateDefaultGenerateGeodatabaseParametersAsync(_extent);
gdbParams.OutSpatialReference = MyMapView.SpatialReference;
gdbParams.SyncModel = SyncModel.Layer;
@@ -85,18 +89,18 @@ private async Task GetLocalGeodatabase()
gdbParams.LayerOptions.Add(new GenerateLayerOption(0));
gdbParams.LayerOptions.Add(new GenerateLayerOption(1));
- // Create a geodatabase job that generates the geodatabase
+ // Create a geodatabase job that generates the geodatabase.
GenerateGeodatabaseJob generateGdbJob = gdbTask.GenerateGeodatabase(gdbParams, localGeodatabasePath);
- // Handle the job changed event and check the status of the job; store the geodatabase when it's ready
+ // Handle the job changed event and check the status of the job; store the geodatabase when it's ready.
generateGdbJob.StatusChanged += (s, e) =>
{
- // See if the job succeeded
+ // See if the job succeeded.
if (generateGdbJob.Status == JobStatus.Succeeded)
{
Microsoft.Maui.ApplicationModel.MainThread.BeginInvokeOnMainThread(() =>
{
- // Hide the progress control and update the message
+ // Hide the progress control and update the message.
LoadingProgressBar.IsVisible = false;
MessageTextBlock.Text = "Created local geodatabase";
});
@@ -105,20 +109,20 @@ private async Task GetLocalGeodatabase()
{
Microsoft.Maui.ApplicationModel.MainThread.BeginInvokeOnMainThread(() =>
{
- // Hide the progress control and report the exception
+ // Hide the progress control and report the exception.
LoadingProgressBar.IsVisible = false;
MessageTextBlock.Text = "Unable to create local geodatabase: " + generateGdbJob.Error.Message;
});
}
};
- // Start the generate geodatabase job
+ // Start the generate geodatabase job.
_localGeodatabase = await generateGdbJob.GetResultAsync();
}
}
catch (Exception ex)
{
- // Show a message for the exception encountered
+ // Show a message for the exception encountered.
Microsoft.Maui.ApplicationModel.MainThread.BeginInvokeOnMainThread(() =>
{
Application.Current.MainPage.DisplayAlert("Generate Geodatabase", "Unable to create offline database: " + ex.Message, "OK");
@@ -126,34 +130,34 @@ private async Task GetLocalGeodatabase()
}
}
- // Function that loads the two point tables from the local geodatabase and displays them as feature layers
+ // Function that loads the two point tables from the local geodatabase and displays them as feature layers.
private async Task LoadLocalGeodatabaseTables()
{
if (_localGeodatabase == null) { return; }
- // Read the geodatabase tables and add them as layers
+ // Read the geodatabase tables and add them as layers.
foreach (GeodatabaseFeatureTable table in _localGeodatabase.GeodatabaseFeatureTables)
{
try
{
- // Load the table so the TableName can be read
+ // Load the table so the TableName can be read.
await table.LoadAsync();
- // Store a reference to the Birds table
+ // Store a reference to the Birds table.
if (table.TableName.ToLower().Contains("birds"))
{
_birdTable = table;
}
- // Store a reference to the Marine table
+ // Store a reference to the Marine table.
if (table.TableName.ToLower().Contains("marine"))
{
_marineTable = table;
}
- // Create a new feature layer to show the table in the map
+ // Create a new feature layer to show the table in the map.
FeatureLayer layer = new FeatureLayer(table);
- Microsoft.Maui.ApplicationModel.MainThread.BeginInvokeOnMainThread(() => MyMapView.Map.OperationalLayers.Add(layer));
+ Microsoft.Maui.ApplicationModel.MainThread.BeginInvokeOnMainThread(() => MyMapView.Map?.OperationalLayers.Add(layer));
}
catch (Exception e)
{
@@ -161,10 +165,10 @@ private async Task LoadLocalGeodatabaseTables()
}
}
- // Handle the transaction status changed event
+ // Handle the transaction status changed event.
_localGeodatabase.TransactionStatusChanged += GdbTransactionStatusChanged;
- // Zoom the map view to the extent of the generated local datasets
+ // Zoom the map view to the extent of the generated local datasets.
Microsoft.Maui.ApplicationModel.MainThread.BeginInvokeOnMainThread(() =>
{
MyMapView.SetViewpoint(new Viewpoint(_marineTable.Extent));
@@ -175,15 +179,15 @@ private async Task LoadLocalGeodatabaseTables()
private void GdbTransactionStatusChanged(object sender, TransactionStatusChangedEventArgs e)
{
- // Update UI controls based on whether the geodatabase has a current transaction
+ // Update UI controls based on whether the geodatabase has a current transaction.
Microsoft.Maui.ApplicationModel.MainThread.BeginInvokeOnMainThread(() =>
{
- // These buttons should be enabled when there IS a transaction
+ // These buttons should be enabled when there IS a transaction.
AddBirdButton.IsEnabled = e.IsInTransaction;
AddMarineButton.IsEnabled = e.IsInTransaction;
StopEditingButton.IsEnabled = e.IsInTransaction;
- // These buttons should be enabled when there is NOT a transaction
+ // These buttons should be enabled when there is NOT a transaction.
StartEditingButton.IsEnabled = !e.IsInTransaction;
SyncEditsButton.IsEnabled = !e.IsInTransaction;
RequireTransactionCheckBox.IsEnabled = !e.IsInTransaction;
@@ -192,83 +196,90 @@ private void GdbTransactionStatusChanged(object sender, TransactionStatusChanged
private string GetGdbPath()
{
- // Set the platform-specific path for storing the geodatabase
+ // Set the platform-specific path for storing the geodatabase.
string folder = string.Empty;
#if WINDOWS
folder = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
-#elif IOS || ANDROID
+#elif IOS || ANDROID || MACCATALYST
folder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
#endif
- // Set the final path
+ // Set the final path.
return Path.Combine(folder, "savethebay.geodatabase");
}
private void BeginTransaction(object sender, EventArgs e)
{
- // See if there is a transaction active for the geodatabase
+ // See if there is a transaction active for the geodatabase.
if (!_localGeodatabase.IsInTransaction)
{
- // If not, begin a transaction
+ // If not, begin a transaction.
_localGeodatabase.BeginTransaction();
MessageTextBlock.Text = "Transaction started";
}
}
- private async void AddNewFeature(object sender, EventArgs args)
+ private void AddNewFeature(object sender, EventArgs args)
{
- // See if it was the "Birds" or "Marine" button that was clicked
+ // See if it was the "Birds" or "Marine" button that was clicked.
Button addFeatureButton = (Button)sender;
try
{
- // Cancel execution of the sketch task if it is already active
- if (MyMapView.SketchEditor.CancelCommand.CanExecute(null))
- {
- MyMapView.SketchEditor.CancelCommand.Execute(null);
- }
-
- // Store the correct table to edit (for the button clicked)
- GeodatabaseFeatureTable editTable = null;
+ // Store the correct table to edit (for the button clicked).
if (addFeatureButton == AddBirdButton)
{
- editTable = _birdTable;
+ _editTable = _birdTable;
}
else
{
- editTable = _marineTable;
+ _editTable = _marineTable;
}
- // Inform the user which table is being edited
- MessageTextBlock.Text = "Click the map to add a new feature to the geodatabase table '" + editTable.TableName + "'";
+ // Inform the user which table is being edited.
+ MessageTextBlock.Text = "Click the map to add a new feature to the geodatabase table '" + _editTable.TableName + "'";
- // Create a random value for the 'type' attribute (integer between 1 and 7)
- Random random = new Random(DateTime.Now.Millisecond);
- int featureType = random.Next(1, 7);
+ // Use the geometry editor to allow the user to draw a point on the map.
+ MyMapView.GeometryEditor.Start(GeometryType.Point);
+
+ MyMapView.GeometryEditor.PropertyChanged += GeometryEditor_PropertyChanged;
+ }
+ catch (Exception ex)
+ {
+ // Report other exception messages.
+ MessageTextBlock.Text = ex.Message;
+ }
+ }
- // Use the sketch editor to allow the user to draw a point on the map
- MapPoint clickPoint = await MyMapView.SketchEditor.StartAsync(SketchCreationMode.Point, false) as MapPoint;
+ private async void GeometryEditor_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ // Check if the user finished drawing a point on the map.
+ if (e.PropertyName == nameof(GeometryEditor.Geometry))
+ {
+ // Disconnect event handler to prevent multiple calls.
+ MyMapView.GeometryEditor.PropertyChanged -= GeometryEditor_PropertyChanged;
- // Create a new feature (row) in the selected table
- Feature newFeature = editTable.CreateFeature();
+ // Get the active geometry.
+ Geometry geometry = MyMapView.GeometryEditor.Geometry;
- // Set the geometry with the point the user clicked and the 'type' with the random integer
- newFeature.Geometry = clickPoint;
+ // Create a new feature (row) in the selected table.
+ Feature newFeature = _editTable.CreateFeature();
+
+ // Create a random value for the 'type' attribute (integer between 1 and 7).
+ Random random = new Random(DateTime.Now.Millisecond);
+ int featureType = random.Next(1, 7);
+
+ // Set the geometry with the point the user clicked and the 'type' with the random integer.
+ newFeature.Geometry = geometry;
newFeature.SetAttributeValue("type", featureType);
- // Add the new feature to the table
- await editTable.AddFeatureAsync(newFeature);
+ // Add the new feature to the table.
+ await _editTable.AddFeatureAsync(newFeature);
- // Clear the message
- MessageTextBlock.Text = "New feature added to the '" + editTable.TableName + "' table";
- }
- catch (TaskCanceledException)
- {
- // Ignore if the edit was canceled
- }
- catch (Exception ex)
- {
- // Report other exception messages
- MessageTextBlock.Text = ex.Message;
+ // Set the newly created feature message.
+ MessageTextBlock.Text = "New feature added to the '" + _editTable.TableName + "' table";
+
+ // Stop the geometry editor, clearing the active geometry.
+ MyMapView.GeometryEditor.Stop();
}
}
@@ -276,32 +287,32 @@ private async void StopEditTransaction(object sender, EventArgs e)
{
try
{
- // Ask the user if they want to commit or rollback the transaction (or cancel to keep working in the transaction)
+ // Ask the user if they want to commit or rollback the transaction (or cancel to keep working in the transaction).
string choice = await Application.Current.MainPage.DisplayActionSheet("Transaction", "Cancel", null, "Commit", "Rollback");
if (choice == "Commit")
{
- // See if there is a transaction active for the geodatabase
+ // See if there is a transaction active for the geodatabase.
if (_localGeodatabase.IsInTransaction)
{
- // If there is, commit the transaction to store the edits (this will also end the transaction)
+ // If there is, commit the transaction to store the edits (this will also end the transaction).
_localGeodatabase.CommitTransaction();
MessageTextBlock.Text = "Edits were committed to the local geodatabase.";
}
}
else if (choice == "Rollback")
{
- // See if there is a transaction active for the geodatabase
+ // See if there is a transaction active for the geodatabase.
if (_localGeodatabase.IsInTransaction)
{
- // If there is, rollback the transaction to discard the edits (this will also end the transaction)
+ // If there is, rollback the transaction to discard the edits (this will also end the transaction).
_localGeodatabase.RollbackTransaction();
MessageTextBlock.Text = "Edits were rolled back and not stored to the local geodatabase.";
}
}
else
{
- // For 'cancel' don't end the transaction with a commit or rollback
+ // For 'cancel' don't end the transaction with a commit or rollback.
}
}
catch (Exception ex)
@@ -310,16 +321,16 @@ private async void StopEditTransaction(object sender, EventArgs e)
}
}
- // Change which controls are enabled if the user chooses to require/not require transactions for edits
+ // Change which controls are enabled if the user chooses to require/not require transactions for edits.
private void RequireTransactionChanged(object sender, EventArgs e)
{
- // If the local geodatabase isn't created yet, return
+ // If the local geodatabase isn't created yet, return.
if (_localGeodatabase == null) { return; }
- // Get the value of the "require transactions" checkbox
+ // Get the value of the "require transactions" checkbox.
bool mustHaveTransaction = RequireTransactionCheckBox.IsToggled;
- // Warn the user if disabling transactions while a transaction is active
+ // Warn the user if disabling transactions while a transaction is active.
if (!mustHaveTransaction && _localGeodatabase.IsInTransaction)
{
Application.Current.MainPage.DisplayAlert("Stop editing to end the current transaction.", "Current Transaction", "OK");
@@ -327,34 +338,34 @@ private void RequireTransactionChanged(object sender, EventArgs e)
return;
}
- // Enable or disable controls according to the checkbox value
+ // Enable or disable controls according to the checkbox value.
StartEditingButton.IsEnabled = mustHaveTransaction;
StopEditingButton.IsEnabled = mustHaveTransaction && _localGeodatabase.IsInTransaction;
AddBirdButton.IsEnabled = !mustHaveTransaction;
AddMarineButton.IsEnabled = !mustHaveTransaction;
}
- // Synchronize edits in the local geodatabase with the service
+ // Synchronize edits in the local geodatabase with the service.
public async void SynchronizeEdits(object sender, EventArgs e)
{
- // Show the progress bar while the sync is working
+ // Show the progress bar while the sync is working.
LoadingProgressBar.IsVisible = true;
try
{
- // Create a sync task with the URL of the feature service to sync
+ // Create a sync task with the URL of the feature service to sync.
GeodatabaseSyncTask syncTask = await GeodatabaseSyncTask.CreateAsync(new Uri(SyncServiceUrl));
- // Create sync parameters
+ // Create sync parameters.
SyncGeodatabaseParameters taskParameters = await syncTask.CreateDefaultSyncGeodatabaseParametersAsync(_localGeodatabase);
- // Create a synchronize geodatabase job, pass in the parameters and the geodatabase
+ // Create a synchronize geodatabase job, pass in the parameters and the geodatabase.
SyncGeodatabaseJob job = syncTask.SyncGeodatabase(taskParameters, _localGeodatabase);
- // Handle the JobChanged event for the job
+ // Handle the JobChanged event for the job.
job.StatusChanged += (s, arg) =>
{
- // Report changes in the job status
+ // Report changes in the job status.
if (job.Status == JobStatus.Succeeded)
{
// Report success ...
@@ -372,17 +383,17 @@ public async void SynchronizeEdits(object sender, EventArgs e)
}
};
- // Await the completion of the job
+ // Await the completion of the job.
await job.GetResultAsync();
}
catch (Exception ex)
{
- // Show the message if an exception occurred
+ // Show the message if an exception occurred.
MessageTextBlock.Text = "Error when synchronizing: " + ex.Message;
}
finally
{
- // Hide the progress bar when the sync job is complete
+ // Hide the progress bar when the sync job is complete.
LoadingProgressBar.IsVisible = false;
}
}
diff --git a/src/MAUI/Maui.Samples/Samples/Data/GeodatabaseTransactions/readme.md b/src/MAUI/Maui.Samples/Samples/Data/GeodatabaseTransactions/readme.md
index f3c805d2ea..5ccf650ca7 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/GeodatabaseTransactions/readme.md
+++ b/src/MAUI/Maui.Samples/Samples/Data/GeodatabaseTransactions/readme.md
@@ -27,6 +27,7 @@ When the sample loads, a feature service is taken offline as a geodatabase. When
* Geodatabase.CommitTransaction
* Geodatabase.IsInTransaction
* Geodatabase.RollbackTransaction
+* GeometryEditor
## About the data
@@ -34,4 +35,4 @@ The sample uses a publicly-editable, sync-enabled [feature service](https://samp
## Tags
-commit, database, geodatabase, transact, transactions
\ No newline at end of file
+commit, database, geodatabase, geometry editor, transact, transactions
diff --git a/src/MAUI/Maui.Samples/Samples/Data/GeodatabaseTransactions/readme.metadata.json b/src/MAUI/Maui.Samples/Samples/Data/GeodatabaseTransactions/readme.metadata.json
index 6bd8737def..07bc56e915 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/GeodatabaseTransactions/readme.metadata.json
+++ b/src/MAUI/Maui.Samples/Samples/Data/GeodatabaseTransactions/readme.metadata.json
@@ -10,6 +10,7 @@
"commit",
"database",
"geodatabase",
+ "geometry editor",
"transact",
"transactions"
],
@@ -22,7 +23,8 @@
"Geodatabase.BeginTransaction",
"Geodatabase.CommitTransaction",
"Geodatabase.IsInTransaction",
- "Geodatabase.RollbackTransaction"
+ "Geodatabase.RollbackTransaction",
+ "GeometryEditor"
],
"snippets": [
"GeodatabaseTransactions.xaml.cs",
diff --git a/src/MAUI/Maui.Samples/Samples/Data/ListRelatedFeatures/ListRelatedFeatures.xaml b/src/MAUI/Maui.Samples/Samples/Data/ListRelatedFeatures/ListRelatedFeatures.xaml
index 362cd332c5..0516576da2 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/ListRelatedFeatures/ListRelatedFeatures.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/ListRelatedFeatures/ListRelatedFeatures.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Data/ManageFeatures/ManageFeatures.xaml b/src/MAUI/Maui.Samples/Samples/Data/ManageFeatures/ManageFeatures.xaml
index ba345be0d7..f6cf35dfd6 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/ManageFeatures/ManageFeatures.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/ManageFeatures/ManageFeatures.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Data/ReadShapefileMetadata/ReadShapefileMetadata.xaml b/src/MAUI/Maui.Samples/Samples/Data/ReadShapefileMetadata/ReadShapefileMetadata.xaml
index b306e13510..19f54d5ba2 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/ReadShapefileMetadata/ReadShapefileMetadata.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/ReadShapefileMetadata/ReadShapefileMetadata.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Data/StatisticalQuery/StatisticalQuery.xaml b/src/MAUI/Maui.Samples/Samples/Data/StatisticalQuery/StatisticalQuery.xaml
index 5b5d49e177..cdd8e456e1 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/StatisticalQuery/StatisticalQuery.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/StatisticalQuery/StatisticalQuery.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Data/SymbolizeShapefile/SymbolizeShapefile.xaml b/src/MAUI/Maui.Samples/Samples/Data/SymbolizeShapefile/SymbolizeShapefile.xaml
index af57c9c57e..d751fdb912 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/SymbolizeShapefile/SymbolizeShapefile.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/SymbolizeShapefile/SymbolizeShapefile.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Data/ToggleBetweenFeatureRequestModes/ToggleBetweenFeatureRequestModes.xaml b/src/MAUI/Maui.Samples/Samples/Data/ToggleBetweenFeatureRequestModes/ToggleBetweenFeatureRequestModes.xaml
index 779d9d142d..54f4839caa 100644
--- a/src/MAUI/Maui.Samples/Samples/Data/ToggleBetweenFeatureRequestModes/ToggleBetweenFeatureRequestModes.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Data/ToggleBetweenFeatureRequestModes/ToggleBetweenFeatureRequestModes.xaml
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Geometry/Buffer/Buffer.xaml b/src/MAUI/Maui.Samples/Samples/Geometry/Buffer/Buffer.xaml
index 28e89b1f11..a1365b362c 100644
--- a/src/MAUI/Maui.Samples/Samples/Geometry/Buffer/Buffer.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Geometry/Buffer/Buffer.xaml
@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui"
xmlns:resources="clr-namespace:ArcGIS.Resources">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Geometry/BufferList/BufferList.xaml b/src/MAUI/Maui.Samples/Samples/Geometry/BufferList/BufferList.xaml
index 9fe73aa043..3ca95a2007 100644
--- a/src/MAUI/Maui.Samples/Samples/Geometry/BufferList/BufferList.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Geometry/BufferList/BufferList.xaml
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Geometry/ConvexHull/ConvexHull.xaml b/src/MAUI/Maui.Samples/Samples/Geometry/ConvexHull/ConvexHull.xaml
index 9f24e7310f..bf65ab6a80 100644
--- a/src/MAUI/Maui.Samples/Samples/Geometry/ConvexHull/ConvexHull.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Geometry/ConvexHull/ConvexHull.xaml
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Geometry/DensifyAndGeneralize/DensifyAndGeneralize.xaml b/src/MAUI/Maui.Samples/Samples/Geometry/DensifyAndGeneralize/DensifyAndGeneralize.xaml
index 971b6a9e24..1ff7fdce84 100644
--- a/src/MAUI/Maui.Samples/Samples/Geometry/DensifyAndGeneralize/DensifyAndGeneralize.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Geometry/DensifyAndGeneralize/DensifyAndGeneralize.xaml
@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui"
xmlns:sampleViewer="clr-namespace:ArcGIS.Resources">
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/CreateAndEditGeometries.xaml b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/CreateAndEditGeometries.xaml
new file mode 100644
index 0000000000..33986e68bf
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/CreateAndEditGeometries.xaml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/CreateAndEditGeometries.xaml.cs b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/CreateAndEditGeometries.xaml.cs
new file mode 100644
index 0000000000..3ae360dabc
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/CreateAndEditGeometries.xaml.cs
@@ -0,0 +1,399 @@
+// Copyright 2023 Esri.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+// language governing permissions and limitations under the License.
+
+using Esri.ArcGISRuntime.Data;
+using Esri.ArcGISRuntime.Geometry;
+using Esri.ArcGISRuntime.Mapping;
+using Esri.ArcGISRuntime.Symbology;
+using Esri.ArcGISRuntime.UI;
+using Esri.ArcGISRuntime.UI.Editing;
+using Color = System.Drawing.Color;
+
+namespace ArcGIS.Samples.CreateAndEditGeometries
+{
+ [ArcGIS.Samples.Shared.Attributes.Sample(
+ name: "Create and edit geometries",
+ category: "GraphicsOverlay",
+ description: "Use the Geometry Editor to create new point, multipoint, polyline, or polygon geometries or to edit existing geometries by interacting with a map view.",
+ instructions: "To create a new geometry, press the button appropriate for the geometry type you want to create (i.e. points, multipoints, polyline, or polygon) and interactively tap and drag on the map view to create the geometry. To edit an existing geometry, tap the geometry to be edited in the map to select it and then edit the geometry by tapping and dragging elements of the geometry. If creating or editing polyline or polygon geometries, choose the desired creation/editing tool (i.e. `VertexTool` or `FreehandTool`).",
+ tags: new[] { "draw", "edit", "freehand", "geometry editor", "sketch", "vertex" })]
+ public partial class CreateAndEditGeometries
+ {
+ private GeometryEditor _geometryEditor;
+ private Graphic _selectedGraphic;
+ private GraphicsOverlay _graphicsOverlay;
+
+ private SimpleFillSymbol _polygonSymbol;
+ private SimpleLineSymbol _polylineSymbol;
+ private SimpleMarkerSymbol _pointSymbol, _multiPointSymbol;
+
+ private Dictionary _geometryButtons;
+ private Dictionary _toolDictionary;
+
+ // Json formatted strings for initial geometries.
+ private readonly string _houseCoordinatesJson = @"{""x"": -1067898.59, ""y"": 6998366.62,
+ ""spatialReference"": {""latestWkid"":3857, ""wkid"":102100}}";
+
+ private readonly string _outbuildingCoordinatesJson = @"{""points"":[[-1067984.26,6998346.28],[-1067966.80,6998244.84],
+ [-1067921.88,6998284.65],[-1067934.36,6998340.74],
+ [-1067917.93,6998373.97],[-1067828.30,6998355.28],
+ [-1067832.25,6998339.70],[-1067823.10,6998336.93],
+ [-1067873.22,6998386.78],[-1067896.72,6998244.49]],
+ ""spatialReference"":{""latestWkid"":3857,""wkid"":102100}}";
+
+ private readonly string _road1CoordinatesJson = @"{""paths"":[[[-1068095.40,6998123.52],[-1068086.16,6998134.60],
+ [-1068083.20,6998160.44],[-1068104.27,6998205.37],
+ [-1068070.63,6998255.22],[-1068014.44,6998291.54],
+ [-1067952.33,6998351.85],[-1067927.93,6998386.93],
+ [-1067907.97,6998396.78],[-1067889.86,6998406.63],
+ [-1067848.08,6998495.26],[-1067832.92,6998521.11]]],
+ ""spatialReference"":{""latestWkid"":3857,""wkid"":102100}}";
+
+ private readonly string _road2CoordinatesJson = @"{""paths"":[[[-1067999.28,6998061.97],[-1067994.48,6998086.59],
+ [-1067964.53,6998125.37],[-1067952.70,6998215.84],
+ [-1067923.13,6998347.54],[-1067903.90,6998391.86],
+ [-1067895.40,6998422.02],[-1067891.70,6998460.18],
+ [-1067889.49,6998483.56],[-1067880.98,6998527.26]]],
+ ""spatialReference"":{""latestWkid"":3857,""wkid"":102100}}";
+
+ private readonly string _boundaryCoordinatesJson = @"{ ""rings"": [[[-1067943.67,6998403.86],[-1067938.17,6998427.60],
+ [-1067898.77,6998415.86],[-1067888.26,6998398.80],
+ [-1067800.85,6998372.93],[-1067799.61,6998342.81],
+ [-1067809.38,6998330.00],[-1067817.07,6998307.85],
+ [-1067838.07,6998285.34],[-1067849.10,6998250.38],
+ [-1067874.02,6998256.00],[-1067879.87,6998235.95],
+ [-1067913.41,6998245.03],[-1067934.84,6998291.34],
+ [-1067948.41,6998251.90],[-1067961.18,6998186.68],
+ [-1068008.59,6998199.49],[-1068052.89,6998225.45],
+ [-1068039.37,6998261.11],[-1068064.12,6998265.26],
+ [-1068043.32,6998299.88],[-1068036.25,6998327.93],
+ [-1068004.43,6998409.28],[-1067943.67,6998403.86]]],
+ ""spatialReference"":{""latestWkid"":3857,""wkid"":102100}}";
+
+ public CreateAndEditGeometries()
+ {
+ InitializeComponent();
+ Initialize();
+ }
+
+ private void Initialize()
+ {
+ // Create a map for the map view and set an inital viewpoint.
+ MyMapView.Map = new Map(BasemapStyle.ArcGISImagery)
+ {
+ InitialViewpoint = new Viewpoint(53.08230, -9.5920, 5000)
+ };
+
+ // Create a graphics overlay and add it to the map view.
+ _graphicsOverlay = new GraphicsOverlay();
+ MyMapView.GraphicsOverlays.Add(_graphicsOverlay);
+
+ // Create a geometry editor and set it to the map view.
+ _geometryEditor = new GeometryEditor();
+ MyMapView.GeometryEditor = _geometryEditor;
+
+ // Create geometry editor tools for the combo box.
+ _toolDictionary = new Dictionary()
+ {
+ { "Vertex Tool", new VertexTool() },
+ { "Freehand Tool", new FreehandTool() },
+ { "Arrow Shape Tool", ShapeTool.Create(ShapeToolType.Arrow) },
+ { "Ellipse Shape Tool", ShapeTool.Create(ShapeToolType.Ellipse) },
+ { "Rectangle Shape Tool", ShapeTool.Create(ShapeToolType.Rectangle) },
+ { "Triangle Shape Tool", ShapeTool.Create(ShapeToolType.Triangle) }
+ };
+ ToolPicker.ItemsSource = _toolDictionary.Keys.ToList();
+
+ // Have the vertex tool selected by default.
+ ToolPicker.SelectedIndex = 0;
+
+ // Create a dictionary to lookup which geometry type corresponds with which button.
+ _geometryButtons = new Dictionary
+ {
+ { GeometryType.Point, PointButton },
+ { GeometryType.Multipoint, MultipointButton },
+ { GeometryType.Polyline, PolylineButton },
+ { GeometryType.Polygon, PolygonButton }
+ };
+
+ CreateInitialGraphics();
+ }
+
+ #region Event handlers
+
+ // Starts the geometry editor with the point geometry type.
+ private void PointButton_Click(object sender, EventArgs e)
+ {
+ if (!_geometryEditor.IsStarted)
+ {
+ // Disable buttons to reflect that the geometry editor has started.
+ DisableOtherGeometryButtons(PointButton);
+
+ // Disable the combo box as this is always a vertex tool when creating a point.
+ ToolPicker.IsEnabled = false;
+
+ // Disable scale checkbox since points don't scale.
+ UniformScaleCheckBox.IsEnabled = false;
+
+ _geometryEditor.Start(GeometryType.Point);
+ }
+ }
+
+ // Start the geometry editor with the multipoint geometry type.
+ private void MultipointButton_Click(object sender, EventArgs e)
+ {
+ if (!_geometryEditor.IsStarted)
+ {
+ // Disable buttons to reflect that the geometry editor has started.
+ DisableOtherGeometryButtons(MultipointButton);
+
+ // Disable the combo box as this is always a vertex tool when creating a point.
+ ToolPicker.IsEnabled = false;
+
+ _geometryEditor.Start(GeometryType.Multipoint);
+ }
+ }
+
+ // Start the geometry editor with the polyline geometry type.
+ private void PolylineButton_Click(object sender, EventArgs e)
+ {
+ if (!_geometryEditor.IsStarted)
+ {
+ // Disable buttons to reflect that the geometry editor has started.
+ DisableOtherGeometryButtons(PointButton);
+
+ _geometryEditor.Start(GeometryType.Polyline);
+ }
+ }
+
+ // Start the geometry editor with the polygon geometry type.
+ private void PolygonButton_Click(object sender, EventArgs e)
+ {
+ if (!_geometryEditor.IsStarted)
+ {
+ // Disable buttons to reflect that the geometry editor has started.
+ DisableOtherGeometryButtons(PointButton);
+
+ _geometryEditor.Start(GeometryType.Polygon);
+ }
+ }
+
+ // Set the geometry editor tool from the picker.
+ private void ToolPicker_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ GeometryEditorTool tool = _toolDictionary[ToolPicker.SelectedItem.ToString()];
+ _geometryEditor.Tool = tool;
+
+ // Account for case when vertex tool is selected and geometry editor is started with a polyline or polygon geometry type.
+ // Ensure point and multipoint buttons are only enabled when the selected tool is a vertex tool.
+ PointButton.IsEnabled = MultipointButton.IsEnabled = !_geometryEditor.IsStarted && tool is VertexTool;
+ }
+
+ // Set the scale mode for every geometry editor tool.
+ private void CheckBox_CheckedChanged(object sender, CheckedChangedEventArgs e)
+ {
+ // Determine the newly selected scale mode.
+ GeometryEditorScaleMode scaleMode =
+ UniformScaleCheckBox.IsChecked ? GeometryEditorScaleMode.Uniform : GeometryEditorScaleMode.Stretch;
+
+ // Update the scale mode for every tool.
+ foreach (GeometryEditorTool tool in _toolDictionary.Values)
+ {
+ if (tool is FreehandTool freehandTool)
+ {
+ freehandTool.Configuration.ScaleMode = scaleMode;
+ }
+ else if (tool is VertexTool vertexTool)
+ {
+ vertexTool.Configuration.ScaleMode = scaleMode;
+ }
+ else if (tool is ShapeTool shapeTool)
+ {
+ shapeTool.Configuration.ScaleMode = scaleMode;
+ }
+ }
+ }
+
+ // Undo the last change made to the geometry while editing is active.
+ private void UndoButton_Click(object sender, EventArgs e)
+ {
+ _geometryEditor.Undo();
+ }
+
+ // Redo the last change made to the geometry while editing is active.
+ private void RedoButton_Click(object sender, EventArgs e)
+ {
+ _geometryEditor.Redo();
+ }
+
+ // Delete the currently selected element of the geometry editor.
+ private void DeleteSelectedButton_Click(object sender, EventArgs e)
+ {
+ _geometryEditor.DeleteSelectedElement();
+ }
+
+ // Update an existing graphic or create a new graphic.
+ private void SaveButton_Click(object sender, EventArgs e)
+ {
+ Geometry geometry = _geometryEditor.Stop();
+
+ if (geometry != null)
+ {
+ if (_selectedGraphic != null)
+ {
+ // Update the geometry of the graphic being edited and make it visible again.
+ _selectedGraphic.Geometry = geometry;
+ }
+ else
+ {
+ // Create a new graphic based on the geometry and add it to the graphics overlay.
+ _graphicsOverlay.Graphics.Add(new Graphic(geometry, GetSymbol(geometry.GeometryType)));
+ }
+ }
+
+ ResetFromEditingSession();
+ }
+
+ // Stop the geometry editor without saving the geometry stored within.
+ private void DiscardButton_Click(object sender, EventArgs e)
+ {
+ _geometryEditor.Stop();
+ ResetFromEditingSession();
+ }
+
+ // Remove all graphics from the graphics overlay.
+ private void DeleteAllButton_Click(object sender, EventArgs e)
+ {
+ _graphicsOverlay.Graphics.Clear();
+ }
+
+ private async void MyMapView_GeoViewTapped(object sender, Esri.ArcGISRuntime.Maui.GeoViewInputEventArgs e)
+ {
+ // Return immediately when in an editing session.
+ if (_geometryEditor.IsStarted) return;
+
+ try
+ {
+ // Identify graphics in the graphics overlay using the mouse point.
+ IReadOnlyList results = await MyMapView.IdentifyGraphicsOverlaysAsync(e.Position, 5, false);
+
+ // Try to get the first graphic from the first result.
+ _selectedGraphic = results.FirstOrDefault()?.Graphics?.FirstOrDefault();
+ }
+ catch (Exception ex)
+ {
+ // Report exceptions.
+ await Application.Current.MainPage.DisplayAlert("Error editing", ex.Message, "OK");
+
+ ResetFromEditingSession();
+ return;
+ }
+
+ // Return since no graphic was selected.
+ if (_selectedGraphic == null) return;
+
+ _selectedGraphic.IsSelected = true;
+
+ // Configure the UI depending on the geometry type.
+ GeometryType geometryType = _selectedGraphic.Geometry.GeometryType;
+ if (geometryType == GeometryType.Point)
+ {
+ ToolPicker.SelectedIndex = 0;
+ UniformScaleCheckBox.IsEnabled = false;
+ }
+ if (geometryType == GeometryType.Multipoint)
+ {
+ ToolPicker.SelectedIndex = 0;
+ }
+ DisableOtherGeometryButtons(_geometryButtons[geometryType]);
+
+ // Hide the selected graphic and start an editing session with a copy of it.
+ _geometryEditor.Start(_selectedGraphic.Geometry);
+ _selectedGraphic.IsVisible = false;
+ }
+
+ #endregion Event handlers
+
+ #region Helper methods
+
+ private void CreateInitialGraphics()
+ {
+ // Create symbols for displaying new geometries.
+ _pointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Square, Color.OrangeRed, 10);
+ _multiPointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Circle, Color.Yellow, 5);
+ _polylineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Color.Blue, 2);
+ var polygonLineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Dash, Color.Black, 1);
+ _polygonSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, Color.FromArgb(70, 255, 0, 0), polygonLineSymbol);
+
+ // Create geometries from Json formatted strings.
+ var houseCoordinates = (MapPoint)Geometry.FromJson(_houseCoordinatesJson);
+ var outbuildingCoordinates = (Multipoint)Geometry.FromJson(_outbuildingCoordinatesJson);
+ var road1Coordinates = (Polyline)Geometry.FromJson(_road1CoordinatesJson);
+ var road2Coordinates = (Polyline)Geometry.FromJson(_road2CoordinatesJson);
+ var boundaryCoordinates = (Polygon)Geometry.FromJson(_boundaryCoordinatesJson);
+
+ // Add new example graphics from the geometries and symbols to the graphics overlay.
+ _graphicsOverlay.Graphics.Add(new Graphic(houseCoordinates) { Symbol = _pointSymbol });
+ _graphicsOverlay.Graphics.Add(new Graphic(outbuildingCoordinates) { Symbol = _multiPointSymbol });
+ _graphicsOverlay.Graphics.Add(new Graphic(road1Coordinates) { Symbol = _polylineSymbol });
+ _graphicsOverlay.Graphics.Add(new Graphic(road2Coordinates) { Symbol = _polylineSymbol });
+ _graphicsOverlay.Graphics.Add(new Graphic(boundaryCoordinates) { Symbol = _polygonSymbol });
+ }
+
+ // Reset the UI after the editor stops.
+ private void ResetFromEditingSession()
+ {
+ // Reset the selected graphic.
+ if (_selectedGraphic != null)
+ {
+ _selectedGraphic.IsSelected = false;
+ _selectedGraphic.IsVisible = true;
+ }
+ _selectedGraphic = null;
+
+ // Point and multipoint sessions do not support the vertex tool.
+ PointButton.IsEnabled = MultipointButton.IsEnabled = _geometryEditor.Tool is VertexTool;
+ PolylineButton.IsEnabled = PolygonButton.IsEnabled = true;
+ ToolPicker.IsEnabled = true;
+
+ UniformScaleCheckBox.IsEnabled = true;
+ }
+
+ // Return the graphic style based on geometry type.
+ private Symbol GetSymbol(GeometryType geometryType)
+ {
+ switch (geometryType)
+ {
+ case GeometryType.Point:
+ return _pointSymbol;
+
+ case GeometryType.Multipoint:
+ return _multiPointSymbol;
+
+ case GeometryType.Polyline:
+ return _polylineSymbol;
+
+ case GeometryType.Polygon:
+ return _polygonSymbol;
+ }
+ return null;
+ }
+
+ // Disable all geometry buttons besides the one that was just clicked.
+ private void DisableOtherGeometryButtons(Button keepEnabled)
+ {
+ foreach (Button button in _geometryButtons.Values)
+ {
+ button.IsEnabled = button == keepEnabled;
+ }
+ }
+
+ #endregion Helper methods
+ }
+}
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/createandeditgeometries.jpg b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/createandeditgeometries.jpg
new file mode 100644
index 0000000000..d00cfe48a3
Binary files /dev/null and b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/createandeditgeometries.jpg differ
diff --git a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/readme.md b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/readme.md
new file mode 100644
index 0000000000..866e1cf714
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/readme.md
@@ -0,0 +1,51 @@
+# Create and edit geometries
+
+Use the Geometry Editor to create new point, multipoint, polyline, or polygon geometries or to edit existing geometries by interacting with a map view.
+
+![CreateAndEditGeometries](createandeditgeometries.jpg)
+
+## Use case
+
+A field worker can mark features of interest on a map using an appropriate geometry. Features such as sample or observation locations, fences or pipelines, and building footprints can be digitized using point, multipoint, polyline, and polygon geometry types. Polyline and polygon geometries can be created and edited using a vertex-based creation and editing tool (i.e. vertex locations specified explicitly via tapping), or using a freehand tool.
+
+## How to use the sample
+
+To create a new geometry, press the button appropriate for the geometry type you want to create (i.e. points, multipoints, polyline, or polygon) and interactively tap and drag on the map view to create the geometry. To edit an existing geometry, tap the geometry to be edited in the map to select it and then edit the geometry by tapping and dragging elements of the geometry. If creating or editing polyline or polygon geometries, choose the desired creation/editing tool (i.e. `VertexTool` or `FreehandTool`).
+
+Use the control panel to undo or redo changes made to the geometry, delete a selected element, save the geometry, stop the editing session and discard any edits, and remove all geometries from the map.
+
+## How it works
+
+1. Create a `GeometryEditor` and set it to the MapView using `MyMapView.GeometryEditor`.
+2. Start the `GeometryEditor` using `GeometryEditor.Start(GeometryType)` to create a new geometry or `GeometryEditor.Start(Geometry)` to edit an existing geometry.
+ * If using the Geometry Editor to edit an existing geometry, the geometry must be retrieved from the graphics overlay being used to visualize the geometry prior to calling the start method. To do this:
+ * Use `MapView.IdentifyGraphicsOverlayAsync(...)` to identify graphics at the location of a tap.
+ * Access the `MapView.IdentifyGraphicsOverlayAsync(...)`.
+ * Find the desired graphic in the `results.FirstOrDefault()` list.
+ * Access the geometry associated with the `Graphic` using `Graphic.Geometry` - this will be used in the `GeometryEditor.Start(Geometry)` method.
+3. Create `VertexTool`, `FreehandTool`, or `ShapeTool` objects which define how the user interacts with the view to create or edit geometries, setting `GeometryEditor.Tool`.
+4. Edit a tool's InteractionConfiguration to set the GeometryEditorScaleMode to allow either uniform or stretch scale mode.
+5. Check to see if undo and redo are possible during an editing session using `GeometryEditor.CanUndo` and `GeometryEditor.CanRedo`. If it's possible, use `GeometryEditor.Undo()` and `GeometryEditor.Redo()`.
+6. Check whether the currently selected `GeometryEditorElement` can be deleted (`GeometryEditor.SelectedElement.CanDelete`). If the element can be deleted, delete using `GeometryEditor.DeleteSelectedElement()`.
+7. Call `GeometryEditor.Stop()` to finish the editing session and store the `Graphic`. The `GeometryEditor` does not automatically handle the visualization of a geometry output from an editing session. This must be done manually by propagating the geometry returned into a `Graphic` added to a `GraphicsOverlay`.
+ * To create a new `Graphic` in the `GraphicsOverlay`:
+ * Using `Graphic(Geometry)`, create a new Graphic with the geometry returned by the `GeometryEditor.Stop()` method.
+ * Append the `Graphic` to the `GraphicsOverlay`(i.e. `GraphicsOverlay.Graphics.Add(Graphic)`).
+ * To update the geometry underlying an existing `Graphic` in the `GraphicsOverlay`:
+ * Replace the existing `Graphic`'s `Geometry` property with the geometry returned by the `GeometryEditor.Stop()` method.
+
+## Relevant API
+
+* Geometry
+* GeometryEditor
+* Graphic
+* GraphicsOverlay
+* MapView
+
+## Additional information
+
+The sample opens with the ArcGIS Imagery basemap centered on the island of Inis Meain (Aran Islands) in Ireland. Inis Meain comprises a landscape of interlinked stone walls, roads, buildings, archaeological sites, and geological features, producing complex geometrical relationships.
+
+## Tags
+
+draw, edit, freehand, geometry editor, sketch, vertex
diff --git a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/readme.metadata.json b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/readme.metadata.json
new file mode 100644
index 0000000000..d6de764534
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/CreateAndEditGeometries/readme.metadata.json
@@ -0,0 +1,33 @@
+{
+ "category": "GraphicsOverlay",
+ "description": "Use the Geometry Editor to create new point, multipoint, polyline, or polygon geometries or to edit existing geometries by interacting with a map view.",
+ "formal_name": "CreateAndEditGeometries",
+ "ignore": false,
+ "images": [
+ "createandeditgeometries.jpg"
+ ],
+ "keywords": [
+ "draw",
+ "edit",
+ "freehand",
+ "geometry editor",
+ "sketch",
+ "vertex"
+ ],
+ "offline_data": [],
+ "redirect_from": [
+ "/net/latest/maui/sample-code/createandeditgeometries.htm"
+ ],
+ "relevant_apis": [
+ "Geometry",
+ "GeometryEditor",
+ "Graphic",
+ "GraphicsOverlay",
+ "MapView"
+ ],
+ "snippets": [
+ "CreateAndEditGeometries.xaml.cs",
+ "CreateAndEditGeometries.xaml"
+ ],
+ "title": "Create and edit geometries"
+}
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/ScenePropertiesExpressions/ScenePropertiesExpressions.xaml b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/ScenePropertiesExpressions/ScenePropertiesExpressions.xaml
index 8f9c4e58bd..ea6de6ce27 100644
--- a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/ScenePropertiesExpressions/ScenePropertiesExpressions.xaml
+++ b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/ScenePropertiesExpressions/ScenePropertiesExpressions.xaml
@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui"
xmlns:resources="clr-namespace:ArcGIS.Resources">
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SketchOnMap/SketchOnMap.xaml.cs b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SketchOnMap/SketchOnMap.xaml.cs
deleted file mode 100644
index c36b71b2cd..0000000000
--- a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SketchOnMap/SketchOnMap.xaml.cs
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright 2022 Esri.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
-// language governing permissions and limitations under the License.
-
-using Esri.ArcGISRuntime.Data;
-using Esri.ArcGISRuntime.Geometry;
-using Esri.ArcGISRuntime.Mapping;
-using Esri.ArcGISRuntime.Symbology;
-using Esri.ArcGISRuntime.UI;
-using Colors = System.Drawing.Color;
-
-namespace ArcGIS.Samples.SketchOnMap
-{
- [ArcGIS.Samples.Shared.Attributes.Sample(
- name: "Sketch on map",
- category: "GraphicsOverlay",
- description: "Use the Sketch Editor to edit or sketch a new point, line, or polygon geometry on to a map.",
- instructions: "Choose which geometry type to sketch from one of the available buttons. Choose from points, multipoints, polylines, polygons, freehand polylines, freehand polygons, circles, ellipses, triangles, arrows and rectangles.",
- tags: new[] { "draw", "edit" })]
- public partial class SketchOnMap : ContentPage
- {
- // Graphics overlay to host sketch graphics.
- private GraphicsOverlay _sketchOverlay;
-
- // Background colors for tool icons.
- private static SolidColorBrush ThemedColor;
- private static SolidColorBrush Red;
-
- // Button for keeping track of the currently enabled tool.
- private static Button EnabledTool;
-
- private TaskCompletionSource _graphicCompletionSource;
-
- private string[] _sketchModes;
-
- private static int _drawModeIndex;
-
- public SketchOnMap()
- {
- InitializeComponent();
-
- // Call a function to set up the map and sketch editor.
- Initialize();
- }
-
- private void Initialize()
- {
- // Create a map.
- Map myMap = new Map(BasemapStyle.ArcGISImageryStandard);
-
- // Create graphics overlay to display sketch geometry.
- _sketchOverlay = new GraphicsOverlay();
- MyMapView.GraphicsOverlays.Add(_sketchOverlay);
-
- // Assign the map to the MapView.
- MyMapView.Map = myMap;
-
- // Set a viewpoint on the map view.
- MyMapView.SetViewpoint(new Viewpoint(64.3286, -15.5314, 72223));
-
- // Create a list of draw modes.
- _sketchModes = Enum.GetNames(typeof(SketchCreationMode));
-
- // Hack to get around linker being too aggressive - this should be done with binding.
- UndoButton.Command = MyMapView.SketchEditor.UndoCommand;
- RedoButton.Command = MyMapView.SketchEditor.RedoCommand;
- CompleteButton.Command = MyMapView.SketchEditor.CompleteCommand;
- CancelButton.Command = MyMapView.SketchEditor.CancelCommand;
-
- // Ensure colors are consistent with XAML colors.
- ThemedColor = (SolidColorBrush)Sketch.Background;
- Red = new SolidColorBrush(Microsoft.Maui.Graphics.Color.FromRgb(255, 0, 0));
-
- // No tool currently selected, so simply instantiate the button.
- EnabledTool = new Button();
- }
-
- #region Graphic and symbol helpers
-
- private Graphic CreateGraphic(Esri.ArcGISRuntime.Geometry.Geometry geometry)
- {
- // Create a graphic to display the specified geometry.
- Symbol symbol = null;
- switch (geometry.GeometryType)
- {
- // Symbolize with a fill symbol.
- case GeometryType.Envelope:
- case GeometryType.Polygon:
- {
- symbol = new SimpleFillSymbol()
- {
- Color = Colors.Red,
- Style = SimpleFillSymbolStyle.Solid
- };
- break;
- }
- // Symbolize with a line symbol.
- case GeometryType.Polyline:
- {
- symbol = new SimpleLineSymbol()
- {
- Color = Colors.Red,
- Style = SimpleLineSymbolStyle.Solid,
- Width = 5d
- };
- break;
- }
- // Symbolize with a marker symbol.
- case GeometryType.Point:
- case GeometryType.Multipoint:
- {
- symbol = new SimpleMarkerSymbol()
- {
- Color = Colors.Red,
- Style = SimpleMarkerSymbolStyle.Circle,
- Size = 15d
- };
- break;
- }
- }
-
- // Pass back a new graphic with the appropriate symbol.
- return new Graphic(geometry, symbol);
- }
-
- #endregion Graphic and symbol helpers
-
- private async void StartSketch(object sender, EventArgs e)
- {
- try
- {
- // Let the user draw on the map view using the chosen sketch mode.
- SketchCreationMode creationMode = (SketchCreationMode)_drawModeIndex;
- Esri.ArcGISRuntime.Geometry.Geometry geometry = await MyMapView.SketchEditor.StartAsync(creationMode, true);
-
- // Create and add a graphic from the geometry the user drew.
- Graphic graphic = CreateGraphic(geometry);
- _sketchOverlay.Graphics.Add(graphic);
-
- // Enable/disable the clear and edit buttons according to whether or not graphics exist in the overlay.
- ClearButton.IsEnabled = _sketchOverlay.Graphics.Count > 0;
- EditButton.IsEnabled = _sketchOverlay.Graphics.Count > 0;
- }
- catch (TaskCanceledException)
- {
- // Ignore ... let the user cancel drawing.
- }
- catch (Exception ex)
- {
- // Report exceptions.
- await Application.Current.MainPage.DisplayAlert("Error", "Error drawing graphic shape: " + ex.Message, "OK");
- }
- }
-
- private void ClearButtonClick(object sender, EventArgs e)
- {
- // Update UI
- UnselectTool(sender, e);
-
- // Remove all graphics from the graphics overlay.
- _sketchOverlay.Graphics.Clear();
-
- // Cancel any uncompleted sketch.
- if (MyMapView.SketchEditor.CancelCommand.CanExecute(null))
- {
- MyMapView.SketchEditor.CancelCommand.Execute(null);
- }
-
- // Disable buttons that require graphics.
- ClearButton.IsEnabled = false;
- EditButton.IsEnabled = false;
- }
-
- private async void EditButtonClick(object sender, EventArgs e)
- {
- try
- {
- // Update UI.
- SelectTool(sender as Button);
-
- // Create a TaskCompletionSource object to wait for a graphic.
- _graphicCompletionSource = new TaskCompletionSource();
-
- // Wait for the user to select a graphic.
- Graphic editGraphic = await _graphicCompletionSource.Task;
-
- // Let the user make changes to the graphic's geometry, await the result (updated geometry).
- Geometry newGeometry = await MyMapView.SketchEditor.StartAsync(editGraphic.Geometry);
-
- // Display the updated geometry in the graphic.
- editGraphic.Geometry = newGeometry;
- }
- catch (TaskCanceledException)
- {
- // Ignore ... let the user cancel editing.
- }
- catch (Exception ex)
- {
- // Report exceptions.
- await Application.Current.MainPage.DisplayAlert("Error", "Error editing shape: " + ex.Message, "OK");
- }
- }
-
- private async void ShowDrawTools(object sender, EventArgs e)
- {
- try
- {
- // Update UI.
- SelectTool(sender as Button);
-
- // Show draw tools and wait for the user to select a mode.
- string choice = await Application.Current.MainPage.DisplayActionSheet("Set draw mode:", "Cancel", null, _sketchModes);
-
- // Set the selected index for the draw mode.
- if (_sketchModes.Contains(choice))
- {
- _drawModeIndex = Array.IndexOf(_sketchModes, choice);
- StartSketch(sender, e);
- }
- else
- {
- // Update UI
- UnselectTool(sender, e);
- }
- }
- catch (Exception ex)
- {
- // Report exceptions.
- await Application.Current.MainPage.DisplayAlert("Error", "Error editing shape: " + ex.Message, "OK");
- }
- }
-
- #region Tool selection UI helpers
-
- private void SelectTool(Button selectedButton)
- {
- // Gray out the background of the currently selected tool.
- if (EnabledTool is not null)
- EnabledTool.Background = ThemedColor;
-
- // Set the static variable to whichever button that was just clicked.
- EnabledTool = selectedButton;
-
- // Set the background of the currently selected tool to red.
- EnabledTool.Background = Red;
- }
-
- private void UnselectTool(object sender, EventArgs e)
- {
- // Gray out the background of the currently selected tool.
- if (EnabledTool is not null)
- EnabledTool.Background = ThemedColor;
-
- // Dereference the unselected tool's button.
- EnabledTool = null;
- }
-
- #endregion Tool selection UI helpers
-
- private async void OnGeoViewTapped(object sender, Esri.ArcGISRuntime.Maui.GeoViewInputEventArgs e)
- {
- try
- {
- if (_graphicCompletionSource is not null && !_graphicCompletionSource.Task.IsCompleted)
- {
- // Identify graphics in the graphics overlay using the point.
- IReadOnlyList results = await MyMapView.IdentifyGraphicsOverlaysAsync(e.Position, 2, false);
-
- // If results were found, get the first graphic.
- IdentifyGraphicsOverlayResult idResult = results.FirstOrDefault();
- if (idResult != null && idResult.Graphics.Count > 0)
- {
- Graphic graphic = idResult.Graphics.FirstOrDefault();
- _graphicCompletionSource.TrySetResult(graphic);
- }
- }
- }
- catch (TaskCanceledException)
- {
- // Ignore ... let the user cancel drawing.
- }
- catch (Exception ex)
- {
- // Report exceptions.
- await Application.Current.MainPage.DisplayAlert("Error", "Error editing shape: " + ex.Message, "OK");
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SketchOnMap/readme.md b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SketchOnMap/readme.md
deleted file mode 100644
index e329e00ef8..0000000000
--- a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SketchOnMap/readme.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Sketch on map
-
-Use the Sketch Editor to edit or sketch a new point, line, or polygon geometry on to a map.
-
-![Image of sketch on map](sketchonmap.jpg)
-
-## Use case
-
-A field worker could annotate features of interest on a map (via the GUI) such as location of dwellings (marked as points), geological features (polylines), or areas of glaciation (polygons).
-
-## How to use the sample
-
-Choose which geometry type to sketch from one of the available buttons. Choose from points, multipoints, polylines, polygons, freehand polylines, freehand polygons, circles, ellipses, triangles, arrows and rectangles.
-
-Use the control panel to cancel the sketch, undo or redo changes made to the sketch and to save the sketch to the graphics overlay. There is also the option to select a saved graphic and edit its geometry using the Sketch Editor. The graphics overlay can be cleared using the clear all button.
-
-## How it works
-
-1. Use `SketchEditor.StartAsync()` to start sketching. If editing an existing graphic's geometry, use `SketchEditor.StartAsync(graphic.Geometry)`.
-2. Use the `UndoCommand` and `RedoCommand` to undo and redo edits in the sketch.
-3. Use a `CompleteCommand` to finish the sketch and get the `Geometry` result. Use the `CancelCommand` to cancel the sketch.
-4. Create a `Graphic` for the geometry and add it to the `GraphicsOverlay` in the map view.
-
-## Relevant API
-
-* Geometry
-* Graphic
-* GraphicsOverlay
-* MapView
-* SketchCreationMode
-* SketchEditor
-
-## Tags
-
-draw, edit
diff --git a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SketchOnMap/readme.metadata.json b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SketchOnMap/readme.metadata.json
deleted file mode 100644
index 05f3ed4062..0000000000
--- a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SketchOnMap/readme.metadata.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "category": "GraphicsOverlay",
- "description": "Use the Sketch Editor to edit or sketch a new point, line, or polygon geometry on to a map.",
- "formal_name": "SketchOnMap",
- "ignore": false,
- "images": [
- "sketchonmap.jpg"
- ],
- "keywords": [
- "draw",
- "edit"
- ],
- "offline_data": [],
- "redirect_from": [
- "/net/latest/maui/sample-code/sketchonmap.htm"
- ],
- "relevant_apis": [
- "Geometry",
- "Graphic",
- "GraphicsOverlay",
- "MapView",
- "SketchCreationMode",
- "SketchEditor"
- ],
- "snippets": [
- "SketchOnMap.xaml.cs",
- "SketchOnMap.xaml"
- ],
- "title": "Sketch on map"
-}
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SketchOnMap/sketchonmap.jpg b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SketchOnMap/sketchonmap.jpg
deleted file mode 100644
index c128391204..0000000000
Binary files a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SketchOnMap/sketchonmap.jpg and /dev/null differ
diff --git a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SurfacePlacements/SurfacePlacements.xaml b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SurfacePlacements/SurfacePlacements.xaml
index 82b5e33df8..975ca37e0f 100644
--- a/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SurfacePlacements/SurfacePlacements.xaml
+++ b/src/MAUI/Maui.Samples/Samples/GraphicsOverlay/SurfacePlacements/SurfacePlacements.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/AddCustomDynamicEntityDataSource.xaml b/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/AddCustomDynamicEntityDataSource.xaml
new file mode 100644
index 0000000000..05a4c4fd51
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/AddCustomDynamicEntityDataSource.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/AddCustomDynamicEntityDataSource.xaml.cs b/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/AddCustomDynamicEntityDataSource.xaml.cs
new file mode 100644
index 0000000000..1fe562bad7
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/AddCustomDynamicEntityDataSource.xaml.cs
@@ -0,0 +1,147 @@
+// Copyright 2023 Esri.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+// language governing permissions and limitations under the License.
+
+using ArcGIS.Samples.Managers;
+using Esri.ArcGISRuntime.ArcGISServices;
+using Esri.ArcGISRuntime.Data;
+using Esri.ArcGISRuntime.Mapping;
+using Esri.ArcGISRuntime.Mapping.Labeling;
+using Esri.ArcGISRuntime.RealTime;
+using Esri.ArcGISRuntime.Symbology;
+using Esri.ArcGISRuntime.UI;
+using System.Text;
+
+namespace ArcGIS.Samples.AddCustomDynamicEntityDataSource
+{
+ [ArcGIS.Samples.Shared.Attributes.Sample(
+ name: "Add custom dynamic entity data source",
+ category: "Layers",
+ description: "Create a custom dynamic entity data source and display it using a dynamic entity layer.",
+ instructions: "Run the sample to view the map and the dynamic entity layer displaying the latest observation from the custom data source. Tap on a dynamic entity to view its attributes in a callout.",
+ tags: new[] { "data", "dynamic", "entity", "label", "labeling", "live", "real-time", "stream", "track" })]
+ [ArcGIS.Samples.Shared.Attributes.ClassFile("SimulatedDataSource.cs")]
+ [ArcGIS.Samples.Shared.Attributes.OfflineData("a8a942c228af4fac96baa78ad60f511f")]
+ public partial class AddCustomDynamicEntityDataSource
+ {
+ // Path to AIS Traffic Data json file.
+ private readonly string _localJsonFile = DataManager.GetDataFolder("a8a942c228af4fac96baa78ad60f511f", "AIS_MarineCadastre_SelectedVessels_CustomDataSource.json");
+
+ public AddCustomDynamicEntityDataSource()
+ {
+ InitializeComponent();
+ Initialize();
+ }
+
+ private void Initialize()
+ {
+ // Create a new map with the navigation basemap style.
+ MyMapView.Map = new Map(BasemapStyle.ArcGISOceans);
+
+ // Set the initial viewpoint.
+ MyMapView.SetViewpoint(new Viewpoint(47.984, -123.657, 3e6));
+
+ // Create a new custom file source.
+ // This takes the path to the simulation file, field name that will be used as the entity id, and the delay between each observation that is processed.
+ // In this example we are using a json file as our custom data source.
+ // This field value should be a unique identifier for each entity.
+ // Adjusting the value for the delay will change the speed at which the entities and their observations are displayed.
+ var customSource = new SimulatedDataSource(_localJsonFile, "MMSI", TimeSpan.FromMilliseconds(10));
+
+ // Create the dynamic entity layer using the custom data source.
+ var dynamicEntityLayer = new DynamicEntityLayer(customSource);
+
+ // Set up the track display properties.
+ SetupTrackDisplayProperties(dynamicEntityLayer);
+
+ // Set up the dynamic entity labeling.
+ SetupLabeling(dynamicEntityLayer);
+
+ // Add the dynamic entity layer to the map.
+ MyMapView.Map.OperationalLayers.Add(dynamicEntityLayer);
+ }
+
+ private void SetupTrackDisplayProperties(DynamicEntityLayer layer)
+ {
+ // Set up the track display properties, these properties will be used to configure the appearance of the track line and previous observations.
+ layer.TrackDisplayProperties.ShowPreviousObservations = true;
+ layer.TrackDisplayProperties.ShowTrackLine = true;
+ layer.TrackDisplayProperties.MaximumObservations = 20;
+ }
+
+ private void SetupLabeling(DynamicEntityLayer layer)
+ {
+ // Define the label expression to be used, in this case we will use the "VesselName" for each of the dynamic entities.
+ var simpleLabelExpression = new SimpleLabelExpression("[VesselName]");
+
+ // Set the text symbol color and size for the labels.
+ var labelSymbol = new TextSymbol() { Color = System.Drawing.Color.Red, Size = 12d };
+
+ // Set the label position.
+ var labelDef = new LabelDefinition(simpleLabelExpression, labelSymbol) { Placement = LabelingPlacement.PointAboveCenter };
+
+ // Add the label definition to the dynamic entity layer and enable labels.
+ layer.LabelDefinitions.Add(labelDef);
+ layer.LabelsEnabled = true;
+ }
+
+ private async void GeoViewTapped(object sender, Esri.ArcGISRuntime.Maui.GeoViewInputEventArgs e)
+ {
+ e.Handled = true;
+ try
+ {
+ MyMapView.DismissCallout();
+
+ // If no dynamic entity layer is present in the map, return.
+ var layer = MyMapView.Map?.OperationalLayers.OfType().FirstOrDefault();
+ if (layer is null) return;
+
+ // Identify the tapped observation.
+ IdentifyLayerResult results = await MyMapView.IdentifyLayerAsync(layer, e.Position, 2d, false);
+ DynamicEntityObservation observation = results.GeoElements.FirstOrDefault() as DynamicEntityObservation;
+ if (observation is null) return;
+
+ // Get the dynamic entity from the observation.
+ var dynamicEntity = observation.GetDynamicEntity();
+ if (dynamicEntity is null) return;
+
+ // Build a string for observation attributes.
+ StringBuilder stringBuilder = new StringBuilder();
+ foreach (var attribute in new string[] { "VesselName", "CallSign", "COG", "SOG" })
+ {
+ var value = dynamicEntity.Attributes[attribute].ToString();
+
+ // Account for when an attribue has an empty value.
+ if (!string.IsNullOrEmpty(value))
+ {
+ stringBuilder.AppendLine(attribute + ": " + value);
+
+ // iOS doesn't support multiline callouts, so only show one attribute.
+#if __IOS__
+ break;
+#endif
+ }
+ }
+
+ // The standard callout takes care of moving when the dynamic entity changes.
+ var calloutDef = new CalloutDefinition(stringBuilder.ToString().TrimEnd());
+ if (layer.Renderer?.GetSymbol(dynamicEntity) is Symbol symbol)
+ {
+ await calloutDef.SetIconFromSymbolAsync(symbol);
+ }
+
+ // Show the callout for the tapped dynamic entity.
+ MyMapView.ShowCalloutForGeoElement(dynamicEntity, e.Position, calloutDef);
+ }
+ catch (Exception ex)
+ {
+ await DisplayAlert("Error identifying dynamic entity.", ex.ToString(), "Ok");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/SimulatedDataSource.cs b/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/SimulatedDataSource.cs
new file mode 100644
index 0000000000..4d1e396657
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/SimulatedDataSource.cs
@@ -0,0 +1,195 @@
+// Copyright 2023 Esri.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+// language governing permissions and limitations under the License.
+
+using Esri.ArcGISRuntime.Data;
+using Esri.ArcGISRuntime.Geometry;
+using Esri.ArcGISRuntime.RealTime;
+using System.Diagnostics;
+using System.Text.Json;
+
+
+namespace ArcGIS.Samples.AddCustomDynamicEntityDataSource
+{
+ public class SimulatedDataSource : DynamicEntityDataSource
+ {
+ // Hold a reference to the file stream reader, the process task, and the cancellation token source.
+ private Task? _processTask;
+ private StreamReader? _streamReader;
+ private CancellationTokenSource? _cancellationTokenSource;
+ private List _fields;
+
+ public SimulatedDataSource(string filePath, string entityIdField, TimeSpan delay)
+ {
+ FilePath = filePath;
+ EntityIdField = entityIdField;
+ Delay = delay;
+ }
+
+ #region Properties
+
+ // Expose the file path, entity ID field, and delay length as properties.
+ public string FilePath { get; }
+ public string EntityIdField { get; }
+ public TimeSpan Delay { get; }
+
+ #endregion
+
+ protected override async Task OnLoadAsync()
+ {
+ // Derive schema from the first row in the custom data source.
+ _fields = GetSchema();
+
+ // Open the file for processing.
+ Stream stream = File.OpenRead(FilePath);
+ _streamReader = new StreamReader(stream);
+
+ // Create a new DynamicEntityDataSourceInfo using the entity ID field and the fields derived from the attributes of each observation in the custom data source.
+ return new DynamicEntityDataSourceInfo(EntityIdField, _fields) { SpatialReference = SpatialReferences.Wgs84 };
+ }
+
+ protected override Task OnConnectAsync(CancellationToken cancellationToken)
+ {
+ // On connecting to the custom data source begin processing the file.
+ _cancellationTokenSource = new();
+ _processTask = Task.Run(() => ObservationProcessLoopAsync(), _cancellationTokenSource.Token);
+ return Task.CompletedTask;
+ }
+
+ protected override async Task OnDisconnectAsync()
+ {
+ // On disconnecting from the custom data source, stop processing the file.
+ _cancellationTokenSource?.Cancel();
+
+ if (_processTask is not null) await _processTask;
+
+ _cancellationTokenSource = null;
+ _processTask = null;
+ }
+
+ private async Task ObservationProcessLoopAsync()
+ {
+ try
+ {
+ while (!_cancellationTokenSource!.IsCancellationRequested)
+ {
+ // Process the next observation.
+ var processed = await ProcessNextObservation();
+
+ // If the end of the file has been reached, break out of the loop.
+ if (_streamReader.EndOfStream) break;
+
+ // If the observation was not processed, continue to the next observation.
+ if (!processed) continue;
+
+ // If there is no delay, yield to the UI thread otherwise delay for the specified amount of time.
+ if (Delay == TimeSpan.Zero)
+ {
+ await Task.Yield();
+ }
+ else
+ {
+ await Task.Delay(Delay, _cancellationTokenSource.Token);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex.ToString());
+ }
+ }
+
+ private async Task ProcessNextObservation()
+ {
+ _ = _streamReader ?? throw new ArgumentNullException("File stream not available.");
+
+ // Read the next observation.
+ var json = await _streamReader.ReadLineAsync();
+
+ // If there is no json to read or the schema is not available, return false.
+ if (string.IsNullOrEmpty(json) || _fields is null) return false;
+
+ try
+ {
+ JsonElement jsonElement = JsonSerializer.Deserialize(json);
+
+ // Create a new MapPoint from the x and y coordinates of the observation.
+ MapPoint? point = null;
+ if (jsonElement.TryGetProperty("geometry", out JsonElement jsonGeometry))
+ {
+ point = new MapPoint(
+ jsonGeometry.GetProperty("x").GetDouble(),
+ jsonGeometry.GetProperty("y").GetDouble(),
+ SpatialReferences.Wgs84);
+ }
+
+ // Get the dictionary of attributes from the observation using the field names as keys.
+ Dictionary attributes = new();
+ if (jsonElement.TryGetProperty("attributes", out JsonElement jsonAttributes))
+ {
+ foreach (var field in _fields)
+ {
+ if (jsonAttributes.TryGetProperty(field.Name, out JsonElement prop))
+ {
+ object? value = null;
+ if (prop.ValueKind != JsonValueKind.Null)
+ {
+ if (prop.ValueKind == JsonValueKind.Number && field.FieldType == FieldType.Float64)
+ {
+ value = prop.GetDouble();
+ }
+ else if (prop.ValueKind == JsonValueKind.Number && field.FieldType == FieldType.Int32)
+ {
+ value = prop.GetInt32();
+ }
+ else if (prop.ValueKind == JsonValueKind.String)
+ {
+ value = prop.GetString();
+ }
+ }
+ attributes.Add(field.Name, value);
+ }
+ }
+ }
+
+ // Add the observation to the custom data source.
+ AddObservation(point, attributes);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"{ex}");
+ return false;
+ }
+ }
+
+ private static List GetSchema()
+ {
+ // Return a list of fields matching the attributes of each observation in the custom data source.
+ return new List()
+ {
+ new Field(FieldType.Text, "MMSI", string.Empty, 256),
+ new Field(FieldType.Float64, "BaseDateTime", string.Empty, 8),
+ new Field(FieldType.Float64, "LAT", string.Empty, 8),
+ new Field(FieldType.Float64, "LONG", string.Empty, 8),
+ new Field(FieldType.Float64, "SOG", string.Empty, 8),
+ new Field(FieldType.Float64, "COG", string.Empty, 8),
+ new Field(FieldType.Float64, "Heading", string.Empty, 8),
+ new Field(FieldType.Text, "VesselName", string.Empty, 256),
+ new Field(FieldType.Text, "IMO", string.Empty, 256),
+ new Field(FieldType.Text, "CallSign", string.Empty, 256),
+ new Field(FieldType.Text, "VesselType", string.Empty, 256),
+ new Field(FieldType.Text, "Status", string.Empty, 256),
+ new Field(FieldType.Float64, "Length", string.Empty, 8),
+ new Field(FieldType.Float64, "Width", string.Empty, 8),
+ new Field(FieldType.Text, "Cargo", string.Empty, 256),
+ new Field(FieldType.Text, "globalid", string.Empty, 256)
+ };
+ }
+ }
+}
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/addcustomdynamicentitydatasource.jpg b/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/addcustomdynamicentitydatasource.jpg
new file mode 100644
index 0000000000..7e79a27180
Binary files /dev/null and b/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/addcustomdynamicentitydatasource.jpg differ
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/readme.md b/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/readme.md
new file mode 100644
index 0000000000..f0916925a6
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/readme.md
@@ -0,0 +1,50 @@
+# Add custom dynamic entity data source
+
+Create a custom dynamic entity data source and display it using a dynamic entity layer.
+
+![Image of add custom dynamic entity data source](addcustomdynamicentitydatasource.jpg)
+
+## Use case
+
+Developers can create a custom `DynamicEntityDataSource` to be able to visualize data from a variety of different feeds as dynamic entities using a `DynamicEntityLayer`. An example of this is in a mobile situational awareness app, where a custom `DynamicEntityDataSource` can be used to connect to peer-to-peer feeds in order to visualize real-time location tracks from teammates in the field.
+
+## How to use the sample
+
+Run the sample to view the map and the dynamic entity layer displaying the latest observation from the custom data source. Tap on a dynamic entity to view its attributes in a callout.
+
+## How it works
+
+Configure the custom data source:
+
+1. Create a custom data source implementation of a `DynamicEntityDataSource`.
+2. Override `OnLoadAsync()` to specify the `DynamicEntityDataSourceInfo` for a given unique entity ID field and a list of `Field` objects matching the fields in the data source.
+3. Override `OnConnectAsync()` to begin processing observations from the custom data source.
+4. Loop through the observations and deserialize each observation into a `MapPoint` object and a `Dictionary` containing the attributes.
+5. Use `DynamicEntityDataSource.AddObservation(mapPoint, attributes)` to add each observation to the custom data source.
+
+Configure the map view:
+
+1. Create a `DynamicEntityLayer` using the custom data source implementation.
+2. Update values in the layer's `TrackDisplayProperties` to customize the layer's appearance.
+3. Set up the layer's `LabelDefinitions` to display labels for each dynamic entity.
+4. Configure a `GeoViewTapped` event handler on the `MapView` to select a dynamic entity and display the entity's attributes in a callout.
+
+## Relevant API
+
+* DynamicEntity
+* DynamicEntityDataSource
+* DynamicEntityLayer
+* LabelDefinition
+* TrackDisplayProperties
+
+## About the data
+
+This sample uses a [.json file containing observations of marine vessels in the Pacific North West](https://www.arcgis.com/home/item.html?id=a8a942c228af4fac96baa78ad60f511f) hosted on ArcGIS Online.
+
+## Additional information
+
+In this sample, we iterate through features in a GeoJSON file to mimic messages coming from a real-time feed. You can create a custom dyamic entity data source to process any data that contains observations which can be translated into `MapPoint` objects with associated `Dictionary` attributes.
+
+## Tags
+
+data, dynamic, entity, label, labeling, live, real-time, stream, track
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/readme.metadata.json b/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/readme.metadata.json
new file mode 100644
index 0000000000..3b4974c881
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/Layers/AddCustomDynamicEntityDataSource/readme.metadata.json
@@ -0,0 +1,37 @@
+{
+ "category": "Layers",
+ "description": "Create a custom dynamic entity data source and display it using a dynamic entity layer.",
+ "formal_name": "AddCustomDynamicEntityDataSource",
+ "ignore": false,
+ "images": [
+ "addcustomdynamicentitydatasource.jpg"
+ ],
+ "keywords": [
+ "data",
+ "dynamic",
+ "entity",
+ "label",
+ "labeling",
+ "live",
+ "real-time",
+ "stream",
+ "track"
+ ],
+ "offline_data": [],
+ "redirect_from": [
+ "/net/latest/maui/sample-code/addcustomdynamicentitydatasource.htm"
+ ],
+ "relevant_apis": [
+ "DynamicEntity",
+ "DynamicEntityDataSource",
+ "DynamicEntityLayer",
+ "LabelDefinition",
+ "TrackDisplayProperties"
+ ],
+ "snippets": [
+ "SimulatedDataSource.cs",
+ "AddCustomDynamicEntityDataSource.xaml.cs",
+ "AddCustomDynamicEntityDataSource.xaml"
+ ],
+ "title": "Add custom dynamic entity data source"
+}
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/AddDynamicEntityLayer/AddDynamicEntityLayer.xaml b/src/MAUI/Maui.Samples/Samples/Layers/AddDynamicEntityLayer/AddDynamicEntityLayer.xaml
index cb82c42588..250feb6916 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/AddDynamicEntityLayer/AddDynamicEntityLayer.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/AddDynamicEntityLayer/AddDynamicEntityLayer.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
-
+
-
+
-
-
+
+
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/AddVectorTiledLayerFromCustomStyle/AddVectorTiledLayerFromCustomStyle.xaml.cs b/src/MAUI/Maui.Samples/Samples/Layers/AddVectorTiledLayerFromCustomStyle/AddVectorTiledLayerFromCustomStyle.xaml.cs
index 929b9690fc..cf7a3627a0 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/AddVectorTiledLayerFromCustomStyle/AddVectorTiledLayerFromCustomStyle.xaml.cs
+++ b/src/MAUI/Maui.Samples/Samples/Layers/AddVectorTiledLayerFromCustomStyle/AddVectorTiledLayerFromCustomStyle.xaml.cs
@@ -24,23 +24,18 @@ namespace ArcGIS.Samples.AddVectorTiledLayerFromCustomStyle
public partial class AddVectorTiledLayerFromCustomStyle
{
// ArcGIS Online portal item strings.
- private readonly string[] _onlineItemIDs =
+ private readonly string[] _portalItemIDs =
{
"1349bfa0ed08485d8a92c442a3850b06",
"bd8ac41667014d98b933e97713ba8377",
"02f85ec376084c508b9c8e5a311724fa",
"1bf0cc4a4380468fbbff107e100f65a5",
- };
- private readonly string[] _offlineItemIDs =
- {
+ // Offline custom style vector tiled layer will be created once a VTPK is exported.
"e01262ef2a4f4d91897d9bbd3a9b1075",
"ce8a34e5d4ca4fa193a097511daa8855"
};
- // Items to fill the ActionDisplaySheet for switching custom styles.
- private readonly string[] styles = { "Default", "Style 1", "Style 2", "Style 3", "Offline custom style - Light", "Offline custom style - Dark" };
-
// Path to Dodge City vector tile package.
private readonly string _localVectorPackagePath = DataManager.GetDataFolder("f4b742a57af344988b02227e2824ca5f", "dodge_city.vtpk");
@@ -66,22 +61,28 @@ private async Task Initialize()
ArcGISPortal portal = await ArcGISPortal.CreateAsync();
// Store a list of all portal items.
- foreach (string item in _onlineItemIDs)
+ foreach (string itemID in _portalItemIDs)
{
- PortalItem portalItem = await PortalItem.CreateAsync(portal, item);
- _vectorTiledLayers.Add(portalItem);
- }
- foreach (string item in _offlineItemIDs)
- {
- PortalItem portalItem = await PortalItem.CreateAsync(portal, item);
+ PortalItem portalItem = await PortalItem.CreateAsync(portal, itemID);
_vectorTiledLayers.Add(portalItem);
}
// Create a map using defaults.
- MyMapView.Map = new Map(new Basemap(new ArcGISVectorTiledLayer(_vectorTiledLayers[0]))) { InitialViewpoint = _defaultViewpoint };
+ MyMapView.Map = new Map { InitialViewpoint = _defaultViewpoint };
+
+ // Populate the picker.
+ StyleChooser.ItemsSource = new string[]
+ {
+ "Default",
+ "Style 1",
+ "Style 2",
+ "Style 3",
+ "Offline custom style - Light",
+ "Offline custom style - Dark"
+ };
- // By default, the UI label will not reflect the default style.
- ChosenStyle.Text = "Current style: Default";
+ // Select the default style.
+ StyleChooser.SelectedIndex = 0;
// Export offline custom styles.
_lightStyleResourceCache = await ExportStyle(_vectorTiledLayers[4]);
@@ -94,38 +95,12 @@ private async Task Initialize()
}
}
- private void ButtonClick(object sender, EventArgs e)
- {
- _ = StyleChooser();
- }
-
- private async Task StyleChooser()
+ private async void StyleChooser_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
- // Get the chosen style, determine that style's index, and update UI label.
- string style = await Application.Current.MainPage.DisplayActionSheet("Select:", "Cancel", null, styles);
-
- // Don't attempt to change the style if the user cancels or misclicks.
- if (style is null || style.Equals("Cancel")) { return; }
-
- int styleIndex = Array.IndexOf(styles, style);
- ChosenStyle.Text = $"Current style: {style}";
-
- // Check if the user selected an online or offline custom style.
- // Create a new basemap with the appropriate style.
- if (_onlineItemIDs.Contains(_vectorTiledLayers[styleIndex].ItemId))
- {
- MyMapView.Map.Basemap = new Basemap(new ArcGISVectorTiledLayer(_vectorTiledLayers[styleIndex]));
- await MyMapView.SetViewpointAsync(_defaultViewpoint);
- }
- else
- {
- // Determine which cache to use based on if the style selected is light (index 4) or dark.
- ItemResourceCache cache = styleIndex == 4 ? _lightStyleResourceCache : _darkStyleResourceCache;
- MyMapView.Map.Basemap = new Basemap(new ArcGISVectorTiledLayer(new VectorTileCache(_localVectorPackagePath), cache));
- await MyMapView.SetViewpointAsync(_dodgeCityViewpoint);
- }
+ // Get the style name and index of the selected item.
+ await ChangeStyleAsync(StyleChooser.SelectedIndex, StyleChooser.SelectedItem.ToString());
}
catch (Exception ex)
{
@@ -134,6 +109,26 @@ private async Task StyleChooser()
}
}
+ private async Task ChangeStyleAsync(int styleIndex, string styleName)
+ {
+ // Check if the user selected an online or offline custom style.
+ // Create a new basemap with the appropriate style.
+ if (styleName.Contains("Offline"))
+ {
+ // Determine which cache to use based on if the style selected is light or dark.
+ ItemResourceCache cache = styleName.Contains("Light") ? _lightStyleResourceCache : _darkStyleResourceCache;
+
+ MyMapView.Map.Basemap = new Basemap(new ArcGISVectorTiledLayer(new VectorTileCache(_localVectorPackagePath), cache));
+ await MyMapView.SetViewpointAsync(_dodgeCityViewpoint);
+ await cache.LoadAsync();
+ }
+ else
+ {
+ MyMapView.Map.Basemap = new Basemap(new ArcGISVectorTiledLayer(_vectorTiledLayers[styleIndex]));
+ await MyMapView.SetViewpointAsync(_defaultViewpoint);
+ }
+ }
+
private async Task ExportStyle(PortalItem vectorTiledLayer)
{
try
@@ -142,13 +137,16 @@ private async Task ExportStyle(PortalItem vectorTiledLayer)
ExportVectorTilesTask exportTask = await ExportVectorTilesTask.CreateAsync(vectorTiledLayer.Url);
// Get the item resource path for the basemap styling.
- string itemResourcePath = Path.Combine(Path.GetTempPath(), vectorTiledLayer.ItemId + "_styleItemResources");
+ string itemResourceCachePath = Path.Combine(Path.GetTempPath(), vectorTiledLayer.ItemId + "_styleItemResources");
// If cache has been created previously, return.
- if (Directory.Exists(itemResourcePath)) { return new ItemResourceCache(itemResourcePath); }
+ if (Directory.Exists(itemResourceCachePath) && (Directory.GetFiles(itemResourceCachePath).Length != 0))
+ {
+ return new ItemResourceCache(itemResourceCachePath);
+ }
// Create the export job and start it.
- ExportVectorTilesJob job = exportTask.ExportStyleResourceCache(itemResourcePath);
+ ExportVectorTilesJob job = exportTask.ExportStyleResourceCache(itemResourceCachePath);
job.Start();
// Wait for the job to complete.
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/AddVectorTiledLayerFromCustomStyle/addvectortiledlayerfromcustomstyle.jpg b/src/MAUI/Maui.Samples/Samples/Layers/AddVectorTiledLayerFromCustomStyle/addvectortiledlayerfromcustomstyle.jpg
index b00bb4f480..c27ce3dc23 100644
Binary files a/src/MAUI/Maui.Samples/Samples/Layers/AddVectorTiledLayerFromCustomStyle/addvectortiledlayerfromcustomstyle.jpg and b/src/MAUI/Maui.Samples/Samples/Layers/AddVectorTiledLayerFromCustomStyle/addvectortiledlayerfromcustomstyle.jpg differ
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/AddVectorTiledLayerFromCustomStyle/readme.md b/src/MAUI/Maui.Samples/Samples/Layers/AddVectorTiledLayerFromCustomStyle/readme.md
index a75ef04d33..395590a6bf 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/AddVectorTiledLayerFromCustomStyle/readme.md
+++ b/src/MAUI/Maui.Samples/Samples/Layers/AddVectorTiledLayerFromCustomStyle/readme.md
@@ -16,16 +16,15 @@ Pan and zoom to explore the vector tile basemap.
1. Create a `PortalItem` for each vector tiled layer.
2. Create a `Map` and set the default `Viewpoint`.
-3. Update the `Basemap` and `Viewpoint` when a new style is selected.
-4. Export the light and dark offline custom styles.
- i. Create a `ExportVectorTilesTask` using the portal item.
- ii. Get the path for where the cache is being stored locally.
- iii. Return with the cache if the path already exists.
- iv. Else, create a `ExportVectorTilesJob` by having the task call `ExportStyleResourceCache` with the path as a parameter.
- v. Start the job.
- vi. When the job completes, store the result as a `ExportVectorTilesResult`.
- vii. Return the result's item resource cache.
-5. Update the basemap upon a style selection change.
+3. Export the light and dark offline custom styles.
+ i. Create a `ExportVectorTilesTask` using the portal item.
+ ii. Get the path for where the cache is being stored locally.
+ iii. Return with the cache if the path already exists.
+ iv. Else, create a `ExportVectorTilesJob` by having the task call `ExportStyleResourceCache` with the path as a parameter.
+ v. Start the job.
+ vi. When the job completes, store the result as a `ExportVectorTilesResult`.
+ vii. Return the result's item resource cache.
+4. Update the `Basemap` and `Viewpoint` when a new style is selected.
## Relevant API
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/ApplyMosaicRule/ApplyMosaicRule.xaml b/src/MAUI/Maui.Samples/Samples/Layers/ApplyMosaicRule/ApplyMosaicRule.xaml
index c043d85b19..b7797bef75 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/ApplyMosaicRule/ApplyMosaicRule.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/ApplyMosaicRule/ApplyMosaicRule.xaml
@@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui"
xmlns:resources="clr-namespace:ArcGIS.Resources">
-
+
-
+
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/ChangeBlendRenderer/ChangeBlendRenderer.xaml b/src/MAUI/Maui.Samples/Samples/Layers/ChangeBlendRenderer/ChangeBlendRenderer.xaml
index b3769b44e2..5c4a9e2507 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/ChangeBlendRenderer/ChangeBlendRenderer.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/ChangeBlendRenderer/ChangeBlendRenderer.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
-
+
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/ControlAnnotationSublayerVisibility/ControlAnnotationSublayerVisibility.xaml b/src/MAUI/Maui.Samples/Samples/Layers/ControlAnnotationSublayerVisibility/ControlAnnotationSublayerVisibility.xaml
index 8729da4e7c..2957757344 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/ControlAnnotationSublayerVisibility/ControlAnnotationSublayerVisibility.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/ControlAnnotationSublayerVisibility/ControlAnnotationSublayerVisibility.xaml
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/DisplayPointsUsingClusteringFeatureReduction/DisplayPointsUsingClusteringFeatureReduction.xaml.cs b/src/MAUI/Maui.Samples/Samples/Layers/DisplayPointsUsingClusteringFeatureReduction/DisplayPointsUsingClusteringFeatureReduction.xaml.cs
new file mode 100644
index 0000000000..77040d68b9
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/Layers/DisplayPointsUsingClusteringFeatureReduction/DisplayPointsUsingClusteringFeatureReduction.xaml.cs
@@ -0,0 +1,79 @@
+// Copyright 2023 Esri.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+// language governing permissions and limitations under the License.
+
+using Esri.ArcGISRuntime.Data;
+using Esri.ArcGISRuntime.Mapping;
+using Esri.ArcGISRuntime.Portal;
+
+namespace ArcGIS.Samples.DisplayPointsUsingClusteringFeatureReduction
+{
+ [ArcGIS.Samples.Shared.Attributes.Sample(
+ name: "Display points using clustering feature reduction",
+ category: "Layers",
+ description: "Display a web map with a point feature layer that has feature reduction enabled to aggregate points into clusters.",
+ instructions: "Pan and zoom the map to view how clustering is dynamically updated. Toggle clustering off to view the original point features that make up the clustered elements. When clustering is on, you can tap on a clustered geoelement to view aggregated information and summary statistics for that cluster. When clustering is toggled off and you tap on the original feature you get access to information about individual power plant features.",
+ tags: new[] { "aggregate", "bin", "cluster", "group", "merge", "normalize", "reduce", "summarize" })]
+ [ArcGIS.Samples.Shared.Attributes.OfflineData()]
+ public partial class DisplayPointsUsingClusteringFeatureReduction
+ {
+ private FeatureLayer _layer;
+
+ public DisplayPointsUsingClusteringFeatureReduction()
+ {
+ InitializeComponent();
+ _ = Initialize();
+ }
+
+ private async Task Initialize()
+ {
+ // Get the power plants web map from the default portal.
+ var portal = await ArcGISPortal.CreateAsync();
+ PortalItem portalItem = await PortalItem.CreateAsync(portal, "8916d50c44c746c1aafae001552bad23");
+
+ // Create a new map from the web map.
+ MyMapView.Map = new Map(portalItem);
+
+ // Get the power plant feature layer once the map has finished loading.
+ await MyMapView.Map.LoadAsync();
+ _layer = (FeatureLayer)MyMapView.Map.OperationalLayers.First();
+
+ // Hide and nullify an opened popup when user taps screen.
+ PopupBackground.GestureRecognizers.Add(new TapGestureRecognizer
+ {
+ Command = new Command(() =>
+ {
+ PopupBackground.IsVisible = false;
+ PopupViewer.Popup = null;
+ })
+ });
+ }
+
+ private async void MyMapView_GeoViewTapped(object sender, Esri.ArcGISRuntime.Maui.GeoViewInputEventArgs e)
+ {
+ // Identify the tapped observation.
+ IdentifyLayerResult results = await MyMapView.IdentifyLayerAsync(_layer, e.Position, 3, true);
+
+ // Return if no observations were found.
+ if (results.Popups.Count == 0) return;
+
+ // Set the popup and make it visible.
+ PopupViewer.Popup = results.Popups.FirstOrDefault();
+ PopupBackground.IsVisible = true;
+ }
+
+ // Enable clustering feature reduction if the checkbox has been checked, disable otherwise.
+ private void CheckBox_CheckChanged(object sender, CheckedChangedEventArgs e)
+ {
+ // This event is raised when sample is initially loaded when layer is null.
+ if (_layer == null) return;
+
+ _layer.FeatureReduction.IsEnabled = (sender as CheckBox).IsChecked;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/DisplayPointsUsingClusteringFeatureReduction/displaypointsusingclusteringfeaturereduction.jpg b/src/MAUI/Maui.Samples/Samples/Layers/DisplayPointsUsingClusteringFeatureReduction/displaypointsusingclusteringfeaturereduction.jpg
new file mode 100644
index 0000000000..20e5923d04
Binary files /dev/null and b/src/MAUI/Maui.Samples/Samples/Layers/DisplayPointsUsingClusteringFeatureReduction/displaypointsusingclusteringfeaturereduction.jpg differ
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/DisplayPointsUsingClusteringFeatureReduction/readme.md b/src/MAUI/Maui.Samples/Samples/Layers/DisplayPointsUsingClusteringFeatureReduction/readme.md
new file mode 100644
index 0000000000..08d7898985
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/Layers/DisplayPointsUsingClusteringFeatureReduction/readme.md
@@ -0,0 +1,38 @@
+# Display points using clustering feature reduction
+
+Display a web map with a point feature layer that has feature reduction enabled to aggregate points into clusters.
+
+![](displaypointsusingclusteringfeaturereduction.jpg)
+
+## Use case
+
+Feature clustering can be used to dynamically aggregate groups of points that are within proximity of each other in order to represent each group with a single symbol. Such grouping allows you to see patterns in the data that are difficult to visualize when a layer contains hundreds or thousands of points that overlap and cover each other.
+
+## How to use the sample
+
+Pan and zoom the map to view how clustering is dynamically updated. Toggle clustering off to view the original point features that make up the clustered elements. When clustering is on, you can tap on a clustered geoelement to view aggregated information and summary statistics for that cluster. When clustering is toggled off and you tap on the original feature you get access to information about individual power plant features.
+
+## How it works
+
+1. Create a map from a web map `PortalItem`.
+2. Get the cluster enabled layer from the map's operational layers.
+3. Get the `FeatureReduction` from the feature layer and set the `IsEnabled` bool to enable or disable clustering on the feature layer.
+4. When the user clicks on the map, call `IdentifyFeatureLayerAsync()`, passing in the layer, map tap location, tolerance, and `returnPopupsOnly` as true.
+5. Set the `Popup` from the resulting `IdentifyLayerResult` to the `PopupViewer.Popup`.
+6. Make the `PopupViewer` visible.
+
+## Relevant API
+
+* AggregateGeoElement
+* FeatureLayer
+* FeatureReduction
+* GeoElement
+* IdentifyLayerResult
+
+## About the data
+
+This sample uses a [web map](https://www.arcgis.com/home/item.html?id=8916d50c44c746c1aafae001552bad23) that displays the Esri [Global Power Plants](https://www.arcgis.com/home/item.html?id=eb54b44c65b846cca12914b87b315169) feature layer with feature reduction enabled. When enabled, the aggregate features symbology shows the color of the most common power plant type, and a size relative to the average plant capacity of the cluster.
+
+## Tags
+
+aggregate, bin, cluster, group, merge, normalize, reduce, summarize
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/DisplayPointsUsingClusteringFeatureReduction/readme.metadata.json b/src/MAUI/Maui.Samples/Samples/Layers/DisplayPointsUsingClusteringFeatureReduction/readme.metadata.json
new file mode 100644
index 0000000000..653736ce73
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/Layers/DisplayPointsUsingClusteringFeatureReduction/readme.metadata.json
@@ -0,0 +1,35 @@
+{
+ "category": "Layers",
+ "description": "Display a web map with a point feature layer that has feature reduction enabled to aggregate points into clusters.",
+ "formal_name": "DisplayPointsUsingClusteringFeatureReduction",
+ "ignore": false,
+ "images": [
+ "displaypointsusingclusteringfeaturereduction.jpg"
+ ],
+ "keywords": [
+ "aggregate",
+ "bin",
+ "cluster",
+ "group",
+ "merge",
+ "normalize",
+ "reduce",
+ "summarize"
+ ],
+ "offline_data": [],
+ "redirect_from": [
+ "/net/latest/maui/sample-code/displaypointsusingclusteringfeaturereduction.htm"
+ ],
+ "relevant_apis": [
+ "AggregateGeoElement",
+ "FeatureLayer",
+ "FeatureReduction",
+ "GeoElement",
+ "IdentifyLayerResult"
+ ],
+ "snippets": [
+ "DisplayPointsUsingClusteringFeatureReduction.xaml.cs",
+ "DisplayPointsUsingClusteringFeatureReduction.xaml"
+ ],
+ "title": "Display points using clustering feature reduction"
+}
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/DisplaySubtypeFeatureLayer/DisplaySubtypeFeatureLayer.xaml b/src/MAUI/Maui.Samples/Samples/Layers/DisplaySubtypeFeatureLayer/DisplaySubtypeFeatureLayer.xaml
index 8707644b66..0b12aa5208 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/DisplaySubtypeFeatureLayer/DisplaySubtypeFeatureLayer.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/DisplaySubtypeFeatureLayer/DisplaySubtypeFeatureLayer.xaml
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/DisplayWfs/DisplayWfs.xaml b/src/MAUI/Maui.Samples/Samples/Layers/DisplayWfs/DisplayWfs.xaml
index e1244bf464..22487bf18d 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/DisplayWfs/DisplayWfs.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/DisplayWfs/DisplayWfs.xaml
@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui"
xmlns:resources="clr-namespace:ArcGIS.Resources">
-
+
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/ExportVectorTiles/ExportVectorTiles.xaml b/src/MAUI/Maui.Samples/Samples/Layers/ExportVectorTiles/ExportVectorTiles.xaml
index e34c3a8e38..1bb676064f 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/ExportVectorTiles/ExportVectorTiles.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/ExportVectorTiles/ExportVectorTiles.xaml
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/FeatureLayerDefinitionExpression/FeatureLayerDefinitionExpression.xaml b/src/MAUI/Maui.Samples/Samples/Layers/FeatureLayerDefinitionExpression/FeatureLayerDefinitionExpression.xaml
index 0bd504a672..f063ce24f5 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/FeatureLayerDefinitionExpression/FeatureLayerDefinitionExpression.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/FeatureLayerDefinitionExpression/FeatureLayerDefinitionExpression.xaml
@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui"
xmlns:resources="clr-namespace:ArcGIS.Resources">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/GroupLayers/GroupLayers.xaml b/src/MAUI/Maui.Samples/Samples/Layers/GroupLayers/GroupLayers.xaml
index ebc1ae790c..1f833ebe50 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/GroupLayers/GroupLayers.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/GroupLayers/GroupLayers.xaml
@@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui"
xmlns:resources="clr-namespace:ArcGIS.Resources">
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/ListKmlContents/ListKmlContents.xaml b/src/MAUI/Maui.Samples/Samples/Layers/ListKmlContents/ListKmlContents.xaml
index 93f1aeb100..ea6d69b013 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/ListKmlContents/ListKmlContents.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/ListKmlContents/ListKmlContents.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/PlayKmlTours/PlayKmlTours.xaml.cs b/src/MAUI/Maui.Samples/Samples/Layers/PlayKmlTours/PlayKmlTours.xaml.cs
index 1e26470727..92f1e82233 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/PlayKmlTours/PlayKmlTours.xaml.cs
+++ b/src/MAUI/Maui.Samples/Samples/Layers/PlayKmlTours/PlayKmlTours.xaml.cs
@@ -10,6 +10,7 @@
using ArcGIS.Samples.Managers;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Ogc;
+using Esri.ArcGISRuntime.UI;
using System.ComponentModel;
using System.Diagnostics;
@@ -19,7 +20,7 @@ namespace ArcGIS.Samples.PlayKmlTours
name: "Play KML tour",
category: "Layers",
description: "Play tours in KML files.",
- instructions: "The sample will load the KMZ file from ArcGIS Online. When a tour is found, the _Play_ button will be enabled. Use _Play_ and _Pause_ to control the tour. When you're ready to show the tour, use the reset button to return the tour to the unplayed state.",
+ instructions: "The sample will load the KMZ file from ArcGIS Online. When a tour is found, the _Play_ button will be enabled. Use _Play_ and _Pause_ to control the tour. Use the _Reset_ button to return the tour to the unplayed state.",
tags: new[] { "KML", "animation", "interactive", "narration", "pause", "play", "story", "tour" })]
[ArcGIS.Samples.Shared.Attributes.OfflineData("f10b1d37fdd645c9bc9b189fb546307c")]
public partial class PlayKmlTours : ContentPage, IDisposable
@@ -27,6 +28,9 @@ public partial class PlayKmlTours : ContentPage, IDisposable
// The KML tour controller provides player controls for KML tours.
private readonly KmlTourController _tourController = new KmlTourController();
+ // Keep track of play/pause status.
+ private bool _tourPlaying;
+
public PlayKmlTours()
{
InitializeComponent();
@@ -68,10 +72,16 @@ private async Task Initialize()
_tourController.Tour.PropertyChanged += Tour_PropertyChanged;
// Enable the play button.
- PlayButton.IsEnabled = true;
+ PlayPauseButton.IsEnabled = true;
// Hide the status bar.
LoadingStatusBar.IsVisible = false;
+
+ // Create scene interaction options which will be disabled when the tour begins.
+ MySceneView.InteractionOptions = new SceneViewInteractionOptions
+ {
+ IsEnabled = false
+ };
}
catch (Exception e)
{
@@ -129,33 +139,59 @@ private void Tour_PropertyChanged(object sender, PropertyChangedEventArgs e)
switch (_tourController.Tour.TourStatus)
{
case KmlTourStatus.Completed:
- case KmlTourStatus.Initialized:
- PlayButton.IsEnabled = true;
- PauseButton.IsEnabled = false;
+ PlayPauseButton.IsEnabled = true;
+ ResetButton.IsEnabled = false;
+ PlayPauseButton.Text = "Play";
+ _tourPlaying = false;
+ MySceneView.InteractionOptions.IsEnabled = true;
+
+ // Return to the initial viewpoint to visually indicate the tour being over.
+ MySceneView.SetViewpointAsync(MySceneView.Scene.InitialViewpoint);
break;
- case KmlTourStatus.Paused:
- PlayButton.IsEnabled = true;
- PauseButton.IsEnabled = false;
- ResetButton.IsEnabled = true;
+ case KmlTourStatus.Initialized:
+ PlayPauseButton.IsEnabled = true;
+ ResetButton.IsEnabled = false;
+ PlayPauseButton.Text = "Play";
+ _tourPlaying = false;
+ MySceneView.InteractionOptions.IsEnabled = true;
break;
case KmlTourStatus.Playing:
ResetButton.IsEnabled = true;
- PlayButton.IsEnabled = false;
- PauseButton.IsEnabled = true;
+ PlayPauseButton.IsEnabled = true;
+ PlayPauseButton.Text = "Pause";
+ _tourPlaying = true;
+ MySceneView.InteractionOptions.IsEnabled = false;
+ break;
+
+ case KmlTourStatus.Paused:
+ PlayPauseButton.Text = "Play";
+ _tourPlaying = false;
break;
}
}
- // Play the tour when the button is pressed.
- private void Play_Clicked(object sender, EventArgs e) => _tourController?.Play();
-
- // Pause the tour when the button is pressed.
- private void Pause_Clicked(object sender, EventArgs e) => _tourController?.Pause();
+ // Play and pause the tour when the button is pressed.
+ private void PlayPause_Clicked(object sender, EventArgs e)
+ {
+ if (_tourPlaying)
+ {
+ _tourController?.Pause();
+ }
+ else
+ {
+ _tourController?.Play();
+ }
+ }
// Reset the tour when the button is pressed.
- private void Reset_Clicked(object sender, EventArgs e) => _tourController?.Reset();
+ private void Reset_Clicked(object sender, EventArgs e)
+ {
+ _tourController?.Reset();
+ MySceneView.SetViewpoint(MySceneView.Scene.InitialViewpoint);
+ PlayPauseButton.Text = "Play";
+ }
public void Dispose()
{
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/PlayKmlTours/playkmltours.jpg b/src/MAUI/Maui.Samples/Samples/Layers/PlayKmlTours/playkmltours.jpg
index b06bc98b6b..63392c4af8 100644
Binary files a/src/MAUI/Maui.Samples/Samples/Layers/PlayKmlTours/playkmltours.jpg and b/src/MAUI/Maui.Samples/Samples/Layers/PlayKmlTours/playkmltours.jpg differ
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/PlayKmlTours/readme.md b/src/MAUI/Maui.Samples/Samples/Layers/PlayKmlTours/readme.md
index 2a3078c4e4..1b60609260 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/PlayKmlTours/readme.md
+++ b/src/MAUI/Maui.Samples/Samples/Layers/PlayKmlTours/readme.md
@@ -10,14 +10,14 @@ KML, the file format used by Google Earth, supports creating tours, which can co
## How to use the sample
-The sample will load the KMZ file from ArcGIS Online. When a tour is found, the _Play_ button will be enabled. Use _Play_ and _Pause_ to control the tour. When you're ready to show the tour, use the reset button to return the tour to the unplayed state.
+The sample will load the KMZ file from ArcGIS Online. When a tour is found, the _Play_ button will be enabled. Use _Play_ and _Pause_ to control the tour. Use the _Reset_ button to return the tour to the unplayed state.
This sample is graphics intensive and includes audio. Performance may be poor on emulated and remote devices. Run the sample on a physical device for best performance.
## How it works
1. Load the KML file and add it to a layer.
-2. Create the KML tour controller. Wire up the buttons to the `Play`, `Pause`, and `Reset` methods.
+2. Create the KML tour controller. Wire up the buttons to the `PlayPause` and `Reset` methods.
3. Explore the tree of KML content to find the first KML tour. Once a tour is found, provide it to the KML tour controller.
4. Enable the buttons to allow the user to play, pause, and reset the tour.
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/QueryCQLFilters/QueryCQLFilters.xaml b/src/MAUI/Maui.Samples/Samples/Layers/QueryCQLFilters/QueryCQLFilters.xaml
index 3e8d1e03fb..1066e90fa9 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/QueryCQLFilters/QueryCQLFilters.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/QueryCQLFilters/QueryCQLFilters.xaml
@@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui"
xmlns:resources="clr-namespace:ArcGIS.Resources">
-
+
-
+
-
+
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/RasterRgbRenderer/RasterRgbRenderer.xaml b/src/MAUI/Maui.Samples/Samples/Layers/RasterRgbRenderer/RasterRgbRenderer.xaml
index 13479fa377..92598e7885 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/RasterRgbRenderer/RasterRgbRenderer.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/RasterRgbRenderer/RasterRgbRenderer.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+ _wmsLayerNames = new List { "1" };
+ private readonly List _wmsLayerNames = new List { "conus_base_reflectivity_mosaic" };
public WMSLayerUrl()
{
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/WMSLayerUrl/readme.md b/src/MAUI/Maui.Samples/Samples/Layers/WMSLayerUrl/readme.md
index 940e466299..0f7646e3f4 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/WMSLayerUrl/readme.md
+++ b/src/MAUI/Maui.Samples/Samples/Layers/WMSLayerUrl/readme.md
@@ -26,7 +26,7 @@ The map will load automatically when the sample starts.
## About the data
-This sample uses a [U.S. National Weather Service radar map](https://nowcoast.noaa.gov/arcgis/services/nowcoast/radar_meteo_imagery_nexrad_time/MapServer/WMSServer?request=GetCapabilities&service=WMS). Because WMS services generate map images on-the-fly, this layer is always up-to-date with the latest [NOAA NEXRAD radar](https://www.ncei.noaa.gov/products/radar/next-generation-weather-radar) observations.
+This sample uses the WMS service behind the [U.S. National Weather Service radar map](https://nowcoast.noaa.gov/arcgis/services/nowcoast/radar_meteo_imagery_nexrad_time/MapServer/WMSServer?request=GetCapabilities&service=WMS). Because WMS services generate map images on-the-fly, this layer is always up-to-date with the latest NOAA nowCOAST real-time coastal observations, forecasts, and warnings.
## Tags
diff --git a/src/MAUI/Maui.Samples/Samples/Layers/WMTSLayer/WMTSLayer.xaml b/src/MAUI/Maui.Samples/Samples/Layers/WMTSLayer/WMTSLayer.xaml
index 3c5103591f..8a2db25315 100644
--- a/src/MAUI/Maui.Samples/Samples/Layers/WMTSLayer/WMTSLayer.xaml
+++ b/src/MAUI/Maui.Samples/Samples/Layers/WMTSLayer/WMTSLayer.xaml
@@ -3,7 +3,7 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
-
+
-
+
-
+