f8g

Bounding Box

こんなん。

var GeoFeatures = function(){};

(function(){
/*
 * Point
 */
GeoFeatures.Point = function(x, y, z, m){
	this.x = x || 0;
	this.y = y || 0;
	this.z = z || 0;
	this.m = m || 0;
};

GeoFeatures.Point.prototype = {
	x: 0,
	y: 0,
	z: 0,
	m: 0,

	toString: function(order){
		order = order || "xyzm".split("");

		var self  = this;
		var value = [];

		order.each(function(k){
			value.push(self[k]);
		});

		return value.toString();
	}
};

/*
 * LineString
 */
GeoFeatures.LineString = function(){
	var self    = arguments.callee;
	var thisObj = Array.prototype.slice.call(arguments, 0, arguments.length);

	thisObj.constructor = self; // お好みで

	objectExtend(thisObj, self._prototype);

	return thisObj;
};

GeoFeatures.LineString._prototype = {
	boundingBox: function(p1, p2){
		var _coordinates = objectClone(this); // deep cloneの方がいいんでしょうか
		var min = new GeoFeatures.Point(Math.min.apply(null, [p1.x, p2.x]), Math.min.apply(null, [p1.y, p2.y]));
		var max = new GeoFeatures.Point(Math.max.apply(null, [p1.x, p2.x]), Math.max.apply(null, [p1.y, p2.y]));

		_coordinates.sort();

		var points = [];
		var item;

		while(_coordinates.length){
			item = _coordinates.shift();

			if(item[0] > max[0] && item[1] > max[1])
				break;

			if(min.x <= item.x && item.x <= max.x
			&& min.y <= item.y && item.y <= max.y)
				points.push(item);
		}

		return points;
	}
};

function objectClone(o){
	var clone = function(){};
	clone.prototype = Object(o);
	return new clone;
};

function objectExtend(obj, ext){
	for(var x in ext)
		obj[x] = ext[x];
	return obj;
};

})();

var l = new GeoFeatures.LineString();
l.push(new GeoFeatures.Point(2,1));
l.push(new GeoFeatures.Point(3,1));
l.push(new GeoFeatures.Point(6,2));
l.push(new GeoFeatures.Point(4,3));
l.push(new GeoFeatures.Point(4,4));
l.push(new GeoFeatures.Point(1,5));
l.push(new GeoFeatures.Point(3,5));
l.push(new GeoFeatures.Point(3,6));
l.push(new GeoFeatures.Point(5,6));

log(l.boundingBox(
	new GeoFeatures.Point(2,3),
	new GeoFeatures.Point(5,5)
).join("\n"));
/*
result:
3,5,0,0
4,3,0,0
4,4,0,0
*/

高速化にはもっと工夫のしようがありますけど。
ポイント

  • Point.prototype.toString でソートと点抽出を速くする
  • LineStringとかはArrayを継承じゃなくて拡張でいい
    • LineString.prototype を使うとダメみたい