yuu_nkjm blog
2011-02-10(Thu) 編集
[MABS][CitySim][MATSim][OSM] OpenStreetMap(OSM オープンストリートマップ)のデータを道路ネットワークに変換する
以下,書きかけ
道路ネットワークのデータが欲しいというとき,OpenStreetMapがなかなか便利.緯度経度だけでなく道路の接続状況も分かるし,取り扱いが簡単.基盤地図情報|国土地理院も使ったことがあるけど,道路と道路の結合情報をどのように作るのが良いのかが分からない.
マルチエージェント交通シミュレーションツールボックスMATSim(Multi-Agent Transport Simulation)には,OpenStreetMap形式のデータを変換する機能がある.この変換方法は日本の座標系と合っていないようだが,ネットワークの生成はできた.なお,MATSimはJavaで書かれたプログラムであるため,予めJavaをインストールしておく必要がある.
ダウンロード
- OpenStreetMapにアクセスする.OpenStreetMap Japanからのたどり方はよく分からないので,http://www.openstreetmap.org/からアクセス.
- 適当なエリアに移動する.
- エクスポートタブを選択する.
- エクスポートするファイル形式で,OSM XMLデータを選択する.
- 「別の範囲を指定する」を選択する.地図上でエクスポートしたい範囲を選択する.
- 出力ボタンを押す.map.ocmという名前でダウンロードされる.
道路ネットワークに変換
-
MATSimで使える形に変換するには,以下の様にする.MATSimは,公式サイトからダウンロードする.0.2以外でNetworkFromOSMクラスが用意されているかは分かりません.
java -cp matsim-0.2.0.jar org/matsim/evacuation/tutorial/NetworkFromOSM map.osm network.xml
-
作成した道路ネットワークデータの定義はwww.matsim.org/files/dtd/network_v1.dtdである.
<!ELEMENT network (nodes,links)> <!ATTLIST network name CDATA #IMPLIED type CDATA #IMPLIED capDivider CDATA #IMPLIED xml:lang NMTOKEN "de-CH"> <!ELEMENT nodes (node)*> <!ELEMENT links (link)*> <!ATTLIST links capperiod CDATA #IMPLIED effectivecellsize CDATA "7.5" effectivelanewidth CDATA "3.75" capPeriod CDATA #IMPLIED capDivider CDATA #IMPLIED capdivider CDATA #IMPLIED> <!ELEMENT node EMPTY> <!ATTLIST node id CDATA #REQUIRED x CDATA #REQUIRED y CDATA #REQUIRED type CDATA #IMPLIED origid CDATA #IMPLIED> <!ELEMENT link EMPTY> <!ATTLIST link id CDATA #REQUIRED from CDATA #REQUIRED to CDATA #REQUIRED length CDATA #REQUIRED freespeed CDATA #REQUIRED capacity CDATA #REQUIRED permlanes CDATA #REQUIRED oneway CDATA #FIXED "1" volume CDATA #IMPLIED origid CDATA #IMPLIED nt_category CDATA #IMPLIED nt_type CDATA #IMPLIED type CDATA #IMPLIED modes CDATA "car">
- シミュレーションをする上で,linkとlinkの連結情報(fromノードとtoノード)があるのが便利.
- MATSimの緯度-平面直角座標系変換はドイツ(?つまり日本以外)を基準にした変換を行っている.自分の欲しい地図データに適した変換を行うには,ちょっとプログラムを書く必要がある.CoordinateTransformationというクラスを継承して,自前で変換ルールを書く.一部を付録として末尾に掲載.MATSimのモジュール使わなくても,OSMプロジェクトでJava用のデータ処理ライブラリが用意されてる気がするが,未調査.
緯度・経度と平面直角座標の変換
世界測地系,日本測地系,平面直角座標系,緯度経度のあれこれ
付録:日本測地系用の変換プログラムの一部
// 道路ネットワークを作成するクラス public class NetworkFromOSMKyoto { public static void main(String[] args) throws SAXException, ParserConfigurationException, IOException { (snip) Scenario sc = new ScenarioImpl(); Network net = sc.getNetwork(); // 自分で作成した変換ルールをネットワークリーダーに渡す. CoordinateTransformation ct = new CoordinateTransformationKyoto(); OsmNetworkReader onr = new OsmNetworkReader(net, ct); onr.parse(osm); new NetworkWriter(net).write(networkFileTmp, networkDtd); new NetworkWriter(net).write(dbNetworkFileTmp, dbNetworkDtd); (snip) } }
import jp.jasminesoft.gcat.scalc.DMSconv; import jp.jasminesoft.gcat.scalc.LatLong2XY; import org.matsim.api.core.v01.Coord; import org.matsim.core.utils.geometry.CoordImpl; import org.matsim.core.utils.geometry.CoordinateTransformation; // 日本測地系用の変換ルール public class CoordinateTransformationKyoto implements CoordinateTransformation { @Override public Coord transform(Coord coord) { LatLong2XY latLong2XY = new LatLong2XY(6); double lat = DMSconv.deg2dms((float) coord.getY()); double lon = DMSconv.deg2dms((float) coord.getX()); latLong2XY.setLatitude(lat); latLong2XY.setLongitude(lon); // TODO nkjm X-Y coord on Matsim and X-Y coord in Japan is // different. double convX = latLong2XY.getY(); double convY = latLong2XY.getX(); return new CoordImpl(convX, convY); } }
2012-02-10(Fri) 編集
[Programming][Java][C/C++] 値渡しと参照渡し,参照とポインタ,直接参照と間接参照
値渡しと参照渡し,参照とポインタ
値渡しと参照渡し (と参照の値渡し) - 予定は未定Blog版が分かりやすかった.
関連ページ
- 値渡しとは (pass by value, call by value) あたいわたし: - IT用語辞典バイナリ
- 参照渡しとは (call by reference) さんしょうわたし: - IT用語辞典バイナリ
- 値渡しと参照渡し (と参照の値渡し) - 予定は未定Blog版
- 「参照渡し」と「参照の値渡し」の差 - 神様なんて信じない僕らのために
- Javascript のスコープとか参照とかクロージャとか - EAGLE 雑記
参照とポインタ,直接参照と間接参照
Javaの参照の値渡しと参照渡し
Javaでは「参照の値渡し」と「参照渡し」を混同しやすい.下記の1番上のページが参考になると思う.
- 値渡しと参照渡し (と参照の値渡し) - 予定は未定Blog版
- 疑問メモ: 値渡し、参照渡し、Java、C - 虎塚
- メソッドの引数の参照渡しはできますか? - Java Solution - @IT
以下,草稿.
#include
void changeValueCallbyRef(int& val) {
// 実引数として与えられた変数をそのまま操作できるイメージ.
// valはaそのもの.エイリアスとも呼ばれる.
printf("val=%d, pointer of val=%d\n",val,&val);
val = 999;
}
void changeValuePointer0(int* val){
// 変数valが作成され,aへのポインタが格納される.
printf("val=%d, pointer of val=%d\n",val,&val);
// 「ポインタ変数」valに代入しても,aに影響はない
int b = 111;
val = &b;
}
void changeValuePointer1(int* val){
//「ポインタ変数」の参照先に値を格納する.
*val = 555;
//Javaだと,参照先の値そのものを変更することはできない.
//Javaでは, 参照先の値やオブジェクトにアクセスすることができる.
//ここの例で行くと,Javaでは,*valにアクセスはできるが,
//*valに代入することはできないイメージ.
}
int main(void){
int a = 10;
int* a_p = &a;
printf("a=%d, pointer of a=%d\n",a,&a);
printf("a_p=%d, pointer of a_p=%d\n",a_p,&a_p);
changeValueCallbyRef(a);
printf("a=%d, pointer of a=%d\n",a,&a);
changeValuePointer0(&a);
printf("a=%d, pointer of a=%d\n",a,&a);
changeValuePointer1(&a);
printf("a=%d, pointer of a=%d\n",a,&a);
}