<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 *
 * This file is part of Weave.
 *
 * The Initial Developer of Weave is the Institute for Visualization
 * and Perception Research at the University of Massachusetts Lowell.
 * Portions created by the Initial Developer are Copyright (C) 2008-2015
 * the Initial Developer. All Rights Reserved.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 * 
 * ***** END LICENSE BLOCK ***** */

package weavejs.data.column
{
	import weavejs.WeaveAPI;
	import weavejs.api.core.ICallbackCollection;
	import weavejs.api.data.ColumnMetadata;
	import weavejs.api.data.IQualifiedKey;
	import weavejs.api.net.IWeaveGeometryTileService;
	import weavejs.geom.Bounds2D;
	import weavejs.geom.GeneralizedGeometry;
	import weavejs.geom.GeometryStreamDecoder;
	import weavejs.geom.KDTree;
	import weavejs.geom.ZoomBounds;
	import weavejs.util.ArrayUtils;
	import weavejs.util.DebugUtils;
	import weavejs.util.JS;
	import weavejs.util.JSByteArray;
	import weavejs.util.StandardLib;
	import weavejs.util.WeavePromise;
	
	/**
	 * StreamedGeometryColumn
	 * 
	 * @author adufilie
	 */
	public class StreamedGeometryColumn extends AbstractAttributeColumn
	{
		private static var _debug:Boolean = false;
		
		public function StreamedGeometryColumn(metadataTileDescriptors:JSByteArray, geometryTileDescriptors:JSByteArray, tileService:IWeaveGeometryTileService, metadata:Object = null)
		{
			super(metadata);
			
			_tileService = Weave.linkableChild(this, tileService);
			
			_geometryStreamDecoder.keyType = metadata[ColumnMetadata.KEY_TYPE];
			
			// handle tile descriptors
			WeaveAPI.Scheduler.callLater(this, _geometryStreamDecoder.decodeMetadataTileList, [metadataTileDescriptors]);
			WeaveAPI.Scheduler.callLater(this, _geometryStreamDecoder.decodeGeometryTileList, [geometryTileDescriptors]);
			
			var self:Object = this;
			boundingBoxCallbacks.addImmediateCallback(this, function():void{
				if (_debug)
					DebugUtils.debugTrace(self,'boundingBoxCallbacks',boundingBoxCallbacks,'keys',keys.length);
			});
			addImmediateCallback(this, function():void{
				if (_debug)
					DebugUtils.debugTrace(self,'keys',keys.length);
			});
		}
		
		public function get boundingBoxCallbacks():ICallbackCollection
		{
			return _geometryStreamDecoder.metadataCallbacks;
		}
		
		override public function getMetadata(propertyName:String):String
		{
			return super.getMetadata(propertyName);
		}
		
		/**
		 * This is a list of unique keys this column defines values for.
		 */
		override public function get keys():Array
		{
			return _geometryStreamDecoder.keys;
		}
		
		override public function containsKey(key:IQualifiedKey):Boolean
		{
			return _geometryStreamDecoder.getGeometriesFromKey(key) != null;
		}
		
		/**
		 * @return The Array of geometries associated with the given key (if dataType not specified).
		 */
		override public function getValueFromKey(key:IQualifiedKey, dataType:Class=null):*
		{
			var value:* = _geometryStreamDecoder.getGeometriesFromKey(key);
			
			// cast to different types
			if (dataType == Boolean)
				value = (value is Array);
			else if (dataType == Number)
			{
				var sum:Number = value is Array ? 0 : NaN;
				for each (var geom:GeneralizedGeometry in value)
					sum += geom.bounds.getArea();
				value = sum;
			}
			else if (dataType == String)
				value = value ? 'Geometry(' + key.keyType + '#' + key.localName + ')' : undefined;
			
			return value;
		}
		
		public function get collectiveBounds():Bounds2D
		{
			return _geometryStreamDecoder.collectiveBounds;
		}
		
		/**
		 * This function returns true if the column is still downloading tiles.
		 * @return True if there are tiles still downloading.
		 */
		public function isStillDownloading():Boolean
		{
			return _metadataStreamDownloadCounter > 0
				|| _geometryStreamDownloadCounter > 0;
		}
		
		private var _tileService:IWeaveGeometryTileService;
		private const _geometryStreamDecoder:GeometryStreamDecoder = Weave.linkableChild(this, GeometryStreamDecoder);
		
		private var _geometryStreamDownloadCounter:int = 0;
		private var _metadataStreamDownloadCounter:int = 0;
		
		
		public var metadataTilesPerQuery:int = 200; //10;
		public var geometryTilesPerQuery:int = 200; //30;
		
		public function requestGeometryDetail(dataBounds:Bounds2D, lowestImportance:Number):void
		{
			//JS.log("requestGeometryDetail",dataBounds,lowestImportance);
			if (dataBounds == null || isNaN(lowestImportance))
				return;
			
			// don't bother downloading if we know the result will be empty
			if (dataBounds.isEmpty())
				return;
			
			var metaRequestBounds:Bounds2D;
			var metaRequestImportance:Number;
			switch (metadataRequestMode)
			{
				case METADATA_REQUEST_MODE_ALL:
					metaRequestBounds = _geometryStreamDecoder.collectiveBounds;
					metaRequestImportance = 0;
					break;
				case METADATA_REQUEST_MODE_XY:
					metaRequestBounds = dataBounds;
					metaRequestImportance = 0;
					break;
				case METADATA_REQUEST_MODE_XYZ:
					metaRequestBounds = dataBounds;
					metaRequestImportance = lowestImportance;
					break;
			}
			// request metadata tiles
			var metadataTileIDs:Array = _geometryStreamDecoder.getRequiredMetadataTileIDs(metaRequestBounds, metaRequestImportance, true);
			// request geometry tiles needed for desired dataBounds and zoom level (filter by XYZ)
			var geometryTileIDs:Array = _geometryStreamDecoder.getRequiredGeometryTileIDs(dataBounds, lowestImportance, true);

			if (_debug)
			{
				if (metadataTileIDs.length > 0)
					JS.log(this, "requesting metadata tiles: " + metadataTileIDs);
				if (geometryTileIDs.length > 0)
					JS.log(this, "requesting geometry tiles: " + geometryTileIDs);
			}
			
			var query:WeavePromise;
			// make requests for groups of tiles
			while (metadataTileIDs.length > 0)
			{
				query = _tileService.getMetadataTiles(metadataTileIDs.splice(0, metadataTilesPerQuery));
				query.then(handleMetadataStreamDownload, handleMetadataDownloadFault);<commit_msg>renamed _debug to debug<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 *
 * This file is part of Weave.
 *
 * The Initial Developer of Weave is the Institute for Visualization
 * and Perception Research at the University of Massachusetts Lowell.
 * Portions created by the Initial Developer are Copyright (C) 2008-2015
 * the Initial Developer. All Rights Reserved.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 * 
 * ***** END LICENSE BLOCK ***** */

package weavejs.data.column
{
	import weavejs.WeaveAPI;
	import weavejs.api.core.ICallbackCollection;
	import weavejs.api.data.ColumnMetadata;
	import weavejs.api.data.IQualifiedKey;
	import weavejs.api.net.IWeaveGeometryTileService;
	import weavejs.geom.Bounds2D;
	import weavejs.geom.GeneralizedGeometry;
	import weavejs.geom.GeometryStreamDecoder;
	import weavejs.geom.KDTree;
	import weavejs.geom.ZoomBounds;
	import weavejs.util.ArrayUtils;
	import weavejs.util.DebugUtils;
	import weavejs.util.JS;
	import weavejs.util.JSByteArray;
	import weavejs.util.StandardLib;
	import weavejs.util.WeavePromise;
	
	/**
	 * StreamedGeometryColumn
	 * 
	 * @author adufilie
	 */
	public class StreamedGeometryColumn extends AbstractAttributeColumn
	{
		public static var debug:Boolean = false;
		
		public function StreamedGeometryColumn(metadataTileDescriptors:JSByteArray, geometryTileDescriptors:JSByteArray, tileService:IWeaveGeometryTileService, metadata:Object = null)
		{
			super(metadata);
			
			_tileService = Weave.linkableChild(this, tileService);
			
			_geometryStreamDecoder.keyType = metadata[ColumnMetadata.KEY_TYPE];
			
			// handle tile descriptors
			WeaveAPI.Scheduler.callLater(this, _geometryStreamDecoder.decodeMetadataTileList, [metadataTileDescriptors]);
			WeaveAPI.Scheduler.callLater(this, _geometryStreamDecoder.decodeGeometryTileList, [geometryTileDescriptors]);
			
			var self:Object = this;
			boundingBoxCallbacks.addImmediateCallback(this, function():void{
				if (debug)
					DebugUtils.debugTrace(self,'boundingBoxCallbacks',boundingBoxCallbacks,keys.length,'keys');
			});
			addImmediateCallback(this, function():void{
				if (debug)
					DebugUtils.debugTrace(self,keys.length,'keys');
			});
		}
		
		public function get boundingBoxCallbacks():ICallbackCollection
		{
			return _geometryStreamDecoder.metadataCallbacks;
		}
		
		override public function getMetadata(propertyName:String):String
		{
			return super.getMetadata(propertyName);
		}
		
		/**
		 * This is a list of unique keys this column defines values for.
		 */
		override public function get keys():Array
		{
			return _geometryStreamDecoder.keys;
		}
		
		override public function containsKey(key:IQualifiedKey):Boolean
		{
			return _geometryStreamDecoder.getGeometriesFromKey(key) != null;
		}
		
		/**
		 * @return The Array of geometries associated with the given key (if dataType not specified).
		 */
		override public function getValueFromKey(key:IQualifiedKey, dataType:Class=null):*
		{
			var value:* = _geometryStreamDecoder.getGeometriesFromKey(key);
			
			// cast to different types
			if (dataType == Boolean)
				value = (value is Array);
			else if (dataType == Number)
			{
				var sum:Number = value is Array ? 0 : NaN;
				for each (var geom:GeneralizedGeometry in value)
					sum += geom.bounds.getArea();
				value = sum;
			}
			else if (dataType == String)
				value = value ? 'Geometry(' + key.keyType + '#' + key.localName + ')' : undefined;
			
			return value;
		}
		
		public function get collectiveBounds():Bounds2D
		{
			return _geometryStreamDecoder.collectiveBounds;
		}
		
		/**
		 * This function returns true if the column is still downloading tiles.
		 * @return True if there are tiles still downloading.
		 */
		public function isStillDownloading():Boolean
		{
			return _metadataStreamDownloadCounter > 0
				|| _geometryStreamDownloadCounter > 0;
		}
		
		private var _tileService:IWeaveGeometryTileService;
		private const _geometryStreamDecoder:GeometryStreamDecoder = Weave.linkableChild(this, GeometryStreamDecoder);
		
		private var _geometryStreamDownloadCounter:int = 0;
		private var _metadataStreamDownloadCounter:int = 0;
		
		
		public var metadataTilesPerQuery:int = 200; //10;
		public var geometryTilesPerQuery:int = 200; //30;
		
		public function requestGeometryDetail(dataBounds:Bounds2D, lowestImportance:Number):void
		{
			//JS.log("requestGeometryDetail",dataBounds,lowestImportance);
			if (dataBounds == null || isNaN(lowestImportance))
				return;
			
			// don't bother downloading if we know the result will be empty
			if (dataBounds.isEmpty())
				return;
			
			var metaRequestBounds:Bounds2D;
			var metaRequestImportance:Number;
			switch (metadataRequestMode)
			{
				case METADATA_REQUEST_MODE_ALL:
					metaRequestBounds = _geometryStreamDecoder.collectiveBounds;
					metaRequestImportance = 0;
					break;
				case METADATA_REQUEST_MODE_XY:
					metaRequestBounds = dataBounds;
					metaRequestImportance = 0;
					break;
				case METADATA_REQUEST_MODE_XYZ:
					metaRequestBounds = dataBounds;
					metaRequestImportance = lowestImportance;
					break;
			}
			// request metadata tiles
			var metadataTileIDs:Array = _geometryStreamDecoder.getRequiredMetadataTileIDs(metaRequestBounds, metaRequestImportance, true);
			// request geometry tiles needed for desired dataBounds and zoom level (filter by XYZ)
			var geometryTileIDs:Array = _geometryStreamDecoder.getRequiredGeometryTileIDs(dataBounds, lowestImportance, true);

			if (debug)
			{
				if (metadataTileIDs.length > 0)
					JS.log(this, "requesting metadata tiles: " + metadataTileIDs);
				if (geometryTileIDs.length > 0)
					JS.log(this, "requesting geometry tiles: " + geometryTileIDs);
			}
			
			var query:WeavePromise;
			// make requests for groups of tiles
			while (metadataTileIDs.length > 0)
			{
				query = _tileService.getMetadataTiles(metadataTileIDs.splice(0, metadataTilesPerQuery));
				query.then(handleMetadataStreamDownload, handleMetadataDownloadFault);
{'fraction_non_alphanumeric': 0.08851577145651643, 'fraction_numerical': 0.00603146140679762, 'mean_word_length': 4.25706940874036, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6342811', 'n_tokens_mistral': 4249, 'n_tokens_neox': 3498, 'n_words': 878}