/// <summary> /// Initializes a new instance of the <see cref="LayerItemViewModel"/> class from a <see cref="LayerLegendInfo"/>.. /// </summary> /// <param name="layer">The layer.</param> /// <param name="layerLegendInfo">The layer legend info.</param> /// <param name="defaultLayerDescription">The default layer description (= the map layer description).</param> internal LayerItemViewModel(Layer layer, LayerLegendInfo layerLegendInfo, string defaultLayerDescription) : this(layer) { Debug.Assert(layerLegendInfo != null); SubLayerID = layerLegendInfo.SubLayerID; Label = layerLegendInfo.LayerName; ParentLabel = layer.DisplayName; LayerType = layerLegendInfo.LayerType; IsHidden = layerLegendInfo.IsHidden; Description = string.IsNullOrEmpty(layerLegendInfo.LayerDescription) ? defaultLayerDescription : layerLegendInfo.LayerDescription; // Convert scale to resolution MinimumScale = layerLegendInfo.MinimumScale == 0.0 ? double.PositiveInfinity : layerLegendInfo.MinimumScale; MaximumScale = layerLegendInfo.MaximumScale; if (layerLegendInfo.LayerLegendInfos != null) { LayerItems = layerLegendInfo.LayerLegendInfos.Select(info => new LayerItemViewModel(layer, info, defaultLayerDescription)).ToObservableCollection(); } if (layerLegendInfo.LegendItemInfos != null) { LegendItems = layerLegendInfo.LegendItemInfos.Select(info => new LegendItemViewModel(info, Geometry.GeometryType.Unknown)).ToObservableCollection(); } }
/// <summary> /// Initializes a new instance of the <see cref="LayerItemViewModel"/> class from a <see cref="LayerLegendInfo"/>.. /// </summary> /// <param name="layer">The layer.</param> /// <param name="layerLegendInfo">The layer legend info.</param> /// <param name="defaultLayerDescription">The default layer description (= the map layer description).</param> /// <param name="map">The map.</param> internal LayerItemViewModel(Layer layer, LayerLegendInfo layerLegendInfo, string defaultLayerDescription, Map map) : this(layer) { Debug.Assert(layerLegendInfo != null); Debug.Assert(map != null); // Needed to convert scale to resolution SubLayerID = layerLegendInfo.SubLayerID; Label = layerLegendInfo.LayerName; ParentLabel = layer.DisplayName ?? layer.ID; LayerType = layerLegendInfo.LayerType; IsHidden = layerLegendInfo.IsHidden; if (string.IsNullOrEmpty(layerLegendInfo.LayerDescription)) { Description = defaultLayerDescription; } else { Description = layerLegendInfo.LayerDescription; } // Convert scale to resolution MaximumResolution = layerLegendInfo.MinimumScale == 0.0 ? double.PositiveInfinity : ConvertToResolution(layerLegendInfo.MinimumScale, map); MinimumResolution = ConvertToResolution(layerLegendInfo.MaximumScale, map); if (layerLegendInfo.LayerLegendInfos != null) { LayerItems = layerLegendInfo.LayerLegendInfos.Select(info => new LayerItemViewModel(layer, info, defaultLayerDescription, map)).ToObservableCollection(); } if (layerLegendInfo.LegendItemInfos != null) { LegendItems = layerLegendInfo.LegendItemInfos.Select(info => new LegendItemViewModel(info)).ToObservableCollection(); } }
/// <summary> /// Initializes a new instance of the <see cref="LayerItemViewModel"/> class from a <see cref="LayerLegendInfo"/>.. /// </summary> /// <param name="layer">The layer.</param> /// <param name="layerLegendInfo">The layer legend info.</param> /// <param name="defaultLayerDescription">The default layer description (= the map layer description).</param> /// <param name="map">The map.</param> internal LayerItemViewModel(Layer layer, LayerLegendInfo layerLegendInfo, string defaultLayerDescription, Map map) : this(layer) { Debug.Assert(layerLegendInfo != null); Debug.Assert(map != null); // Needed to convert scale to resolution SubLayerID = layerLegendInfo.SubLayerID; Label = layerLegendInfo.LayerName; ParentLabel = layer.DisplayName ?? layer.ID; LayerType = layerLegendInfo.LayerType; IsHidden = layerLegendInfo.IsHidden; if (string.IsNullOrEmpty(layerLegendInfo.LayerDescription)) Description = defaultLayerDescription; else Description = layerLegendInfo.LayerDescription; // Convert scale to resolution MaximumResolution = layerLegendInfo.MinimumScale == 0.0 ? double.PositiveInfinity : ConvertToResolution(layerLegendInfo.MinimumScale, map); MinimumResolution = ConvertToResolution(layerLegendInfo.MaximumScale, map); if (layerLegendInfo.LayerLegendInfos != null) { LayerItems = layerLegendInfo.LayerLegendInfos.Select(info => new LayerItemViewModel(layer, info, defaultLayerDescription, map)).ToObservableCollection(); } if (layerLegendInfo.LegendItemInfos != null) { LegendItems = layerLegendInfo.LegendItemInfos.Select(info => new LegendItemViewModel(info)).ToObservableCollection(); } }
/// <summary> /// Iteratively called to create nodes for all sub-layers in a Dynamic Map Service /// </summary> private void CreateDynamicLayerTree(string mapID, LayerLegendInfo legendInfo, TreeViewItem layerNode, LayerInfo[] lyrInfos, List <int> layerIDs, List <int> visibleLayerIDs, bool toggleLayer, bool parentVisible) { if (legendInfo.LayerLegendInfos != null) { foreach (LayerLegendInfo layerLegendInfo in legendInfo.LayerLegendInfos) { if (layerIDs.IndexOf(layerLegendInfo.SubLayerID) > -1) { LayerInfo lyrInfo = lyrInfos[layerLegendInfo.SubLayerID]; bool hasSubLayers = lyrInfo.SubLayerIds != null; bool lyrVisib = (toggleLayer) ? ((visibleLayerIDs.Count > 0) ? false : lyrInfo.DefaultVisibility) : lyrInfo.DefaultVisibility; if (!hasSubLayers && lyrVisib && parentVisible) { visibleLayerIDs.Add(layerLegendInfo.SubLayerID); } TreeViewItem fLayerNode = CreateFeatureLayerNode(mapID, lyrInfo.Name, lyrInfo.ID, layerLegendInfo.MinimumScale, layerLegendInfo.MaximumScale, lyrVisib, hasSubLayers, toggleLayer); fLayerNode.ItemTemplate = this.Resources["SymbolTreeNode"] as DataTemplate; fLayerNode.ItemsSource = layerLegendInfo.LegendItemInfos; layerNode.Items.Add(fLayerNode); CreateDynamicLayerTree(mapID, layerLegendInfo, fLayerNode, lyrInfos, layerIDs, visibleLayerIDs, false, lyrVisib && parentVisible); } } } }
/// <summary> /// Queries for the legend infos of a layer. /// </summary> /// <remarks> /// The returned result is encapsulated in a <see cref="LayerLegendInfo" /> object containing one legend item showing the heat map gradient. /// </remarks> /// <param name="callback">The method to call on completion.</param> /// <param name="errorCallback">The method to call in the event of an error.</param> public void QueryLegendInfos(Action <LayerLegendInfo> callback, Action <Exception> errorCallback) { // Create one legend item with a radial brush using the heat map gradient (reversed) // Create the UI element RadialGradientBrush brush = new RadialGradientBrush() { Center = new Point(0.5, 0.5), RadiusX = 0.5, RadiusY = 0.5, GradientOrigin = new Point(0.5, 0.5), GradientStops = new GradientStopCollection() }; if (Gradient != null) { foreach (GradientStop stop in Gradient) { brush.GradientStops.Add(new GradientStop() { Color = stop.Color, Offset = 1 - stop.Offset }); } } Rectangle rect = new Rectangle() { Height = 20, Width = 20, Fill = brush }; // Create the imagesource ImageSource imageSource; #if SILVERLIGHT imageSource = new WriteableBitmap(rect, null); #else RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(20, 20, 96, 96, PixelFormats.Pbgra32); renderTargetBitmap.Render(rect); imageSource = renderTargetBitmap; #endif // Create a layerItemInfo array (so enumerable) with one item LegendItemInfo legendItemInfo = new LegendItemInfo() { Label = ID, ImageSource = imageSource }; LegendItemInfo[] legendItemInfos = new LegendItemInfo[] { legendItemInfo }; // Create the returned layerLegendInfo LayerLegendInfo layerLegendInfo = new LayerLegendInfo() { LegendItemInfos = legendItemInfos }; if (callback != null) { callback(layerLegendInfo); } }
/// <summary> /// Initializes a new instance of the <see cref="LayerItemViewModel"/> class from a <see cref="LayerLegendInfo"/>.. /// </summary> /// <param name="layer">The layer.</param> /// <param name="layerLegendInfo">The layer legend info.</param> /// <param name="defaultLayerDescription">The default layer description (= the map layer description).</param> internal LayerItemViewModel(Layer layer, LayerLegendInfo layerLegendInfo, string defaultLayerDescription) : this(layer) { Debug.Assert(layerLegendInfo != null); SubLayerID = layerLegendInfo.SubLayerID; Label = layerLegendInfo.LayerName; ParentLabel = layer.DisplayName; LayerType = layerLegendInfo.LayerType; IsHidden = layerLegendInfo.IsHidden; Description = string.IsNullOrEmpty(layerLegendInfo.LayerDescription) ? defaultLayerDescription : layerLegendInfo.LayerDescription; // Convert scale to resolution MinimumScale = layerLegendInfo.MinimumScale == 0.0 ? double.PositiveInfinity : layerLegendInfo.MinimumScale; MaximumScale = layerLegendInfo.MaximumScale; if (layerLegendInfo.LayerLegendInfos != null) { LayerItems = layerLegendInfo.LayerLegendInfos.Select(info => new LayerItemViewModel(layer, info, defaultLayerDescription)).ToObservableCollection(); } if (layerLegendInfo.LegendItemInfos != null) { LegendItems = layerLegendInfo.LegendItemInfos.Select(info => new LegendItemViewModel(info, Geometry.GeometryType.Unknown)).ToObservableCollection(); } if (Layer is ArcGISDynamicMapServiceLayer) { ArcGISDynamicMapServiceLayer dynamicLayer = (ArcGISDynamicMapServiceLayer)Layer; if (dynamicLayer.VisibleLayers.Contains(SubLayerID)) { _isEnabled = true; } else { _isEnabled = false; } } }
LayerLegendInfo _layerLegendInfo = null; // save info to avoid new web request /// <summary> /// Queries for the legend infos of a layer. /// </summary> /// <remarks> /// The returned result is encapsulated in a <see cref="LayerLegendInfo" /> object. /// This object represents the legend of the map service layer and contains a collection of LayerLegendInfos (one by sublayer) /// </remarks> /// <param name="callback">The method to call on completion.</param> /// <param name="errorCallback">The method to call in the event of an error.</param> public void QueryLegendInfos(Action <LayerLegendInfo> callback, Action <Exception> errorCallback) { if (callback == null) { return; } if (_layerLegendInfo == null && IsInitialized) { // Create legend tree from the LayerList _layerLegendInfo = new LayerLegendInfo { LayerLegendInfos = CreateLegendInfos(LayerList), LayerName = Title, LayerDescription = Abstract, LayerType = "WMS Layer", SubLayerID = 0 }; } callback(_layerLegendInfo); }
private void OnLegendInfoSucceed(LayerLegendInfo legendInfo, TreeViewItem mapTreeNode) { layerCount++; // Count Legend-Initialized LivingMap if (mapTreeNode != null && mapTreeNode.Tag != null) { LivingMapLayer mapConfig = mapTreeNode.Tag as LivingMapLayer; if (legendInfo.LayerLegendInfos != null) { if (this.MapControl.Layers[mapConfig.ID] is ArcGISDynamicMapServiceLayer) { ArcGISDynamicMapServiceLayer dynamicLayer = this.MapControl.Layers[mapConfig.ID] as ArcGISDynamicMapServiceLayer; List <int> layerIDs = GetDynamicMapLayerIDs(mapConfig, dynamicLayer.Layers); List <int> visibleLayerIDs = new List <int>(); CreateDynamicLayerTree(mapConfig.ID, legendInfo, mapTreeNode, dynamicLayer.Layers, layerIDs, visibleLayerIDs, mapConfig.ToggleLayer, true); // Initialize map visibilities dynamicLayer.VisibleLayers = visibleLayerIDs.ToArray(); EventCenter.DispatchMapLayerVisibilityChangeEvent(this, new MapLayerVisibilityChangeEventArgs(dynamicLayer, new int[0])); } else { CreateCachedLayerTree(mapConfig.ID, legendInfo, mapTreeNode); } } else if (legendInfo.LegendItemInfos != null) // Feature Layer { mapTreeNode.ItemTemplate = this.Resources["SymbolTreeNode"] as DataTemplate; mapTreeNode.ItemsSource = legendInfo.LegendItemInfos; } } if (layerCount == MapContentTree.Items.Count) { this.IsBusy = false; } }
/// <summary> /// Iteratively called to create nodes for all sub-layers in a Cached Map Service /// </summary> private void CreateCachedLayerTree(string mapID, LayerLegendInfo legendInfo, TreeViewItem layerNode) { if (legendInfo.LayerLegendInfos != null) { foreach (LayerLegendInfo layerLegendInfo in legendInfo.LayerLegendInfos) { TreeViewItem tLayerNode = new TreeViewItem() { Header = legendInfo.LayerName, Tag = new TOCNodeInfo() { MapID = mapID, IsTiledMap = true, LayerID = legendInfo.SubLayerID } }; tLayerNode.MouseRightButtonDown += new MouseButtonEventHandler(LayerNode_RightClick); tLayerNode.ItemTemplate = this.Resources["SymbolTreeNode"] as DataTemplate; tLayerNode.ItemsSource = layerLegendInfo.LegendItemInfos; layerNode.Items.Add(tLayerNode); CreateCachedLayerTree(mapID, layerLegendInfo, tLayerNode); } } }
/// <summary> /// Initializes a new instance of the <see cref="LayerItemViewModel"/> class from a <see cref="LayerLegendInfo"/>.. /// </summary> /// <param name="layer">The layer.</param> /// <param name="layerLegendInfo">The layer legend info.</param> /// <param name="defaultLayerDescription">The default layer description (= the map layer description).</param> /// <param name="scale">The scale.</param> internal LayerItemViewModel(Layer layer, LayerLegendInfo layerLegendInfo, string defaultLayerDescription, double scale) : this(layer) { Debug.Assert(layerLegendInfo != null); SubLayerID = layerLegendInfo.SubLayerID; Label = layerLegendInfo.LayerName; ParentLabel = layer.DisplayName; LayerType = layerLegendInfo.LayerType; IsHidden = layerLegendInfo.IsHidden; // Take care of 'ShowLegend' flag that might be defined for sublayers in the portal service item // Would be better to do that in the implementation of ILegendSupport in the client package // but this one has no access to the portal package. So doing that here is a shortcut for lazy dev. if (!IsHidden && Layer.Tag is IList<WebMapLayer>) { var webMapLayers = Layer.Tag as IList<WebMapLayer>; IsHidden = webMapLayers.Where(wml => wml.SubLayers != null) .SelectMany(wml => wml.SubLayers) .Any(sl => sl.Id == SubLayerID && sl.ShowLegend.HasValue && !sl.ShowLegend.Value); } Description = string.IsNullOrEmpty(layerLegendInfo.LayerDescription) ? defaultLayerDescription : layerLegendInfo.LayerDescription; // Convert scale to resolution MinimumScale = layerLegendInfo.MinimumScale == 0.0 ? double.PositiveInfinity : layerLegendInfo.MinimumScale; MaximumScale = layerLegendInfo.MaximumScale; if (layerLegendInfo.LayerLegendInfos != null) { LayerItems = layerLegendInfo.LayerLegendInfos.Select(info => new LayerItemViewModel(layer, info, defaultLayerDescription, scale)).ToObservableCollection(); } if (layerLegendInfo.LegendItemInfos != null) { LegendItems = layerLegendInfo.LegendItemInfos.Select(info => new LegendItemViewModel(info)).ToObservableCollection(); } }
/// <summary> /// Refreshes the legend from infos coming from the map layer. /// </summary> internal async void Refresh() { if (_isQuerying || Layer == null) { return; // already querying } //if (!(Layer is GroupLayerBase)) // GroupLayer : don't wait for layer intialized, so the user will see the layer hierarchy even if the group layer is not initialized yet (else would need to wait for all sublayers initialized) //{ if (Layer.Status < LayerStatus.Initialized) { IsBusy = true; // set busy indicator waiting for layer initialized return; // Refresh will be done on event Initialized } LayerItems = null; //} LegendItems = null; if (Layer is ILegendSupport) { IsBusy = true; _isQuerying = true; var legendSupport = Layer as ILegendSupport; LayerLegendInfo result = null; Exception exception = null; try { result = await legendSupport.GetLegendInfosAsync(); } catch (Exception ex) { exception = ex; } if (LegendTree == null) { // The legend item has been detached ==> result no more needed IsBusy = _isQuerying = false; return; } if (exception != null) { // Fire event Refreshed with an exception if (LegendTree != null) { LegendTree.OnRefreshed(this, new Legend.RefreshedEventArgs(this, exception)); } _isQuerying = false; IsBusy = false; return; } if (result != null) { Description = result.LayerDescription; if (string.IsNullOrEmpty(Label)) // Label is set with LayerID : keep it if not null { Label = result.LayerName; } // Combine Layer and Service scale double minScale = result.MinimumScale == 0.0 ? double.PositiveInfinity : result.MinimumScale; _serviceMinScale = minScale; if (Layer.MinScale != 0.0 && !double.IsNaN(Layer.MinScale)) { minScale = Math.Min(minScale, Layer.MinScale); } double maxScale = result.MaximumScale; _serviceMaxScale = maxScale; if (!double.IsNaN(Layer.MaxScale)) { maxScale = Math.Max(maxScale, Layer.MaxScale); } MinimumScale = minScale; MaximumScale = maxScale; IsHidden = result.IsHidden; // For feature layers, force the geometry type since GeometryType.Unknown doesn't work well with advanced symbology. Geometry.GeometryType geometryType = Geometry.GeometryType.Unknown; if (Layer is FeatureLayer) { var fl = Layer as FeatureLayer; if (fl.FeatureTable != null && fl.FeatureTable.ServiceInfo != null) { geometryType = fl.FeatureTable.ServiceInfo.GeometryType; } } if (result.LayerLegendInfos != null) { LayerItems = result.LayerLegendInfos.Select(info => new LayerItemViewModel(Layer, info, Description)).ToObservableCollection(); } if (result.LegendItemInfos != null) { LegendItems = result.LegendItemInfos.Select(info => new LegendItemViewModel(info, geometryType)).ToObservableCollection(); } } // If groupLayer -> add the child layers //AddGroupChildLayers(); // Kml layer particular case : if a KML layer has only a child which is not another KML layer ==> set the child item as transparent so it doesn't appear in the legend //ProcessKmlLayer(); LegendTree.UpdateLayerVisibilities(); _isQuerying = false; // Fire event Refreshed without exception LegendTree.OnRefreshed(this, new Legend.RefreshedEventArgs(this, null)); IsBusy = false; } else { IsBusy = false; // Fire event Refreshed if (LegendTree != null) { LegendTree.OnRefreshed(this, new Legend.RefreshedEventArgs(this, null)); } } }
/// <summary> /// Queries for the legend infos of the layer. /// </summary> /// <remarks> /// The returned result is encapsulated in a <see cref="LayerLegendInfo" /> object. /// A group layer returns only one item describing the group layer (the legends of the sublayers are not returned by this method) /// </remarks> /// <param name="callback">The method to call on completion.</param> /// <param name="errorCallback">The method to call in the event of an error (cant' happen with a group layer).</param> public override void QueryLegendInfos(Action<LayerLegendInfo> callback, Action<Exception> errorCallback) { if (callback != null) { if (IsInitialized) { // create one default layerLegendInfo item. LayerLegendInfo layerLegendInfo = new LayerLegendInfo { LegendItemInfos = null, LayerName = Name, LayerDescription = Name, IsHidden = IsHidden }; callback(layerLegendInfo); } else { // delay the answer until initialization EventHandler<EventArgs> handler = null; handler = delegate(object s, EventArgs e) { KmlLayer kmlLayer = s as KmlLayer; if (kmlLayer == null) return; kmlLayer.Initialized -= handler; // create one default layerLegendInfo item. LayerLegendInfo layerLegendInfo = new LayerLegendInfo { LegendItemInfos = null, LayerName = kmlLayer.Name, LayerDescription = kmlLayer.Name, IsHidden = kmlLayer.IsHidden }; callback(layerLegendInfo); }; Initialized += handler; } } }
LayerLegendInfo _layerLegendInfo = null; // save info to avoid new web request /// <summary> /// Queries for the legend infos of a layer. /// </summary> /// <remarks> /// The returned result is encapsulated in a <see cref="LayerLegendInfo" /> object. /// This object represents the legend of the map service layer and contains a collection of LayerLegendInfos (one by sublayer) /// </remarks> /// <param name="callback">The method to call on completion.</param> /// <param name="errorCallback">The method to call in the event of an error.</param> public void QueryLegendInfos(Action<LayerLegendInfo> callback, Action<Exception> errorCallback) { if (callback == null) return; if (_layerLegendInfo == null && IsInitialized) { // Create legend tree from the LayerList _layerLegendInfo = new LayerLegendInfo { LayerLegendInfos = CreateLegendInfos(LayerList), LayerName = Title, LayerDescription = Abstract, LayerType = "WMS Layer", SubLayerID = 0 }; } callback(_layerLegendInfo); }
#pragma warning restore 0067 public void QueryLegendInfos(Action<LayerLegendInfo> callback, Action<Exception> errorCallback) { if (!IsSupported) throw new NotImplementedException(); var featureLayer = _layer as FeatureLayer; var layerLegendInfo = new LayerLegendInfo(); var layerInfo = featureLayer == null ? null : featureLayer.LayerInfo; if (layerInfo != null) { layerLegendInfo.LayerDescription = layerInfo.Description; layerLegendInfo.MinimumScale = layerInfo.MinimumScale; layerLegendInfo.MaximumScale = layerInfo.MaximumScale; } if (featureLayer != null) layerLegendInfo.LayerType = "Feature Layer"; callback(layerLegendInfo); }
/// <summary> /// Queries for the legend infos of a layer. /// </summary> /// <remarks> /// The returned result is encapsulated in a <see cref="LayerLegendInfo" /> object containing one legend item showing the heat map gradient. /// </remarks> /// <param name="callback">The method to call on completion.</param> /// <param name="errorCallback">The method to call in the event of an error.</param> public void QueryLegendInfos(Action<LayerLegendInfo> callback, Action<Exception> errorCallback) { // Create one legend item with a radial brush using the heat map gradient (reversed) // Create the UI element RadialGradientBrush brush = new RadialGradientBrush() { Center = new Point(0.5, 0.5), RadiusX = 0.5, RadiusY = 0.5, GradientOrigin = new Point(0.5, 0.5), GradientStops = new GradientStopCollection() }; if (Gradient != null) { foreach (GradientStop stop in Gradient) brush.GradientStops.Add(new GradientStop() { Color = stop.Color, Offset = 1 - stop.Offset }); } Rectangle rect = new Rectangle() { Height = 20, Width = 20, Fill = brush }; // Create the imagesource ImageSource imageSource; #if SILVERLIGHT imageSource = new WriteableBitmap(rect, null); #else RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(20, 20, 96, 96, PixelFormats.Pbgra32); renderTargetBitmap.Render(rect); imageSource = renderTargetBitmap; #endif // Create a layerItemInfo array (so enumerable) with one item LegendItemInfo legendItemInfo = new LegendItemInfo() { Label = ID, ImageSource = imageSource }; LegendItemInfo[] legendItemInfos = new LegendItemInfo[] { legendItemInfo }; // Create the returned layerLegendInfo LayerLegendInfo layerLegendInfo = new LayerLegendInfo() { LegendItemInfos = legendItemInfos }; if (callback != null) callback(layerLegendInfo); }