( function() {
"use strict";
/**
* uGisMapPlatForm 지도 객체.
*
* 다양한 타입의 레이어({@link ugmp.layer})를 추가할 수 있으며, 지도의 기본 객체이다.
*
* @constructor
*
* @example
*
* <pre>
* var ugMap = new ugmp.uGisMap( {
* target : 'map',
* crs : 'EPSG:3857',
* center : [ 0, 0 ],
* useMaxExtent : true,
* useAltKeyOnly : false
* } );
*
* // ol.Map 객체에 직접 접근
* ugMap.getMap().addLayer( new ol.layer.Tile( {
* source : new ol.source.OSM()
* } ) );
*
* // uGisMap에 WMS 레이어 추가
* ugMap.addWMSLayer( {
* uWMSLayer : new ugmp.layer.uGisWMSLayer( {...} )
* ...
* } );
* </pre>
*
* @param opt_options {Object}
* @param opt_options.crs {String} 좌표계. Default is `EPSG:3857`.
* @param opt_options.center {Array.<Number>} 중심점. Default is `[0, 0]`.
* @param opt_options.target {String} 지도가 그려질 DIV ID.
* @param opt_options.useAltKeyOnly {Boolean} 마우스 휠줌 스크롤 시 AltKey 조합 설정 사용 여부.
*
* `true`면 AltKey를 누를 상태에서만 마우스 휠줌 스크롤 사용이 가능하다. Default is `false`.
*
* @param opt_options.useMaxExtent {Boolean} 이동할 수 있는 영역을 해당 좌표계의 최대 영역으로 한정한다. Default is `false`.
*
* @class
*/
ugmp.uGisMap = ( function(opt_options) {
var _self = this;
this.olMap = null;
this.mapCRS = null;
this.useAltKeyOnly = null;
this.layers = null;
this.dataViewId = null;
this.loadingSrcDiv = null;
/**
* Initialize
*/
( function() {
var options = opt_options || {};
_self.layers = [];
_self.mapCRS = ( options.crs !== undefined ) ? options.crs.toUpperCase() : "EPSG:3857";
_self.useAltKeyOnly = ( typeof ( options.useAltKeyOnly ) === "boolean" ) ? options.useAltKeyOnly : false;
var center = options.center;
if ( !Array.isArray( center ) ) {
center = [ 0, 0 ];
}
var maxExtent = ( options.useMaxExtent ) ? ol.proj.get( _self.mapCRS ).getExtent() : undefined;
var view = new ol.View( {
zoom : 2,
center : center,
extent : maxExtent,
projection : _self.mapCRS
} );
_self.dataViewId = ol.getUid( view );
_self.olMap = new ol.Map( {
target : options.target,
layers : [],
renderer : "canvas",
controls : _self._createDefaultControls(),
interactions : _self._createDefaultInteractions(),
view : view
} );
_self._createScrollElement();
_self._createLoadingElement();
/**
* view 변경 시 overlay transform
*
* 로딩 심볼 초기화
*/
_self.olMap.on( "change:view", function() {
var newProjection = _self.olMap.getView().getProjection().getCode();
_self.mapCRS = newProjection;
var overlays = _self.olMap.getOverlays().getArray();
for ( var i = overlays.length - 1; i >= 0; i-- ) {
var origin = overlays[ i ].get( "origin" );
if ( origin ) {
var position = ol.proj.transform( origin[ "position" ], origin[ "projection" ], _self.mapCRS );
overlays[ i ].setPosition( position );
overlays[ i ].set( "CRS", _self.mapCRS );
}
}
ugmp.uGisConfig.resetLoading( _self.dataViewId );
} );
var tag = ( options.target instanceof Element ) ? options.target : "#" + options.target;
_$( tag ).resize( function() {
_self.refresh();
} );
_$( window ).resize( function() {
_self.refresh();
} );
console.log( "####### uGisMap Init #######" );
console.log( "Projection : " + _self.mapCRS );
} )();
// END initialize
return {
_this : _self,
refresh : _self.refresh,
getCRS : _self.getCRS,
getMap : _self.getMap,
setExtent : _self.setExtent,
getLayers : _self.getLayers,
setAltKeyOnly : _self.setAltKeyOnly,
removeLayer : _self.removeLayer,
addWMSLayer : _self.addWMSLayer,
addWFSLayer : _self.addWFSLayer,
addWCSLayer : _self.addWCSLayer,
addWMTSLayer : _self.addWMTSLayer,
addVectorLayer : _self.addVectorLayer,
addClusterLayer : _self.addClusterLayer,
addVector3DLayer : _self.addVector3DLayer,
calculateScale : _self.calculateScale,
getDataViewId : _self.getDataViewId,
getScaleForZoom : _self.getScaleForZoom,
setLoadingVisible : _self.setLoadingVisible,
removeAllListener : _self.removeAllListener,
removeAllInteraction : _self.removeAllInteraction,
setActiveAllInteraction : _self.setActiveAllInteraction
}
} );
/**
* 지도 영역 스크롤 이벤트 Element
*
* @private
*/
ugmp.uGisMap.prototype._createScrollElement = function() {
var _self = this._this || this;
var selector = '.ol-viewport[data-view="' + _self.dataViewId + '"]';
var element = document.querySelector( selector );
var altEmpty = document.createElement( "div" );
altEmpty.setAttribute( "altText", "" );
altEmpty.style.top = "0px";
altEmpty.style.zIndex = 2;
altEmpty.style.opacity = 0;
altEmpty.style.width = "100%";
altEmpty.style.height = "100%";
altEmpty.style.position = "absolute";
altEmpty.style.pointerEvents = "none";
altEmpty.style.transitionDuration = "1s";
altEmpty.style.backgroundColor = "rgba( 0, 0, 0, 0.5 )";
var text = document.createElement( "p" );
text.textContent = "지도를 확대/축소하려면 Alt를 누른 채 스크롤하세요.";
text.style.left = "0px";
text.style.right = "0px";
text.style.top = "50%";
text.style.color = "white";
text.style.fontSize = "25px";
text.style.margin = "0 auto";
text.style.textAlign = "center";
text.style.position = "absolute";
text.style.transform = "translateY(-50%)";
altEmpty.appendChild( text );
element.insertBefore( altEmpty, element.firstChild );
_self.olMap.scrollCallBack = new _scrollCallBack( altEmpty, function() {
return _self.useAltKeyOnly
} );
function _scrollCallBack(altElement_, getAltKeyOnly_) {
var _this = this;
this.tId = null;
this.altElement = null;
this.getAltKeyOnly = null;
( function(altElement_, getAltKeyOnly_) {
_this.altElement = altElement_;
_this.getAltKeyOnly = getAltKeyOnly_;
} )( altElement_, getAltKeyOnly_ );
function _none() {
_this.altElement.style.opacity = 0;
_this.altElement.style.transitionDuration = "0.8s";
}
this.run = function() {
_this.altElement.style.opacity = 1;
_this.altElement.style.transitionDuration = "0.3s";
window.clearTimeout( _this.tId );
_this.tId = window.setTimeout( function() {
_none();
}, 1500 );
};
this.clear = function() {
window.clearTimeout( _this.tId );
_none();
};
return {
run : _this.run,
clear : _this.clear,
getAltKeyOnly : _this.getAltKeyOnly
}
}
};
/**
* 로딩 심볼 Element
*
* @private
*/
ugmp.uGisMap.prototype._createLoadingElement = function() {
var _self = this._this || this;
var selector = '.ol-viewport[data-view="' + _self.dataViewId + '"]';
var element = document.querySelector( selector );
var loadingDiv = document.createElement( "div" );
loadingDiv.id = "loadingDIV";
loadingDiv.style.zIndex = 1;
loadingDiv.style.top = "0px";
loadingDiv.style.left = "0px";
loadingDiv.style.right = "0px";
loadingDiv.style.bottom = "0px";
loadingDiv.style.display = "none";
loadingDiv.style.margin = "auto";
loadingDiv.style.position = "absolute";
loadingDiv.style.pointerEvents = "none";
_self.loadingSrcDiv = new Image();
_self.loadingSrcDiv.src = ugmp.uGisConfig.getLoadingImg();
_self.loadingSrcDiv.onload = function(evt) {
loadingDiv.style.width = evt.target.width + "px";
loadingDiv.style.height = evt.target.height + "px";
loadingDiv.appendChild( _self.loadingSrcDiv );
element.insertBefore( loadingDiv, element.firstChild );
};
ugmp.uGisConfig.addProgress( _self.dataViewId, function(state_) {
if ( state_ ) {
loadingDiv.style.display = "block";
} else {
loadingDiv.style.display = "none";
}
} );
};
/**
* Default Interactions 설정.
*
* -베이스맵(배경지도)과 자연스러운 싱크를 맞추기 위해 각 Interaction의 기본 효과 제거.
*
* -모든 Intercation 삭제 시 꼭 필요한 Interaction은 제외하기 위해 속성값 추가.
*
* @private
*
* @return interactions {Array.<ol.interaction.Interaction>}
*/
ugmp.uGisMap.prototype._createDefaultInteractions = function() {
var interactions = [ new ol.interaction.DragPan( {
kinetic : false
} ), new ol.interaction.DragZoom( {
duration : 0,
condition : ol.events.condition.shiftKeyOnly
} ), new ol.interaction.DragRotate( {
duration : 0
} ), new ol.interaction.DoubleClickZoom( {
duration : 0
} ), new ol.interaction.MouseWheelZoom( {
duration : 0,
constrainResolution : true
} ), new ol.interaction.PinchZoom( {
duration : 0,
constrainResolution : true
} ), new ol.interaction.PinchRotate( {
duration : 0
} ) ];
for ( var i in interactions ) {
interactions[ i ].set( "necessary", true );
}
return interactions;
};
/**
* Default Controls 설정.
*
* -베이스맵(배경지도)과 자연스러운 싱크를 맞추기 위해 각 Control의 기본 효과 제거.
*
* -모든 Control 삭제 시 꼭 필요한 Control은 제외하기 위해 속성값 추가.
*
* @private
*
* @return controls {Array.<ol.control.Control>}
*/
ugmp.uGisMap.prototype._createDefaultControls = function() {
var controls = [ new ol.control.Rotate(), new ol.control.Zoom( {
duration : 0
} ) ];
for ( var i in controls ) {
controls[ i ].set( "necessary", true );
}
return controls;
};
/**
* 현재 {@link ugmp.uGisMap}에 설정된 ol.Map 객체를 가져온다.
*
* @return olMap {ol.Map} ol.Map 객체.
*/
ugmp.uGisMap.prototype.getMap = function() {
var _self = this._this || this;
return _self.olMap;
};
/**
* 현재 지도 좌표계를 가져온다.
*
* @return mapCRS {String} 현재 지도 좌표계.
*/
ugmp.uGisMap.prototype.getCRS = function() {
var _self = this._this || this;
return _self.mapCRS;
};
/**
* 지정된 Extent로 지도 영역 맞추기.
*
* @param envelop {Array.<Double>} Extent.
*/
ugmp.uGisMap.prototype.setExtent = function(envelop_) {
var _self = this._this || this;
_self.olMap.getView().fit( envelop_ );
};
/**
* 현재 {@link ugmp.uGisMap}에 추가된 {@link ugmp.layer} 목록을 가져온다.
*
* @param layerType {String} 레이어 타입. (WMS, WFS, WMTS, Vector...)
*
* @return layers {Array.<ugmp.layer>} 레이어 목록.
*/
ugmp.uGisMap.prototype.getLayers = function(layerType_) {
var _self = this._this || this;
var layers = [];
if ( _self.layers && layerType_ ) {
for ( var i in _self.layers ) {
var layer = _self.layers[ i ];
if ( layer.getLayerType() === layerType_ ) {
layers.push( layer );
}
}
} else {
layers = _self.layers;
}
return layers;
};
/**
* WMS 레이어를 추가한다.
*
* @param opt_options {Object}
* @param opt_options.uWMSLayer {ugmp.layer.uGisWMSLayer} {@link ugmp.layer.uGisWMSLayer} 객체.
* @param opt_options.extent {Array.<Number>} 레이어 추가 후 설정될 extent.
* @param opt_options.resolution {Float} 레이어 추가 후 설정될 resolution.
* @param opt_options.useExtent {Boolean} 레이어 추가 후 extent 설정 사용 여부.
*
* `true`면 해당 레이어의 영역으로 지도 영역을 맞춘다. Default is `false`.
*
* ※`extent`가 정상적이지 않을 경우 {@link ugmp.service.uGisGetCapabilitiesWMS}의 extent로 설정.
*
* @return promise {Object} jQuery.Deferred.promise.
*/
ugmp.uGisMap.prototype.addWMSLayer = function(opt_options) {
var _self = this._this || this;
var options = opt_options || {};
var uWMSLayer = ( options.uWMSLayer !== undefined ) ? options.uWMSLayer : undefined;
var useExtent = ( options.useExtent !== undefined ) ? options.useExtent : false;
var extent = ( options.extent !== undefined ) ? options.extent : undefined;
var resolution = ( options.resolution !== undefined ) ? options.resolution : undefined;
var deferred = _$.Deferred();
try {
_self.olMap.addLayer( uWMSLayer.getOlLayer() );
_self.layers.push( uWMSLayer );
var source = uWMSLayer.getOlLayer().getSource();
source.on( [ "imageloadstart", "tileloadstart" ], function(evt) {
if ( ugmp.uGisConfig.isUseLoading() ) {
ugmp.uGisConfig.loading( _self.dataViewId, true );
}
} );
source.on( [ "imageloadend", "tileloadend" ], function() {
if ( ugmp.uGisConfig.isUseLoading() ) {
ugmp.uGisConfig.loading( _self.dataViewId, false );
}
} );
source.on( [ "imageloaderror", "tileloaderror" ], function() {
if ( ugmp.uGisConfig.isUseLoading() ) {
ugmp.uGisConfig.loading( _self.dataViewId, false );
}
} );
/**
* extent로 이동
*/
if ( useExtent ) {
// extent 매개변수 값이 있으면
if ( Array.isArray( extent ) ) {
for ( var i in extent ) {
extent[ i ] = parseFloat( extent[ i ] );
}
_self.setExtent( extent );
if ( resolution ) {
_olMap.getView().setResolution( resolution );
}
} else {
var capabilities = new ugmp.service.uGisGetCapabilitiesWMS( {
useProxy : true,
version : "1.3.0",
serviceURL : uWMSLayer.getServiceURL(),
dataViewId : _self.dataViewId
} );
capabilities.then(
function(result_) {
if ( result_.state ) {
var transExtent = ol.proj.transformExtent( capabilities.data.serviceMetaData.maxExtent,
capabilities.data.serviceMetaData.crs, _self.mapCRS );
_self.setExtent( transExtent );
} else {
ugmp.uGisConfig.alert_Error( result_.message );
deferred.reject( result_.message );
return deferred.promise();
}
} ).fail( function(e) {
ugmp.uGisConfig.alert_Error( "Error : " + e );
deferred.reject( false );
return deferred.promise();
} );
}
}
deferred.resolve( true );
} catch ( e ) {
ugmp.uGisConfig.alert_Error( "Error : " + e );
deferred.reject( false );
return deferred.promise();
}
return deferred.promise();
};
/**
* WFS 레이어를 추가한다.
*
* @param opt_options {Object}
* @param opt_options.uWFSLayer {ugmp.layer.uGisWFSLayer} {@link ugmp.layer.uGisWFSLayer} 객체.
* @param opt_options.useExtent {Boolean} 레이어 추가 후 extent 설정 사용 여부.
*
* `true`면 해당 레이어의 영역으로 지도 영역을 맞춘다. Default is `false`.
*
* @return promise {Object} jQuery.Deferred.promise.
*/
ugmp.uGisMap.prototype.addWFSLayer = function(opt_options) {
var _self = this._this || this;
var options = opt_options || {};
var uWFSLayer = ( options.uWFSLayer !== undefined ) ? options.uWFSLayer : undefined;
var useExtent = ( options.useExtent !== undefined ) ? options.useExtent : false;
var deferred = _$.Deferred();
try {
var olWFSLayer = uWFSLayer.getOlLayer();
_self.olMap.addLayer( olWFSLayer );
_self.layers.push( uWFSLayer );
var uFeatures = uWFSLayer.getFeatures( _self.dataViewId );
uFeatures.then( function(result_) {
if ( result_.state ) {
olWFSLayer.getSource().addFeatures( result_.features );
if ( useExtent ) {
var transExtent = ol.proj.transformExtent( olWFSLayer.getSource().getExtent(), uWFSLayer.srsName, _self.mapCRS );
_self.setExtent( transExtent );
}
deferred.resolve( true );
} else {
ugmp.uGisConfig.alert_Error( result_.message );
deferred.reject( result_.message );
return deferred.promise();
}
} ).fail( function(e) {
ugmp.uGisConfig.alert_Error( "Error : " + e );
deferred.reject( false );
return deferred.promise();
} );
} catch ( e ) {
ugmp.uGisConfig.alert_Error( "Error : " + e );
deferred.reject( false );
return deferred.promise();
}
return deferred.promise();
};
/**
* WCS 레이어 추가
*
* @param opt_options {Object}
* @param opt_options.uWCSLayer {ugmp.layer.uGisWCSLayer} {@link ugmp.layer.uGisWCSLayer} 객체.
* @param opt_options.extent {Array} 레이어 추가 후 설정될 extent.
* @param opt_options.useExtent {Boolean} 레이어 추가 후 extent 설정 사용 여부. Default is `false`.
*
* `true`면 해당 레이어의 영역으로 지도 영역을 맞춘다. Default is `false`.
*
* ※`extent`가 정상적이지 않을 경우 {@link ugmp.service.uGisGetCapabilitiesWCS}의 extent로 설정.
*
* @return promise {Object} jQuery.Deferred.promise.
*/
ugmp.uGisMap.prototype.addWCSLayer = function(opt_options) {
var _self = this._this || this;
var options = opt_options || {};
var uWCSLayer = ( options.uWCSLayer !== undefined ) ? options.uWCSLayer : undefined;
var useExtent = ( options.useExtent !== undefined ) ? options.useExtent : false;
var extent = ( options.extent !== undefined ) ? options.extent : undefined;
var deferred = _$.Deferred();
try {
var olWCSLayer = uWCSLayer.getOlLayer();
if ( uWCSLayer.getBoundingBox() && uWCSLayer.getBoundingBox().length > 3 ) {
_self.olMap.addLayer( olWCSLayer );
_self.layers.push( uWCSLayer );
uWCSLayer.setMap( _self.olMap, _load );
var extent = ol.proj.transformExtent( uWCSLayer.getBoundingBox(), "EPSG:4326", _self.getCRS() );
setExtent( extent );
deferred.resolve( true );
} else {
var capabilities = new ugmp.service.uGisGetCapabilitiesWCS( {
useProxy : true,
version : uWCSLayer.version,
serviceURL : uWCSLayer.getServiceURL(),
dataViewId : _self.dataViewId
} );
capabilities.then( function(result_) {
if ( result_.state ) {
var serviceMetaData = capabilities.data.serviceMetaData;
var coverageList = serviceMetaData.coverages;
for ( var i in coverageList ) {
if ( coverageList[ i ][ "Identifier" ] === uWCSLayer.identifier ) {
uWCSLayer.setBoundingBox( coverageList[ i ][ "BBOX" ] );
break;
}
}
_self.olMap.addLayer( olWCSLayer );
_self.layers.push( uWCSLayer );
uWCSLayer.setMap( _self.olMap, _load );
if ( extent && Array.isArray( extent ) ) {
setExtent( extent );
} else {
var extent = ol.proj.transformExtent( uWCSLayer.getBoundingBox(), "EPSG:4326", _self.getCRS() );
setExtent( extent );
}
deferred.resolve( true );
} else {
ugmp.uGisConfig.alert_Error( result_.message );
_self.deferred.reject( result_.message );
return deferred.promise();
}
} );
}
deferred.resolve( true );
} catch ( e ) {
ugmp.uGisConfig.alert_Error( "Error : " + e );
deferred.reject( false );
return deferred.promise();
}
function setExtent(extent_) {
if ( useExtent ) {
// extent 매개변수 값이 있으면
if ( Array.isArray( extent_ ) ) {
for ( var i in extent_ ) {
extent_[ i ] = parseFloat( extent_[ i ] );
}
_self.setExtent( extent_ );
}
}
}
function _load(state_) {
if ( ugmp.uGisConfig.isUseLoading() ) {
ugmp.uGisConfig.loading( _self.dataViewId, state_ );
}
}
return deferred.promise();
};
/**
* WMTS 레이어를 추가한다.
*
* @param opt_options {Object}
* @param opt_options.uWMTSLayer {ugmp.layer.uGisWMTSLayer} {@link ugmp.layer.uGisWMTSLayer} 객체.
* @param opt_options.extent {Array.<Number>} 레이어 추가 후 설정될 extent.
* @param opt_options.useExtent {Boolean} 레이어 추가 후 extent 설정 사용 여부.
*
* `true`면 해당 레이어의 영역으로 지도 영역을 맞춘다. Default is `false`.
*
* ※`extent`가 정상적이지 않을 경우 {@link ugmp.service.uGisGetCapabilitiesWMTS}의 extent로 설정.
*
* @return promise {Object} jQuery.Deferred.promise.
*/
ugmp.uGisMap.prototype.addWMTSLayer = function(opt_options) {
var _self = this._this || this;
var options = opt_options || {};
var uWMTSLayer = ( options.uWMTSLayer !== undefined ) ? options.uWMTSLayer : undefined;
var useExtent = ( options.useExtent !== undefined ) ? options.useExtent : false;
var extent = ( options.extent !== undefined ) ? options.extent : undefined;
var deferred = _$.Deferred();
try {
var olWMTSLayer = uWMTSLayer.getOlLayer();
if ( uWMTSLayer.getWmtsCapabilities() && uWMTSLayer.getOriginExtent() ) {
uWMTSLayer.update( true );
_self.olMap.addLayer( olWMTSLayer );
_self.layers.push( uWMTSLayer );
var extent = ol.proj.transformExtent( uWMTSLayer.getOriginExtent(), "EPSG:4326", _self.getCRS() );
setExtent( extent );
setOn();
deferred.resolve( true );
} else {
var capabilities = new ugmp.service.uGisGetCapabilitiesWMTS( {
useProxy : true,
version : uWMTSLayer.version,
serviceURL : uWMTSLayer.getServiceURL(),
dataViewId : _self.dataViewId
} );
capabilities.then( function(result_) {
if ( result_.state ) {
var layers = capabilities.data.olJson.Contents.Layer;
for ( var i in layers ) {
if ( layers[ i ][ "Identifier" ] === uWMTSLayer.layer ) {
uWMTSLayer.setOriginExtent( layers[ i ][ "WGS84BoundingBox" ] );
break;
}
}
uWMTSLayer.setWmtsCapabilities( capabilities.data );
uWMTSLayer.update( true );
_self.olMap.addLayer( olWMTSLayer );
_self.layers.push( uWMTSLayer );
if ( extent && Array.isArray( extent ) ) {
setExtent( extent );
} else {
var extent = ol.proj.transformExtent( uWMTSLayer.getOriginExtent(), "EPSG:4326", _self.getCRS() );
setExtent( extent );
}
setOn();
deferred.resolve( true );
} else {
ugmp.uGisConfig.alert_Error( result_.message );
_self.deferred.reject( result_.message );
return deferred.promise();
}
} );
}
// deferred.resolve( true );
} catch ( e ) {
ugmp.uGisConfig.alert_Error( "Error : " + e );
deferred.reject( false );
return deferred.promise();
}
function setExtent(extent_) {
if ( useExtent ) {
// extent 매개변수 값이 있으면
if ( Array.isArray( extent_ ) ) {
for ( var i in extent_ ) {
extent_[ i ] = parseFloat( extent_[ i ] );
}
_self.setExtent( extent_ );
}
}
}
function setOn() {
var source = uWMTSLayer.getOlLayer().getSource();
source.on( "tileloadstart", function(evt) {
if ( ugmp.uGisConfig.isUseLoading() ) {
ugmp.uGisConfig.loading( _self.dataViewId, true );
}
} );
source.on( "tileloadend", function() {
if ( ugmp.uGisConfig.isUseLoading() ) {
ugmp.uGisConfig.loading( _self.dataViewId, false );
}
} );
source.on( "tileloaderror", function() {
if ( ugmp.uGisConfig.isUseLoading() ) {
ugmp.uGisConfig.loading( _self.dataViewId, false );
}
} );
}
return deferred.promise();
};
/**
* Vector 레이어를 추가한다.
*
* @param opt_options {Object}
* @param opt_options.uVectorLayer {ugmp.layer.uGisVectorLayer} {@link ugmp.layer.uGisVectorLayer} 객체.
* @param opt_options.useExtent {Boolean} 레이어 추가 후 extent 설정 사용 여부.
*
* `true`면 해당 레이어의 영역으로 지도 영역을 맞춘다. Default is `false`.
*
* @return promise {Object} jQuery.Deferred.promise.
*/
ugmp.uGisMap.prototype.addVectorLayer = function(opt_options) {
var _self = this._this || this;
var options = opt_options || {};
var uVectorLayer = ( options.uVectorLayer !== undefined ) ? options.uVectorLayer : undefined;
var useExtent = ( options.useExtent !== undefined ) ? options.useExtent : false;
var deferred = _$.Deferred();
try {
var olVectorLayer = uVectorLayer.getOlLayer();
_self.olMap.addLayer( olVectorLayer );
_self.layers.push( uVectorLayer );
if ( useExtent ) {
var extent = olVectorLayer.getSource().getExtent();
if ( extent && extent[ 0 ] !== Infinity ) {
var transExtent = ol.proj.transformExtent( olVectorLayer.getSource().getExtent(), uVectorLayer.srsName, _self.mapCRS );
_self.setExtent( transExtent );
}
}
deferred.resolve( true );
} catch ( e ) {
ugmp.uGisConfig.alert_Error( "Error : " + e );
deferred.reject( false );
return deferred.promise();
}
return deferred.promise();
};
/**
* Vector3D 레이어를 추가한다.
*
* @param opt_options {Object}
* @param opt_options.uVector3DLayer {ugmp.layer.uGisVector3DLayer} {@link ugmp.layer.uGisVector3DLayer} 객체.
* @param opt_options.useExtent {Boolean} 레이어 추가 후 extent 설정 사용 여부.
*
* `true`면 해당 레이어의 영역으로 지도 영역을 맞춘다. Default is `false`.
*
* @return promise {Object} jQuery.Deferred.promise.
*/
ugmp.uGisMap.prototype.addVector3DLayer = function(opt_options) {
var _self = this._this || this;
var options = opt_options || {};
var uVector3DLayer = ( options.uVector3DLayer !== undefined ) ? options.uVector3DLayer : undefined;
var useExtent = ( options.useExtent !== undefined ) ? options.useExtent : false;
var deferred = _$.Deferred();
try {
var olVectorLayer = uVector3DLayer.getOlLayer();
_self.olMap.addLayer( olVectorLayer );
_self.layers.push( uVector3DLayer );
if ( useExtent ) {
var extent = olVectorLayer.getSource().getExtent();
if ( extent && extent[ 0 ] !== Infinity ) {
var transExtent = ol.proj.transformExtent( olVectorLayer.getSource().getExtent(), uVector3DLayer.srsName, _self.mapCRS );
_self.setExtent( transExtent );
}
}
deferred.resolve( true );
} catch ( e ) {
ugmp.uGisConfig.alert_Error( "Error : " + e );
deferred.reject( false );
return deferred.promise();
}
return deferred.promise();
};
/**
* Cluster 레이어를 추가한다.
*
* @param opt_options {Object}
* @param opt_options.uClusterLayer {ugmp.layer.uGisClusterLayer} {@link ugmp.layer.uGisClusterLayer} 객체.
*
* @return promise {Object} jQuery.Deferred.promise.
*/
ugmp.uGisMap.prototype.addClusterLayer = function(opt_options) {
var _self = this._this || this;
var options = opt_options || {};
var uClusterLayer = ( options.uClusterLayer !== undefined ) ? options.uClusterLayer : undefined;
var deferred = _$.Deferred();
try {
var olClusterLayer = uClusterLayer.getOlLayer();
_self.olMap.addLayer( olClusterLayer );
_self.layers.push( uClusterLayer );
deferred.resolve( true );
} catch ( e ) {
ugmp.uGisConfig.alert_Error( "Error : " + e );
deferred.reject( false );
return deferred.promise();
}
return deferred.promise();
};
/**
* 지도 새로고침.
*/
ugmp.uGisMap.prototype.refresh = function() {
var _self = this._this || this;
if ( _self.olMap ) {
var view = _self.olMap.getView();
view.dispatchEvent( {
type : 'change:center'
} );
view.dispatchEvent( {
type : 'change:rotation'
} );
view.dispatchEvent( {
type : 'change:resolution'
} );
_self.olMap.updateSize();
}
};
/**
* 현재 {@link ugmp.uGisMap}에 등록된 {@link ugmp.layer}를 삭제한다.
*
* @param uGisLayerKey {String} 삭제할 {@link ugmp.layer}의 KEY.
*/
ugmp.uGisMap.prototype.removeLayer = function(uGisLayerKey_) {
var _self = this._this || this;
for ( var i = 0; i < _self.layers.length; i++ ) {
var uGisLayer = _self.layers[ i ];
if ( uGisLayer.getLayerKey() === uGisLayerKey_ ) {
uGisLayer.destroy();
_self.olMap.removeLayer( uGisLayer.getOlLayer() );
_self.layers.splice( i, 1 );
}
}
};
/**
* Temp Scale -> Resolution
*
* @param scale {Double} scale
*
* @private
*
* @return resolution {Double} resolution
*/
ugmp.uGisMap.prototype.getResolutionFromScale = function(scale_) {
var projection = _self.olMap.getView().getProjection();
var metersPerUnit = projection.getMetersPerUnit();
var inchesPerMeter = 39.37;
var dpi = 96;
return scale_ / ( metersPerUnit * inchesPerMeter * dpi );
};
/**
* Temp Resolution -> Scale
*
* @param resolution {Double} resolution
*
* @private
*
* @return scale {Double} scale
*/
ugmp.uGisMap.prototype.getScaleFromResolution = function(resolution_) {
var projection = _self.olMap.getView().getProjection();
var metersPerUnit = projection.getMetersPerUnit();
var inchesPerMeter = 39.37;
var dpi = 96;
return resolution_ * ( metersPerUnit * inchesPerMeter * dpi );
};
/**
* 현재 지도에서 해당 Extent의 스케일을 계산한다.
*
* @param opt_options {Object}
* @param opt_options.extent {Array.<Number>} 스케일을 계산할 Extent. Default is 현재 지도 영역.
* @param opt_options.originCRS {String} 레이어 원본 좌표계. Default is 현재 지도 좌표계.
*
* @return scale {Double} 스케일.
*/
ugmp.uGisMap.prototype.calculateScale = function(opt_options) {
var _self = this._this || this;
var scale = null;
var extent = null;
var viewCRS = null;
var originCRS = null;
var PPI = 0.000264583;
/**
* Initialize
*/
( function(opt_options) {
var options = opt_options || {};
viewCRS = _self.mapCRS;
originCRS = ( options.originCRS !== undefined ) ? options.originCRS : _self.getCRS();
extent = ( options.extent !== undefined ) ? options.extent : _self.olMap.getView().calculateExtent( _self.olMap.getSize() );
var mapDistance;
var canvasDistance;
var eWidth = ol.extent.getWidth( extent );
var eHeight = ol.extent.getHeight( extent );
var pixelWidth = _self.olMap.getSize()[ 0 ];
var pixelHeight = _self.olMap.getSize()[ 1 ];
var resX = eWidth / pixelWidth;
var resY = eHeight / pixelHeight;
if ( resX >= resY ) {
mapDistance = _getMapWidthInMeter();
canvasDistance = pixelWidth * PPI;
scale = mapDistance / canvasDistance;
} else {
mapDistance = _getMapHeightInMeter();
canvasDistance = pixelHeight * PPI;
scale = mapDistance / canvasDistance;
}
} )( opt_options );
function _getMapWidthInMeter() {
var p1 = [ extent[ 0 ], extent[ 1 ] ];
var p2 = [ extent[ 2 ], extent[ 1 ] ];
return _getDistanceInMeter( p1, p2 );
}
function _getMapHeightInMeter() {
var p1 = [ extent[ 0 ], extent[ 1 ] ];
var p2 = [ extent[ 0 ], extent[ 3 ] ];
return _getDistanceInMeter( p1, p2 );
}
function _getDistanceInMeter(p1_, p2_) {
var latLon1 = _getLatLon( p1_ );
var latLon2 = _getLatLon( p2_ );
var dx = latLon2[ 0 ] - latLon1[ 0 ];
var dy = latLon2[ 1 ] - latLon1[ 1 ];
return Math.sqrt( Math.pow( dx, 2 ) + Math.pow( dy, 2 ) );
}
function _getLatLon(p_) {
var latLon = new Array( 2 );
if ( viewCRS === null || ( viewCRS === originCRS ) ) {
latLon[ 0 ] = p_[ 0 ];
latLon[ 1 ] = p_[ 1 ];
return latLon;
}
try {
var np = ol.proj.transform( p_, viewCRS, originCRS );
latLon[ 0 ] = np[ 0 ];
latLon[ 1 ] = np[ 1 ];
return latLon;
} catch ( e ) {
}
}
return scale;
};
/**
* 현재 지도에서 해당 줌 레벨의 스케일을 계산한다.
*
* @param zoom {Integer} 줌 레벨.
*
* @return scale {Double} 스케일.
*/
ugmp.uGisMap.prototype.getScaleForZoom = function(zoom_) {
var _self = this._this || this;
var resolution = _self.olMap.getView().getResolutionForZoom( zoom_ );
var eWidth = resolution * _self.olMap.getSize()[ 0 ];
var eHeight = resolution * _self.olMap.getSize()[ 1 ];
var dummyExtent = [ 0, 0, eWidth, eHeight ];
return _self.calculateScale( {
extent : dummyExtent,
originCRS : _self.getCRS()
} );
};
/**
* 현재 지도에 등록된 모든 이벤트리스너를 제거한다.
*
* @param type {String} 이벤트 타입
*/
ugmp.uGisMap.prototype.removeAllListener = function(type_) {
var _self = this._this || this;
var clickListeners = ol.events.getListeners( _self.olMap, type_ );
for ( var i = clickListeners.length - 1; i >= 0; i-- ) {
ol.Observable.unByKey( clickListeners[ i ] );
}
};
/**
* 현재 지도에 등록된 모든 Interaction을 제거한다. (Default Interaction 제외)
*/
ugmp.uGisMap.prototype.removeAllInteraction = function() {
var _self = this._this || this;
var interactions = _self.olMap.getInteractions().getArray();
for ( var i = interactions.length - 1; i >= 0; i-- ) {
if ( !( interactions[ i ].get( "necessary" ) ) ) {
_self.olMap.removeInteraction( interactions[ i ] );
}
}
};
/**
* 현재 지도에 등록된 모든 Interaction 사용 설정. (Default Interaction 포함)
*
* @param state {Boolean} 사용 설정 값.
*/
ugmp.uGisMap.prototype.setActiveAllInteraction = function(state_) {
var _self = this._this || this;
var interactions = _self.olMap.getInteractions().getArray();
for ( var i = interactions.length - 1; i >= 0; i-- ) {
interactions[ i ].setActive( state_ );
}
};
/**
* 마우스 휠줌 스크롤 시 AltKey 조합 설정 사용 여부를 설정한다.
*
* @param state {Boolean} 사용 설정 값.
*/
ugmp.uGisMap.prototype.setAltKeyOnly = function(state_) {
var _self = this._this || this;
if ( _self.useAltKeyOnly === state_ ) {
return;
}
_self.useAltKeyOnly = state_;
};
/**
* 로딩 심볼 표시 여부를 설정한다.
*
* @param state {Boolean} 사용 설정 값.
*/
ugmp.uGisMap.prototype.setLoadingVisible = function(state_) {
var _self = this._this || this;
if ( state_ ) {
_self.loadingSrcDiv.style.display = "block";
} else {
_self.loadingSrcDiv.style.display = "none";
}
};
/**
* 현재 지도의 View ID를 가져온다. View ID는 고유값이므로 해당 지도의 Key로 사용한다.
*
* @return dataViewId {String} View ID.
*/
ugmp.uGisMap.prototype.getDataViewId = function() {
var _self = this._this || this;
return _self.dataViewId;
};
} )();