マッププラグインの機能を利用することで、緯度経度と割り当てられた投影座標系のXYの変換が可能になります。
ここではそれをアプリケーション側から利用する方法を紹介します。
C++(CFx) の場合
GEODATAオブジェクトが利用可能なときは、transformToLonLatAlt() や transformFromLonLatAlt() で緯度経度とXYの変換が可能です。
#include "stdafx.h"
#include "FXHeaders.h" // ほとんどのCFxのヘッダが入っている
#include "DbGeoData.h" // GEODATA オブジェクト
//===========================================================
// JDTESTCmd Class
//===========================================================
int JDTESTCmd::Execute(CFxCommandContext* pCmdCtx)
{
CFxDocumentPtr doc = pCmdCtx->GetFxDocument();
CFxUserIO* io = doc->GetFxUserIO();
CFxDatabasePtr db = doc->GetFxDatabase();
CFxString prompt;
OdResult rt;
// 座標系が用意できているか
OdDbObjectId geoid;
if (oddbGetGeoDataObjId(db, geoid) != eOk)
{
io->Write(L"\nNo GEODATA.");
return RTNORM;
}
OdDbGeoDataPtr geodata = geoid.safeOpenObject();
OdGePoint3d p1;
OdGePoint3d p2;
int rc = io->GetPoint(L"\n位置を指定 : ", nullptr, nullptr, &p1);
if (rc == RTNORM)
{
rt = geodata->transformToLonLatAlt(p1, p2);
prompt.format(L"\n(%f,%f,%f) - (%f,%f,%f) ", p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
io->Write(prompt);
OdError e(rt);
io->Write(e.description());
}
rc = io->GetString(false, L"\n経度,緯度を指定 : ", L"", &prompt);
if (rc == RTNORM)
{
rc = io->GetUnitsFormatter()->StringToPoint(p1, prompt);
if (rc == RTNORM)
{
rt = geodata->transformFromLonLatAlt(p1,p2);
prompt.format(L"\n(%f,%f,%f) - (%f,%f,%f)", p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
io->Write(prompt);
OdError e(rt);
io->Write(e.description());
}
}
return RTNORM;
}
transformFromLonLatAlt() の戻り値 XYZ の Z がおかしいとき(緯度の値がそのまま入っていることがある)は無視してください。
OdGePoint3dを受け渡す関数と、 transformFromLonLatAlt(lon, lat, alt, x, y, z) のように、経度(longitude)、緯度(lattitude)、標高/水深(Altitude) と、投影座標系のX,Y,Z 値を受け渡す関数の2通りがあります。
実行結果
: JDTEST
No GEODATA.
:
座標系が割り当てられました: PROJCS: "WGS_1984_Web_Mercator_Auxiliary_Sphere"
: JDTEST
位置を指定 :
(-17683.641550,6711173.100805,0.000000) - (-0.158855,51.505335,0.000000)
エラーはありません
経度,緯度を指定 : 0.15,50.0
(0.150000,50.000000,0.000000) - (16697.923619,6446275.841017,50.000000)
エラーはありません
C# (ARES マネージド API) の場合
GEODATA オブジェクトが利用可能でなければなりません。
POSITIONMARKER 図形を図面に追加して、緯度経度を読み取ったり、緯度経度を設定してXY値を読み取る必要があります。
using Teigha.ApplicationServices;
using Teigha.DatabaseServices;
using Teigha.EditorInput;
using Teigha.Geometry;
using Teigha.Runtime;
using CADException = Teigha.Runtime.Exception;
namespace geodata
{
public class Class1
{
[CommandMethod("TESTCS")]
public void cmdTestCS()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var ed = doc.Editor;
var db = doc.Database;
try
{
var id = db.GeoDataObject;
ed.WriteMessage("\nGEODATA [{0}]", id.Handle.ToString());
}
catch (CADException)
{
ed.WriteMessage("\nNo GEODATA.");
return;
}
var ret = ed.GetPoint("Specify location");
if(ret.Status != PromptStatus.OK )
{
return;
}
var model = db.CurrentSpaceId.GetObject(OpenMode.ForWrite) as BlockTableRecord;
GeoPositionMarker marker = new GeoPositionMarker();
marker.Position = ret.Value;
model.AppendEntity(marker);
Point3d rts = marker.GeoPosition;
ed.WriteMessage("\n{0} -> {1}", ret.Value, rts);
var ret2 = ed.GetString("経度,緯度を入力");
if (ret2.Status == PromptStatus.OK)
{
string text = ret2.StringResult;
int len = text.IndexOf(",");
double lon = System.Convert.ToDouble(text.Substring(0, len));
double lat = System.Convert.ToDouble(text.Substring(len + 1));
Point3d geo = new Point3d(lon,lat,0);
marker.GeoPosition = geo;
rts = marker.Position;
ed.WriteMessage("\n{0} -> {1}", geo, rts);
}
marker.Erase();
}
}
}
緯度経度からXYZに変換したときに、 Z がおかしいとき(緯度の値がそのまま入っていることがある)は無視してください。
実行結果
: TESTCS
GEODATA [10E]
Specify location: »
(15086629.5460905,4121448.60999969,0) -> (135.525499071023,34.6871623638417,0)
経度,緯度を入力: » 135.5255,34.6871
(135.5255,34.6871,0) -> (15086629.6495038,4121440.16715828,34.6871)
LISP の場合
ARES LISPには、GEODATA オブジェクトやPOSITIONMARKER図形を利用する方法はありません。
GEODATAやPOSITIONMARKERをオートメーションインタフェースで利用する方法がない。
緯度経度とXYZ座標を変換するLISP関数はない。