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

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

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



domenica 19 dicembre 2010

Autocomplete con dojo API

Con le ArcGIS JavaScript API potrebbe essere utile utilizzare l'Autocomplete. Per questo ci viene incontro il dojox.data.QueryReadStore. In dojo campus possiamo vedere degli esempi.





Innanzitutto creiamo il servizio lato server che verrà chiamato lato client. In questo esempio che vi illustro usiamo il template WCF Rest per il Framework 4.0 (CS) , ci connettiamo ad un servizio Geodata e ci facciamo restituire i dati richiesti.

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.ADF.Connection.AGS;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.GeoDatabaseDistributed;
using ESRI.ArcGIS.Server;
 
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class GeoData : IGeoData
{
 
    #region IGeoDataService Members
 
    [WebGet(UriTemplate = "/Comune?q={filter}&limite={limit}", ResponseFormat  = WebMessageFormat.Json)]
    public ListaComuni GetListaComuni(string filter, int limit)
    {
        List<Comune> items = new List<Comune>();
 
        if (string.IsNullOrEmpty(filter))
            return new ListaComuni() { Items = items };
 
        filter = filter.Substring(0, filter.Length - 1);
 
        if (filter.Length <= limit)
            return new ListaComuni() { Items = items };
        
 
 
        IServerContext serverContext = null;
        try
        {
            // Connessione ad ArcGIS Server
            Identity identity = new Identity();
            identity.UserName = ConfigurationManager.AppSettings.Get("utenteAGS");
            identity.Password = ConfigurationManager.AppSettings.Get("passwordAGS");
 
            string domain = ConfigurationManager.AppSettings.Get("domainAGS");
 
 
            if (!string.IsNullOrEmpty(domain))
              identity.Domain = domain;
            
 
            using (AGSServerConnection agsServerConnection = new AGSServerConnection(ConfigurationManager.AppSettings.Get("hostnameAGS"), identity))
            {
                try
                {
                    agsServerConnection.Connect();
                }
                catch
                {
                    throw;
                }
 
                // get a server context
                IServerObjectManager som = agsServerConnection.ServerObjectManager;
                serverContext = som.CreateServerContext(ConfigurationManager.AppSettings.Get("serviceGeoData"), "GeodataServer");
 
                // get the workspace from the GeodataServer
                IGeoDataServer gds = serverContext.ServerObject as IGeoDataServer;
                IGeoDataServerObjects geoDataServerObjects = gds as IGeoDataServerObjects;
                IWorkspace workspace = geoDataServerObjects.DefaultWorkingWorkspace;
 
 
                IFeatureWorkspace featureWorkspace = workspace as IFeatureWorkspace;
                IFeatureClass featureClass = featureWorkspace.OpenFeatureClass("Comuni");
                string nomeCampo = "COMUNE";
                int idxField = featureClass.FindField(nomeCampo);
 
 
                IQueryFilter queryFilter = serverContext.CreateObject("esriGeodatabase.QueryFilter"as IQueryFilter;
 
 
                queryFilter.SubFields = nomeCampo;
 
                if (!string.IsNullOrEmpty(filter))
                {
                    ISQLSyntax sqlSyntax = workspace as ISQLSyntax;
                    string wildcardMany = sqlSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_WildcardManyMatch);
                    string prefixDI = sqlSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierPrefix);
                    string suffixDI = sqlSyntax.GetSpecialCharacter(esriSQLSpecialCharacters.esriSQL_DelimitedIdentifierSuffix);
                    
                    string where = string.Format("{0}{1}{2} LIKE '{3}{4}'", prefixDI, nomeCampo, suffixDI, filter.ToUpper(), wildcardMany);
                    queryFilter.WhereClause = where;
                }
 
                using (ComReleaser comReleaser = new ComReleaser())
                {
                    IFeatureCursor featureCursor = featureClass.Search(queryFilter, true);
                    comReleaser.ManageLifetime(featureCursor);
                    IFeature feature = null;
                    string item = null;
                    while ((feature = featureCursor.NextFeature()) != null)
                    {
                        item = Convert.ToString(feature.get_Value(idxField));
                        items.Add(new Comune() { Name = item });
                    }
                }
 
                items = items.OrderBy(x => x.Name).ToList();
 
                //if (limit > 0)
                //  items = items.Take(limit).ToList();
 
            }
            return new ListaComuni() { Items = items };
        }
        catch
        {
            return new ListaComuni() { Items = new List<Comune>() };
        }
        finally
        {
            if (serverContext != null) serverContext.ReleaseContext();
        }
    }
 
    #endregion
}

using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;


[ServiceContract]
public interface IGeoData
{

    [OperationContract]
    ListaComuni GetListaComuni(string filter,int limit);

}


[DataContract]
public class ListaComuni
{
    [DataMember(Name = "items")]
    public List<Comune> Items
    {
        get;
        set;
    }
}

[DataContract]
public class Comune
{

    [DataMember(Name = "name")]
    public string Name
    {
        get;
        set;
    }
}



Dalla nostra pagina che esegue codice lato client utilizziamo il QueryReadStore e richiamiamo il nostro servizio REST.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
       <meta http-equiv="X-UA-Compatible" content="IE=7" />
       <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
        on iOS devices-->
       <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>


        <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.1/js/dojo/dijit/themes/claro/claro.css">

        <script type="text/javascript">
            var djConfig = {
                parseOnLoad: true, isDebug: true, baseUrl: './', modulePaths: { 'custom''custom' }
            };
        </script> 
        <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.1"></script>

<script type="text/javascript">

    dojo.require("dijit.dijit"); // optimize: load dijit layer
    dojo.require("dijit.layout.BorderContainer");
    dojo.require("dijit.layout.ContentPane");
    dojo.require("dijit.layout.TabContainer");
    dojo.require("dijit.Tooltip");
    dojo.require("dijit.TitlePane");
    dojo.require("esri.map");

    dojo.require("dojox.data.QueryReadStore");
    dojo.require("dijit.form.ComboBox");
    dojo.require("custom.ComboBoxReadStore");




    var map;


    function Init() {

        dojo.style(dojo.byId("map"), { width: dojo.contentBox("map").w + "px", height: (esri.documentBox.h - dojo.contentBox("navTable").h - 40) + "px" });
        var initExtent = new esri.geometry.Extent({ "xmin": 6.55059928850006, "ymin": 45.0006208151578,
            "xmax": 8.22229873550003, "ymax": 45.6702338525465, "spatialReference": { "wkid": 4326 }
        });
        map = new esri.Map("map", { extent: initExtent });


        var layer = new esri.layers.ArcGISDynamicMapServiceLayer("http://localhost/ArcGIS/rest/services/LimitiComuni/MapServer", { "opacity": 0.5 });
        var layerBaseMap = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer");
        map.addLayer(layerBaseMap);
        map.addLayer(layer);

        var resizeTimer;
        dojo.connect(map, 'onLoad'function (theMap) {

            dojo.connect(dijit.byId('map'), 'resize'function () {
                clearTimeout(resizeTimer);
                resizeTimer = setTimeout(function () {
                    map.resize();
                    map.reposition();
                }, 500);
            });
        });




    }
    dojo.addOnLoad(Init);

</script>
</head>
<body class="tundra">

<table style="width:100%">
<tr>
<td>
<table id="navTable" width="100%">
<tbody>
<tr valign="top">
<td id="breadcrumbs">
ArcGIS JavaScript API: LimitiComuni
</td>

<td align="right" id="help">

<div dojoType="custom.ComboBoxReadStore" jsId="theStore" url="http://localhost:1385/GeoData/Comune?"
               requestMethod="get">
</div>

<input dojoType="dijit.form.ComboBox"
        searchAttr="name" name="theSelect" id="theSelect" 
        store="theStore" placeHolder="Cerca comune" hasDownArrow="false">
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
<div id="map" style="margin:auto;width:97%;border:1px solid #000;"></div>
</body>
</html>



In custom/ComboBoxReadStore.js subclassiamo dojox.data.QueryReadStore per poter modificare eventualmente il passaggio dei parametri dal client al server:

dojo.provide("custom.ComboBoxReadStore");
 
dojo.require("dojox.data.QueryReadStore");
 
dojo.declare("custom.ComboBoxReadStore", dojox.data.QueryReadStore, {
  fetch:function(request) {
    request.serverQuery = {q:request.query.name, limite:2};
    // Call superclasses' fetch
    return this.inherited("fetch", arguments);
  }
});