ホーム » C# (ページ 2)

C#」カテゴリーアーカイブ

ArcObjects メモリレイヤを追加

ArcObjectsはレイヤの扱いが直観的ではなく忘れやすい。

以下ではポリゴン、EPSG=2451のメモリレイヤを作成してMapControlに追加

[code]
try
{

IFields fields = new Fields();
IFieldsEdit fieldsEdit = (IFieldsEdit)fields;

IField field = new Field();
IFieldEdit fieldEdit = (IFieldEdit)field;

fieldEdit.Name_2 = "OID";
fieldEdit.Type_2 = esriFieldType.esriFieldTypeOID;
fieldsEdit.AddField(fieldEdit);

field = new Field();
fieldEdit = (IFieldEdit)field;
fieldEdit.Name_2 = "NAME";
fieldEdit.Length_2 = 10;
fieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
fieldsEdit.AddField(fieldEdit);

field = new Field();
fieldEdit = (IFieldEdit)field;
fieldEdit.Name_2 = "GEOM";
fieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;

IGeometryDef geometryDef = new GeometryDef();
IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
geometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolygon;

ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass();
ISpatialReference spatialReference =
spatialReferenceFactory.CreateProjectedCoordinateSystem((int)2451);
ISpatialReferenceResolution spatialReferenceResolution = (ISpatialReferenceResolution)spatialReference;
spatialReferenceResolution.ConstructFromHorizon();
ISpatialReferenceTolerance spatialReferenceTolerance = (ISpatialReferenceTolerance)spatialReference;
spatialReferenceTolerance.SetDefaultXYTolerance();
geometryDefEdit.SpatialReference_2 = (ISpatialReference)spatialReference;

fieldEdit.GeometryDef_2 = geometryDefEdit;

fieldsEdit.AddField(fieldEdit);

Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.InMemoryWorkspaceFactory");
IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
IWorkspaceName workspaceName = workspaceFactory.Create("", "MyWorkspace", null, 0);
IName name = (IName)workspaceName;
IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)name.Open();

IFeatureClass featureClass =
featureWorkspace.CreateFeatureClass(
"NewPolygon",
fields,
null,
null,
esriFeatureType.esriFTSimple,
"GEOM", "");

IFeatureLayer featureLayer = new FeatureLayer();
featureLayer.FeatureClass = featureClass;
featureLayer.Name = "mempoly";

axMapControl1.AddLayer(featureLayer);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
}
[/code]

参考にしたサイト

InMemoryWorkspaceFactory CoClass

Creating a featureclass in memory and adding to the map error

IFeatureWorkspace.CreateFeatureClass Example

IFeatureClass CreateFeature Example

IFeatureClass Example


How to create geodatabases

ArcObjectsのシンボルにイメージを使用

[code]
using ESRI.ArcGIS;
using ESRI.ArcGIS.Carto;

IWorkspaceFactory featureWorkspace = (ESRI.ArcGIS.Geodatabase.IFeatureWorkspace)workspaceFactory.OpenFromFile(System.IO.Path.GetDirectoryName(@"C:\work\mypoint.shp"), 0);
IFeatureClass featureClass = featureWorkspace.OpenFeatureClass(System.IO.Path.GetFileNameWithoutExtension(@"mypoint"));
IFeatureLayer featureLayer = new ESRI.ArcGIS.Carto.FeatureLayerClass();
featureLayer.FeatureClass = featureClass;
featureLayer.Name = "ポイント";
featureLayer.Visible = true;

IRgbColor mskrgb = new RgbColorClass();
mskrgb.Red = 255;
mskrgb.Green = 255;
mskrgb.Blue = 255;

IPictureMarkerSymbol bitmapPictureMarkerSymbolCls = new PictureMarkerSymbolClass();
bitmapPictureMarkerSymbolCls.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureBitmap, "c:\\work\\flag.bmp");
bitmapPictureMarkerSymbolCls.Angle = 0;
bitmapPictureMarkerSymbolCls.BitmapTransparencyColor = mskrgb;
bitmapPictureMarkerSymbolCls.Size = 32;
bitmapPictureMarkerSymbolCls.XOffset = 0;
bitmapPictureMarkerSymbolCls.YOffset = 0;

IGeoFeatureLayer pGeoFeatureLayer = (IGeoFeatureLayer)featureLayer;
IFeatureRenderer pSimpleRenderer = new SimpleRenderer();
pSimpleRenderer.Symbol = (ISymbol)bitmapPictureMarkerSymbolCls;
pGeoFeatureLayer.Renderer = (IFeatureRenderer)pSimpleRenderer;

axMapControl1.AddLayer(featureLayer);
[/code]

ArcObjectsでOpenFeatureClassを行うとエラー0x80040351

以下を実行するとOpenFeatureClassでエラーが発生
[code]
Geodatabase.IWorkspaceFactory workspaceFactory =
new DataSourcesFile.ShapefileWorkspaceFactoryClass();
Geodatabase.IFeatureWorkspace featureWorkspace = (Geodatabase.IFeatureWorkspace)workspaceFactory.OpenFromFile(System.IO.Path.GetDirectoryName(@"C:\work"), 0);
Geodatabase.IFeatureClass featureClass = featureWorkspace1.OpenFeatureClass(System.IO.Path.GetFileNameWithoutExtension(@"mypoint"));
[/code]

以下を実行すると正しく動作する。違いはディレクトリの階層だけ。
[code]
Geodatabase.IWorkspaceFactory workspaceFactory =
new DataSourcesFile.ShapefileWorkspaceFactoryClass();
Geodatabase.IFeatureWorkspace featureWorkspace = (Geodatabase.IFeatureWorkspace)workspaceFactory.OpenFromFile(System.IO.Path.GetDirectoryName(@"C:\work\test"), 0);
Geodatabase.IFeatureClass featureClass = featureWorkspace1.OpenFeatureClass(System.IO.Path.GetFileNameWithoutExtension(@"mypoint"));
[/code]

問題は明らかにSystem.IO.Path.GetDirectoryNameなのでSystem.IO.Path.GetDirectoryNameにはShapeファイルのフルパスを渡す

[code]
Geodatabase.IWorkspaceFactory workspaceFactory =
new DataSourcesFile.ShapefileWorkspaceFactoryClass();
Geodatabase.IFeatureWorkspace featureWorkspace = (Geodatabase.IFeatureWorkspace)workspaceFactory.OpenFromFile(System.IO.Path.GetDirectoryName(@"C:\work\mypoint.shp"), 0);
Geodatabase.IFeatureClass featureClass = featureWorkspace1.OpenFeatureClass(System.IO.Path.GetFileNameWithoutExtension(@"mypoint"));
[/code]

C#でSpatialiteにShapeをインポート

SpatialiteはSQLiteに空間データを扱う機能を拡張したデータベース。
C#からSpatialiteにアクセスするにはSQLiteの.Net ProviderとSpatialiteの拡張機能のmod_spatialite.dllを使用する。

(1)SQLiteの.net providerのダウンロード
今回は.NET Framework4.0で使用するため、以下のサイトより
https://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki
Precompiled Binaries for 32-bit Windows (.NET Framework 4.0)である
sqlite-netFx40-binary-Win32-2010-1.0.99.0.zip
または
sqlite-netFx40-binary-bundle-Win32-2010-1.0.99.0.zip
をダウンロードし、
System.Data.SQLite.dll、
SQLite.Interop.dll
を使用

(2)mod_spatialite.dllのダウンロード
Spatialiteより
32bitならば
http://www.gaia-gis.it/gaia-sins/windows-bin-x86/mod_spatialite-4.3.0a-win-x86.7z
64bitならば
http://www.gaia-gis.it/gaia-sins/windows-bin-amd64/mod_spatialite-4.3.0a-win-amd64.7z
をダウンロード

以下のファイルが入っている(32bitの場合)
libfreexl-1.dll
libgcc_s_dw2-1.dll
libgeos-3-5-0.dll
libgeos_c-1.dll
libiconv-2.dll
liblzma-5.dll
libproj-9.dll
libsqlite3-0.dll
libstdc++-6.dll
libxml2-2.dll
mod_spatialite.dll
sqlite3.exe
zlib1.dll

(3)検証プログラムの作成

C:\temp\svg\T02.shp

を仮想テーブル「T02」に読み込む

SQLiteの.net providerを参照設定しmod_spatialite.dllと関連ファイルにPATHを通す。
[code]
using System.Data.SQLite;

public partial class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
string filename = @"c:\temp\db.sqlite";
SQLiteConnection con = new SQLiteConnection();
con.ConnectionString = string.Format("Data Source={0}", filename);
con.Open();
// 拡張DLLのロード
using (SQLiteCommand cmd = new SQLiteCommand("SELECT load_extension(\"mod_spatialite\")", con))
{
cmd.ExecuteNonQuery();
SQLiteCommand cmd2 = new SQLiteCommand("CREATE VIRTUAL TABLE T02 USING VirtualShape(\"C:\\temp\\svg\\T02\", \"CP1252\", 23032)", con);
md2.ExecuteNonQuery();
}
con.Close();
con = null;
}
}
[/code]
CP1252は文字コードなのでSHIFT JISならば[SHIFT_JIS]を設定
23032はEPSGなのでデータのEPSGを設定
VirtualShapeは以前はmod_spatialiteとは異なる拡張DLLだったが、今は同じようだ?

C# Chartコントロール

C# Chartコントロールについてわかりきったことや忘れやすいことのまとめ

Chart.Seriesはグラフ(データ)のコレクション
Chart.ChartAreasはXY軸や目盛りのコレクション

1つの棒グラフを表示
[code]
chart1.Series.Clear();
//グラフ1
Series series = new Series();
series.Color = Color.Red;
series.ChartType = SeriesChartType.Column;
series.Points.AddXY(1, 5);
series.Points.AddXY(2, 2);
series.Points.AddXY(3, 8);
chart1.Series.Add(series);
[/code]
棒グラフ1

複数のグラフを重ねて表示するときはChart.Seriesに追加

2種類の棒グラフを重ねて表示
[code]
chart1.Series.Clear();
//グラフ1
Series series = new Series();
series.Color = Color.Red;
series.ChartType = SeriesChartType.Column;
series.Points.AddXY(1, 5);
series.Points.AddXY(2, 2);
series.Points.AddXY(3, 8);
chart1.Series.Add(series);
//グラフ2
series = new Series();
series.Color = Color.Blue;
series.ChartType = SeriesChartType.Column;
series.Points.AddXY(1, 3);
series.Points.AddXY(2, 1);
series.Points.AddXY(3, 5);
chart1.Series.Add(series);
[/code]
棒グラフ

複数の棒グラフを表示すると重ならないように表示される。
重ねたいときはグラフ2をSeriesChartType.RangeColumnにしてグラフ幅を設定
[code]
chart1.Series.Clear();
//グラフ1
Series series = new Series();
series.Color = Color.Red;
series.ChartType = SeriesChartType.Column;
series.Points.AddXY(1, 5);
series.Points.AddXY(2, 2);
series.Points.AddXY(3, 8);
series["PointWidth"] = "0.8";
chart1.Series.Add(series);
//グラフ2
series = new Series();
series.Color = Color.Blue;
series.ChartType = SeriesChartType.RangeColumn;
series.Points.AddXY(1, 3);
series.Points.AddXY(2, 1);
series.Points.AddXY(3, 5);
series["PointWidth"] = "0.2";
chart1.Series.Add(series);
[/code]
棒グラフ3

グラフの説明(凡例)のテキストと表示、非表示は以下で設定
[code]
series.LegendText = "グラフ1";
series.IsVisibleInLegend = true;
[/code]

App.configに独自セクションを追加してHashTableで読み込む

stackoverflowさん、そのままです
app.configのconfigSectionsセクションに追加セクション(MajorCommands)を記載
[code]
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="MajorCommands" type="System.Configuration.DictionarySectionHandler" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
省略・・・
</appSettings>
<MajorCommands>
<add key="Standby" value="STBY"/>
<add key="Operate" value="OPER"/>
<add key="Remote" value="REMOTE"/>
<add key="Local" value="LOCAL"/>
<add key="Reset" value="*RST" />
</MajorCommands>
</configuration>
[/code]

C#ではConfigurationManagerのGetSectionでセクション以下をハッシュに読み込み
[code]
System.Collections.Hashtable nb = System.Configuration.ConfigurationManager.GetSection("MajorCommands") as System.Collections.Hashtable;
[/code]

Proxyサーバーの検証

作成したProxyサーバーの動作検証の為にC#でテストプログラムを作成
[code]
System.Net.WebClient wc = new System.Net.WebClient();
wc.Proxy = new System.Net.WebProxy("http://192.9.200.123:8080");
wc.Proxy.Credentials = new System.Net.NetworkCredential("test2", "test");
string source = wc.DownloadString("https://www.google.co.jp");
Console.WriteLine(source);
wc.Dispose();
[/code]
参考にしたサイト

C#(Npgsql)でPostgresqlに大量データを追加

PostgresqlにNpgsqlを使用してデータを追加するには一般的にはNpgsqlCommandでINSERTを実行。
しかし大量のデータを追加するにはこれでは時間がかかりすぎる。
その為Postgresqlのコピー機能のラッパーであるNpgsqlCopyInの使い方を記載。
Postgresqlのコピー機能についてはこちら
追加対象のテーブル
[code]
CREATE TABLE tbl_test
(
rec_no decimal(6,0) NOT NULL,
rec_name varchar(60) NOT NULL,
add_dt timestamp without time zone NOT NULL,
CONSTRAINT pkey_tbl_test PRIMARY KEY
(
rec_no
)
)
WITH (
OIDS=FALSE
);
[/code]
追加用データCSVファイル
文字コードはUTF8
改行はCRLF
デリミタはタブ
[code]
1 NAME1 2013-09-26 00:00:00
2 NAME2 2013-09-26 00:00:00
3 NAME3 2013-09-26 00:00:00
[/code]

以下はコード
[code]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using Npgsql;
namespace pcopy
{
class Program
{
static void Main(string[] args)
{
NpgsqlConnection conn = new NpgsqlConnection("Server=ホスト名;User id=ID;password=パスワード;Database=DB名;SyncNotification=true;");
conn.Open();
FileStream fs = File.OpenRead(@"CSVファイルのフルパス");
NpgsqlCommand command = new NpgsqlCommand("COPY tbl_test FROM STDIN", conn);
NpgsqlCopyIn cin = new NpgsqlCopyIn(command, conn, fs);
cin.Start();
cin.End();
}
}
}
[/code]