Lihat kode c # di bawah ini. (Diperbarui: refactored)
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))
Kedua sisi operator OR identik.Untuk metode GetDir, parameter kedua dan ketiga harus kode pabrik dari sistem koordinat geografis dasar dari sumber dan sistem koordinat target. Untuk sistem koordinat yang diproyeksikan, antarmuka ISpatialReference akan memberikan kode pabrik dari sistem koordinat tetapi bukan sistem koordinat geografis dasar. Misalnya, NAD27 Zona 12 sama dengan kode pabrik 26712 dan sistem koordinat geografis dasar adalah 4267 (NAD27 geografis). Parameter 'out' dari geoTrans.GetSpatialReferences (keluar dariSR, out toSR); hanya akan menjadi kode pabrik untuk sistem koordinat geografis.
Anda bisa mendapatkan sistem koordinat geografis dasar dari sistem koordinat yang diproyeksikan dengan membuat objek sistem koordinat yang diproyeksikan dan kemudian mendapatkan geogr dasarnya. coord sys kode pabrik.
Kode di bawah ini akan membantu. Bilangan bulat untuk sistem koordinat target dan asli harus disediakan untuk membuat objek dengan benar. Dan kode mengharapkan tipe (diproyeksikan vs geografis) dari sistem koordinat sumber / target telah disediakan.
sumber
Metode paling sederhana adalah menulis skrip python (arcpy) dan memaparkannya bagaimana toolbox di arcobjects. Kemudian Anda menggunakan arcobjects dan memanggil alat ini.
Di arcpy Anda memiliki ListTransformations ( http://resources.arcgis.com/en/help/main/10.1/index.html#/ListTransformations/018v0000001p000000/ )
toolbox alat terbuka dengan kotak alat:
Dalam arcobjects:
Jadi, Anda hanya memiliki transformasi datum yang tersedia untuk tingkat input
Berita: sekarang di ArcGIS Server 10.3 API Rest Anda telah tersedia di GeometryService -> Project FindTransformasi yang mengembalikan daftar transformasi geografis yang berlaku yang harus digunakan ketika memproyeksikan geometri dari referensi spasial input ke referensi spasial output
sumber