-----------------------------------

Acquista i software ArcGIS tramite Studio A&T srl, rivenditore autorizzato dei prodotti Esri.

I migliori software GIS, il miglior supporto tecnico!

I migliori software GIS, il miglior supporto tecnico!
Azienda operante nel settore GIS dal 2001, specializzata nell’utilizzo della tecnologia ArcGIS e aderente ai programmi Esri Italia Business Network ed Esri Partner Network

-----------------------------------



sabato 15 novembre 2008

Object initializers con AO

In .NET 3.0 è stato introdotto un nuovo approccio all'inizializzazione degli oggetti: object initializers.
Questo consente di istanziare e inizializzare il tutto in una singola riga.

Una istanza di ESRI.ArcGIS.Geometry.Point può essere creata in .NET 3.0:

IPoint point = new PointClass { X = 3.5, Y = 5.8 };




Può essere pratico nel caso in cui multiple Interface sono richieste per inizializzare un oggetto che richiederebbero nel caso del casting (per esempio utilizzando IQueryFilter and IQueryFilterDefinition per inizializzare un query filter).

IQueryFilter queryFilter = new QueryFilterClass { WhereClause = "PID > 40", PostfixClause = "ORDER BY PID" };

 

        IDatasetName datasetName = new FeatureClassNameClass { Name = "Parcels", WorkspaceName = wsName };

 

        ILine line = new LineClass { FromPoint = point1, ToPoint = point2 };



Questo approccio è comunque da evitare quando:

- una proprietà può gettare un errore perchè nel caso sarebbe difficoltoso 'debuggare'.

- il codice può diventare difficile da leggere quando siamo in presenza di diverse interfacce ereditate dalla classe (per esempio Field)

Vedi articolo

Singleton class in c#

Quando hai bisogno di creare una classe che ha una sola istanza nella tua applicazione occorre creare una singleton class.

In c# con l'inizializzazione statica è semplice:

public sealed class Singleton

    {

        private static readonly Singleton instance = new Singleton();

 

        private Singleton() { }

 

        public static Singleton Instance

        {

            get

            {

                return instance;

            }

        }

    }



Mettendo a readonly la variabile privata statica instance verrà inizializzata solo o in un costruttore statico o in una inizializzazione statica (come in questo caso).

L'istanziazione della classe avverrà solo quando verrà chiamata la proprietà pubblica instance.

La classe è sealed per evitare di creare istanze dalle classi derivate.


Lavorare in ambiente multithreaded ed assicurarti la thread safety

Con questo approccio ci assicuriamo che venga creata una sola istanza e soltanto quando necessario.
La variabile è volatile per permettere di accederci una volta completato l'assegnamento alla variable stessa.
Per evitate deadlock si utilizza una istanza di un oggetto (syncRoot) sul lock.


using System;

 

public sealed class Singleton

{

    private static volatile Singleton instance;

    private static object syncRoot = new Object();

 

    private Singleton() { }

 

    public static Singleton Instance

    {

        get

        {

            if (instance == null)

            {

                lock (syncRoot)

                {

                    if (instance == null)

                        instance = new Singleton();

                }

            }

 

            return instance;

        }

    }

}

venerdì 7 novembre 2008

ProgIDFromCLSID

using System;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.Server;


public static class AOFactory <T>
{
        public static T CreateObject(IServerContext SC, object ArcObject)
        {
            string progId = string.Empty;

            try
            {
                Type t = ArcObject.GetType();
                Guid guid = t.GUID;

                progId = Win32API.ProgIDFromCLSID(ref guid);
            }
            catch { }

            if (!string.IsNullOrEmpty(progId))
                return (T)SC.CreateObject(progId);
            else
                return default(T);
        }

}



public static class Win32API
{
       [DllImport("ole32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
        public static extern string ProgIDFromCLSID([In()]ref Guid clsid);
}


Sample:

ESRI.ArcGIS.Geometry.IPoint aoPoint = AOFactory<Geometry.IPoint>.CreateObject(sc, new ESRI.ArcGIS.Geometry.PointClass());




Qui puoi scaricare il codice

Background worker

using System;

using System.ComponentModel;

using System.Windows.Forms;

using ESRI.ArcGIS.ADF;

using ESRI.ArcGIS.Geodatabase;

 

//Author: Domenico Ciavarella

//www.studioat.it

namespace Studioat.ArcEngine.Forms

{

    public partial class frmBW : Form

    {

 

        BackgroundWorker backGroundWorker = null;

        enum operation { start, stop };

        public IFeatureClass FeatureClass

        {

            get;

            set;

        }

 

 

        #region Ctor

        public frmBW()

        {

            InitializeComponent();

 

        }

 

        public frmBW(IFeatureClass featureClass):this()

        {

 

 

            FeatureClass = featureClass;

 

 

        }

        #endregion Ctor

 

        private void btnStart_Click(object sender, EventArgs e)

        {

 

            Operation(operation.start);

            RunWorker();

 

 

        }

        private void btnStop_Click(object sender, EventArgs e)

        {

 

            backGroundWorker.CancelAsync();

 

 

        }

 

        #region private method

        void Operation(operation op)

        {

 

            btnStart.Enabled = (op == operation.stop);

            btnStop.Enabled = (op == operation.start);

            InitializeProgressBar();

        }

        void InitializeProgressBar()

        {

            progressBar.Maximum = 100;

            progressBar.Minimum = 0;

            progressBar.Value = 0;

        }

        void RunWorker()

        {

 

           backGroundWorker = new BackgroundWorker();

           backGroundWorker.WorkerReportsProgress = true;

           backGroundWorker.WorkerSupportsCancellation = true;

           backGroundWorker.DoWork += new DoWorkEventHandler(doWork);

           backGroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(runWorkerCompleted);

           backGroundWorker.ProgressChanged += new ProgressChangedEventHandler(progressChanged);

           backGroundWorker.RunWorkerAsync(FeatureClass);

 

        }

        #endregion private method

 

        #region BackgroundWorker

        void doWork(object sender, DoWorkEventArgs e) {

 

                BackgroundWorker senderWorker = sender as BackgroundWorker;

 

                IFeatureClass featureClass = e.Argument as IFeatureClass;

                int featureCount = featureClass.FeatureCount(null);

 

                IFeatureCursor featureCursor = featureClass.Search(null, true);

                IFeature feature = featureCursor.NextFeature();

 

                int i = 0;

                while (feature != null)

                {

 

                    //////////////////////////////////////

                    //////////////here your work

                    //System.Threading.Thread.Sleep(1000);

                    //////////////////////////////////////

 

                    ++i;

                    int progressInPercent = (int)(((decimal)(i) / (decimal)featureCount) * 100);

 

                    backGroundWorker.ReportProgress(progressInPercent, feature.OID);

 

 

 

 

 

                    if(senderWorker.CancellationPending) {

 

                        e.Cancel = true;

 

                        break;

 

                    }

 

                    feature = featureCursor.NextFeature();

 

                }

 

                ComReleaser.ReleaseCOMObject(featureCursor);

 

            }

        void runWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

        {

 

 

 

                if (e.Cancelled)

                   lblStatus.Text = "work was cancelled.";

                else

                   lblStatus.Text = "work finished processing request.";

 

                Operation(operation.stop);

 

        }

        void progressChanged(object sender, ProgressChangedEventArgs e) {

 

            progressBar.Value = e.ProgressPercentage;

 

            lblStatus.Text = string.Format("working on OID of: {0}",e.UserState);

 

        }

        #endregion

 

 

 

    }

}





Qui puoi scaricare la soluzione in VS2008 MapControlBW

mercoledì 5 novembre 2008

Extension method

Esempio di Extension method su IFields

namespace Studioat.ArcEngine

{

    public static class Helper

    {

 

        public static IField get_Field(this IFields fields, string FieldName)

        {

            int i = fields.FindField(FieldName);

 

            return (i==-1)?null:fields.get_Field(i);

 

        }

 

    }

 

}






IField field = featureClass.Fields.get_Field("MyFieldName");