お盆休みよこしなさーい!

Houdiniがバージョン11になったんですってよ。まぁせっかく快適になったPCに入れるつもりはないですが。それはさておき、久しぶりにSideEffects社のサイトをダラダラと読んでいたら、こんな紹介がありました。

cmiVFX presents: PROCEDURAL CITY SKELETIONS

Generating Regional Procedural City Skeletons

OpenStreetMapで配布されている地図データをPythonで読み込む方法、の広告ですね。本文を読むにはcmiVFXを購読する必要があります。

とはいえ別にHoudiniがなきゃ遊べないわけではないです。地図データ(osm xml)をダウンロードして、

会社の周り(右下は大阪城)

Processingで読んで描画してみました。メルカトル図法とか投影方法はいろいろありますけど、適当。

読み込んでみた

「ふ~ん」って感じですね。まっ、そのうち何かの役にたつんじゃないかと。実在/架空問わず、町の俯瞰をCGでつくったりすることがたまにあるんですよね。Illustratorで一から作るとなんか嘘っぽくなるんですがこれならいいかも。

ソースです。地図データは別途用意してください。

/* 
 * osmParse.pde
 * made with Processing 1.2.1
 * Auther: hTaka
*/

import java.util.Hashtable;

XMLElement xml;
XMLElement bounds;
int numOfNode = 0;
int numOfWay = 0;
float minLat,minLon,maxLat,maxLon;
Hashtable nodeTable;

void setup() {
  //size(640, 640);
  noLoop();
  smooth();
  
  xml = new XMLElement(this, "map.osm");

  //get data region
  bounds = xml.getChild("bounds");
  minLat = bounds.getFloatAttribute("minlat");
  minLon = bounds.getFloatAttribute("minlon");
  maxLat = bounds.getFloatAttribute("maxlat");
  maxLon = bounds.getFloatAttribute("maxlon");
  float aspect = (maxLon-minLon)/(maxLat-minLat)/2;
  
  nodeTable = new Hashtable();
  size(1024,(int)(1024*aspect));
  
  stroke(255);
}

void draw() {
  background(0,0,128);
  int num = xml.getChildCount();

  //get nodes
  for (int i = 0; i < num; i++) {
    XMLElement node = xml.getChild(i);

    if(node.getName().equals("node")) {
      PVector location = new PVector(node.getFloatAttribute("lon"),node.getFloatAttribute("lat"));
      nodeTable.put(node.getIntAttribute("id"),location);
      strokeWeight(3);
      point(map(node.getFloatAttribute("lon"),minLon,maxLon,0,width),map(node.getFloatAttribute("lat"),minLat,maxLat,height,0));
      numOfNode ++;
    }
  }
  //get way and draw
  for (int i = 0; i < num; i++) {
    XMLElement way = xml.getChild(i);
    strokeWeight(1);
    stroke(128);
    if(way.getName().equals("way")) {
      int numOfNdRef = way.getChildCount();
      noFill();
      beginShape();
      for(int j = 0;j < numOfNdRef; j++) {
        XMLElement ndRef = way.getChild(j);
        if(ndRef.getName().equals("nd")) {
          PVector vec = (PVector)nodeTable.get(ndRef.getIntAttribute("ref"));
          vertex(map(vec.x, minLon, maxLon, 0, width), map(vec.y, minLat, maxLat, height, 0));
        }
      }
      endShape();
      numOfWay ++;
    }
  }

  println("Root:" + xml.getName());
  println("version:" + xml.getFloatAttribute("version"));
  println("# of node:" + numOfNode);
  println("# of way:" + numOfWay);
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です