f8g

万単位の点を打つ

GPSで取ったデータで、標高ごとに色を変えて点を打っていこうと思った。
サンプル

  • 線データ: 30ぐらい
  • 点データ: 22000ぐらい

(面倒なのでArray.prototype.eachなど前提)

一つずつ打ってく

単純にこんな感じで。

data.geometries.each(function(geom){
  geom.coordinates.each(function(coord){
      canvas.children.add(makePoint(coord));
  });
}

万単位となるとJavaScriptがいちいち停止してしまう。

タイマーを使う

data.geometries.each(function(geom){
  var n = 0;
  var timer = setInterval(function(){
    canvas.children.add(makePoint(geom.coordinates[n]));
    if(n++ > geom.coordinates.length)
        clearInterval(timer);
  }, 1);
});

各線について並列的に点を打っていく。JavaScriptは停止しないものの、処理が進むにつれて速度が落ちていく感じでイライラ。1点を追加するたびに再描画してるのが原因だと思う。

まとめて追加する

1点ごとの追加ではなく、複数の点をまとめて追加するようにする。色々と調べてみたらGeometryGroupというのがそれっぽい。

  1. XAMLで書くと Path > Path.Data > GeometryGroup というような構造
  2. 色はPathで定義するので、色ごとにPathを作る必要がある

ということで、最大でも16777216以内に収まる。いや、そんな高低差ねえので多分減る。

var points = {};
var finish = 0;

data.geometries.each(function(geom){
  var n = 0;
  var timer = setInterval(function(){
    var color = makeColor(geom.coordinates[n]);

    if(!points[color])
      points[color] = [];

    points[color].push(makePoint(point));

    if(n++ >= geom.coordinates.length){
      clearInterval(timer);
      finish ++;

      if(finish == data.geometries.length)
        draw();
    }
  }, 1);
});

function draw(){
  for(var color in points){
    canvas.children.add(makePath(color, points[color]));
  }
}

これで描画する回数が22000から400ぐらいに減り、測ってないけど速度もかなりよくなった。
http://gyazo.com/22dd65dcc7a9fe83c9907cbd65aa696b.png
水彩みたい。

まとめ

  • 画面に表示される系のものはまとめて表示するようにする
  • XAMLで図形をグループ化するときにもっと使い勝手のいいやつはないのか
  • CreateFromXAMLが通らないと涙が出る