Come dire... alla faccia :(

Sto estendendo la "mia" NetTopologySuite, e mi sto scontrando con un problema "concettuale", e sinceramente non riesco a capire dove sia l'errore...

Alla base c'è una struttura di classi relativa alle sole geometrie in cui alla radice c'è Geometry, da cui ereditano tutte le altre feature geometriche come Point, Polygon... fino a GeometryCollection ( i nomi sono abbastanza esplicativi direi... ).

Ho creato quindi una classe ShapeWriter, che scrive genericamente features singole in formato binario in standard ESRI (per chi di GIS ne capisce qualcosa...) così definita (in breve):

public class ShapeWriter
{
    
protected virtual void Write(Coordinate coordinate, BinaryWriter writer) { }   

    
protected virtual void Write(Point point, BinaryWriter writer) { }

    
protected virtual void Write(LineString lineString, BinaryWriter writer) { }
    
    
protected virtual void Write(Polygon polygon, BinaryWriter writer) { }
    
    
protected virtual void Write(MultiPoint multiPoint, BinaryWriter writer) { }

    
protected virtual void Write(MultiLineString multiLineString, BinaryWriter writer) { }

    
protected virtual void Write(MultiPolygon multiPolygon, BinaryWriter writer) { }
}

Ovviamente ogni metodo ha un suo comportamento, che per brevità ho omesso perchè non è importante cosa faccia, ma come si comporti... sarà chiaro + avanti, non temete!

Ho quindi definito GDBWriter, che estende ShapeWriter e semplicemente chiama i metodi giusti in funzione della feature da scrivere:

public class GDBWriter : ShapeWriter
{        
    
public virtual void Write(Geometry geometry, Stream stream)
    {           
        
using (BinaryWriter writer = new BinaryWriter(stream))
        {
        
if (geometry is Point)
            Write(geometry 
as Point, writer);
        
else if (geometry is LineString)
            Write(geometry 
as LineString, writer);
        
else if (geometry is Polygon)
            Write(geometry 
as Polygon, writer);
        
else if (geometry is MultiPoint)
            Write(geometry 
as MultiPoint, writer);
        
else if (geometry is MultiLineString)
            Write(geometry 
as MultiLineString, writer);
        
else if (geometry is MultiPolygon)
            Write(geometry 
as MultiPolygon, writer);
        
else if (geometry is GeometryCollection)
            
throw new NotSupportedException("GeometryCollection not supported!");
        
else throw new ArgumentException("Geometry not recognized: " + geometry.ToString());
        }
    }
}

Ho definito anche ShapeFileWriter, con l'intenzione di scrivere file in formato shapefile a partire da una collezione di Geometrie (GeometryCollection):

public class ShapeFileWriter : ShapeWriter
{        
    
public virtual void Write(GeometryCollection geometries, Stream stream)
    {        
        
using (BinaryWriter writer = new BinaryWriter(stream))
        {    
        
foreach (Geometry geometry in geometries.Geometries)
            Write(geometry, writer);
        }            
    }

    
protected virtual void Write(Geometry geometry, BinaryWriter writer)
    {  
        
// Using simply Write(...) and not base.Write(...) 
        // program calls this method: ShapeFileWriter.Write(Geometry, BinaryWriter)
        // and not methods in base class ShapeWriter!

        
if (geometry is Point)                     
        
base.Write(geometry as Point, writer);
        
else if (geometry is LineString)
        
base.Write(geometry as LineString, writer);
        
else if (geometry is Polygon)
        
base.Write(geometry as Polygon, writer);
        
else if (geometry is MultiPoint)
        
base.Write(geometry as MultiPoint, writer);
        
else if (geometry is MultiLineString)
        
base.Write(geometry as MultiLineString, writer);
        
else if (geometry is MultiPolygon)
        
base.Write(geometry as MultiPolygon, writer);
        
else Assert.ShouldNeverReachHere("Unsupported Geometry implementation:" + geometry.GetType());
    }        
}

Qui stanno i problemi! Se vedete il codice di quest'ultimo metodo, ho inserito base.Write(...) per poter accedere ai metodi della classe base, in quanto omettendo base viene richiamato ricorsivamente il metodo stesso.

I cast funzionano perfettamente, e del resto lo stesso metodo in GDBWriter funziona... ho anche verificato che lo stesso comportamento sia nel VS 2005 che nel 2003, quindi non è un bug, sono io che non ci ho capito proprio... :(

 

powered by IMHO 1.2