Get symbols from Feature Layer

1994
4
Jump to solution
04-26-2021 10:48 AM
brysageek
New Contributor II

Looking to make a palette of sorts for symbols to be selected for Feature edits, was wondering if someone had some ideas on how one could get all of the symbols used in a feature service (Feature Layer).  Have been prying and poking--nothing too obvious as of yet, any suggestions?

0 Kudos
1 Solution

Accepted Solutions
PreetiMaske
Esri Contributor

Alternatively you could also use SymbolDisplay toolkit control to display the symbols to get the palette/picker experience.

https://github.com/Esri/arcgis-toolkit-dotnet/blob/807302b3b613b93c54731c722be101eaf0fc62a9/src/Samp...

Another great example is the SymbolEditor demo available here:
https://github.com/Esri/arcgis-runtime-demos-dotnet/tree/main/src/SymbolEditor

View solution in original post

0 Kudos
4 Replies
PreetiMaske
Esri Contributor

You can query layer for its feature templates and use those templates to create a palette. For e.g this layer http://sampleserver6.arcgisonline.com/arcgis/rest/services/Sync/WildfireSync/FeatureServer/0 has templates. This info is available after layer has loaded. You can fetch these templates and create your palette. The benefit of using templates is that it will create a feature with the attributes pre-defined in it.

If there are no templates then you will have to query layer's renderer info, find the symbols and create your symbol palette. You will have to do some additional work to assign attributes at the time of feature creation and choose the symbol selected from the palette. Note, this second workflow will vary depending on the renderer defined in the layer.

JoeHershman
MVP Regular Contributor

@PreetiMaske is correct although I have found it a tad more complex and it depends what you mean by palette, and what you are doing it in.  If your in WPF it is pretty straight forward because WPF does not have things going on behind the scenes to optimize.

The basic approach is to create a Model that expose an ImageSource which can be bound to your palette in the DataTemplate.  The ViewModel would contain the ObservableCollection of that Model.  Which is bound to the list being used to display the palette.

Then you have to get the ImageSource.  Something along these lines.  When the Model object is created the RuntimeImage is converted to an ImageSource.  Having a .Wait()  in the constructor is certainly not a best practice, but it is how I implemented.  Using something like a static  CreateAsync on the Model object is probably a better pattern

 

//this is the model - the item of the collection being bound
public class SymbolItem
	public SymbolItem(LegendInfo legendInfo, ...)
	{
		LegendInfo = legendInfo;
		...

		Task t = Task.Run(InitializeAsync);
		t.Wait();
	}

	private async Task InitializeAsync()
	{
		//A little unclear on best way to adjust the parameters to get the image to size best
		RuntimeImage runtimeImage;
		if ( FeatureTable.GeometryType == GeometryType.Polyline )
		{
			runtimeImage = await LegendInfo.Symbol.CreateSwatchAsync(24, 24, 128f, Color.Transparent, new Polyline(new [] {new MapPoint(-10, 0), new MapPoint(10, 0) }));
		}
		else
		{
			runtimeImage = await LegendInfo.Symbol.CreateSwatchAsync(24, 24, 128f, Color.Transparent, new MapPoint(0, 0));
		}
		
		ImageSource source = await runtimeImage.ToImageSourceAsync();
		
		//http://stackoverflow.com/questions/26361020/error-must-create-dependencysource-on-same-thread-as-the-dependencyobject-even
		source.Freeze();
		
		Dispatcher.CurrentDispatcher.Invoke(() => ImageSource = source);
	}

	public ImageSource ImageSource { get; set; }
	...
}
		

 

In my ViewModel there is the ObservableCollection of these

 

public ObservableCollection<SymbolItem> SymbolItems { get; set; } = new ObservableCollection<SymbolItem>();

 

In Xaml I bind to the ImageSource

 

<!-- Would be nice to use this control, but have no control over image size with it -->
<!--<esritoolkit:SymbolDisplay Symbol="{Binding LegendInfo.Symbol, Mode=OneTime}" Margin="0,0,5,0" />-->
<Grid>
	<Grid.ColumnDefinitions>
		<ColumnDefinition Width="60" />
		<ColumnDefinition Width="*" />
	</Grid.ColumnDefinitions>
	<Image Grid.Column="0" Source="{Binding ImageSource}" />
</Grid>

 

As noted there, the esri toolkit does have a SymbolItem but at least in 100.6 I found it did not provide enough control over sizing.

In Xamarin Forms you have an added complexity in how it recycles images.  That required creating custom ViewCells to handle this issue... I won't go into that at this time

 

Thanks,
-Joe
PreetiMaske
Esri Contributor

Alternatively you could also use SymbolDisplay toolkit control to display the symbols to get the palette/picker experience.

https://github.com/Esri/arcgis-toolkit-dotnet/blob/807302b3b613b93c54731c722be101eaf0fc62a9/src/Samp...

Another great example is the SymbolEditor demo available here:
https://github.com/Esri/arcgis-runtime-demos-dotnet/tree/main/src/SymbolEditor

0 Kudos
JoeHershman
MVP Regular Contributor

@PreetiMaske As I noted, I found that the SymbolDisplay toolkit control lacked the ability to adjust the size.  This may have changed after 100.6.  Because of that issue, the control was not usable in my application.  Had it worked I would have used it

Thanks,
-Joe
0 Kudos