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 を使うとダメみたい