using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using DelftTools.Utils.Reflection;
using DelftTools.Utils;
using GeoAPI.Extensions.Feature;
using NetTopologySuite.Extensions.Features;
using SharpMap.Api.Layers;
namespace SharpMap.Layers
{
public class LayerAttribute
{
private readonly string attributeName;
private readonly ILayer layer;
private IComparable maxValue;
private IComparable minValue;
public override string ToString()
{
return AttributeName;
}
public string AttributeName
{
get { return attributeName; }
}
public string DisplayName
{
get
{
//try to find to the display name on the feature otherwise use attribute name
if (layer.DataSource.Features.Count != 0)
{
return FeatureAttributeAccessorHelper.GetAttributeDisplayName(layer.DataSource.GetFeature(0), attributeName);
}
return FeatureAttributeAccessorHelper.GetPropertyDisplayName(layer.DataSource.FeatureType, attributeName);
}
}
public LayerAttribute(ILayer layer, string attributeName)
{
this.layer = layer;
this.attributeName = attributeName;
//TODO : check the attribute name is ok...?>
}
///
/// TODO: these are not attribute values but attribute values without NoDataValues
///
public IEnumerable AttributeValues
{
get { return GetAttributeValues(); }
}
private IEnumerable GetAttributeValues()
{
return GetAttributeValuesFromFeatures();
}
public IComparable MinValue
{
get
{
if (minValue != null)
{
return minValue;
}
GetMinMaxValue(out minValue, out maxValue);
return minValue;
}
}
public IComparable MaxValue
{
get
{
if (maxValue != null)
{
return maxValue;
}
GetMinMaxValue(out minValue, out maxValue);
return maxValue;
}
}
public List UniqueValues
{
get
{
var uniqueValues = new HashSet();
IEnumerable values = null;
if(layer is VectorLayer)
{
values = GetAttributeValuesFromFeatures();
}
else
{
return new List();
}
foreach (IComparable attributeValue in values)
{
uniqueValues.Add(attributeValue);
}
return uniqueValues.ToList();
}
}
public bool IsNumerical
{
get
{
return (MinValue != null) && MinValue.GetType().IsNumericalType();
}
}
public double MinNumValue
{
get
{
return (IsNumerical) ? Convert.ToDouble(MinValue) : 0;
}
}
public double MaxNumValue
{
get
{
return (IsNumerical) ? Convert.ToDouble(MaxValue) : 0;
}
}
private IEnumerable GetAttributeValuesFromFeatures()
{
if (layer == null || layer.DataSource == null)
yield break;
foreach (var feature in layer.DataSource.Features.Cast())
{
//check if value can be cast to icomparable ie DBnull value wil yield null
var value =
FeatureAttributeAccessorHelper.GetAttributeValue(feature, attributeName, false) as IComparable;
if (value != null)
{
yield return value;
}
}
}
private IComparable GetMinValue()
{
return AttributeValues != null ? AttributeValues.Min() : null;
}
private IComparable GetMaxValue()
{
return AttributeValues != null ? AttributeValues.Max() : null;
}
///
/// Retrieve min & max as double and only go through the values once
///
///
///
private void GetMinMaxValue(out IComparable min, out IComparable max)
{
var first = true;
var minComparable = default(IComparable);
var maxComparable = default(IComparable);
foreach (var value in AttributeValues)
{
if (first)
{
minComparable = value;
maxComparable = value;
first = false;
}
if (value.IsSmaller(minComparable))
minComparable = value;
if (value.IsBigger(maxComparable))
maxComparable = value;
}
if (first) //nothing found
{
min = 0;
max = 0;
}
else
{
min = minComparable;
max = maxComparable;
}
}
}
}