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

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 30 novembre 2013

Servizio WCTS del PCN

Sin dalla versione 10.1, ArcGIS Server permette di esporre un servizio arcgis server di geoprocessing come WPS (Web Processing Service) ovvero uno standard OGC per esporre modelli di geoprocessing come servizio web mediante un'interfaccia standardizzata che facilita la pubblicazione e l'utilizzo dei 'processi' da parte dei client.
Ad oggi ArcGIS non dispone di un client per poter 'consumare' i servizi WPS ma, essendo servizi che utilizzano standard di comunicazione, possiamo effettuare direttamente le chiamate in HTTP GET o in HTTP POST o mediante messaggi SOAP.
Come esempio di prova possiamo prendere in considerazione il servizio WCTS del PCN (Portale Cartografico Nazionale) cioè il servizio web di trasformazione delle coordinate realizzato come Application Profile di WPS. Il servizio utilizza i grigliati IGM e copre tutto il territorio nazionale.

Le operazioni messe a disposizione del WPS sono: getCapabilities, DescribeProcess ed Execute.

L'operazione di getCapabilities fornisce l'accesso ad informazioni generali su un'implementazione diretta del WPS ed elenca le operazioni e i metodi di accesso supportati da tale implementazione. L'implementazione deve supportare l'operazione di getCapabilities via HTTP GET mentre il supporto HTTP POST è opzionale.

Via HTTP GET possiamo fornire i parametri di richiesta come KVP (Key Value Pair) codificate. Nel nostro esempio (ho inserito solo le KVP obbligatorie):
http://wms.pcn.minambiente.it/wps?service=wps&request=getCapabilities

O via POST:
  
                     XElement root = new XElement(
                        Global.wps + Enum.GetName(typeof(RequestWPS), RequestWPS.getCapabilities),
                        new XAttribute(XNamespace.Xmlns + "ows"Global.ows.NamespaceName),
                        new XAttribute(XNamespace.Xmlns + "wps"Global.wps.NamespaceName),
                        new XAttribute(XNamespace.Xmlns + "xlink"Global.xlink.NamespaceName),
                        new XAttribute(XNamespace.Xmlns + "xsi"Global.xsi.NamespaceName),
                        new XAttribute(Global.xsi + "schemaLocation"Global.schemaLocation.NamespaceName),
                        new XAttribute("language""en"),
                        new XAttribute("service"Global.serviceWPS),
                        new XElement(Global.wps + "AcceptVersions"new XElement(Global.ows + "Version"Global.versionWPS)));
 
                    XDocument xDoc = new XDocument(new XDeclaration(Global.versionXML, Encoding.UTF8.WebName, null), root);
 
                    using (var mem = new MemoryStream())
                    using (var writer = new XmlTextWriter(mem, Encoding.UTF8))
                    {
                        writer.Formatting = Formatting.Indented;
                        xDoc.WriteTo(writer);
                        writer.Flush();
                        mem.Flush();
                        mem.Seek(0, SeekOrigin.Begin);
                        using (var reader = new StreamReader(mem))
                        {
                            string xml = reader.ReadToEnd();
                            XDocument xDocument = this.ResponseWCTSPCN(xml);
 
                            var result = xDocument.Elements().Where(k => (k.Name == Global.wps + "Capabilities")).Elements().Where(h => (h.Name == Global.wps + "ProcessOfferings")).Elements().Where(x => (x.Name == Global.wps + "Process"));
 
                            foreach (var e in result)
                            {
                                if (e.Elements().Where(x => (x.Name == Global.ows + "Identifier") && (x.Value == this.wctsPCNIdentifier)).Count() == 1)
                                {
                                    jsonObject.AddString("title", e.Elements().Where(x => (x.Name == Global.ows + "Title")).Select(x => x.Value).FirstOrDefault());
                                    jsonObject.AddString("abstract", e.Elements().Where(x => (x.Name == Global.ows + "Abstract")).Select(x => x.Value).FirstOrDefault());
                                    break;
                                }
                            }
                        }
                    }
        /// <summary>
        /// return response wps pcn
        /// </summary>
        /// <param name="request">request wps</param>
        /// <returns>object XDocument</returns>
        private XDocument ResponseWCTSPCN(string request)
        {
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(this.wctsPCNUrl);
            webRequest.Method = WebRequestMethods.Http.Post;
            byte[] requestBytes = System.Text.Encoding.ASCII.GetBytes(request);
            webRequest.ContentLength = requestBytes.Length;
            webRequest.ContentType = "text/xml;charset=utf-8";
 
            using (Stream streamWriter = webRequest.GetRequestStream())
            {
                streamWriter.Write(requestBytes, 0, requestBytes.Length);
                HttpWebResponse response = null;
                try
                {
                    response = (HttpWebResponse)webRequest.GetResponse();
                    Console.WriteLine(response.StatusDescription);
 
                    using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
                    {
                        TextReader textReader = new StringReader(streamReader.ReadToEnd());
                        return XDocument.Load(textReader);
                    }
                }
                catch
                {
                    throw;
                }
                finally
                {
                    if (response != null)
                    {
                        response.Close();
                    }
                }
            }
        }

Qui potete vederla live

L'operazione DescribeProcess consente al client WPS di richiedere una descrizione completa di uno o più processi che possono essere eseguiti dal servizio. Questa descrizione include l'input e i parametri di output e i formati e può essere utilizzata per creare automaticamente un'interfaccia utente per acquisire i valori di parametro da utilizzare per eseguire un processo.
Come per il getCapabilities l'implementazione deve supportare l'operazione di DescribeProcess via HTTP GET mentre il supporto HTTP POST è opzionale.

Via HTTP GET possiamo fornire i parametri di richiesta come KVP (Key Value Pair) codificate. Nel nostro esempio (ho inserito solo le KVP obbligatorie):
http://wms.pcn.minambiente.it/wps?service=wps&request=DescribeProcess&version=1.0.0&identifier=TransformCoordinates
oppure
http://wms.pcn.minambiente.it/wps?service=wps&request=DescribeProcess&version=1.0.0&identifier=ALL

Con il primo desideriamo visualizzare il processo nominato TransformCoordinates mentre utilizzando ALL desideriamo listare tutti i processi. Comunque nel caso specifico ne abbiamo solo uno (TransformCoordinates).

Qui potete vederla live

Infine l'operazione di Execute permette al client WPS di eseguire un processo specifico implementato dal server, utilizzando i valori di parametro di input forniti e restituendo i valori di output prodotti. Gli Input possono essere inclusi direttamente nella richiesta Execute, o mediante riferimenti web.
Per l'operazione di Execute l'implementazione dell'HTTP POST è obbligatoria mentre è facoltativa quella dell'HTTP GET.
I parametri di ingresso sono l'Identifier (TransformCoordinate), il SourceCRS, il TargetCRS e l'InputData. Per il SourceCRS e TargetCRS occorre visualizzare l'elenco fornito dalla richiesta di DescribeProcess mentre per l'InputData occorre passare i dati in formato GML nelle versioni supportate indicate sempre nella richiesta di DescribeProcess.


                   XElement root = new XElement(
                        Global.wps + Enum.GetName(typeof(RequestWPS), RequestWPS.Execute),
                        new XAttribute(XNamespace.Xmlns + "ows"Global.ows.NamespaceName),
                        new XAttribute(XNamespace.Xmlns + "wps"Global.wps.NamespaceName),
                        new XAttribute(XNamespace.Xmlns + "xlink"Global.xlink.NamespaceName),
                        new XAttribute(XNamespace.Xmlns + "xsi"Global.xsi.NamespaceName),
                        new XAttribute(Global.xsi + "schemaLocation"Global.schemaLocation.NamespaceName),
                        new XAttribute(XNamespace.Xmlns + "gml"Global.gml.NamespaceName),
                        new XAttribute("service"Global.serviceWPS),
                        new XAttribute("version"Global.versionWPS),
                        new XElement(Global.ows + "Identifier"this.wctsPCNIdentifier),
                        new XElement(Global.wps + "DataInputs"new XElement(Global.wps + "Input"new XElement(Global.ows + "Identifier""SourceCRS"), new XElement(Global.wps + "Data"new XElement(Global.wps + "LiteralData", sourceCRSValue))), new XElement(Global.wps + "Input"new XElement(Global.ows + "Identifier""TargetCRS"), new XElement(Global.wps + "Data"new XElement(Global.wps + "LiteralData", targetCRSValue))), new XElement(Global.wps + "Input"new XElement(Global.ows + "Identifier""TestTransformation"), new XElement(Global.wps + "Data"new XElement(Global.wps + "LiteralData""false"))), new XElement(Global.wps + "Input"new XElement(Global.ows + "Identifier""InputData"), new XElement(Global.wps + "Data"new XElement(Global.wps + "ComplexData"new XAttribute("mimeType""text/xml; subtype=gml/3.1.1"), new XElement(Global.gml + "MultiGeometry"new XAttribute("srsName", sourceCRSValue)))))),
                        new XElement(Global.wps + "ResponseForm"new XElement(Global.wps + "RawDataOutput"new XAttribute("mimeType""text/xml; subtype=gml/3.1.1"), new XElement(Global.ows + "Identifier""TransformedData"))));
 
                    XDocument xDoc = new XDocument(new XDeclaration(Global.versionXML, Encoding.UTF8.WebName, null), root);
 
                    XElement xElementMultiGeometry = xDoc.Descendants(Global.gml + "MultiGeometry").First();
 
                    foreach (IGeometry geometry in geometries)
                    {
                        if (geometry is IPoint)
                        {
                            IPoint point = geometry as IPoint;
                            xElementMultiGeometry.Add(new XElement(Global.gml + "geometryMember"new XElement(Global.gml + "Point"new XAttribute("srsName", sourceCRSValue), new XElement(Global.gml + "coordinates"string.Format("{0},{1}", point.X.ToString(Global.CultureUS), point.Y.ToString(Global.CultureUS))))));
                        }
                    }
 
                    using (var mem = new MemoryStream())
                    using (var writer = new XmlTextWriter(mem, Encoding.UTF8))
                    {
                        writer.Formatting = Formatting.Indented;
                        xDoc.WriteTo(writer);
                        writer.Flush();
                        mem.Flush();
                        mem.Seek(0, SeekOrigin.Begin);
                        using (var reader = new StreamReader(mem))
                        {
                            string xml = reader.ReadToEnd();
                            XDocument xDocument = this.ResponseWCTSPCN(xml);
 
                            var result = xDocument.Elements().Where(k => (k.Name == Global.gml + "MultiGeometry")).Elements().Where(h => (h.Name == Global.gml + "geometryMember"));
 
                            IList<IPoint> points = new List<IPoint>();
                            foreach (var e in result)
                            {
                                XElement xElement = e.Elements().Where(x => (x.Name == Global.gml + "Point")).ElementAtOrDefault(0);
                                string[] xy = xElement.Value.Split(new char[] { ' ' });
                                IPoint point = new PointClass();
                                point.PutCoords(Convert.ToDouble(xy[0], Global.CultureUS), Convert.ToDouble(xy[1], Global.CultureUS));
                                points.Add(point);
                            }
...


Qui potete vederla live mentre qui potete vedere l'help.