リフレクションとJson


ようやっと続き

リフレクション

ソフトウェアは車みたいなもので目的地へは連れて行ってくれるが目的地は自分で探す必要がある。
コロプレスマップ作って共有するだけなら高い金払ういみないし、低レベルAPIの自由度が欲しいなぁ。

シンボルやレンダラをJSON化する試みだが他にも使いどころはありそう。
デリゲート作ってインタフェース個別に値保持の処理と不要プロパ名設定が必要かなぁ。
あと親が取れるプロパがあったら無限ループするな。

ちなみにPythonからJson化できるかと思ったがシンボル周りはさっぱりだった。
内部的にはなんか持ってんだろうけどAPIが足りない。

public static void ArcGisTest()
{
  string mxdPath = @"C:\data\てすと.mxd";

  using (ComReleaser com = new ComReleaser())
  {
    IMapDocument mapDoc = new MapDocumentClass();
    com.ManageLifetime(mapDoc);//解放をマーク
    mapDoc.Open(mxdPath, null);

    var map = mapDoc.get_Map(0);
    com.ManageLifetime(map);
    var layer = map.get_Layer(0);
    com.ManageLifetime(layer);

    ArcGisDict dict = new ArcGisDict();
    dict.Type = typeof(FeatureLayerClass);

    dict.SetDict(layer);

    var json = Newtonsoft.Json.JsonConvert.SerializeObject(dict.Dictionary);
    Console.WriteLine(json);

  }//enmd com
}//end method

辞書化実体

public class ArcGisDict
{
  public Dictionary<string, object> Dictionary
  {
    get;
    set;
  }//end prop

  /// <summary>
  /// このインスタンスが対象とするタイプ
  /// </summary>
  public Type Type
  {
    get;
    set;
  }//end prop

  public List<Type> ValueTypes
  {
    get;
    set;
  }//end prop

  public List<Type> ArcGisTypes
  {
    get;
    set;
  }//end prop


  public ArcGisDict()
  {
    var valTypes = new List<Type>();
    valTypes.Add(typeof(Int16));
    valTypes.Add(typeof(Int32));
    valTypes.Add(typeof(Int64));
    valTypes.Add(typeof(decimal));
    valTypes.Add(typeof(float));
    valTypes.Add(typeof(double));
    valTypes.Add(typeof(UInt16));
    valTypes.Add(typeof(UInt32));
    valTypes.Add(typeof(UInt64));
    valTypes.Add(typeof(string));
    valTypes.Add(typeof(bool));
    valTypes.Add(typeof(DateTime));

    this.ValueTypes = valTypes;

    var arcTypes = new List<Type>();
    arcTypes.Add(typeof(ILayer));
    arcTypes.Add(typeof(FeatureLayerClass));

    arcTypes.Add(typeof(SimpleRendererClass));
    arcTypes.Add(typeof(UniqueValueRendererClass));

    arcTypes.Add(typeof(SimpleMarkerSymbolClass));
    arcTypes.Add(typeof(PictureMarkerSymbolClass));

    arcTypes.Add(typeof(SimpleLineSymbolClass));
    arcTypes.Add(typeof(SimpleFillSymbolClass));

    arcTypes.Add(typeof(RgbColorClass));
    this.ArcGisTypes = arcTypes;
  }


  public void SetDict(object obj)
  {
    var type = this.Type;
    //if (!t.IsInstanceOfType(obj))
    //    throw new ArgumentException("引数は指定された型のインスタンスではありません。");
    this.Dictionary = new Dictionary<string, object>();

    var valTypes = this.ValueTypes;
    var arcGisTypes = this.ArcGisTypes;

    List<string> propNames = new List<string>();
    Type[] interfaces = type.GetInterfaces();

    foreach (var t in interfaces)
    {
      var props = t.GetProperties();

      //プロパティのループ
      foreach (sys.PropertyInfo p in props)
      {
        try
        {
          if (!p.CanRead)
            continue;

          //パラメータ付の場合は飛ばす。
          var propParams = p.GetIndexParameters();
          if (propParams != null && propParams.Length > 0)
            continue;

          //一度セットされてれば以後無視
          if (this.Dictionary.ContainsKey(p.Name))
            continue;

          //列挙
          if (p.PropertyType.IsSubclassOf(typeof(Enum)))
          {
            var val = (Enum)p.GetValue(obj, null);

            this.Dictionary.Add(p.Name, val.ToString("G"));
            continue;
          }

          //値型
          if (valTypes.Contains(p.PropertyType))
          {
            var val = p.GetValue(obj, null);

            this.Dictionary.Add(p.Name, val);
            continue;
          }//end if
          else
          {
            var val = p.GetValue(obj, null);

            foreach (var arcType in arcGisTypes)
            {
              //if (!arcType.IsInstanceOfType(val))
              if (!isArcType(arcType, val))
                continue;
              //ArcGISの値セット
              var propVal = new ArcGisDict();
              propVal.ArcGisTypes = arcGisTypes;
              propVal.ValueTypes = valTypes;
              propVal.Type = arcType;
              propVal.SetDict(val);

              this.Dictionary.Add(p.Name, propVal.Dictionary);
              break;
            }//end loop type
          }//end if
        }
        catch (Exception ex)
        {
          Debug.Print(ex.Message);
          Debug.Print(ex.StackTrace);
        }
      }//end loop

    }//end loop
  }//end method

  private bool isArcType(Type t, object obj)
  {
    if (t.IsInterface && t.IsInstanceOfType(obj))
      return true;

    var interfaces = t.GetInterfaces();
    if (interfaces == null || interfaces.Length < 1)
      return false;

    foreach (var inf in interfaces)
    {
      if (!inf.IsInstanceOfType(obj))
        return false;
    }
    return true;
  }//end method

}//end class
カテゴリー: 開発 タグ: パーマリンク