MongoDBを試す


点のみの時に試してはいるが2.4以降はGeoJsonが格納検索できるので試してみる。
DB性能以前に描画性能の方がまいってしまうので複雑な使い方がしずらいこともあり(Map-Reduce除く)
地図的にはタイル画像格納程度しか使い道が考え付かないけれども実験と今後の為。

マニュアルは下記
http://docs.mongodb.org/manual/reference/operator/query-geospatial/

http://docs.mongodb.org/manual/administration/indexes-geo/

とりあえずSQL Serverと同じようなことをやらせたいので、Win機に放り込む。

SQL Serverから輸入するのでSQLGeometry⇒Jsonを適当に書く ( とりあえずポリゴンのみ )

カンマで切ったりしてないので更新した、下記を参照
GeoJson化

以下不完全なコード

if (!geom.STIsValid().Value)
  geom.MakeValid();

var type = geom.STGeometryType().Value;

StringBuilder sb = new StringBuilder();

sb.AppendFormat("{{\"type\": \"{0}\", \"coordinates\": ", type);

if (type == "MultiPolygon" || type == "Polygon")
{
  if (type == "MultiPolygon")
    sb.Append("[");

  for (int i = 0; i < geom.STNumGeometries().Value; i++)
  {
    var ngeom = geom.STGeometryN(i + 1);
    sb.Append("[");

    List<SqlGeometry> lstGeom = new List<SqlGeometry>();
    lstGeom.Add(ngeom.STExteriorRing());
    for (int ir = 0; ir < ngeom.STNumInteriorRing().Value; ir++)
    {
      var ring = ngeom.STInteriorRingN(ir + 1);
      lstGeom.Add(ring);
    }

    foreach (var ring in lstGeom)
    {
      sb.Append("[");
      SqlGeometry pt = ring.STPointN(1);
      sb.AppendFormat("[{0},{1}]", pt.STX.Value, pt.STY.Value);

      for (int j = 1; j < ring.STNumPoints().Value; j++)
      {
        pt = ring.STPointN(j + 1);
        sb.AppendFormat(",[{0},{1}]", pt.STX.Value, pt.STY.Value);
      }//end point loop
      if (pt.STX.Value != ring.STPointN(1).STX.Value ||
          pt.STY.Value != ring.STPointN(1).STY.Value)
      {
        sb.AppendFormat(",[{0},{1}]", ring.STPointN(1).STX.Value, ring.STPointN(1).STY.Value);
      }
      sb.Append("]");
    }

    sb.Append("]");
  }//end geom loop
  //sb.Append("]");

  if (type == "MultiPolygon")
    sb.Append("]");

Mongo C#ドライバいれてコレクションとったらドキュメントとして保存。

チュートリアル
http://docs.mongodb.org/ecosystem/tutorial/use-csharp-driver/

JsonからParse出来るのでDataRowをJson化 (Geometry:オブジェクト以外は列名:値)

var bson = BsonDocument.Parse(json);

入ったら空間インデックスつける

db.これくしょん.ensureIndex( { "Geometry": "2dsphere" })

エラーが出る…市区町村界入れてみたが、いくつかエラーになった。
原因は調査中だが道路一本で境界があり、頂点が変に重なる部分があるのが原因?
結構ピーキーな感じ(検索条件も始終端一致必須だし)

{ SIKUCHOSON: “紫波町” }
{ SIKUCHOSON: “船橋市” }
{ SIKUCHOSON: “四街道市” }….

エラー出るのをコレクションから除外して、検索確認(点)

db.これくしょん.find(
{ Geometry: { $geoIntersects:
     { $geometry: { 
         type: "Point", 
         coordinates: [ 135, 35 ] 
     } } 
 } })

エラー出るのをコレクションから除外して、検索確認(面)

db.jpn.find(
{ Geometry: { $geoIntersects:
     { $geometry: { 
         type: "Polygon", 
         coordinates: [ [ [ 134.5 , 34.5 ] , [ 135.5 , 34.5 ] , [ 135.5 , 35.5 ] , [ 134.5 , 35.5 ] , [134.5 , 34.5 ] ] ]
     } } 
 } })

今日はここまで、やはり暫定の点格納とタイル以外はやはりまだ考えない方がよいかな.。

カテゴリー: 開発, 設計 タグ: パーマリンク