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

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

sabato 9 gennaio 2010

More...button

Using this sample and ESRI Google Maps API, we can show or hide tile ( TiledMapServiceLayer ) and dynamic ( DynamicMapServiceLayer ) layers.

Looking at the beginning of the file more.js in folder js, you can set the layers you want to add in the menu and you also can set other settings.
In a nutshell, to add a tile layer you have to put in layersDefinition variable an instruction such as the following:

{'type':'Tiled',
'service':'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Portland/ESRI_LandBase_WebMercator/MapServer',
'visible':true,
'caption':'Portland LandBase',
'options':{ opacity: 0.65, minResolution: 0, maxResolution: 19 }}

service: ArcGIS Server REST resource identified url
visible: the initial visibility
caption: the caption name in the menu
options: the layer options

Instead, in order to add a dynamic layer, put a line such as the following:

{'type':'Dynamic',
'service':'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Population_World/MapServer',
'visible':false,
'caption':'Population World',
'parameter':null,'opacity':0.75}

service: ArcGIS Server REST resource identified url
visible: the initial visibility
caption: the caption name in the menu
parameter: the layer parameter
opacity: the layer opacity



In this case, two layers were added (Portland Land and Population World).

To enrich the page with some more functionalities, they were drawn from Google Maps API Demo Gallery:

- Tabbed Max InfoWindow + Dynamic Content ( you can see it by clicking on a building in the town of Portland )


  

In the code it is easy to customize the visualization of your data following what has been done for the layer building.

- Professional DragZoomControl



-KeyDragZoom  (shift + drag )