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

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

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



Visualizzazione post con etichetta arcgis. Mostra tutti i post
Visualizzazione post con etichetta arcgis. Mostra tutti i post

sabato 20 giugno 2009

Load-only mode

IFeatureClassLoad è un'interfaccia opzionale per FeatureClass ArcSDE e per FeatureClass e Table file geodatabase. Abilitando la modalità 'Load-Only' miglioriamo le prestazioni di caricamento dei dati.
Con questa modalità disabilitiamo l'aggiornamento degli indici spaziali e degli indici sugli attributi (questi ultimi solo per il file geodatabase) mentre si esegue un'operazione di inserimento di rows o features. Gli indici verranno ricostruiti una volta che si disabilita la modalità Load-Only.
Quando una feature class o una tabella è in modalità load-only altre applicazioni non possono lavorare su questi dati, pertanto occorre acquisire un lock esclusivo dello schema sulla tabella o feature class tramite l'interfaccia ISchemaLock

Qui potete vedere un esempio di caricamento dati in una feature class in modalità Load-Only
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.esriSystem;
using System.IO;
using ESRI.ArcGIS.Geodatabase;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.ADF;
using System.Diagnostics;
 
namespace caCursors
{
    class Program
    {
        static void Main(string[] args)
        {
 
            Arguments CommandLine = new Arguments(args);
 
            if ((args.Length == 0)  (CommandLine["help"] != null)  (CommandLine["h"] != null))
            {
                Console.WriteLine("The arguments to the utility are:");
                Console.WriteLine("caCursors [-hhelp] [-lloadOnlyMode]");
                Console.WriteLine("caCursors -l true");
                Console.WriteLine("Press Enter to continue...");
                Console.ReadLine();
                return;
 
            }
 
            bool loadOnlyMode;
 
            if ((CommandLine["loadOnlyMode"] != null)  (CommandLine["l"] != null))
            {
                string sloadOnlyMode = CommandLine["l"] ?? CommandLine["loadOnlyMode"];
                bool result;
                if (!Boolean.TryParse(sloadOnlyMode, out result))
                {
                    Console.WriteLine("Parametro loadOnlyMode non corretto. Indicare: {0} o {1}", Boolean.TrueString, Boolean.FalseString);
                    return;
                }
                loadOnlyMode = result;
            }
            else
            {
                Console.WriteLine("Indicare il parametro loadOnlyMode: caCursors -l ({0} or {1})", Boolean.TrueString, Boolean.FalseString);
                return; 
            }
 
 
            #region Licensing
 
            IAoInitialize aoInitialize = new AoInitializeClass();
            esriLicenseStatus licenseStatus = aoInitialize.Initialize(esriLicenseProductCode.esriLicenseProductCodeArcInfo);
            if (licenseStatus != esriLicenseStatus.esriLicenseCheckedOut)
            {
                Console.WriteLine("Licenza ArcInfo non trovata, errore numero: {0}", licenseStatus);
                return;
            }
            #endregion
 
 
            Console.WriteLine("Cancellazione gdb ...");
            if (Directory.Exists("Comuni.gdb"))
                Directory.Delete("Comuni.gdb", true);
 
            Console.WriteLine("Copia gdb per test ...");
 
            Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
            IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
 
            IWorkspaceName sourceWorkspaceName = new WorkspaceNameClass { PathName = @"..\..\Data\Comuni.gdb", WorkspaceFactoryProgID = "esriDataSourcesGDB.FileGDBWorkspaceFactory" };
 
            IWorkspaceName copiedWorkspaceName = null;
            workspaceFactory.Copy(sourceWorkspaceName, Environment.CurrentDirectory, out copiedWorkspaceName);
 
 
            IName copiedName = (IName)copiedWorkspaceName;
            IWorkspace workspace = (IWorkspace)copiedName.Open();
            IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
 
 
 
            IFeatureClass featureClass = featureWorkspace.OpenFeatureClass("Comuni");
 
            IWorkspace workspaceInput = ShapefileWorkspaceFromPath(@"..\..\Data");
            IFeatureClass featureClassInput = ((IFeatureWorkspace)workspaceInput).OpenFeatureClass("Comuni");
 
            Console.WriteLine("Inserimento dati in gdb ...");
            InsertCursor(workspace, featureClass, featureClassInput, loadOnlyMode);
 
 
 
            aoInitialize.Shutdown();
        }
 
 
        private static void InsertCursor(IWorkspace workspace, IFeatureClass featureClass, IFeatureClass featureClassInput, bool LoadOnlyMode)
        {
 
 
 
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
 
            IFeatureClassLoad featureClassLoad = (IFeatureClassLoad)featureClass;
 
            ISchemaLock schemaLock = null;
            if (LoadOnlyMode)
            {
                featureClassLoad.LoadOnlyMode = LoadOnlyMode;
                schemaLock = (ISchemaLock)featureClass;
            }
 
 
            IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)workspace;
            workspaceEdit.StartEditing(true);
            workspaceEdit.StartEditOperation();
 
 
            using (ComReleaser comReleaser = new ComReleaser())
            {
 
                IFeatureCursor featureCursor = featureClass.Insert(true);
                comReleaser.ManageLifetime(featureCursor);
 
 
                IFeatureBuffer featureBuffer = featureClass.CreateFeatureBuffer();
                comReleaser.ManageLifetime(featureBuffer);
 
                IFeatureCursor featureCursorInput = featureClassInput.Search(null, true);
                comReleaser.ManageLifetime(featureCursorInput);
 
                try
                {
                    IFeature feature = null;
                    while ((feature = featureCursorInput.NextFeature()) != null)
                    {
 
 
 
                        featureBuffer.Shape = feature.ShapeCopy;
                        featureBuffer.set_Value(2, feature.get_Value(2)); //istat_new (campo con indice)
                        featureBuffer.set_Value(5, feature.get_Value(5)); //comune (campo con indice)
 
                        //for (int i = 2; i < 8; i++)
                        //    featureBuffer.set_Value(i, feature.get_Value(i));
 
 
 
                        featureCursor.InsertFeature(featureBuffer);
                    }
 
 
                    featureCursor.Flush();
 
 
                    workspaceEdit.StopEditOperation();
                    workspaceEdit.StopEditing(true);
 
                }
                catch (COMException)
                {
 
                    workspaceEdit.AbortEditOperation();
                    workspaceEdit.StopEditing(false);
                }
            }
 
            if (LoadOnlyMode)
            {
                featureClassLoad.LoadOnlyMode = false;
                schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
 
            }
 
 
            stopWatch.Stop();
            TimeSpan ts = stopWatch.Elapsed;
 
 
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:000}",
                ts.Hours, ts.Minutes, ts.Seconds,
                ts.Milliseconds);
            Console.WriteLine(elapsedTime);
            Console.WriteLine("Premere invio ...");
            Console.Read();
        }
 
 
 
        public static IWorkspace ShapefileWorkspaceFromPath(String path)
        {
            Type factoryType = Type.GetTypeFromProgID(
              "esriDataSourcesFile.ShapefileWorkspaceFactory");
            IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)
              Activator.CreateInstance(factoryType);
            return workspaceFactory.OpenFromFile(path, 0);
        }
    }
}
 
Scarica qui la soluzione.

domenica 28 dicembre 2008

What's Coming in ArcGIS 9.3.1

- High-Performance Dynamic Map Publishing

- Better Sharing of Geographic Information

- Enhanced Support for Java Developers

- Easy to Migrate

ArcGIS 9.3.1 is scheduled to be available in Q2 2009.

For details

mercoledì 24 dicembre 2008

ComReleaser - gestione del ciclo di vita dei cursori

I cursori del geodatabase dovrebbero sempre venire esplicitamente distrutti in un ambiente che utilizza la garbage collection. La regola è sempre rilasciare un oggetto COM non appena l'applicazione ha finito di utilizzare il suo riferimento. Questo è particolarmente importante con i cursori del geodatabase poichè fallire il rilascio dei cursori può mettere in uno stato di lock il sistema e le risorse dbms; un sintomo comune è il blocco di una tabella per un tempo indeterminato dopo
aver finito di ciclare sulle righe con un search cursor.
Questo articolo è una lettura fondamentale per gli sviluppatori che usano il geodatabase API: dimostra l'importanza di rilasciare gli oggetti COM (e specialmente i cursori) e di utilizzare un approccio diverso.
Molti sviluppatori .NET che hanno lavorato con il COM interop conosceranno già il metodo statico Marshal.ReleaseComObject, ma c'è anche una sezione dedicata ad una classe nell'ADF chiamata ComReleaser che è veramente utile quando si lavora con i cursori.

Ecco un esempio dell'uso del ComReleaser per assicurarsi che il cursore sia propriamente rilasciato:


using (ComReleaser comReleaser = new ComReleaser())

        {

 

            // Istanzia un cursore e gestisci il ciclo di vita con il ComReleaser.

 

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

 

            comReleaser.ManageLifetime(featureCursor);

 

 

 

            // Cicla attraverso le features.

 

            IFeature feature = null;

 

            while ((feature = featureCursor.NextFeature()) != null)

            {

 

                // Fai qualcosa

 

            }

 

        }



Indipendentemente da come il codice lascia questo blocco using (se un valore è restituito, se viene gettata un'eccezione o esce) il
cursore comunque avrà il proprio reference count correttamente decrementato.

Vedi articolo

lunedì 15 dicembre 2008

EMAB (Logger)

I have used EMAB for simplification ( EMAB download )
for this project.

Nevertheless now it has been overcome by Enterprise Library 4.1 ( Enterprise Library 4.1 download )

For details see Best practises Microsoft


App.Config:


<?xml version="1.0"?>

<configuration>

 

 

 

 

  <configSections>

    <section name="exceptionManagement" type="Microsoft.ApplicationBlocks.ExceptionManagement.ExceptionManagerSectionHandler,Microsoft.ApplicationBlocks.ExceptionManagement" />

  </configSections>

 

 

  <exceptionManagement mode="on">

    <publisher assembly="MapControlEMAB" type="Studioat.ArcEngine.AppBase.Classes.EM" fileName="LogError.txt" sendEMail="off" operatorMail="xxxx@gmail.it" operatorFrom="xxxx@yahoo.it" subject="Logger MapControlEMAB"  host="smtp.mail.yahoo.it" user="" password=""/>

  </exceptionManagement>

 

</configuration>




mode="on|off" enable/disable log
assembly="MapControlEMAB" assembly which holds the custom class to manage log
type="Studioat.ArcEngine.AppBase.Classes.EM" custom class to manage log
fileName="LogError.txt" name of the log file created in bin

sendEMail="on|off" enable/disable log on email
operatorMail="xxxx@gmail.it" mail to
operatorFrom="xxxx@yahoo.it" mail from
subject="Logger MapControlEMAB" subject
host="smtp.mail.yahoo.it" smtp
user="" authentication user mail
password="" authentication password mail


From menu select 'Demo Log':

In this sample the error is in the log:

try

            {

                int a = 1, b = 0, c;

 

                c = a / b;

 

            }

            catch (Exception ex)

            {

 

                ExceptionManager.Publish(ex);

 

            }

            finally

            {

 

                MessageBox.Show("See new entry in LogError.txt", "Logger");

 

            }




In this sample the error is in the log plus your extra information:

try

            {

                int a = 1, b = 0, c;

 

                c = a / b;

 

            }

            catch (Exception ex)

            {

 

                NameValueCollection nvc = new NameValueCollection();

                nvc.Add("Info", "My comments bla bla bla:\n\n");

                ExceptionManager.Publish(ex, nvc);

 

 

            }

            finally

            {

 

                MessageBox.Show("See new entry in LogError.txt", "Logger");

 

            }




In this sample the error without handling Exception (remember that to see this error you can't be in debug but you must run directly exe.)


int a = 1, b = 0, c;

 

            c = a / b;





In form main we set UnhandledException for unhandling errors

/// <summary>

    /// The main entry point for the application.

    /// </summary>

    [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]

    [STAThread]

    static void Main()

    {

 

 

        #region manager error

        Application.ThreadException += new ThreadExceptionEventHandler(frmMain.UIThreadException);

        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

 

 

        AppDomain.CurrentDomain.UnhandledException +=

            new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        #endregion manager error

 

 

        Application.Run(new frmMain());

    }

    #region manager error

    private static void UIThreadException(object sender, ThreadExceptionEventArgs t)

    {

        DialogResult result = DialogResult.Cancel;

        try

        {

            result = ShowThreadExceptionDialog("Error", t.Exception);

        }

        catch (Exception ex)

        {

            try

            {

                MessageBox.Show("Error", "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);

                ExceptionManager.Publish(ex);

            }

            finally

            {

                Application.Exit();

            }

        }

 

 

        if (result == DialogResult.Abort)

            Application.Exit();

    }

    private static DialogResult ShowThreadExceptionDialog(string title, Exception e)

    {

        string errorMsg = "Contact admin with following info:\n\n";

        errorMsg += e.Message + "\n\nStack Trace:\n" + e.StackTrace;

        return MessageBox.Show(errorMsg, title, MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);

    }

    private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)

    {

        try

        {

            Exception ex = (Exception)e.ExceptionObject;

 

 

            NameValueCollection nvc = new NameValueCollection();

            nvc.Add("Info", "Contact admin with these info errors:\n\n");

            ExceptionManager.Publish(ex, nvc);

 

 

        }

        catch (Exception exc)

        {

            try

            {

 

                ExceptionManager.Publish(exc);

            }

            finally

            {

                Application.Exit();

            }

        }

    }

    #endregion manager error





class EM inherits from IExceptionPublisher and is the custom class used for the logger.



Here you can download the soluzion VS2008 Logger Error

venerdì 5 dicembre 2008

Linq to XML

Con linq è semplice interrogare un element: in questo esempio ho copiato una parte di file GML.

XElement gml = XElement.Parse(

        @"<features><feature fid=""142"" featuretype=""school"" description=""A middle school"">

        <polygon name=""extent"" srsname=""epsg:27354"">

        <linestring name=""extent"" srsname=""epsg:27354"">

        <cdata>

        491888.999999459,5458045.99963358 491904.999999458,5458044.99963358

        491908.999999462,5458064.99963358 491924.999999461,5458064.99963358

        491925.999999462,5458079.99963359 491977.999999466,5458120.9996336

        491953.999999466,5458017.99963357 </cdata>

        </linestring>

        </polygon>

        </feature><feature fid=""143"" featuretype=""house"" description=""a house"">

        <polygon name=""extent"" srsname=""epsg:27354"">

        <linestring name=""extent"" srsname=""epsg:27354"">

        <cdata>

        491888.999999459,5458045.99963358 491904.999999458,5458044.99963358

        491908.999999462,5458064.99963358 491924.999999461,5458064.99963358

        491925.999999462,5458079.99963359 491977.999999466,5458120.9996336

        491953.999999466,5458017.99963357 </cdata>

        </linestring>

        </polygon>

        </feature></features>");

 

 

        //Seleziono la feature con fid = 143

 

        var query = from p in gml.Elements("feature") where (int)p.Attribute("fid") == 143 select p;

 

        //visualizzo i suoi attributi

        foreach (var rec in query)

            Console.WriteLine("Feature: type:{0} - description: {1}", rec.Attribute("featureType").Value, rec.Attribute("Description").Value);

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

venerdì 7 novembre 2008

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