Yahoo! UI Library

CHZERO  1.0.0

Yahoo! UI Library > CHZERO > ZeroMapMeasure.js (source view)
Search:
 
Filters
/**
 * CHZERO.Control.ZeroMapMeasure<br/>
 * 거리 및 면적 측정하는 control
 * @class ZeroMapMeasure
 * @extends OpenLayers.Control.Measure
 * @constructor
 * @namespace CHZERO.Control
 * @param {OpenLayers.Handler} handler
 * @param {Object} options 옵션 hashtable
 */
CHZERO.Control.ZeroMapMeasure = OpenLayers.Class(OpenLayers.Control.Measure, {
	CLASS_NAME: 'CHZERO.Control.ZeroMapMeasure',

	EVENT_TYPES: ['measure', 'measurepartial'],

	vector: null,

	measureGroup: null,

	currentMeasure: null,

	movePopup: null,
	/**
	* 디폴트 true
	* @property immediate
	* @type {Boolean}
	*/
	immediate: true,

	initialize: function(handler, options) {
		this.EVENT_TYPES =
				OpenLayers.Control.Measure.prototype.EVENT_TYPES.concat(
				OpenLayers.Control.prototype.EVENT_TYPES
			);
		OpenLayers.Control.prototype.initialize.apply(this, [options]);
		if (handler == OpenLayers.Handler.Path) {
			this.displayClass = this.displayClass.replace(/ /g, "") + "Path";
		}
		else if (handler == OpenLayers.Handler.Polygon) {
			this.displayClass = this.displayClass.replace(/ /g, "") + "Polygon";
		}
		var callbacks = { done: this.measureComplete,
			point: this.measurePartial
		};
		if (this.immediate) {
			callbacks.modify = this.measureImmediate;
		}
		this.callbacks = OpenLayers.Util.extend(callbacks, this.callbacks);

		/* let the handler options override, so old code that passes 'persist' 
		 directly to the handler does not need an update*/
		this.handlerOptions = OpenLayers.Util.extend(
				{ persist: this.persist }, this.handlerOptions
			);
		this.handler = new handler(this, this.callbacks, this.handlerOptions);
		this.vector = null;
		if (this.handlerOptions && this.handlerOptions.layerOptions) {
			this.vector = new CHZERO.Layer.ZeroMapVector('Measure Vector', this.handlerOptions.layerOptions);
		}
		else {
			this.vector = new CHZERO.Layer.ZeroMapVector('Measure Vector');
		}
		this.measureGroup = [];
	},

	destroy: function() {
		this.erase();
		this.measureGroup = null;
		if (this.vector) {
			if (this.map.getLayerIndex(this.vector) > -1) {
				this.map.removeLayer(this.vector);
			}
			this.vector.destroy();
			this.vector = null;
		}
		OpenLayers.Control.prototype.destroy.apply(this, arguments);
	},
	/**
	* @method erase
	*/
	erase: function() {
		var mg = null;
		while (mg = this.measureGroup.pop()) {
			this.clear(mg);
		}
		this.measureGroup = [];

		if (this.currentMeasure && this.currentMeasure.complated) {
			this.clear(this.currentMeasure);
			this.currentMeasure = null;
		}



		if (this.movePopup != null) {
			this.map.removePopup(this.movePopup);
			this.movePopup.destroy();
			this.movePopup = null;
		}
	},
	/**
	* @method activate
	* @return {Boolean} alreadyActive
	*/
	activate: function() {
		if (this.map && this.vector && this.map.getLayerIndex(this.vector) == -1) {
			this.map.addLayer(this.vector);
		}
		OpenLayers.Control.Measure.prototype.activate.apply(this, arguments);
	},
	/**
	* @method deactivate
	* @return {Boolean} alreadyDeactive
	*/
	deactivate: function() {
		this.cancelDelay();
		if (this.currentMeasure && !this.currentMeasure.complated) {
			this.clear(this.currentMeasure);
			this.currentMeasure = null;
		}
		if (this.movePopup != null) {
			this.map.removePopup(this.movePopup);
			this.movePopup.destroy();
			this.movePopup = null;
		}

		return OpenLayers.Control.prototype.deactivate.apply(this, arguments);
	},

	measureImmediate: function(point, feature, drawing) {
		if (drawing && this.delayedTrigger === null &&
                                !this.handler.freehandMode(this.handler.evt)) {
			this.measure(feature.geometry, "measureImmediate");
		}
	},
	

	measurePartial: function(point, geometry) {
		this.cancelDelay();

		if (geometry.CLASS_NAME == 'OpenLayers.Geometry.LineString' && geometry.components.length == 2) {
			point = point.clone();
			if (this.currentMeasure && !this.currentMeasure.complated) {
				this.clear(this.currentMeasure);
			}
			this.currentMeasure = { 'point': [], 'popup': [], 'line': null };
			var pp = this.createPopup('start', point.getBounds().getCenterLonLat(), '시작점');
			var pointFeature = new OpenLayers.Feature.Vector(point);
			this.map.addPopup(pp);
			this.currentMeasure.point.push(pointFeature);
			this.currentMeasure.popup.push(pp);
			this.vector.addFeatures(pointFeature);
		}
		else if (geometry.CLASS_NAME == 'OpenLayers.Geometry.Polygon' && geometry.components[0].components.length == 3) {
			point = point.clone();
			if (this.currentMeasure && !this.currentMeasure.complated) {
				this.clear(this.currentMeasure);
			}
			this.currentMeasure = { 'popup': [], 'polygon': null };
		}

		geometry = geometry.clone();

		if (this.handler.freehandMode(this.handler.evt)) {
			/* no dblclick in freehand mode*/
			this.measure(geometry, "measurepartial");
		} else {
			this.delayedTrigger = window.setTimeout(
                OpenLayers.Function.bind(function() {
                	this.delayedTrigger = null;
                	this.measure(geometry, "measurepartial");
                }, this),
                this.partialDelay
            );
		}
	},
	measure: function(geometry, eventType) {
		var stat, order;

		if (geometry.CLASS_NAME.indexOf('LineString') > -1) {
			stat = this.getBestLength(geometry);
			order = 1;
			var g = geometry.components[geometry.components.length - 1];
			var point = new OpenLayers.Geometry.Point(g.x, g.y);
			var lonlat = point.getBounds().getCenterLonLat();

			if (eventType == 'measure' && this.currentMeasure) {
				if (this.movePopup != null) {
					this.map.removePopup(this.movePopup);
					this.movePopup.destroy();
					this.movePopup = null;
				}
				var lineFeature = new OpenLayers.Feature.Vector(geometry);

				walkingStat = this.getTime('walking', stat[0], stat[1]);
				walkingStr = null;
				if (walkingStat[0] == 0) {
					walkingStr = '<span class="distance_tb_p">' + walkingStat[1] + '</span>분';
				}
				else {
					walkingStr = '<span class="distance_tb_p">' + walkingStat[0] + '</span>시간 ';
					walkingStr += '<span class="distance_tb_p">' + walkingStat[1] + '</span>분';
				}
				bikingStat = this.getTime('biking', stat[0], stat[1]);
				bikingStr = null;
				if (bikingStat[0] == 0) {
					bikingStr = '<span class="distance_tb_p">' + bikingStat[1] + '</span>분';
				}
				else {
					bikingStr = '<span class="distance_tb_p">' + bikingStat[0] + '</span>시간 ';
					bikingStr += '<span class="distance_tb_p">' + bikingStat[1] + '</span>분';
				}
				str = '<div class="distance_divtb2">';
				str += '<table cellspacing="0" cellpadding="0" class="distance_tb2">';
				str += '<tr><td width="60px" class="distance_tb_t">· 총거리</td>';
				str += '<td class="distance_tb_tx"><span class="distance_tb_p">' + stat[0].toFixed(1) + '</span>' + stat[1] + '</td>';
				str += '</tr><tr><td class="distance_tb_t">· 도보</td>';
				str += '<td class="distance_tb_tx">' + walkingStr + '</td>';
				str += '</tr><tr><td class="distance_tb_t">· 자전거</td>';
				str += '<td class="distance_tb_tx">' + bikingStr + '</td>';
				str += '</tr></table></div>';

				var pp = this.createPopup('end', lonlat, str);
				this.map.addPopup(pp);
				this.currentMeasure.complated = true;
				this.currentMeasure.line = lineFeature;
				this.currentMeasure.popup.push(pp);
				this.vector.addFeatures(lineFeature);
				pp.currentMeasure = this.currentMeasure;
				pp.measure = this;
				this.measureGroup.push(this.currentMeasure);
				this.currentMeasure = null;
			}
			else if (eventType == 'measurepartial') {
				if (geometry.components.length > 2 && this.currentMeasure != null && this.currentMeasure.point.length > 0) {
					var pointFeature = new OpenLayers.Feature.Vector(point);
					var pp = this.createPopup('point', lonlat, stat[0].toFixed(1) + stat[1]);
					this.map.addPopup(pp);
					this.currentMeasure.point.push(pointFeature);
					this.currentMeasure.popup.push(pp);
					this.vector.addFeatures(pointFeature);
				}
			}
			else if (eventType == 'measureImmediate' && 'OpenLayers.Handler.Path' == this.handler.CLASS_NAME && this.currentMeasure) {
				if (this.movePopup != null) {
					this.map.removePopup(this.movePopup);
					this.movePopup.destroy();
					this.movePopup = null;
				}
				walkingStat = this.getTime('walking', stat[0], stat[1]);
				walkingStr = null;
				if (walkingStat[0] == 0) {
					walkingStr = '<span class="distance_tb_p">' + walkingStat[1] + '</span>분';
				}
				else {
					walkingStr = '<span class="distance_tb_p">' + walkingStat[0] + '</span>시간 ';
					walkingStr += '<span class="distance_tb_p">' + walkingStat[1] + '</span>분';
				}
				bikingStat = this.getTime('biking', stat[0], stat[1]);
				bikingStr = null;
				if (bikingStat[0] == 0) {
					bikingStr = '<span class="distance_tb_p">' + bikingStat[1] + '</span>분';
				}
				else {
					bikingStr = '<span class="distance_tb_p">' + bikingStat[0] + '</span>시간 ';
					bikingStr += '<span class="distance_tb_p">' + bikingStat[1] + '</span>분';
				}
				str = '<div class="distance_divtb">';
				str += '<table cellspacing="0" cellpadding="0" class="distance_tb">';
				str += '<tr><td width="66px" class="distance_tb_t">· 총거리</td>';
				str += '<td class="distance_tb_tx"><span class="distance_tb_p">' + stat[0].toFixed(1) + '</span>' + stat[1] + '</td>';
				str += '</tr><tr><td class="distance_tb_t">· 도보</td>';
				str += '<td class="distance_tb_tx">' + walkingStr + '</td>';
				str += '</tr><tr><td class="distance_tb_t">· 자전거</td>';
				str += '<td class="distance_tb_tx">' + bikingStr + '</td>';
				str += '</tr><tr><td height="3"></td></tr>';
				str += '<tr><td colspan="2" class="distance_tb_tx" style="border-top:solid 1px #CCC; padding:3px">더블클릭눌르면 마칩니다</td>';
				str += '</tr></table></div>';
				this.movePopup = this.createPopup('move', lonlat, str);

				this.map.addPopup(this.movePopup);
			}
		}
		else {
			var linerLing = geometry.components[0];
			var g = linerLing.components[linerLing.components.length - 2];
			var point = new OpenLayers.Geometry.Point(g.x, g.y);
			var lonlat = point.getBounds().getCenterLonLat();

			stat = this.getBestArea(geometry);
			order = 2;

			if (eventType == 'measure') {
				if (this.movePopup != null) {
					this.map.removePopup(this.movePopup);
					this.movePopup.destroy();
					this.movePopup = null;
				}
				var polygonFeature = new OpenLayers.Feature.Vector(geometry);

				str = '<span>';
				str += '<table cellspacing="0" cellpadding="0">';
				str += '<tr><td width="60px" class="distance_tb_t">· 총면적</td>';
				str += '<td class="distance_tb_tx"><span class="distance_tb_p">' + stat[0].toFixed(1) + '</span>' + stat[1] + '<sup>2</sup></td>';
				str += '</tr></table></span>';

				var pp = this.createPopup('end', lonlat, str);
				this.map.addPopup(pp);
				this.currentMeasure.complated = true;
				this.currentMeasure.polygon = polygonFeature;
				this.currentMeasure.popup.push(pp);
				this.vector.addFeatures(polygonFeature);
				pp.currentMeasure = this.currentMeasure;
				pp.measure = this;
				this.measureGroup.push(this.currentMeasure);
				this.currentMeasure = null;
			}
			else if (eventType == 'measureImmediate') {
				if (this.movePopup != null) {
					this.map.removePopup(this.movePopup);
					this.movePopup.destroy();
					this.movePopup = null;
				}
				str = '<span>';
				str += '<table cellspacing="0" cellpadding="0">';
				str += '<tr><td width="60px" class="distance_tb_t">· 총면적</td>';
				str += '<td class="distance_tb_tx"><span class="distance_tb_p">' + stat[0].toFixed(1) + '</span>' + stat[1] + '<sup>2</sup></td>';
				str += '</tr><tr><td height="3"></td></tr>';
				str += '<tr><td colspan="2" class="distance_tb_tx" style="border-top:solid 1px #CCC; padding:3px">더블클릭눌르면 마칩니다</td></tr>';
				str += '</table></span>';
				
				/*str = '<span class="distance_tb_tx">더블클릭눌르면<br/> 마칩니다</span>';*/
				this.movePopup = this.createPopup('move', lonlat, str);
				this.map.addPopup(this.movePopup);
				return;
			}

		}
		this.events.triggerEvent(eventType, {
			measure: stat[0],
			units: stat[1],
			order: order,
			geometry: geometry
		});
		if (eventType == 'measure') {
			this.deactivate();
		}
	},

	getTime: function(t, dis, unit) {
		if (unit == 'km') {
			dis = dis * 1000;
		}
		res = 1;
		if (t == 'walking') {
			res = 66.6;
		}
		else if (t == 'biking') {
			res = 250;
		}
		var minute = parseInt(dis / res) + 1;
		var hour = parseInt(minute / 60);
		if (hour > 0)
			minute = minute % 60;
		return [hour, minute];
	},

	createPopup: function(popupType, lonlat, contentHtml) {
		var pp = null;
		if (popupType == 'move') {
			pp = new OpenLayers.Popup.Anchored(OpenLayers.Util.createUniqueID('measure_popup'),
											 lonlat,
											 null,
											 contentHtml,
											 null, false, null);

			pp.calculateNewPx = function(px) {
				var newPx = px.offset(this.anchor.offset);

				/*use contentSize if size is not already set*/
				var size = this.size || this.contentSize;

				var top = (this.relativePosition.charAt(0) == 't');
				newPx.y += (top) ? -(size.h + 5) : 5;

				var left = (this.relativePosition.charAt(1) == 'l');
				newPx.x += (left) ? -(size.w + 5) : 5;

				return newPx;
			};

			pp.autoSize = true;
			pp.setBorder('1px solid #FF0000');
			pp.contentDiv.style.fontFamily = 'Dotum AppleGothic';
			pp.contentDiv.style.fontSize = '15px';
			pp.contentDiv.style.lineHeight = '18px';
			pp.contentDiv.style.overflow = 'hidden';
			pp.contentDiv.style.padding = '2px';
			pp.contentDiv.style.margin = '0';
			pp.isMeasure = true;
		}
		else if (popupType == 'point') {
			pp = new OpenLayers.Popup.Anchored(OpenLayers.Util.createUniqueID('measure_popup'),
												 lonlat,
												 new OpenLayers.Size(contentHtml.length * 8, 15),
												 contentHtml,
												 null, false, null);
			pp.calculateNewPx = function(px) {
				var newPx = px.offset(this.anchor.offset);

				/*use contentSize if size is not already set*/
				var size = this.size || this.contentSize;

				var top = (this.relativePosition.charAt(0) == 't');
				newPx.y += (top) ? -(size.h + 2) : 2;

				var left = (this.relativePosition.charAt(1) == 'l');
				newPx.x += (left) ? -(size.w + 2) : 2;

				return newPx;
			};
			pp.setBorder('1px solid #FF0000');
			pp.contentDiv.style.color = '#FF0000';
			pp.contentDiv.style.fontFamily = 'Dotum AppleGothic';
			pp.contentDiv.style.fontSize = '11px';
			pp.contentDiv.style.lineHeight = '11px';
			pp.contentDiv.style.overflow = 'hidden';
			pp.contentDiv.style.float = 'left';
			pp.contentDiv.style.padding = '2px';
			pp.contentDiv.style.margin = '0';
			pp.isMeasure = true;
		}
		else if (popupType == 'start') {
			pp = new OpenLayers.Popup.Anchored(OpenLayers.Util.createUniqueID('measure_popup'),
												 lonlat,
												 new OpenLayers.Size(50, 20),
												 contentHtml,
												 null, false, null);
			pp.setBorder('1px solid #FF0000');
			pp.setOpacity(1.0);
			pp.contentDiv.style.fontFamily = 'Dotum AppleGothic';
			pp.contentDiv.style.fontSize = '15px';
			pp.contentDiv.style.lineHeight = '18px';
			pp.contentDiv.style.overflow = 'hidden';
			pp.contentDiv.style.padding = '2px';
			pp.contentDiv.style.margin = '0';
			pp.contentDiv.style.background = '#FF0000';
			pp.contentDiv.style.color = '#FFFFFF';
			pp.isMeasure = true;
		}
		else if (popupType == 'end') {
			pp = new OpenLayers.Popup.Anchored(OpenLayers.Util.createUniqueID('measure_popup'),
											 lonlat,
											 null,
											 contentHtml,
											 null, true, function(evt) {
											 	if (this.measure && this.currentMeasure) {
											 		OpenLayers.Util.removeItem(this.measure.measureGroup, this.currentMeasure);
											 		this.measure.clear(this.currentMeasure);
											 	}
											 });

			pp.autoSize = true;
			pp.setBorder('1px solid #FF0000');
			pp.contentDiv.style.fontFamily = 'Dotum AppleGothic';
			pp.contentDiv.style.fontSize = '15px';
			pp.contentDiv.style.lineHeight = '18px';
			pp.contentDiv.style.overflow = 'hidden';
			pp.contentDiv.style.padding = '2px';
			pp.contentDiv.style.margin = '0';
			pp.isMeasure = true;
		}
		return pp;
	},
	clear: function(measure) {
		var p = null;
		if (measure.point) {
			while (p = measure.point.pop()) {
				this.vector.removeFeatures(p);
			}
			measure.point = null;
		}
		if (measure.popup) {
			while (p = measure.popup.pop()) {
				if (p.div) {
					if (this.map) this.map.removePopup(p);
					p.measure = null;
					p.currentMeasure = null;
					p.destroy();
				}
			}
			measure.popup = null;
		}
		if (measure.line) {
			this.vector.removeFeatures(measure.line);
			measure.line = null;
		}
		if (measure.polygon) {
			this.vector.removeFeatures(measure.polygon);
			measure.polygon = null;
		}
	}
});

Copyright © 2012 Yahoo! Inc. All rights reserved.