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

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

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



lunedì 29 marzo 2010

ArcGIS Server in the cloud (Amazon Web Services - EC2)

ESRI Inc. annuncia l'accordo con Amazon per la realizzazione di soluzioni e servizi in ambiente di cloud computing (per dettagli).

Le AMI ospitate nell'infrastruttura di AWS saranno disponibili con la versione di ArcGIS Server 10 alla fine del 2010. Il licensing sarà annunciato alla UC di luglio 2010.

ESRI comunque intanto propone un servizio professionale nominato ArcGIS for Amazon Jumpstart per il cloud.

Come possiamo vedere ESRI compare tra i solution providers di AWS.

Per quantificare il costo di una soluzione su cloud, indipendentemente dall'utilizzo di ArcGIS Server, potete farvi un' idea con il nuovo simply monthly calculator, scoprirete che i costi sono molto più bassi rispetto alle classiche soluzioni di hosting/housing.
Recentemente sono state introdotte anche le istanze reserved che permettono un ulteriore sconto rispetto all'utilizzo per hour.

Qui potete vedere un video che ho realizzato per utilizzare ArcGIS Server in the cloud.




Per maggiori dettagli visitate questo link http://blogs.esri.com/Dev/blogs/arcgisserver/archive/2010/07/27/ArcGIS-Server-on-Amazon-EC2_3A00_-The-Basics.aspx?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ArcgisServerDevelopmentBlog+%28ArcGIS+Server+Development+Blog%29


Le AMI sono, per ora, disponibili solo per il mercato americano.

sabato 6 marzo 2010

YouTube API location

In questo post volevo segnalarvi la possibilità di aggiungere alle ricerche di video su YouTube anche filtri e visualizzazione geografica. Difatti come si evince dalla Reference Guide: YouTube APIs sono presenti i parametri location e location-radius che permetto di definire un'area geografica nella quale restringere la ricerca e visualizzare la posizione. Ovviamente in questa ricerca verranno trovati i video, ammesso che l'utente che li ha caricati li abbia anche georeferenziati. In questa immagine potete vedere come si presenta l'interfaccia di YT per georeferenziare il proprio video:


Nell'esempio che vi propongo ho creato un Custom Map Controls da utilizzare in Google Maps.

Google Maps API consente di creare un custom map control 'subclassando' il GControl.
Anche se, tecnicamente, non si può parlare di subclassing di un oggetto in Javascript ma di assegnare un oggetto prototipo ad una istanza dell'oggetto GControl.

 /*
  
  Author: Domenico Ciavarella
  
  http://www.studioat.it
  
  http://nicogis.blogspot.com
  
 */
  
 var options =null;
  
 // We define the function first 
  
 function YouTubeControl() { 
  
 } 
  
 // To "subclass" the GControl, we set the prototype object to 
  
 // an instance of the GControl object 
  
 YouTubeControl.prototype = new GControl(); 
  
 // Creates a one DIV for each of the buttons and places them in a container 
  
 // DIV which is returned as our control element. We add the control to 
  
 // to the map container and return the element for the map class to 
  
 // position properly. 
  
 YouTubeControl.prototype.initialize = function(map) { 
  
  var container = document.createElement("div");
  
  container.id = "containerYT";
  
  var divBtn = document.createElement("div");
  
  divBtn.setAttribute("id","divBtn");
  
  var divSearch = document.createElement("div");
  
  divSearch.setAttribute("id","divSearch");
  
  this.setButtonStyle_(divSearch ); 
  
  divSearch.style.width = "67px";
  
  divBtn.appendChild(divSearch); 
  
  divSearch.appendChild(document.createTextNode("Search")); 
  
  GEvent.addDomListener(divSearch, "click", function() {
  
     options = {};
  
     options.pt = (currentMarker == null)?map.getCenter():currentMarker.getLatLng(); 
  
     var r = jQuery('#ytRadious').val();
  
     if (r != '')
  
     {
  
      options.radious = parseInt(r);    
  
     }
  
     //options.radious= 10; //default (10 mi)
  
     options.keywords = jQuery('#ytKeyword').val();
  
     options.max = 25; //default
  
     options.position = 1; //default
  
     jQuery("#divNavigation").css({display : "block"});
  
     geoSearchYouTube('youtubeCallback', options);
  
  });
  
  var divClear = document.createElement("div");
  
  divClear.setAttribute("id","divClear"); 
  
  this.setButtonStyle_(divClear);
  
  divClear.style.width = "67px"; 
  
  divBtn.appendChild(divClear); 
  
  divClear.appendChild(document.createTextNode("Cancel")); 
  
  GEvent.addDomListener(divClear, "click", function() {
  
    reset();
  
    if (currentMarker != null)
  
    {
  
     map.removeOverlay(currentMarker);
  
     currentMarker = null;
  
    }
  
    panelVideos(false);
  
  });
  
  container.appendChild(divBtn); 
  
  var divNavigation = document.createElement("div");
  
  divNavigation.id = "divNavigation";
  
  var btnFirst = document.createElement("div");
  
  btnFirst.setAttribute("id","nfirst"); 
  
  this.setButtonStyle_(btnFirst);
  
  btnFirst.style.width = "32px";
  
  btnFirst.appendChild(document.createTextNode("<<"));
  
  GEvent.addDomListener(btnFirst, "click", function() {
  
     if (options.position == 1) return;
  
     options.position = 1;
  
     geoSearchYouTube('youtubeCallback', options);  
  
  });
  
  divNavigation.appendChild(btnFirst); 
  
  var btnPrevious = document.createElement("div");
  
  btnPrevious.setAttribute("id","nprevious"); 
  
  this.setButtonStyle_(btnPrevious);
  
  btnPrevious.style.width = "31px";
  
  btnPrevious.appendChild(document.createTextNode("<"));
  
  GEvent.addDomListener(btnPrevious, "click", function() {
  
    if (options.position == 1) return;
  
    options.position += -options.max;
  
    geoSearchYouTube('youtubeCallback', options);   
  
  });
  
  divNavigation.appendChild(btnPrevious);
  
  var btnNext = document.createElement("div");
  
  btnNext.setAttribute("id","nnext"); 
  
  this.setButtonStyle_(btnNext);
  
  btnNext.style.width = "31px";
  
  btnNext.appendChild(document.createTextNode(">"));
  
  GEvent.addDomListener(btnNext, "click", function() {
  
    if ((options.positionLast) && (options.positionLast == options.position))
  
    {
  
      return;
  
    }
  
    options.position += options.max;
  
    geoSearchYouTube('youtubeCallback', options);
  
  });
  
  divNavigation.appendChild(btnNext);
  
  var btnLast = document.createElement("div");
  
  btnLast.setAttribute("id","nlast"); 
  
  this.setButtonStyle_(btnLast);
  
  btnLast.style.width = "32px";
  
  btnLast.appendChild(document.createTextNode(">>"));
  
  GEvent.addDomListener(btnLast, "click", function() {
  
    if (!options.positionLast) return;
  
    if (options.position == options.positionLast)return;
  
    options.position = options.positionLast;
  
    geoSearchYouTube('youtubeCallback', options);   
  
  });
  
  divNavigation.appendChild(btnLast);
  
  container.appendChild(divNavigation); 
  
  jQuery("<label>").attr("for","ytKeyword").html("Keyword:").appendTo(container);
  
  jQuery("<br>").appendTo(container);
  
  jQuery("<input type='text'>").attr("id","ytKeyword").attr("title","keyword").appendTo(container);
  
  jQuery("<br>").appendTo(container);
  
  jQuery("<label>").attr("for","ytRadious").html("Radious (mi):").appendTo(container);
  
  jQuery("<br>").appendTo(container);
  
  jQuery("<input type='text'>").attr("id","ytRadious").attr("title","radious (mi)").keypress(function (e){  
  
   if( e.which!=8 && e.which!=0 && (e.which<48 || e.which>57)) 
  
   {   
  
    return false; 
  
   }}).appendTo(container);
  
  //jQuery("<div>").attr("id","videos").appendTo(jQuery("#divVideos"));
  
  var videos = document.createElement("div");
  
  videos.id = "videos";
  
  container.appendChild(videos);
  
  //jQuery("<div>").attr("id","videos").appendTo(container); 
  
  map.getContainer().appendChild(container); 
  
  return container; 
  
 } 
  
 // By default, the control will appear in the top left corner of the 
  
 // map with 7 pixels of padding. 
  
 YouTubeControl.prototype.getDefaultPosition = function() { 
  
  return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(7, 7)); 
  
 } 
  
 // Sets the proper CSS for the given button element. 
  
 YouTubeControl.prototype.setButtonStyle_ = function(button) { 
  
  button.style.textDecoration = "underline"; 
  
  button.style.color = "#0000cc"; 
  
  button.style.backgroundColor = "white"; 
  
  button.style.font = "small Arial"; 
  
  button.style.border = "1px solid black"; 
  
  button.style.padding = "2px"; 
  
  button.style.marginBottom = "3px"; 
  
  button.style.textAlign = "center"; 
  
  button.style.width = "4em"; 
  
  button.style.cursor = "pointer"; 
  
 }  


Qui vediamo la chiamata alle API YT:

  var youtubeFeed = 
  
     ['http://gdata.youtube.com/feeds/api/videos?callback=',callback, '&alt=json-in-script&q=', k,
  
     '&location=', pt.lat(), ',', pt.lng(), '!&location-radius=', 
  
     radious ,'mi', '&v=2&start-index=',position,'&max-results=', max,'&strict=true'].join(''); 
  
    var script = document.createElement('script'); 
  
    script.src = youtubeFeed; 
  
    document.body.appendChild(script);  


Passeremo al parametro callback il nome di una funzione di callback per farci restituire il risultato e passeremo contestualmente al parametro alt il valore json-in-script, per aggirare problematiche dovute al cross-domain security, tipiche di client Javascript. Normalmente il browser impedisce a script scaricati dalla rete di accedere, tramite qualsiasi tipo di richiesta HTTP, a risorse che si trovano su server diversi rispetto a quello iniziale che ha inviato lo script per evitare potenziali attacchi.
Il json-in-script ci consente di caricare la risposta in un tag script sul client.
In questo esempio vengono passati anche le coordinate della location, il raggio dalla location (in questo caso ho utilizzato come unità di misura le miglia [mi] ma avete a disposizione anche i metri [m], i chilometri [km] e i piedi [ft]) , la q che rappresenta un filtro sui metadati dei video (titoli, parole chiave, descrizioni, nome degli autori e categorie), il numero massimo di risultati (max-results) restituiti (default 25 e massimo 50) che, utilizzato contestualmente con start-index, determina il set di risultati da restituire. Occorre tener conto che comunque il numero massimo di risultati restituiti è 999.

Qui potete vedere un'anteprima del GControl per visualizzare su mappa i video cercati:




Scarica qui la soluzione

Visualizza

Sample SOE to REST

In questo video vengono illustrate alcune funzionalità sviluppate lato desktop ed esposte anche lato server senza dover modificare il codice. In sintesi sono state create delle dll condivise (parte core: funzionalità generazione scheda cameretta, profili, goccia), dll UI lato desktop e dll SOE lato server esposte via REST per facilitare l'utilizzo con la maggior parte dei client.