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

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

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



mercoledì 20 gennaio 2010

SOE to REST

Proseguendo il post del  23 giugno 2009, per esporre la SOE (Server Object Extension), potrebbe essere comodo utilizzare uno stile architetturale REST.
Per l'implementazione usiamo ad esempio WCF che nello specifico, poichè si serve dello stile architetturale REST, sarà definito un servizio RESTful. Qui potete trovare una introduzione all'argomento.

Se il servizio WCF può accedere alla SOM tramite DCOM, possiamo fare la connessione direttamente dal servizio, altrimenti dobbiamo esporre la nostra SOE via SOAP e solo poi il servizio WCF potrà comunicare via http alle funzionalià esposte dalla SOE.

Vediamo il caso in cui possiamo comunicare alla SOM direttamente tramite DCOM. Per non stare ad inventarci niente di nuovo, possiamo utilizzare l'esempio della ESRI (ArcGIS Spatial Query Server Object Extension) che usa i dati in -ArcGIS install location-\DeveloperKit\SamplesNet\Server\data\Yellowstone.
In sintesi, questa SOE riceve in input le coordinate di un punto ed una distanza; in seguito, in funzione del layer X (tipo poligonale) e del campo Y impostato nelle property della SOE (configurabili con ArcCatalog), vengono restituite le somme delle aree in funzione del valori nel campo Y all'interno del buffer indicato dai dati di input.


[ErrorBehavior(typeof(YellowstoneServiceErrorHandler))]
    public sealed class YellowstoneService : IYellowstoneService
    {
        public List<VegetationSumType> GetSumVegetationType(double x, double y, double distance)
        {
            IServerContext serverContext = null;
            List<VegetationSumType> vegetationSumType = new List<VegetationSumType>();
            try
            {
                // Connection to ArcGIS Server
                Identity identity = new Identity();
                identity.UserName = ConfigurationManager.AppSettings.Get("userAGS");
                identity.Password = ConfigurationManager.AppSettings.Get("passwordAGS");


                using (AGSServerConnection agsServerConnection = new AGSServerConnection(ConfigurationManager.AppSettings.Get("hostnameAGS"), identity))
                {
                    try
                    {
                        agsServerConnection.Connect();
                    }
                    catch (ServerHostNullException)
                    {
                        throw new FaultException(YellowstoneRes.ServerHostNullException);
                    }
                    catch
                    {
                        throw;
                    }

                    // Reference SOM
                    IServerObjectManager serverObjectManager = agsServerConnection.ServerObjectManager;
                    serverContext = serverObjectManager.CreateServerContext(ConfigurationManager.AppSettings.Get("ServiceName"), "MapServer");

                    IMapServer mapServer = (IMapServer)serverContext.ServerObject;
                    IServerObjectExtensionManager serverObjectExtensionManager = (IServerObjectExtensionManager)mapServer;
                    IServerObjectExtension serverObjectExtension = serverObjectExtensionManager.FindExtensionByTypeName(ConfigurationManager.AppSettings.Get("SOEName"));
                    IVegUtilsSOE vegutils = (IVegUtilsSOE)serverObjectExtension;

                    IVegResultsSOE result = vegutils.sumVegetationType(x, y, distance);

                    IRecordSet stats = result.Stats;

                    using (ComReleaser comReleaser = new ComReleaser())
                    {
                        ICursor cursor = stats.get_Cursor(true);
                        comReleaser.ManageLifetime(cursor);

                        IRow row = cursor.NextRow();

                        while (row != null)
                        {
                            vegetationSumType.Add(new VegetationSumType() { Type = Convert.ToString(row.get_Value(0)), Area = Convert.ToDouble(row.get_Value(1)) });

                            row = cursor.NextRow();
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
            finally
            {

                if (serverContext != null)
                {
                    serverContext.ReleaseContext();
                }
            }

            return vegetationSumType;
        }

    }

Nel Web.Config memorizzeremo le impostazioni per connettersi ad ArcGIS Server (deve essere un utente che appartiene al gruppo degli utenti agsUser)

<appSettings>
    <!-- user ArcGIS Server group agsUser-->
    <add key="userAGS" value="youragsUser"/>
    <add key="passwordAGS" value="xxxxxxxx"/>
    <add key="domainAGS" value=""/>
    <!--**********************-->
    <add key="hostnameAGS" value="localhost"/>
    <add key="ServiceName" value="YellowStone"/>
    <add key="SOEName" value="VegUtilitiesSOE_CSharp"/>
  </appSettings>


Il nostro service contract sarà:

namespace Studioat.Samples
{
    [ServiceContract(Namespace = "http://Studioat.Samples")]
    public interface IYellowstoneService
    {

        [OperationContract]
        [WebGet(UriTemplate = "Vegetation?x={x}&y={y}&distance={distance}", ResponseFormat = WebMessageFormat.Json,BodyStyle= WebMessageBodyStyle.WrappedResponse)]
        List<VegetationSumType> GetSumVegetationType(double x, double y, double distance);

    }

    [DataContract]
    public class VegetationSumType
    {

        [DataMember]
        public string Type
        {
            get;
            set;
        }

        [DataMember]
        public double Area
        {
            get;
            set;
        }

    }
}


A questo punto possiamo fare un test e, servendoci ad esempio del fiddler oppure direttamente del browser, verificare il risultato. Eseguiamo una request Builder di tipo GET da fiddler: http://localhost/wsYellowStone/YellowstoneService.svc/Vegetation?x=541131&y=4908614&distance=5500.0



In questo caso la risposta è in formato JSON ma, se volete la risposta in Xml, potete semplimente modificarla utilizzando ResponseFormat = WebMessageFormat.Xml.

Nel caso in cui abbiate già esposto la vostra SOE via SOAP, potete far riferimento nel servizio WCF al servizio SOAP senza dovervi connettere alla SOM e quindi evitando anche la comunicazione DCOM.


Scarica qui la soluzione

Nessun commento: