パーソナルジオデータベース上のラスタカタログをaxMapControlに表示

ラスタカタログ名は「cat」

間違ったコードを修正

IWorkspaceFactory2 wsf = new ESRI.ArcGIS.DataSourcesGDB.AccessWorkspaceFactoryClass();
IRasterWorkspaceEx ws = (IRasterWorkspaceEx)wsf.OpenFromFile(@"f:\img3.mdb", 0);
IRasterCatalog cat  = ws.OpenRasterCatalog("cat");
IGdbRasterCatalogLayer rastercatalogLayer = new GdbRasterCatalogLayerClass();
rastercatalogLayer.Setup((ITable)cat);
axMapControl1.AddLayer((ILayer)rastercatalogLayer);

間違ったコード

IWorkspaceFactory2 wsf = new ESRI.ArcGIS.DataSourcesGDB.AccessWorkspaceFactoryClass();
IRasterWorkspaceEx ws = (IRasterWorkspaceEx)wsf.OpenFromFile(@"f:\img3.mdb", 0);
IRasterDataset rasterDataset = ws.OpenRasterDataset("rc");
IRasterLayer rasterLayer = new RasterLayer();
rasterLayer.CreateFromDataset(rasterDataset);
axMapControl1.AddLayer(rasterLayer);
IWorkspaceFactory2 wsf = new ESRI.ArcGIS.DataSourcesGDB.AccessWorkspaceFactoryClass();
IRasterWorkspaceEx ws = (IRasterWorkspaceEx)wsf.OpenFromFile(@"f:\img3.mdb", 0);
IRasterCatalog cat  = ws.OpenRasterCatalog("cat");
IGdbRasterCatalogLayer rastercatalogLayer = new GdbRasterCatalogLayerClass();
rastercatalogLayer.Setup((ITable)cat);
axMapControl1.AddLayer((ILayer)rastercatalogLayer);



IRasterDataset rasterDataset = ws.OpenRasterDataset("rc");
IRasterLayer rasterLayer = new RasterLayer();
rasterLayer.CreateFromDataset(rasterDataset);
axMapControl1.AddLayer(rasterLayer);

ちなみにファイルジオデータベースでは以下?未確認

IWorkspaceFactory2 workspaceFactory = new FileGDBWorkspaceFactoryClass();
IRasterWorkspaceEx ws = (IRasterWorkspaceEx)workspaceFactory.OpenFromFile(FGDBPath,0);
以下省略

How to access raster workspaces

パーソナルジオデータベースにラスタカタログを作成

ArcMap上で複数のラスタデータを同一のレイヤとして扱うためにパーソナルジオデータベースにラスタカタログを作成。
※ArcMapからはRasterliteを塚なかったため!

ArcMap10.4のカタログ上でパーソナルジオデータベース「newimg.mdb」を新規作成

clip_2

同様にカタログ上で作成したデータベースを選択してラスタカタログを新規作成

clip_5

名称以外はデフォルトの設定

clip_5

clip_6

以上でラスタカタログの作成は終了

次に作成したラスタカタログにラスタデータセットを追加

カタログ上で先ほど作成したカタログを選択してラスタデータセットの読み込みを選択

clip_7

対象の画像ファイルを選択
※もちろんワールドファイルはあるものとする

スクリーンショット 2016-10-31 14.54.30

spatialiteにイメージをimport(gdal_transfer編)

rasterlite2にこてんぱにやられたので今回はgdal_transferを試す。

参考にしたのはgdal_translateのリファレンスとRasterlite – Rasters in SQLite DB

今回使用したGDAL関連のモジュールはQGISをインストールした際にC:\OSGeo4W\binにインストールしたファイル。

rasterlite2編と同様に「空間データを使うために必要なテーブルを作成」までを実行。

各画像をインポート

C:\work\pasco>gdal_translate -of Rasterlite 2135.jpg RASTERLITE:work.sqlite,table=source -co DRIVER=JPEG
Input file size is 5000, 3750
0...10...20...30...40...50...60...70...80...90...100 - done.
C:\work\pasco>gdal_translate -of Rasterlite 2136.jpg RASTERLITE:work.sqlite,table=source -co DRIVER=JPEG
Input file size is 5000, 3750
0...10...20...30...40...50...60...70...80...90...100 - done.
C:\work\pasco>gdal_translate -of Rasterlite 2137.jpg RASTERLITE:work.sqlite,table=source -co DRIVER=JPEG
Input file size is 5000, 3750
0...10...20...30...40...50...60...70...80...90...100 - done.

Creating internal overviews

C:\work\pasco>gdaladdo RASTERLITE:work.sqlite,table=source 2 4 8 16
0...10...20...30...40...50...60...70...80...90...100 - done.
0...10...20...30...40...50...60...70...80...90...100 - done.
0...10...20...30...40...50...60...70...80...90...100 - done.
0...10...20...30...40...50...60...70...80...90...100 - done.

Creating internal overviewsは以下のほうがよさそうなので改めてGDAL1.10以上バージョンを実行
Creating internal overviews with options (GDAL 1.10 or later):

C:\work\pasco>gdaladdo RASTERLITE:work.sqlite,table=source 2 4 8 16 --config RASTERLITE_OVR_OPTIONS DRIVER=JPEG,COMPRESS
=JPEG,PHOTOMETRIC=YCbCr
Warning 6: Unexpected option 'COMPRESS' for driver 'JPEG'
Warning 6: Unexpected option 'PHOTOMETRIC' for driver 'JPEG'
0...10...20...30...40...50...60...70...80...90...100 - done.
Warning 6: Unexpected option 'COMPRESS' for driver 'JPEG'
Warning 6: Unexpected option 'PHOTOMETRIC' for driver 'JPEG'
0...10...20...30...40...50...60...70...80...90...100 - done.
Warning 6: Unexpected option 'COMPRESS' for driver 'JPEG'
Warning 6: Unexpected option 'PHOTOMETRIC' for driver 'JPEG'
0...10...20...30...40...50...60...70...80...90...100 - done.
Warning 6: Unexpected option 'COMPRESS' for driver 'JPEG'
Warning 6: Unexpected option 'PHOTOMETRIC' for driver 'JPEG'
0...10...20...30...40...50...60...70...80...90...100 - done.
Creating internal overviews with options (GDAL 1.10 or later):

Cleaning internal overviews :

C:\work\pasco>gdaladdo -clean RASTERLITE:work.sqlite,table=source

Creating external overviews in a .ovr file:

C:\work\pasco>gdaladdo -ro RASTERLITE:work.sqlite,table=source 2 4 8 16
ERROR 6: Cannot add external overviews to a dataset with internal overviews
Overview building failed.

「Creating external overviews in a .ovr file:」はエラーが発生したが、QGISで閲覧すると十分なスピードが確保できた。

以上

spatialiteにイメージをimport(rasterlite2 その2 結局失敗編)

前回は「rl2tool CREATE」でエラーが発生した今回はエラーが発生しないようにテーブル「strict_resolution」のNOT NULL制約の付いている項目にdefault 0を設定。

CREATE TABLE raster_coverages (
coverage_name TEXT NOT NULL PRIMARY KEY,
title TEXT NOT NULL DEFAULT '*** missing Title ***',
abstract TEXT NOT NULL DEFAULT '*** missing Abstract ***',
sample_type TEXT NOT NULL DEFAULT '*** undefined ***',
pixel_type TEXT NOT NULL DEFAULT '*** undefined ***',
num_bands INTEGER NOT NULL DEFAULT 1,
compression TEXT NOT NULL DEFAULT 'NONE',
quality INTEGER NOT NULL DEFAULT 100,
tile_width INTEGER NOT NULL DEFAULT 512,
tile_height INTEGER NOT NULL DEFAULT 512,
horz_resolution DOUBLE NOT NULL,
vert_resolution DOUBLE NOT NULL,
srid INTEGER NOT NULL,
nodata_pixel BLOB NOT NULL,
palette BLOB,
statistics BLOB,
geo_minx DOUBLE,
geo_miny DOUBLE,
geo_maxx DOUBLE,
geo_maxy DOUBLE,
extent_minx DOUBLE,
extent_miny DOUBLE,
extent_maxx DOUBLE,
extent_maxy DOUBLE,
strict_resolution INTEGER NOT NULL DEFAULT 0,
mixed_resolutions INTEGER NOT NULL DEFAULT 0,
section_paths INTEGER NOT NULL DEFAULT 0,
section_md5 INTEGER NOT NULL DEFAULT 0,
section_summary INTEGER NOT NULL DEFAULT 0,
is_queryable INTEGER,
red_band_index INTEGER,
green_band_index INTEGER,
blue_band_index INTEGER,
nir_band_index INTEGER,
enable_auto_ndvi INTEGER,
CONSTRAINT fk_rc_srs FOREIGN KEY (srid) REFERENCES spatial_ref_sys (srid))

今度はrl2too.を使わずに「Tutorial: building and testing the Planet Earth sample – full SQL」
に従ってインポート。

「空間データを使うために必要なテーブルを作成」までは前回で終了している。

Coverage作成

sqlite> SELECT RL2_CreateCoverage('Test', 'UINT8', 'RGB', 3, 'JPEG', 80, 512, 512, 2451, 0.0138888889);
1
sqlite> SELECT RL2_LoadRaster('Test', '0108.jpg');
Importing: 0108.jpg
------------------
    Image Size (pixels): 5000 x 3750
                   SRID: -1
       LowerLeft Corner: X=-63999.92 Y=-36600.08
      UpperRight Corner: X=-63199.92 Y=-36000.08
       Pixel resolution: X=0.16 Y=0.16
INSERT INTO sections; sqlite3_step() error: Test_sections.geometry violates Geometry constraint [geom-type or SRI
llowed]
0
sqlite> SELECT RL2_LoadRaster('Test', '0108.jpg', 1, 2451);
Importing: 0108.jpg
------------------
    Image Size (pixels): 5000 x 3750
                   SRID: 2451
       LowerLeft Corner: X=-63999.92 Y=-36600.08
      UpperRight Corner: X=-63199.92 Y=-36000.08
       Pixel resolution: X=0.16 Y=0.16
  ----------
    Pyramid levels successfully built for: 0108
1
sqlite> select RL2_Pyramidize('test');
1
sqlite> select RL2_SetCoverageInfos('test','test1','hello');
1
sqlite> .quit

とりあえずエラーが発生せずに終了

動作確認のためにwmsliteを実行してみると

wmslite -db test.sqlite

======================================================
              WmsLite server startup
======================================================
         SQLite version: 3.8.5
     SpatiaLite version: 4.2.0
    RasterLite2 version: 1.0.0-rc0
======================================================
the DB "test.sqlite" doesn't contain any valid Raster Coverage
wmslite server shutdown in progress
wmslite shutdown completed ... bye bye

「doesn’t contain any valid Raster Coverage」失敗のようだ!

wmsliteのソースを追えば問題箇所が判明するかもしれないが、とりあえず一旦終了して次回はGDALのTOOLで試す。

spatialiteにイメージをimport(rasterlite2 その1 失敗編)

某自治体全域の航空写真をタイル画像にしてGIS上で使用する為にspatialiteにインポートの記録(失敗談)。

当初はブログ「waigani’s diary」を参考にrasterliteを使用する予定だったが、windows版のバイナリがなくなっていたために断念。
※「waigani’s diary」は合同会社MIERUNEの方が書かれているとのことなので朝日さんでしょうか

rasterliteの後継「rasterlite2」を使用。

今回インポート対象の画像はGIOTIFFをJPEGに変換したファイル。(もちろんワールドファイルもあり)
JPEGもGEOTIFFを同様にgdalinfo.exeでファイルの詳細情報を確認できる。

gdalinfo 2135.jpg

Driver: JPEG/JPEG JFIF
Files: 2135.jpg
       2135.jgw
Size is 5000, 3750
Coordinate System is `'
Origin = (-42400.000000000000000,-48000.000000000000000)
Pixel Size = (0.160000000000000,-0.160000000000000)
Metadata:
  EXIF_BitsPerSample=8 8 8
  EXIF_ColorSpace=65535
  EXIF_Compression=1
  EXIF_DateTime=2016:02:26 13:56:17
  EXIF_Orientation=1
  EXIF_PhotometricInterpretation=2
  EXIF_PixelXDimension=5000
  EXIF_PixelYDimension=3750
  EXIF_PlanarConfiguration=1
  EXIF_ResolutionUnit=2
  EXIF_SamplesPerPixel=3
  EXIF_Software=Adobe Photoshop CS5.1 Windows
  EXIF_XResolution=(72)
  EXIF_YResolution=(72)
Image Structure Metadata:
  COMPRESSION=JPEG
  INTERLEAVE=PIXEL
  SOURCE_COLOR_SPACE=YCbCr
Corner Coordinates:
Upper Left  (  -42400.000,  -48000.000)
Lower Left  (  -42400.000,  -48600.000)
Upper Right (  -41600.000,  -48000.000)
Lower Right (  -41600.000,  -48600.000)
Center      (  -42000.000,  -48300.000)
Band 1 Block=5000x1 Type=Byte, ColorInterp=Red
  Overviews: 2500x1875, 1250x938, 625x469
  Image Structure Metadata:
    COMPRESSION=JPEG
Band 2 Block=5000x1 Type=Byte, ColorInterp=Green
  Overviews: 2500x1875, 1250x938, 625x469
  Image Structure Metadata:
    COMPRESSION=JPEG
Band 3 Block=5000x1 Type=Byte, ColorInterp=Blue
  Overviews: 2500x1875, 1250x938, 625x469
  Image Structure Metadata:
    COMPRESSION=JPEG

rasterlite2のサイトhttps://www.gaia-gis.it/fossil/librasterlite2から以下をダウンロード。

  • mod_rasterlite2.dll
  • http://www.gaia-gis.it/gaia-sins/rasterlite2-win-x86/mod_rasterlite2-1.0.0-rc0-win-x86.7z
    mod_rasterlite2.dllはsqliteにラスタ機能を追加する拡張モジュール。
    ※SQLITEは関数:sqlite3_create_functionを利用してSQLから呼べる関数を登録できる。
    例)SQLITE内にCoverageを作成する「SELECT RL2_CreateCoverage(): 」の「RL2_CreateCoverage」はmod_rasterlite2.dllが提供する。

  • rl2tool.exe
  • http://www.gaia-gis.it/gaia-sins/rasterlite2-win-x86/rl2tool-1.0.0-rc0-win-x86.7z
    rl2tool.exeはラスタファイルをDBに追加するためのツール。
    ※rl2tool.exeはmod_rasterlite2.dllが提供する関数をコールするためのラッパー。

作業用のディレクトリにmod_rasterlite2.dllとその関連dll、rl2tool.exe、sqlite3.exe、mod_spatialite.dllを配置。
環境変数に「SPATIALITE_SECURITY=relaxed」を設定

以降はRasterlite2のドキュメント「Tutorial: building and testing the Planet Earth sample」を参考に作業

インポート対象のDB「test.sqlite」を作成してsqliteを起動

sqlite3 work.sqlite

拡張DLLを呼び出し

sqlite> select load_extension('mod_rasterlite2');
sqlite> select load_extension('mod_spatialite');

空間データを使うために必要なテーブルを作成

sqlite> select initSpatialMetadata(1);
1
sqlite> select CreaterasterCoveragesTable();
1
sqlite> select CreateStylingTables();

Coverage作成

C:\work\pasco>rl2tool CREATE -db work.sqlite -src 2135.jpg -ext .jpg -cov test -srid 2451 -smp UINT8 -pxl RGB -cpr JPEG -res 0.0138888889

rl2_tool: request is CREATE
===========================================================
              DB path: raster.sqlite
             Coverage: test
          Sample Type: UINT8
           Pixel Type: RGB
      Number of Bands: 3
          Compression: JPEG (lossy)
  Compression Quality: 80
   Tile size (pixels): 512 x 512
                 Srid: 2451
Pixel base resolution: X=0.0138888889 Y=0.0138888889
===========================================================

     SQLite version: 3.8.5
 SpatiaLite version: 4.2.0
RasterLite2 version: 1.0.0-rc0

sqlite3_step() error: INSERT INTO raster_coverages "NOT NULL constraint failed: raster_coverages.strict_resolution"
restoring the DB to its previous state (ROLLBACK)

※上記で指定した解像度は間違っている

raster_coveragesテーブルの項目「strict_resolution」にはnullは設定できないとエラーが発生。

raster_coveragesの定義を確認すると、確かにstrict_resolutionはNOT NULLになっている。

※raster_coveragesテーブルは先ほど実行したCreaterasterCoveragesTableで作成しており、mod_spatialite.dllが提供する関数
※「rl2tool CREATE」は内部では mod_rasterlite2.dllのRL2_CreateCoverageを呼んでいる。
関数RL2_CreateCoverageの実装を確認すると確かにstrict_resolutionには何も設定していない。

よってエラーは避けられない

MapDocumentClassのコンストラクタはないと言われました

このコードをコンパイルすると

IMapDocument mapdoc = new MapDocumentClass();

エラーが表示された

The type 'ESRI.ArcGIS.Carto.MapDocumentClass' has no constructors defined

いやいやほかのプロジェクトでは全く問題ないしと思って調べると

stackoverflowさんに答えがありました
Interop type cannot be embedded
問題となったクラスのアセンブリの参照設定のプロパティ「embed Interrop Type」をfalseにすればよいらしい
img

※以下のようにコードを修正してもよいみたい

IMapDocument mapdoc = new MapDocument();