Hi!
I created non-geo map view and placed 1000 of points.
I want to cluster them using FeatureReduction.
When i start application i can see:

But when I click "draw cluster" i got an error:

Pulse Failed: Invalid argument: Not a GCS or PCS
Here is my MainWindow.xaml.cs:
using Esri.ArcGISRuntime.ArcGISServices;
using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Mapping.Labeling;
using Esri.ArcGISRuntime.Mapping.Popups;
using Esri.ArcGISRuntime.Portal;
using Esri.ArcGISRuntime.Reduction;
using Esri.ArcGISRuntime.Symbology;
using Esri.ArcGISRuntime.UI;
using Esri.ArcGISRuntime.UI.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Clusters
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private FeatureLayer _layer;
GraphicsOverlay _theGraphicsOverlays;
GraphicsOverlay _theGraphicsOverlaysNon;
private ClusteringFeatureReduction _clusteringFeatureReduction;
public MainWindow()
{
InitializeComponent();
_ = Initialize();
}
bool generatePoints = true;
int countPoints = 200;
void addIncidents()
{
_theGraphicsOverlays = new GraphicsOverlay();
// Get the graphic collection from the graphics overlay.
GraphicCollection theGraphicCollection = _theGraphicsOverlays.Graphics;
SimpleMarkerSymbol theSimpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Square, System.Drawing.Color.Red, 28);
theSimpleMarkerSymbol.Outline = new SimpleLineSymbol();
theSimpleMarkerSymbol.Outline.Color = System.Drawing.Color.Black;
List<Graphic> mapPoints = new List<Graphic>();
List<Graphic> mapPoints1 = new List<Graphic>();
if (generatePoints)
{
Random random = new Random();
for (int i = 0; i < countPoints; i++)
{
double x = random.Next(0, 2000); // Replace 10000 with your desired range for X coordinates
double y = random.Next(-1000, 0); // Replace 10000 with your desired range for Y coordinates
double z = 0; // If you need random Z values, generate them here
MapPoint point = new MapPoint(x, y, z);
var textSymbol = new TextSymbol
{
Text = $"{x},{y}",
Color = System.Drawing.Color.Black,
HaloColor = System.Drawing.Color.White,
HaloWidth = 2,
Size = 4,
VerticalAlignment = Esri.ArcGISRuntime.Symbology.VerticalAlignment.Middle,
HorizontalAlignment = Esri.ArcGISRuntime.Symbology.HorizontalAlignment.Center
};
var compositeSymbol = new CompositeSymbol
{
Symbols = { theSimpleMarkerSymbol, textSymbol }
};
mapPoints.Add(new Graphic(point, compositeSymbol));
mapPoints1.Add(new Graphic(point, compositeSymbol));
}
}
theGraphicCollection.AddRange(mapPoints);
MyMapViewNonGeo.GraphicsOverlays.Add(_theGraphicsOverlays);
}
private async void LoadRaster(RasterLayer myRasterLayer)
{
await myRasterLayer.LoadAsync();
await MyMapViewNonGeo.SetViewpointGeometryAsync(myRasterLayer.FullExtent);
}
private async Task Initialize()
{
//MyMapView.Map = new Map(SpatialReferences.WebMercator);
MyMapViewNonGeo.Map = new Map();
string filename = System.IO.Path.GetFullPath(@"C:\Files\QuartzTest\QuartzTest\NonGeo\worldmap-countries-hd.jpg");
// Create the layer
RasterLayer imageLayer = new RasterLayer(filename);
LoadRaster(imageLayer);
MyMapViewNonGeo.Map.Basemap.BaseLayers.Add(imageLayer);
DrawClustersButton.IsEnabled = true;
addIncidents();
}
private void CreateCustomFeatureReduction()
{
try
{
// Create a class breaks renderer to apply to the custom feature reduction.
ClassBreaksRenderer classBreaksRenderer = new ClassBreaksRenderer();
classBreaksRenderer.DefaultSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Diamond, System.Drawing.Color.White, 24)
{
Outline = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, System.Drawing.Color.FromArgb(0, 122, 204), 2)
};
_clusteringFeatureReduction = new ClusteringFeatureReduction(classBreaksRenderer);
// Set the feature reduction for the layer.
//_layer.FeatureReduction = _clusteringFeatureReduction;
var incidents = MyMapViewNonGeo.GraphicsOverlays.First();
incidents.FeatureReduction = _clusteringFeatureReduction;
var simpleLabelExpression = new SimpleLabelExpression("[cluster_count]");
var textSymbol = new TextSymbol()
{
Color = System.Drawing.Color.Black,
Size = 15,
HaloColor = System.Drawing.Color.White,
HaloWidth = 2
};
var labelDefinition = new LabelDefinition(simpleLabelExpression, textSymbol) { Placement = LabelingPlacement.PointCenterCenter };
// Add the label definition to the feature reduction.
//_clusteringFeatureReduction.LabelDefinitions.Add(labelDefinition);
// Populate the cluster radius and max scale pickers with default values.
List<double> items = new List<double> { 0, 1, 2, 3, 4, 5, 6, 10, 15, 30, 45, 60, 75, 90, 100,200,300, 1000 };
ClusterRadiusPicker.ItemsSource = items;
// Set initial picker values.
// Note that the default value for cluster radius is 60.
// Increasing the cluster radius increases the number of features that are grouped together into a cluster.
ClusterRadiusPicker.SelectedValue = _clusteringFeatureReduction.Radius;
}
catch (Exception ex)
{
}
}
#region EventHandlers
private void DisplayLabelsCheckBox_Checked(object sender, RoutedEventArgs e)
{
if ((bool)(sender as CheckBox).IsChecked)
{
// Create a label definition with a simple label expression.
var simpleLabelExpression = new SimpleLabelExpression("[cluster_count]");
var textSymbol = new TextSymbol() { Color = System.Drawing.Color.Black,
Size = 15,
HaloColor = System.Drawing.Color.White,
HaloWidth = 2
};
var labelDefinition = new LabelDefinition(simpleLabelExpression, textSymbol) { Placement = LabelingPlacement.PointCenterCenter };
// Add the label definition to the feature reduction.
_clusteringFeatureReduction?.LabelDefinitions.Add(labelDefinition);
}
else
{
_clusteringFeatureReduction.LabelDefinitions.Clear();
}
}
// When a new picker item is selected, update the feature reduction cluster radius.
private void ClusterRadiusPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (_layer != null)
{
((ClusteringFeatureReduction)_layer.FeatureReduction).Radius = (double)ClusterRadiusPicker.SelectedItem;
}
if (_theGraphicsOverlaysNon != null)
{
((ClusteringFeatureReduction)_theGraphicsOverlaysNon.FeatureReduction).Radius = (double)ClusterRadiusPicker.SelectedItem;
}
}
private void DrawClustersButton_Clicked(object sender, RoutedEventArgs e)
{
try
{
// Create a new clustering feature reduction.
CreateCustomFeatureReduction();
// Show the feature reduction's clustering options.
ClusteringOptions.Visibility = Visibility.Visible;
// Hide the draw clusters button.
DrawClustersButton.Visibility = Visibility.Collapsed;
}
catch(Exception ex)
{
}
}
// Hide and nullify the opened popup when user left clicks.
private void PopupBackground_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
PopupBackground.Visibility = Visibility.Collapsed;
//PopupViewer.Popup = null;
}
#endregion EventHandlers
}
}Here is MainWindow.xaml
<Window x:Class="Clusters.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Clusters"
xmlns:quartz="http://schemas.esri.com/arcgis/runtime/2013"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<quartz:MapView x:Name="MyMapViewNonGeo" />
<Border Width="auto"
Height="auto">
<StackPanel Orientation="Vertical">
<Button x:Name="DrawClustersButton"
Padding="5"
HorizontalAlignment="Center"
Click="DrawClustersButton_Clicked"
Content="Draw clusters"
IsEnabled="False" />
<Grid x:Name="ClusteringOptions" Visibility="Collapsed">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.ColumnSpan="2"
Padding="5"
HorizontalAlignment="Center"
FontSize="16"
FontWeight="Bold"
Text="Clustering Properties" />
<TextBlock Grid.Row="1"
Grid.Column="0"
Padding="5"
HorizontalAlignment="Right"
VerticalAlignment="Center"
FontWeight="Bold"
Text="Display labels:" />
<CheckBox x:Name="DisplayLabelsCheckBox"
Grid.Row="1"
Grid.Column="1"
VerticalAlignment="Center"
Checked="DisplayLabelsCheckBox_Checked"
IsChecked="true"
Unchecked="DisplayLabelsCheckBox_Checked" />
<TextBlock Grid.Row="2"
Grid.Column="0"
Padding="5"
HorizontalAlignment="Right"
VerticalAlignment="Center">
<Run FontWeight="Bold" Text="Cluster radius:" />
<Run Text="{Binding ElementName=ClusterRadiusSlider, Path=Value, Mode=OneWay, StringFormat=n0}" />
</TextBlock>
<ComboBox x:Name="ClusterRadiusPicker"
Grid.Row="2"
Grid.Column="1"
Width="75"
HorizontalAlignment="Left"
VerticalAlignment="Center"
SelectionChanged="ClusterRadiusPicker_SelectionChanged" />
<TextBlock Grid.Row="3"
Grid.Column="0"
Padding="5"
HorizontalAlignment="Right"
VerticalAlignment="Center">
<Run FontWeight="Bold" Text="Maximum map scale:" />
<Run Text="{Binding ElementName=MaxScaleSlider, Path=Value, Mode=OneWay, StringFormat=n0}" />
</TextBlock>
<TextBlock Grid.Row="4"
Grid.Column="0"
Grid.ColumnSpan="2"
Padding="5"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Run FontWeight="Bold" Text="Current map scale: " />
<Run Text="1:" />
<Run Text="{Binding ElementName=MyMapView, Path=MapScale, Mode=OneWay, StringFormat=n0}" />
</TextBlock>
</Grid>
</StackPanel>
</Border>
<TextBlock x:Name="DistanceTextBlock" Foreground="Black"
HorizontalAlignment="Left" VerticalAlignment="Center"
Text="Distance between points: " TextWrapping="Wrap" FontWeight="Bold" Margin="28,10,0,395" Height="auto" Width="266"/>
<Grid x:Name="PopupBackground"
Background="#AA333333"
MouseLeftButtonDown="PopupBackground_MouseLeftButtonDown"
Visibility="Collapsed">
<Border HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="White">
<!--<quartz:PopupViewer x:Name="PopupViewer"
MaxWidth="400"
MaxHeight="400"
Margin="5"
Padding="5" />-->
</Border>
</Grid>
</Grid>
</Window>
My question is do you support clustering at all for Non geo maps, if yes, what should i change to have it working?
Thanks