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 5 aprile 2009

Simple Photo gallery per MapViewer

This is a simple task to visualize a photo list associated to a feature: the task was developed integrating it in the map viewer ( http://resources.esri.com/arcgisserver/adf/dotnet/index.cfm?fa=codeGalleryDetails&scriptID=15963 ) framework. In the code, you will have to point out the id layer and the field name on which the feature must be searched (variable LayerId and fieldName). Besides, in the static function LoadImages you will have to write your business logic in order to get back the photo list.
For instance, in this function I get back the photo list from a table (many) joined with the feature class passing to the function the value in fieldName in feature class (one). In this particular case the join is between ObjectId in feature class and the relevant value in a many table field, while the value searched in input in the user's floating panel is another one, in this case the fieldName string type field parameter key passed to the function. The last sentence highlights that, if the field is of numeric type, the apostrophes in the query must be removed.
The function returning the photo list could become more than one because it can be modified in runtime (through the property methodImages) as it is called via reflection.

namespace Studioat.ARCGIS.ADF.Tasks
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration;
using System.Data.OleDb;
using System.Reflection;
using System.Text;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using ESRI.ArcGIS.ADF.Web;
using ESRI.ArcGIS.ADF.Web.DataSources;
using ESRI.ArcGIS.ADF.Web.UI.WebControls;
using ESRI.Solutions.NITK.Framework.Results;
using ESRI.Solutions.NITK.Framework.TaskResults;
//Author: Domenico Ciavarella
[AjaxControlToolkit.ClientScriptResource("Studioat.ARCGIS.ADF.Tasks.PhotoGalleryTask", "Studioat.ARCGIS.ADF.Tasks.javascript.PhotoGalleryTask.js")]
[System.Web.UI.ToolboxData(@"<{0}:PhotoGalleryTask runat=""server"" BackColor=""White""
        BorderColor=""LightSteelBlue"" BorderStyle=""Outset"" BorderWidth=""1px"" Font-Names=""Verdana""
        Font-Size=""8pt"" ForeColor=""Black"" TitleBarColor=""WhiteSmoke"" TitleBarHeight=""20px""
        TitleBarSeparatorLine=""True"" Transparency=""35"" Width=""130px"">
public class PhotoGalleryTask : ResultProducingTask
static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
static readonly string taskFullName = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName;
static readonly string taskNamespace = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;
ITaskResultsContainer m_TaskResults;
//Change here your data
string LayerId = "1";
string fieldName = "YourNameFieldSearchUserFeature";
[DisplayName("Method for list images")]
public string MethodImages
object o = StateManager.GetProperty("methodImages");
return (o == null) ? "LoadImages" : o as string;
StateManager.SetProperty("methodImages", value);
        #region CreateChildControls, Render
HtmlGenericControl container = null;
HtmlGenericControl containerDivPG = null;
Image progressImage = null;
Image htmlPrevButton = null;
Image htmlNextButton = null;
HtmlGenericControl containerDiv = null;
Image photoImage = null;
public HtmlInputText txtValue = null;
public HtmlInputButton btnFind = null;
protected override void CreateChildControls()
container = new HtmlGenericControl("div");
container.ID = "photoGallery";
containerDivPG = new HtmlGenericControl("div");
htmlPrevButton = new Image();
htmlPrevButton.ID = "prevButton";
htmlPrevButton.ImageUrl = GetSource("backDisabled.png");
htmlNextButton = new Image();
htmlNextButton.ID = "nextButton";
htmlNextButton.ImageUrl = GetSource("forwardDisabled.png");
progressImage = new Image();
progressImage.ID = "progress";
progressImage.ImageUrl = GetSource("activity_indicator.gif");
containerDiv = new HtmlGenericControl("div");
photoImage = new Image();
photoImage.ID = "image";
photoImage.ImageUrl = GetSource("gray_x_button.gif");
txtValue = new HtmlInputText();
txtValue.ID = "txtValue";
btnFind = new HtmlInputButton();
btnFind.ID = "btnFind";
btnFind.Value = "Find";
StringBuilder KeyValues = new StringBuilder();
KeyValues.Append(string.Format("'{0}=' + $get('{1}').value", "txtFindValue", txtValue.ClientID));
string onClick = string.Format("executeTask({0},\"{1}\");", KeyValues.ToString(), CallbackFunctionString);
btnFind.Attributes.Add("onclick", onClick);
private string GetSource(string image)
return Page.ClientScript.GetWebResourceUrl(typeof(PhotoGalleryTask), string.Format("{0}.images.{1}", taskNamespace, image));
protected override void OnPreRender(System.EventArgs e)
if (!base.IsAsync)
protected string ControlClientID
return container.ClientID;
void RegisterScriptControl()
StringBuilder script = new StringBuilder();
script.Append("Sys.Application.add_init(function() {");
script.AppendFormat("'imageElement': $get('{0}'),", photoImage.ClientID);
script.AppendFormat("'prevElement': $get('{0}'),", htmlPrevButton.ClientID);
script.AppendFormat("'nextElement': $get('{0}'),", htmlNextButton.ClientID);
script.AppendFormat("'progressElement': $get('{0}'),", progressImage.ClientID);
script.AppendFormat("'forwardDisabledUrl': '{0}',", GetSource("forwardDisabled.png"));
script.AppendFormat("'backwardDisabledUrl': '{0}',", GetSource("backDisabled.png"));
script.AppendFormat("'forwardUrl': '{0}',", GetSource("forward.png"));
script.AppendFormat("'backwardUrl': '{0}',", GetSource("back.png"));
script.AppendFormat("'noPhotoUrl': '{0}',", GetSource("gray_x_button.gif"));
script.Append("'images': []");
script.AppendFormat("}}, {{}}, {{}}, $get('{0}'));", ControlClientID);
System.Web.UI.ScriptManager.RegisterStartupScript(this, this.GetType(), this.ClientID + "_startup", script.ToString(), true);
/// <summary>
/// sample method used for list of images
/// </summary>
/// <param name="key">your key</param>
/// <returns>string: 'http://www.myphoto.com/01.jpg','http://www.myphoto.com/02.jpg' or string.Empty</returns>
static string LoadImages(string key)
//change with your code. This is an example.
string connectionString = ConfigurationManager.AppSettings["ConnectionDB"];
string pathFoto = ConfigurationManager.AppSettings["PhysicalPathFoto"];
string queryString = "SELECT Photo from featureclassOne,tableMany "
+ "WHERE (featureclassOne.objectid = tableMany.foreignKey) and (YourFieldName = ?)";
using (OleDbConnection connection = new OleDbConnection(connectionString))
OleDbCommand command = new OleDbCommand(queryString, connection);
command.Parameters.AddWithValue("@key", key);
string result=null;
using (OleDbDataReader reader = command.ExecuteReader())
while (reader.Read())
result += string.Format("'{0}{1}{2}",pathFoto, reader[0].ToString().Replace("\\","/"),"',");
result = result.Substring(0, result.Length - 1);
return result;
return string.Empty;
public override void ExecuteTask()
Results = null;
if (Input == null) return;
NameValueCollection keyValColl = Input as NameValueCollection;
string stxtFindValue = keyValColl["txtFindValue"] as string;
string sWhere = string.Format("{0} = {2}{1}{2}", fieldName, stxtFindValue,"'");
ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisresource = Map.PrimaryMapResourceInstance;
IQueryFunctionality queryFunctionality = (IQueryFunctionality)gisresource.CreateFunctionality(typeof(IQueryFunctionality), null);
SpatialFilter spatialfilter = new SpatialFilter();
spatialfilter.ReturnADFGeometries = true;
spatialfilter.MaxRecords = 1;
spatialfilter.WhereClause = sWhere;
System.Data.DataTable datatable = queryFunctionality.Query(null, LayerId, spatialfilter);
if ((datatable == null)  (datatable.Rows.Count == 0))
NoSelectionsTaskResult setResultsTaskResult = new NoSelectionsTaskResult((datatable == null) ? "Error!" : "No found value!");
Results = setResultsTaskResult;
SetResults(ref datatable, null, LayerId, true);
TaskResults.DisplayResults(null, null, null, this.Results);
MethodInfo dynMethod = GetType().GetMethod(MethodImages, BindingFlags.NonPublic  BindingFlags.Static);
object o = dynMethod.Invoke(this, new object[] { stxtFindValue });
CallbackResults.Add(CallbackResult.CreateJavaScript(string.Format("$find('{0}').set_images([{1}]);", ControlClientID, o)));
catch (Exception ex)
UnableToSetResultsTaskResult setResultsTaskResult = new UnableToSetResultsTaskResult(this.Title, ex.Message);
Results = setResultsTaskResult;
private ITaskResultsContainer TaskResults
if ((m_TaskResults == null) && (TaskResultsContainers[0] != null))
m_TaskResults = ESRI.ArcGIS.ADF.Web.UI.WebControls.Utility.FindControl(TaskResultsContainers[0].Name, Page) as ITaskResultsContainer;
return m_TaskResults;
public override string GetCallbackResult()
NameValueCollection keyValColl = CallbackUtility.ParseStringIntoNameValueCollection(CallbackEventArgument);
Input = keyValColl;
return base.GetCallbackResult();
public override List<GISResourceItemDependency> GetGISResourceItemDependencies()
throw new System.NotImplementedException();

Here you can download the source code http://resources.esri.com/arcgisserver/adf/dotnet/index.cfm?fa=codeGalleryDetails&scriptID=16219


For Adalmj:
I used the same logic as this sample
and from the task I pass information to maptips

"if (result.StreetView != '')" +
                       "      {{" +
                              "mapTips.add_expanded(ExpandMapTips);" +
                              "mapTips.set_width(405);" +
                              "mapTips.set_maxheight(350);" +
                              "mapTips.set_contentTemplate('<span><b><a href=\'{{@StreetView}}\' target=\'_blank\'>Street View</a><br><br><a href=\'{{@GoogleMaps}}\' target=\'_blank\'>Google Maps</a></b></span><div onclick=\'var coords = new GLatLng({{@Lat}},{{@Lon}});panoramaOptions = {{ latlng:coords }};var myPano = new GStreetviewPanorama($get(""{{@Id}}""), panoramaOptions);\' name=\'{{@Id}}\' id=\'{{@Id}}\' style=\'width: 400px; height: 300px\'></div>');" +

4 commenti:

Adamlj ha detto...

How did you get the Google street view into your viewer? It is a task somewhere?

Anonimo ha detto...

Could you provide some basic steps needed to make this work without the mapviewer application? Or if that is possible at all. Thanks!

Augusto ha detto...

Salve Ing. Ciavarella. Vorrei integrare questo task in una applicazione web creata con il wizard di ArcGis Server. E' possibile farlo invece di utilizzare l'applicazione NITK Map Viewer? Se si, potrei sapere in che modo? La ringrazio in attesa di risposta.

Il mio indirizzo email: a_ielo@virgilio.it


Ing. Domenico Ciavarella ha detto...

For 'Anonimo' and Augusto.

This is a simple task. Instead of inheriting from ResultProducingTask you have to inherit from FloatingPanelTask.
While in ExecuteTask, instead of sending setResultsTaskResult, use the classic code for tasks SimpleTaskResult str = new SimpleTaskResult(heading, detail);

see Simple Task