Skip to content

Commit

Permalink
1 - locking for InMemoryBusinessObjectSource
Browse files Browse the repository at this point in the history
     add method InserFeature to support efficient incremental updates to InMemoryBusinessObjectSource
2 - implement FilterDelegate on BusinessObjectProvider, similar to GeometryFeatureProvider
  • Loading branch information
terribletim authored and FObermaier committed Dec 8, 2017
1 parent e3e4850 commit 248ff44
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SharpMap.Data.Providers.Business
{
public abstract class BusinessObjectFilterProvider
{
public delegate bool FilterMethod(object bo);
public FilterMethod FilterDelegate { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,15 @@ public static IProvider Create<T>(IBusinessObjectSource<T> source)
}

[Serializable]
public class BusinessObjectProvider<TFeature> : IProvider
public class BusinessObjectProvider<TFeature> : BusinessObjectFilterProvider, IProvider
{

[NonSerialized]
private static FeatureDataTable SchemaTable;

[NonSerialized]
private static readonly List<Func<TFeature, object>> GetDelegates;

static BusinessObjectProvider()
{
GetDelegates = new List<Func<TFeature, object>>();
Expand Down Expand Up @@ -108,7 +109,7 @@ static IEnumerable<Tuple<string, BusinessObjectAttributeAttribute>> GetPublicMem
foreach (var kvp in dict)
list.Add(Tuple.Create(kvp.Key, kvp.Value));
list.Sort((a, b) => a.Item2.Ordinal.CompareTo(b.Item2.Ordinal));

return list;
}

Expand All @@ -118,7 +119,7 @@ static void GetPublicMembers(Type t,
var pis = t.GetProperties(/*BindingFlags.Public | BindingFlags.Instance*/);
foreach (var pi in pis)
{
var att = pi.GetCustomAttributes(typeof (BusinessObjectAttributeAttribute), true);
var att = pi.GetCustomAttributes(typeof(BusinessObjectAttributeAttribute), true);
if (att.Length > 0)
{
if (!collection.ContainsKey(pi.Name))
Expand All @@ -135,7 +136,7 @@ static void GetPublicMembers(Type t,
collection.Add(fi.Name, (BusinessObjectAttributeAttribute)att[0]);
}
}
if (t.BaseType != typeof (object))
if (t.BaseType != typeof(object))
GetPublicMembers(t.BaseType, collection);
}

Expand All @@ -160,9 +161,9 @@ public void Dispose()
}

public string ConnectionID { get; private set; }

public bool IsOpen { get; private set; }

public int SRID { get; set; }

/// <summary>
Expand All @@ -175,7 +176,10 @@ public Collection<IGeometry> GetGeometriesInView(Envelope bbox)
var res = new Collection<IGeometry>();
foreach (TFeature feature in _source.Select(bbox))
{
res.Add(_source.GetGeometry(feature));
if (FilterDelegate == null || FilterDelegate(feature))
{
res.Add(_source.GetGeometry(feature));
}
}
return res;
}
Expand All @@ -185,7 +189,10 @@ public Collection<uint> GetObjectIDsInView(Envelope bbox)
var res = new Collection<uint>();
foreach (TFeature feature in _source.Select(bbox))
{
res.Add(_source.GetId(feature));
if (FilterDelegate == null || FilterDelegate(feature))
{
res.Add(_source.GetId(feature));
}
}
return res;
}
Expand All @@ -204,8 +211,11 @@ public void ExecuteIntersectionQuery(IGeometry geom, FeatureDataSet ds)
resTable.BeginLoadData();
foreach (var feature in _source.Select(geom))
{
var fdr = (FeatureDataRow)resTable.LoadDataRow(ToItemArray(feature), LoadOption.OverwriteChanges);
fdr.Geometry = _source.GetGeometry(feature);
if (FilterDelegate == null || FilterDelegate(feature))
{
var fdr = (FeatureDataRow)resTable.LoadDataRow(ToItemArray(feature), LoadOption.OverwriteChanges);
fdr.Geometry = _source.GetGeometry(feature);
}
}
resTable.EndLoadData();
ds.Tables.Add(resTable);
Expand All @@ -218,8 +228,11 @@ public void ExecuteIntersectionQuery(Envelope box, FeatureDataSet ds)
resTable.BeginLoadData();
foreach (var feature in _source.Select(box))
{
var fdr = (FeatureDataRow)resTable.LoadDataRow(ToItemArray(feature), LoadOption.OverwriteChanges);
fdr.Geometry = _source.GetGeometry(feature);
if (FilterDelegate == null || FilterDelegate(feature))
{
var fdr = (FeatureDataRow)resTable.LoadDataRow(ToItemArray(feature), LoadOption.OverwriteChanges);
fdr.Geometry = _source.GetGeometry(feature);
}
}
resTable.EndLoadData();
ds.Tables.Add(resTable);
Expand Down Expand Up @@ -299,5 +312,6 @@ public void Close()
{
IsOpen = false;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using System.Collections.Generic;
using GeoAPI.Geometries;
using NetTopologySuite.Geometries;
using System.Collections;

namespace SharpMap.Data.Providers.Business
{
Expand All @@ -36,8 +37,8 @@ public class InMemoryBusinessObjectSource<T> : BaseBusinessObjectSource<T>
/// Creates an instance of this class
/// </summary>
public InMemoryBusinessObjectSource()
:this(typeof(T).Name)
{}
: this(typeof(T).Name)
{ }

/// <summary>
/// Creates an instance of this class, assigning a <see cref="Title"/>
Expand All @@ -55,7 +56,6 @@ public override string Title
get { return _title; }
}


/// <summary>
/// Select a set of features based on <paramref name="box"/>
/// </summary>
Expand All @@ -75,12 +75,15 @@ public override IEnumerable<T> Select(IGeometry geom)
{
var prep = NetTopologySuite.Geometries.Prepared.PreparedGeometryFactory.Prepare(geom);

foreach (T value in _businessObjects.Values)
lock (((ICollection)_businessObjects).SyncRoot)
{
var g = _getGeometry(value);
if (g != null && prep.Intersects(g))
foreach (T value in _businessObjects.Values)
{
yield return value;
var g = _getGeometry(value);
if (g != null && prep.Intersects(g))
{
yield return value;
}
}
}
}
Expand All @@ -94,9 +97,12 @@ public override IEnumerable<T> Select(IGeometry geom)
public override T Select(uint id)
{
T res;
if (_businessObjects.TryGetValue(id, out res))
return res;
throw new ArgumentException("No feature with this id", "id");
lock (((ICollection)_businessObjects).SyncRoot)
{
if (_businessObjects.TryGetValue(id, out res))
return res;
}
throw new ArgumentException("No feature with this id", id.ToString());
}

/// <summary>
Expand All @@ -106,9 +112,13 @@ public override T Select(uint id)
public override void Update(IEnumerable<T> features)
{
Delete(features);
foreach (T feature in features)

lock (((ICollection)_businessObjects).SyncRoot)
{
_businessObjects.Add(_getId(feature), feature);
foreach (T feature in features)
{
_businessObjects.Add(_getId(feature), feature);
}
}
}

Expand All @@ -118,11 +128,14 @@ public override void Update(IEnumerable<T> features)
/// <param name="features">The features that need to be deleted</param>
public override void Delete(IEnumerable<T> features)
{
foreach (T feature in features)
lock (((ICollection)_businessObjects).SyncRoot)
{
_businessObjects.Remove(_getId(feature));
foreach (T feature in features)
{
_businessObjects.Remove(_getId(feature));
}
CachedExtents = null;
}
CachedExtents = null;
}

/// <summary>
Expand All @@ -131,16 +144,39 @@ public override void Delete(IEnumerable<T> features)
/// <param name="features">The features that need to be inserted</param>
public override void Insert(IEnumerable<T> features)
{
foreach (T feature in features)
lock (((ICollection)_businessObjects).SyncRoot)
{
foreach (T feature in features)
{
_businessObjects.Add(_getId(feature), feature);
}
CachedExtents = null;
}
}

public void InsertFeature(T feature)
{
lock (((ICollection)_businessObjects).SyncRoot)
{
_businessObjects.Add(_getId(feature), feature);

// expand to include
var res = CachedExtents ?? new Envelope();

var g = _getGeometry(feature);
if (g != null && !g.IsEmpty)
res.ExpandToInclude(g.EnvelopeInternal);
CachedExtents = res;
}
CachedExtents = null;
}

public override int Count
{
get { return _businessObjects.Count; }
get
{
lock (((ICollection)_businessObjects).SyncRoot)
return _businessObjects.Count;
}
}

public override Envelope GetExtents()
Expand All @@ -150,14 +186,17 @@ public override Envelope GetExtents()

private Envelope ComputeExtents()
{
var res = new Envelope();
foreach (var bo in _businessObjects.Values)
lock (((ICollection)_businessObjects).SyncRoot)
{
var g = _getGeometry(bo);
if (g != null && !g.IsEmpty)
res.ExpandToInclude(g.EnvelopeInternal);
var res = new Envelope();
foreach (var bo in _businessObjects.Values)
{
var g = _getGeometry(bo);
if (g != null && !g.IsEmpty)
res.ExpandToInclude(g.EnvelopeInternal);
}
return res;
}
return res;
}
}
}

0 comments on commit 248ff44

Please sign in to comment.