Vea el código C # a continuación. (Actualizado: refactorizado)
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ESRI.ArcGIS.Geometry;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Framework;
namespace HansenAddin
{
public class PickGeoTransButton : ESRI.ArcGIS.Desktop.AddIns.Button
{
public PickGeoTransButton()
{
}
protected override void OnClick()
{
try
{
// let user choose a transformation for projecting from featureclass's spatial ref
// into the dataframe's spatial ref.
var featClass = ((IFeatureLayer)ArcMap.Document.FocusMap.get_Layer(0)).FeatureClass;
var fromSR = ((IGeoDataset)featClass).SpatialReference;
var toSR = ArcMap.Document.FocusMap.SpatialReference;
IGeoTransformation geoTrans;
esriTransformDirection direction;
ChooseGeotrans(fromSR, toSR, ArcMap.Application.hWnd, out geoTrans, out direction);
if (geoTrans != null)
{
MessageBox.Show(String.Format("{0} \n{1} \n{2} \n{3}", geoTrans.Name, fromSR.Name, toSR.Name, direction));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public static void ChooseGeotrans(ISpatialReference fromSR, ISpatialReference toSR, int hWnd,
out IGeoTransformation geoTrans, out esriTransformDirection direction)
{
geoTrans = null;
direction = esriTransformDirection.esriTransformForward;
var list = GetTransformations(fromSR, toSR);
if (list.Count == 0)
{
MessageBox.Show(String.Format("No geotransforms to go from {0} to {1}", fromSR.Name, toSR.Name));
return;
}
IListDialog dlg = new ListDialogClass();
foreach (IGeoTransformation gt in list)
dlg.AddString(gt.Name);
if (dlg.DoModal("Choose a Geotransformation", 0, hWnd))
{
geoTrans = list[dlg.Choice];
direction = GetDir(geoTrans, fromSR, toSR);
}
}
public static List<IGeoTransformation> GetTransformations(ISpatialReference fromSR, ISpatialReference toSR)
{
int fromFactcode = GetGCSFactoryCode(fromSR);
int toFactcode = GetGCSFactoryCode(toSR);
var outList = new List<IGeoTransformation>();
// Use activator to instantiate arcobjects singletons ...
var type = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment");
var srf = Activator.CreateInstance(type) as ISpatialReferenceFactory2;
var gtSet = srf.CreatePredefinedGeographicTransformations();
gtSet.Reset();
for (int i = 0; i < gtSet.Count; i++)
{
ISpatialReference fromGcsSR;
ISpatialReference toGcsSR;
var geoTrans = (IGeoTransformation)gtSet.Next();
geoTrans.GetSpatialReferences(out fromGcsSR, out toGcsSR);
if ((fromGcsSR.FactoryCode == fromFactcode && toGcsSR.FactoryCode == toFactcode) ||
(fromGcsSR.FactoryCode == toFactcode && toGcsSR.FactoryCode == fromFactcode))
{
outList.Add(geoTrans);
}
}
return outList;
}
private static esriTransformDirection GetDir(IGeoTransformation geoTrans, ISpatialReference sr1, ISpatialReference sr2)
{
int code1 = GetGCSFactoryCode(sr1);
int code2 = GetGCSFactoryCode(sr2);
ISpatialReference fromSR;
ISpatialReference toSR;
geoTrans.GetSpatialReferences(out fromSR, out toSR);
if (fromSR.FactoryCode == code1 && toSR.FactoryCode == code2)
return esriTransformDirection.esriTransformForward;
else if (fromSR.FactoryCode == code2 && toSR.FactoryCode == code1)
return esriTransformDirection.esriTransformReverse;
else
throw new Exception(String.Format("{0} does not support going between {1} and {2}",
geoTrans.Name, sr1.Name, sr2.Name));
}
private static int GetGCSFactoryCode(ISpatialReference sr)
{
if (sr is IProjectedCoordinateSystem)
return ((IProjectedCoordinateSystem)sr).GeographicCoordinateSystem.FactoryCode;
else if (sr is IGeographicCoordinateSystem)
return ((IGeographicCoordinateSystem)sr).FactoryCode;
else
throw new Exception("unsupported spatialref type");
}
protected override void OnUpdate()
{
}
}
}
if ((fromGcsSR.FactoryCode == fromFactcode && toGcsSR.FactoryCode == toFactcode) || (fromGcsSR.FactoryCode == fromFactcode && toGcsSR.FactoryCode == toFactcode))
ambos lados del operador OR son idénticos.Para el método GetDir, los parámetros segundo y tercero deben ser los códigos de fábrica de los sistemas de coordenadas geográficas base de los sistemas de coordenadas de origen y destino. Para los sistemas de coordenadas proyectadas, la interfaz ISpatialReference proporcionará el código de fábrica del sistema de coordenadas, pero no el sistema de coordenadas geográficas base. Por ejemplo, la Zona 12 de NAD27 equivale a un código de fábrica 26712 y el sistema de coordenadas geográficas base es 4267 (geográfico NAD27). Los parámetros 'out' de geoTrans.GetSpatialReferences (fuera de SR, fuera de SR); solo serán códigos de fábrica para sistemas de coordenadas geográficas.
Puede obtener el sistema de coordenadas geográficas base de un sistema de coordenadas proyectado creando un objeto de sistema de coordenadas proyectado y luego obteniendo su geogr base. Código de fábrica coord sys.
El siguiente código debería ayudar. Tendrían que proporcionarse los enteros para los sistemas de coordenadas original y objetivo para crear correctamente el objeto. Y el código espera que se haya proporcionado el tipo (proyectado frente a geográfico) de los sistemas de coordenadas de origen / destino.
fuente
El método más simple es escribir una secuencia de comandos de python (arcpy) y exponerlo como toolbox en arcobjects. Luego usas arcobjects y llamas a esta herramienta.
En arcpy tienes ListTransformations ( http://resources.arcgis.com/en/help/main/10.1/index.html#/ListTransformations/018v0000001p000000/ )
herramienta de caja de herramientas expuesta con una caja de herramientas:
En arcobjects:
Por lo tanto, solo tiene disponibles transformaciones de datos para la extensión de la entrada
Noticias: ahora en ArcGIS Server 10.3 API Rest que tiene disponible en GeometryService -> Project FindTransformations que devuelve una lista de transformaciones geográficas aplicables que uno debe usar al proyectar geometrías desde la referencia espacial de entrada a la referencia espacial de salida
fuente