Skip to content

Instantly share code, notes, and snippets.

@george-silva
Created November 3, 2012 13:05
Show Gist options
  • Save george-silva/4007335 to your computer and use it in GitHub Desktop.
Save george-silva/4007335 to your computer and use it in GitHub Desktop.
Testes bobos #2
public class ParentFinders
{
private static ILog _log = LogManager.GetLogger(typeof(ParentFinders));
public static IObject FindParentAmbiguous(IObject obj, ITable parentTable)
{
_log.IfInfo("Utilizando método 'toca' para encontrar objeto pai.");
if (!(parentTable is IFeatureClass))
throw new ArgumentException("parentTable não é uma feature class.");
if (!(obj is IFeature))
throw new ArgumentException("obj não é uma feature");
var featureClass = (IFeatureClass)parentTable;
var childFeature = (IFeature)obj;
var testGeometry = childFeature.ShapeCopy;
ISpatialFilter spatialFilter = new SpatialFilterClass();
spatialFilter.Geometry = testGeometry;
spatialFilter.GeometryField = featureClass.ShapeFieldName;
spatialFilter.SearchOrder = esriSearchOrder.esriSearchOrderSpatial;
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
var count = featureClass.FeatureCount(spatialFilter);
if (count <= 0)
{
_log.IfError("Não foi possível encontrar o pai deste objeto {0}.", obj.OID.ToString());
return null;
}
IFeatureCursor cursor = null;
if (count > 1)
{
_log.IfInfo("Não foi possível encontrar o pai deste objeto {0}", obj.OID.ToString());
return null;
}
cursor = featureClass.Search(spatialFilter, false);
var parentFeature = cursor.NextFeature();
_log.IfInfo("Pai do objeto encontrado. Retornando feição {0}", parentFeature.OID.ToString());
Marshal.FinalReleaseComObject(cursor);
return parentFeature;
}
/// <summary>
/// Encurta a linha e tenta buscar os objetos que tocam
/// esta linha
/// </summary>
/// <param name="obj"></param>
/// <param name="parentTable"></param>
/// <returns></returns>
public static IObject FindParentShortIntersect(IObject obj, ITable parentTable)
{
_log.IfInfo("Utilizando método 'toca' para encontrar objeto pai.");
if (!(parentTable is IFeatureClass))
throw new ArgumentException("parentTable não é uma feature class.");
if (!(obj is IFeature))
throw new ArgumentException("obj não é uma feature");
var featureClass = (IFeatureClass)parentTable;
var childFeature = (IFeature)obj;
var testGeometry = childFeature.ShapeCopy;
if (testGeometry.GeometryType != esriGeometryType.esriGeometryPolyline)
throw new ArgumentException("A geometria que está sendo utilizada não é do tipo linha.");
ICurve shortenedCurve = null;
var lineGeometry = (IPolyline)testGeometry;
lineGeometry.GetSubcurve(.1, .9, true, out shortenedCurve);
IPolyline resultPolyline = shortenedCurve as IPolyline;
ISpatialFilter spatialFilter = new SpatialFilterClass();
spatialFilter.Geometry = resultPolyline;
spatialFilter.GeometryField = featureClass.ShapeFieldName;
spatialFilter.SearchOrder = esriSearchOrder.esriSearchOrderSpatial;
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
var count = featureClass.FeatureCount(spatialFilter);
if (count <= 0)
{
_log.IfError("Não foi possível encontrar o pai deste objeto {0}.", obj.OID.ToString());
return null;
}
IFeatureCursor cursor = null;
if (count > 1)
{
Dictionary<double, IObject> intersectionDictionary = new Dictionary<double, IObject>();
cursor = featureClass.Search(spatialFilter, false);
IFeature tempFeature = null;
while ((tempFeature = cursor.NextFeature()) != null)
{
var topologicalOperator = (ITopologicalOperator) testGeometry;
var intersection = topologicalOperator.Intersect(tempFeature.ShapeCopy,
esriGeometryDimension.esriGeometryNoDimension);
var polyIntersection = (IPolyline) intersection;
intersectionDictionary.Add(polyIntersection.Length,tempFeature);
}
var maxLength = intersectionDictionary.Keys.Max(x => x);
Marshal.FinalReleaseComObject(cursor);
return intersectionDictionary[maxLength];
}
cursor = featureClass.Search(spatialFilter, false);
var parentFeature = cursor.NextFeature();
_log.IfInfo("Pai do objeto encontrado. Retornando feição {0}", parentFeature.OID.ToString());
Marshal.FinalReleaseComObject(cursor);
return parentFeature;
}
/// <summary>
/// Retorna um determinado objeto pai se
/// a geometria do objeto filho estiver contida
/// na geometria do objeto pai.
/// </summary>
/// <param name="obj">IObject</param>
/// <param name="parentTable">ITable</param>
/// <returns>IObject</returns>
public static IObject FindParentWithin(IObject obj, ITable parentTable)
{
_log.IfInfo("Utilizando método geometria pura para encontrar objeto pai.");
if (!(parentTable is IFeatureClass))
throw new ArgumentException("parentTable não é uma feature class.");
if (!(obj is IFeature))
throw new ArgumentException("obj não é uma feature");
var featureClass = (IFeatureClass)parentTable;
var childFeature = (IFeature)obj;
var testGeometry = childFeature.ShapeCopy;
ISpatialFilter spatialFilter = new SpatialFilterClass();
spatialFilter.Geometry = testGeometry;
spatialFilter.GeometryField = featureClass.ShapeFieldName;
spatialFilter.SearchOrder = esriSearchOrder.esriSearchOrderSpatial;
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin;
var count = featureClass.FeatureCount(spatialFilter);
if (count <= 0)
{
_log.IfError("Não foi possível encontrar o pai deste objeto {0}.", obj.OID.ToString());
return null;
}
if (count > 1)
{
_log.IfError("Existe mais de um pai para o objeto {0}. Não é possível determinar com precisão quem é o pai deste objeto.", obj.OID.ToString());
return null;
}
var cursor = featureClass.Search(spatialFilter, true);
var parentFeature = cursor.NextFeature();
_log.IfInfo("Pai do objeto encontrado. Retornando feição {0}", parentFeature.OID.ToString());
Marshal.FinalReleaseComObject(cursor);
return parentFeature;
}
/// <summary>
/// Determina o pai pelo centróide do filho.
/// </summary>
/// <param name="obj"></param>
/// <param name="parentTable"></param>
/// <returns></returns>
public static IObject FindParentCentroidWithin(IObject obj, ITable parentTable)
{
_log.IfInfo("Utilizando método de centróide para encontrar objeto pai.");
if (!(parentTable is IFeatureClass))
throw new ArgumentException("parentTable não é uma feature class.");
if (!(obj is IFeature))
throw new ArgumentException("obj não é uma feature");
var featureClass = (IFeatureClass) parentTable;
var childFeature = (IFeature) obj;
var testGeometry = childFeature.ShapeCopy;
IPoint testPoint = null;
switch (testGeometry.GeometryType)
{
case esriGeometryType.esriGeometryPolygon:
var area = (IArea) testGeometry;
testPoint = area.Centroid;
break;
case esriGeometryType.esriGeometryPolyline:
var line = (IPolyline) testGeometry;
testPoint = new PointClass();
line.QueryPoint(esriSegmentExtension.esriNoExtension, 0.5, true, testPoint);
break;
case esriGeometryType.esriGeometryMultipoint:
var envelope = testGeometry.Envelope;
testPoint = envelope.Center();
break;
case esriGeometryType.esriGeometryPoint:
testPoint = (IPoint) testGeometry;
break;
default:
_log.IfError("Tipo de geometria não suportado pelo algoritmo de centróide.");
throw new ArgumentException("Somente os tipos POLYGON,POLYLINE,POINT e MULTIPOINT são suportados.");
}
ISpatialFilter spatialFilter = new SpatialFilterClass();
spatialFilter.Geometry = testPoint;
spatialFilter.GeometryField = featureClass.ShapeFieldName;
spatialFilter.SearchOrder = esriSearchOrder.esriSearchOrderSpatial;
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin;
var count = featureClass.FeatureCount(spatialFilter);
if (count <= 0)
{
_log.IfError("Não foi possível encontrar o pai deste objeto {0}.", obj.OID.ToString());
return null;
}
if (count > 1)
{
_log.IfError("Existe mais de um pai para o objeto {0}. Não é possível determinar com precisão quem é o pai deste objeto.", obj.OID.ToString());
return null;
}
var cursor = featureClass.Search(spatialFilter, false);
var parentFeature = cursor.NextFeature();
_log.IfInfo("Pai do objeto encontrado. Retornando feição {0}", parentFeature.OID.ToString());
Marshal.FinalReleaseComObject(cursor);
return parentFeature;
}
}
public class ParentFinder:IParentFinder
{
private static ILog _log = LogManager.GetLogger(typeof (ParentFinder));
private ITable _relatedTable;
private ParentFinderAlgorithm _algorithm;
public ParentFinder(ParentFinderAlgorithm algorithm, ITable relatedTable)
{
if (algorithm == null)
throw new ArgumentNullException("algorithm");
if (relatedTable == null)
throw new ArgumentNullException("relatedTable");
_relatedTable = relatedTable;
_algorithm = algorithm;
}
public ITable RelatedTable
{
get { return _relatedTable; }
}
public ParentFinderAlgorithm Algorithm
{
get { return _algorithm; }
}
public IObject FindRelated(IObject obj)
{
if (obj == null)
throw new ArgumentNullException("obj");
_log.IfInfo("Buscando pai do objeto {0}", obj.OID.ToString());
try
{
var parent = _algorithm.Invoke(obj, RelatedTable);
if (parent == null)
{
_log.IfInfo(
"Não foi possível encontrar o pai deste objeto. Retornando sem fazer nenhuma associação.");
return null;
}
_log.IfInfo("Pai encontrado.");
return parent;
}
catch (Exception ex)
{
var parentDataset = (IDataset) _relatedTable;
throw new ParentFinderException(
String.Format("Something went wrong while finding the parent element of {0} in table {1}. Algorithm used: {2}", obj.OID,
parentDataset.FullName,_algorithm.Method.Name));
}
}
}
[TestFixture]
public class ParentFindersUnitTest
{
private ITable _blockEdgeTable;
private ITable _parcelTable;
private ITable _blockTable;
private ITable _parcelEdgeTable;
private ITable _districtTable;
private ITable _sectorTable;
private ITable _pavementTable;
private ITable _buildingTable;
[SetUp]
public void Init()
{
var aoInit = new AoInitializeClass();
aoInit.Initialize(esriLicenseProductCode.esriLicenseProductCodeArcInfo);
var ctx = ArcMapContext.GetInstance();
var gdb = (IFeatureWorkspace)ctx.Geodatabase;
_blockEdgeTable = (ITable) gdb.OpenFeatureClass("FFQD_FACES_QUADRAS");
_blockTable = (ITable) gdb.OpenFeatureClass("FQDA_QUADRAS");
_parcelTable = (ITable) gdb.OpenFeatureClass("FLTE_LOTES");
_parcelEdgeTable = (ITable) gdb.OpenFeatureClass("FTES_TESTADAS_LOTES");
_pavementTable = (ITable) gdb.OpenFeatureClass("FPAV_PAVIMENTOS");
_buildingTable = (ITable) gdb.OpenFeatureClass("FEDF_EDIFICACOES");
_sectorTable = (ITable) gdb.OpenFeatureClass("FSET_SETORES");
_districtTable = (ITable) gdb.OpenFeatureClass("FDIS_DISTRITOS");
}
[TestCase(17,1)]
public void TestParentCentroidWithinDistrictAndSector(int inputOid, int expectedOid)
{
var oid = inputOid;
var feature = _sectorTable.GetRow(oid);
var parentFinder = new ParentFinder(ParentFinders.FindParentCentroidWithin, _districtTable);
var parent = parentFinder.FindRelated((IObject)feature);
Assert.IsNotNull(parent);
Assert.AreEqual(expectedOid, parent.OID);
}
[TestCase(1196,16)]
[TestCase(1224,17)]
[TestCase(2508,23)]
public void TestParentCentroidWithinSectorAndBlock(int inputOid, int expectedOid)
{
var oid = inputOid;
var feature = _blockTable.GetRow(oid);
var parentFinder = new ParentFinder(ParentFinders.FindParentCentroidWithin, _sectorTable);
var block = parentFinder.FindRelated((IObject)feature);
Assert.IsNotNull(block);
Assert.AreEqual(expectedOid, block.OID);
}
[TestCase(73128,2535)]
[TestCase(148710,5452)]
[TestCase(148763, 5452)]
[TestCase(148738, 5452)]
[TestCase(148729, 5452)]
[TestCase(148773, 5452)]
[TestCase(148819, 5452)]
public void TestParentCentroidWithinBlockAndParcel(int inputOid,int expectedOid)
{
var oid = inputOid;
var feature = _parcelTable.GetRow(oid);
var parentFinder = new ParentFinder(ParentFinders.FindParentCentroidWithin, _blockTable);
var block = parentFinder.FindRelated((IObject)feature);
Assert.IsNotNull(block);
Assert.AreEqual(expectedOid,block.OID);
}
[TestCase(83088,59861)]
[TestCase(83107,59826)]
[TestCase(83119,59826)]
[TestCase(83098,59812)]
[TestCase(83086,59812)]
public void TestParentCentroidWithinParcelAndBuilding(int inputOid, int expectedOid)
{
var oid = inputOid;
var feature = _buildingTable.GetRow(oid);
var parentFinder = new ParentFinder(ParentFinders.FindParentCentroidWithin, _parcelTable);
var block = parentFinder.FindRelated((IObject)feature);
Assert.IsNotNull(block);
Assert.AreEqual(expectedOid, block.OID);
}
[TestCase(115600, 82840)]
[TestCase(113314, 82840)]
[TestCase(115515, 82753)]
public void TestParentCentroidWithinBuildingAndPavement(int inputOid, int expectedOid)
{
var oid = inputOid;
var feature = _pavementTable.GetRow(oid);
var parentFinder = new ParentFinder(ParentFinders.FindParentCentroidWithin, _buildingTable);
var block = parentFinder.FindRelated((IObject)feature);
Assert.IsNotNull(block);
Assert.AreEqual(expectedOid, block.OID);
}
[TestCase(148102, 5445)]
[TestCase(148181, 5445)]
[TestCase(148190, 5445)]
[TestCase(148199, 5445)]
[TestCase(148205, 5445)]
[TestCase(148215, 5445)]
[TestCase(148220, 5445)]
[TestCase(72962, 2593)]
[TestCase(72927, 2593)]
[TestCase(72901, 2593)]
[TestCase(72868, 2593)]
[TestCase(72195, 2593)]
public void TestParentWithin(int inputOid,int expectedOid)
{
var oid = inputOid;
var feature = _parcelTable.GetRow(oid);
var parentFinder = new ParentFinder(ParentFinders.FindParentWithin, _blockTable);
var block = parentFinder.FindRelated((IObject)feature);
Assert.IsNotNull(block);
Assert.AreEqual(expectedOid,block.OID);
}
[TestCase(148035,5442)]
[TestCase(148034,5442)]
[TestCase(148033,5442)]
[TestCase(148047,5442)]
[TestCase(148045,5442)]
public void TestParentWithinFail(int inputOid, int expectedOid)
{
var oid = inputOid;
var feature = _parcelTable.GetRow(oid);
var parentFinder = new ParentFinder(ParentFinders.FindParentWithin, _blockTable);
var block = parentFinder.FindRelated((IObject)feature);
Assert.IsNull(block);
}
[TestCase(7513, 1960)]
[TestCase(21124,5696)]
[TestCase(21162,5709)]
[TestCase(21155,5708)]
[TestCase(21154,5708)]
[TestCase(21010,5661)]
[TestCase(20820,5609)]
public void TestParentShortIntersectBlockAndBlockEdge(int inputOid,int expectedOid)
{
var oid = inputOid;
var feature = _blockEdgeTable.GetRow(oid);
var parentFinder = new ParentFinder(ParentFinders.FindParentShortIntersect, _blockTable);
var block = parentFinder.FindRelated((IObject)feature);
Assert.IsNotNull(block);
Assert.AreEqual(block.OID, expectedOid);
}
[TestCase(379605, 8667)]
[TestCase(379624, 8692)]
[TestCase(379632, 8703)]
[TestCase(251924,151022)]
[TestCase(249643,149125)]
public void TestParentShortIntersectParcelAndParcelEdge(int inputOid,int expectedOid)
{
var oid = inputOid;
var feature = _parcelEdgeTable.GetRow(oid);
var parentFinder = new ParentFinder(ParentFinders.FindParentShortIntersect, _parcelTable);
var block = parentFinder.FindRelated((IObject)feature);
Assert.IsNotNull(block);
Assert.AreEqual(block.OID, expectedOid);
}
[TestCase(10906, null)]
[TestCase(10933,null)]
[TestCase(10938,null)]
[TestCase(10925, null)]
[TestCase(10906,null)]
[TestCase(11043, null)]
public void TestParentIntersectionParcelAndBlockEdgeAmbigous(int inputOid, object obj)
{
var oid = inputOid;
var feature = _parcelTable.GetRow(oid);
var parentFinder = new ParentFinder(ParentFinders.FindParentAmbiguous, _blockEdgeTable);
var blockEdge = parentFinder.FindRelated((IObject) feature);
Assert.IsNull(blockEdge);
}
[TestCase(10877, 1303)]
[TestCase(10868, 1303)]
[TestCase(10851, 1303)]
[TestCase(10830, 1303)]
[TestCase(10812, 1303)]
[TestCase(10780, 1303)]
[TestCase(10819, 1306)]
[TestCase(10837, 1306)]
public void TestParentIntersectionParcelAndBlockEdge100percent(int inputOid, object obj)
{
var oid = inputOid;
var feature = _parcelTable.GetRow(oid);
var parentFinder = new ParentFinder(ParentFinders.FindParentAmbiguous, _blockEdgeTable);
var blockEdge = parentFinder.FindRelated((IObject)feature);
Assert.IsNotNull(blockEdge);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment