UNPKG

openlayermap

Version:

openlayer Map Component for Vue 2.0

1,067 lines (998 loc) 36.9 kB
import {SuperMap} from '../SuperMap' import './BaseTypes' export var Util = SuperMap.Util = SuperMap.Util || {} /** * @name Util * @memberOf SuperMap * @namespace * @description common工具类。 */ /** * @description 复制源对象的所有属性到目标对象上,源对象上的没有定义的属性在目标对象上也不会被设置。 * @example * 要复制SuperMap.Size对象的所有属性到自定义对象上,使用方法如下: * var size = new SuperMap.Size(100, 100) * var obj = {}; * SuperMap.Util.extend(obj, size) * @param destination - {Object} 目标对象。 * @param source - {Object} 源对象,其属性将被设置到目标对象上。 * @return {Object} 目标对象。 */ SuperMap.Util.extend = function (destination, source) { destination = destination || {} if (source) { for (var property in source) { var value = source[property] if (value !== undefined) { destination[property] = value } } /** * IE doesn't include the toString property when iterating over an object's * properties with the for(property in object) syntax. Explicitly check if * the source has its own toString property. */ /* * FF/Windows < 2.0.0.13 reports "Illegal operation on WrappedNative * prototype object" when calling hawOwnProperty if the source object * is an instance of window.Event. */ var sourceIsEvt = typeof window.Event === 'function' && source instanceof window.Event if (!sourceIsEvt && source.hasOwnProperty && source.hasOwnProperty('toString')) { destination.toString = source.toString } } return destination } /** * @description 对象拷贝。 * @param des - {Object} 目标对象。 * @param soc - {Object} 源对象 */ SuperMap.Util.copy = function (des, soc) { des = des || {} var v if (soc) { for (var p in des) { v = soc[p] if (typeof v !== 'undefined') { des[p] = v } } } } /** * @description 销毁对象,将其属性置空 * @param obj - {Object} 目标对象。 */ SuperMap.Util.reset = function (obj) { obj = obj || {} for (var p in obj) { if (obj.hasOwnProperty(p)) { if (typeof obj[p] === 'object' && obj[p] instanceof Array) { for (var i in obj[p]) { if (obj[p][i].destroy) { obj[p][i].destroy() } } obj[p].length = 0 } else if (typeof obj[p] === 'object' && obj[p] instanceof Object) { if (obj[p].destroy) { obj[p].destroy() } } obj[p] = null } } } /** * @description 获取HTML元素数组。 * @param argument - {String | HTMLElement | Window} * @return {Array<HTMLElement>} HTML元素数组。 */ SuperMap.Util.getElement = function () { var elements = [] for (var i = 0, len = arguments.length; i < len; i++) { var element = arguments[i] if (typeof element === 'string') { element = document.getElementById(element) } if (arguments.length === 1) { return element } elements.push(element) } return elements } /** * @description instance of的跨浏览器实现。 * @param o - {Object} 对象。 * @return {boolean} 是否是页面元素 */ SuperMap.Util.isElement = function (o) { return !!(o && o.nodeType === 1) } /** * @description 判断一个对象是否是数组。 * @param a - {Object} 对象。 * @return {boolean} 是否是数组。 */ SuperMap.Util.isArray = function (a) { return (Object.prototype.toString.call(a) === '[object Array]') } /** * @description 从数组中删除某一项。 * @param array - {Array} 数组。 * @param item - {Object} 数组中要删除的一项。 * @return {Array} 执行删除操作后的数组。 */ SuperMap.Util.removeItem = function (array, item) { for (var i = array.length - 1; i >= 0; i--) { if (array[i] === item) { array.splice(i, 1) // breakmore than once?? } } return array } /** * @description 获取某对象再数组中的索引值。 * @param array - {Array} 数组。 * @param obj - {Object} 对象。 * @return {number} 某对象再数组中的索引值。 */ SuperMap.Util.indexOf = function (array, obj) { if (array == null) { return -1 } else { // use the build-in function if available. if (typeof array.indexOf === 'function') { return array.indexOf(obj) } else { for (var i = 0, len = array.length; i < len; i++) { if (array[i] === obj) { return i } } return -1 } } } /** * @description 修改某DOM元素的许多属性。 * @param element - {HTMLElement} 待修改的DOM元素。 * @param id - {string} DOM元素的id。 * @param px - {SuperMap.Pixel} 包含DOM元素的style属性的left和top属性。 * @param sz - {SuperMap.Size} 包含DOM元素的width和height属性。 * @param position - {string} DOM元素的position属性。 * @param border - {string} DOM元素的style属性的border属性。 * @param overflow - {string} DOM元素的style属性的overflow属性。 * @param opacity - {number} 不透明度值。取值范围为 (0.0 - 1.0)。 */ SuperMap.Util.modifyDOMElement = function (element, id, px, sz, position, border, overflow, opacity) { if (id) { element.id = id } if (px) { element.style.left = px.x + 'px' element.style.top = px.y + 'px' } if (sz) { element.style.width = sz.w + 'px' element.style.height = sz.h + 'px' } if (position) { element.style.position = position } if (border) { element.style.border = border } if (overflow) { element.style.overflow = overflow } if (parseFloat(opacity) >= 0.0 && parseFloat(opacity) < 1.0) { element.style.filter = 'alpha(opacity=' + (opacity * 100) + ')' element.style.opacity = opacity } else if (parseFloat(opacity) === 1.0) { element.style.filter = '' element.style.opacity = '' } } /** * @description Takes an object and copies any properties that don't exist from * another properties, by analogy with SuperMap.Util.extend() from * Prototype.js. * * @param to -{Object} The destination object. * @param from -{Object} The source object. Any properties of this object that * are undefined in the to object will be set on the to object. * * @return {Object} A reference to the to object. Note that the to argument is modified * in place and returned by this function. */ SuperMap.Util.applyDefaults = function (to, from) { to = to || {} /* * FF/Windows < 2.0.0.13 reports "Illegal operation on WrappedNative * prototype object" when calling hawOwnProperty if the source object is an * instance of window.Event. */ var fromIsEvt = typeof window.Event === 'function' && from instanceof window.Event for (var key in from) { if (to[key] === undefined || (!fromIsEvt && from.hasOwnProperty && from.hasOwnProperty(key) && !to.hasOwnProperty(key))) { to[key] = from[key] } } /** * IE doesn't include the toString property when iterating over an object's * properties with the for(property in object) syntax. Explicitly check if * the source has its own toString property. */ if (!fromIsEvt && from && from.hasOwnProperty && from.hasOwnProperty('toString') && !to.hasOwnProperty('toString')) { to.toString = from.toString } return to } /** * @param params - {Object} 参数对象。 * @return {string} HTTP的GEI请求中的参数字符串。 * @description 将参数对象转换为HTTP的GEI请求中的参数字符串。例如:"key1=value1&key2=value2&key3=value3"。 */ SuperMap.Util.getParameterString = function (params) { var paramsArray = [] for (var key in params) { var value = params[key] if ((value != null) && (typeof value !== 'function')) { var encodedValue if (typeof value === 'object' && value.constructor === Array) { /* value is an array encode items and separate with "," */ var encodedItemArray = [] var item for (var itemIndex = 0, len = value.length; itemIndex < len; itemIndex++) { item = value[itemIndex] encodedItemArray.push(encodeURIComponent( (item === null || item === undefined) ? '' : item) ) } encodedValue = encodedItemArray.join(',') } else { /* value is a string simply encode */ encodedValue = encodeURIComponent(value) } paramsArray.push(encodeURIComponent(key) + '=' + encodedValue) } } return paramsArray.join('&') } /** * @description 给url追加参数。 * @param url - {string} 待追加参数的url字符串。 * @param paramStr - {string} 待追加的参数。 * @return {string} The new url */ SuperMap.Util.urlAppend = function (url, paramStr) { var newUrl = url if (paramStr) { var parts = (url + ' ').split(/[?&]/) newUrl += (parts.pop() === ' ' ? paramStr : parts.length ? '&' + paramStr : '?' + paramStr) } return newUrl } /** * @description 为了避免浮点精度错误而保留的有效位数。 * @type {number} * @default 14 */ SuperMap.Util.DEFAULT_PRECISION = 14 /** * @description 将字符串以接近的精度转换为数字。 * @param number - {string} 字符串。 * @param precision - {number} 精度。 * @return {number} 数字。 */ SuperMap.Util.toFloat = function (number, precision) { if (precision == null) { precision = SuperMap.Util.DEFAULT_PRECISION } if (typeof number !== 'number') { number = parseFloat(number) } return precision === 0 ? number : parseFloat(number.toPrecision(precision)) } /** * @description 角度转弧度。 * @param x - {number} 角度。 * @return {number} 弧度。 */ SuperMap.Util.rad = function (x) { return x * Math.PI / 180 } /** * @description 从URL字符串中解析出参数对象。 * @param url - {string} url。 * @return {Object} 解析出的参数对象。 */ SuperMap.Util.getParameters = function (url) { // if no url specified, take it from the location bar url = (url === null || url === undefined) ? window.location.href : url // parse out parameters portion of url string var paramsString = '' if (SuperMap.String.contains(url, '?')) { var start = url.indexOf('?') + 1 var end = SuperMap.String.contains(url, '#') ? url.indexOf('#') : url.length paramsString = url.substring(start, end) } var parameters = {} var pairs = paramsString.split(/[&]/) for (var i = 0, len = pairs.length; i < len; ++i) { var keyValue = pairs[i].split('=') if (keyValue[0]) { var key = keyValue[0] try { key = decodeURIComponent(key) } catch (err) { key = unescape(key) } // being liberal by replacing "+" with " " var value = (keyValue[1] || '').replace(/\+/g, ' ') try { value = decodeURIComponent(value) } catch (err) { value = unescape(value) } // follow OGC convention of comma delimited values value = value.split(',') // if there's only one value, do not return as array if (value.length === 1) { value = value[0] } parameters[key] = value } } return parameters } /** * @description 不断递增计数变量,用于生成唯一ID。 * @type {number} * @default 0 */ SuperMap.Util.lastSeqID = 0 /** * @description 创建唯一ID值。 * @param prefix {string} 前缀。 * @return {string} 唯一的ID值。 */ SuperMap.Util.createUniqueID = function (prefix) { if (prefix == null) { prefix = 'id_' } SuperMap.Util.lastSeqID += 1 return prefix + SuperMap.Util.lastSeqID } /** * @memberOf SuperMap * @description 每单位的英尺数。 * @type {Object} * @constant */ SuperMap.INCHES_PER_UNIT = { 'inches': 1.0, 'ft': 12.0, 'mi': 63360.0, 'm': 39.3701, 'km': 39370.1, 'dd': 4374754, 'yd': 36 } SuperMap.INCHES_PER_UNIT['in'] = SuperMap.INCHES_PER_UNIT.inches SuperMap.INCHES_PER_UNIT['degrees'] = SuperMap.INCHES_PER_UNIT.dd SuperMap.INCHES_PER_UNIT['nmi'] = 1852 * SuperMap.INCHES_PER_UNIT.m // Units from CS-Map SuperMap.METERS_PER_INCH = 0.02540005080010160020 SuperMap.Util.extend(SuperMap.INCHES_PER_UNIT, { 'Inch': SuperMap.INCHES_PER_UNIT.inches, 'Meter': 1.0 / SuperMap.METERS_PER_INCH, // EPSG:9001 'Foot': 0.30480060960121920243 / SuperMap.METERS_PER_INCH, // EPSG:9003 'IFoot': 0.30480000000000000000 / SuperMap.METERS_PER_INCH, // EPSG:9002 'ClarkeFoot': 0.3047972651151 / SuperMap.METERS_PER_INCH, // EPSG:9005 'SearsFoot': 0.30479947153867624624 / SuperMap.METERS_PER_INCH, // EPSG:9041 'GoldCoastFoot': 0.30479971018150881758 / SuperMap.METERS_PER_INCH, // EPSG:9094 'IInch': 0.02540000000000000000 / SuperMap.METERS_PER_INCH, 'MicroInch': 0.00002540000000000000 / SuperMap.METERS_PER_INCH, 'Mil': 0.00000002540000000000 / SuperMap.METERS_PER_INCH, 'Centimeter': 0.01000000000000000000 / SuperMap.METERS_PER_INCH, 'Kilometer': 1000.00000000000000000000 / SuperMap.METERS_PER_INCH, // EPSG:9036 'Yard': 0.91440182880365760731 / SuperMap.METERS_PER_INCH, 'SearsYard': 0.914398414616029 / SuperMap.METERS_PER_INCH, // EPSG:9040 'IndianYard': 0.91439853074444079983 / SuperMap.METERS_PER_INCH, // EPSG:9084 'IndianYd37': 0.91439523 / SuperMap.METERS_PER_INCH, // EPSG:9085 'IndianYd62': 0.9143988 / SuperMap.METERS_PER_INCH, // EPSG:9086 'IndianYd75': 0.9143985 / SuperMap.METERS_PER_INCH, // EPSG:9087 'IndianFoot': 0.30479951 / SuperMap.METERS_PER_INCH, // EPSG:9080 'IndianFt37': 0.30479841 / SuperMap.METERS_PER_INCH, // EPSG:9081 'IndianFt62': 0.3047996 / SuperMap.METERS_PER_INCH, // EPSG:9082 'IndianFt75': 0.3047995 / SuperMap.METERS_PER_INCH, // EPSG:9083 'Mile': 1609.34721869443738887477 / SuperMap.METERS_PER_INCH, 'IYard': 0.91440000000000000000 / SuperMap.METERS_PER_INCH, // EPSG:9096 'IMile': 1609.34400000000000000000 / SuperMap.METERS_PER_INCH, // EPSG:9093 'NautM': 1852.00000000000000000000 / SuperMap.METERS_PER_INCH, // EPSG:9030 'Lat-66': 110943.316488932731 / SuperMap.METERS_PER_INCH, 'Lat-83': 110946.25736872234125 / SuperMap.METERS_PER_INCH, 'Decimeter': 0.10000000000000000000 / SuperMap.METERS_PER_INCH, 'Millimeter': 0.00100000000000000000 / SuperMap.METERS_PER_INCH, 'Dekameter': 10.00000000000000000000 / SuperMap.METERS_PER_INCH, 'Decameter': 10.00000000000000000000 / SuperMap.METERS_PER_INCH, 'Hectometer': 100.00000000000000000000 / SuperMap.METERS_PER_INCH, 'GermanMeter': 1.0000135965 / SuperMap.METERS_PER_INCH, // EPSG:9031 'CaGrid': 0.999738 / SuperMap.METERS_PER_INCH, 'ClarkeChain': 20.1166194976 / SuperMap.METERS_PER_INCH, // EPSG:9038 'GunterChain': 20.11684023368047 / SuperMap.METERS_PER_INCH, // EPSG:9033 'BenoitChain': 20.116782494375872 / SuperMap.METERS_PER_INCH, // EPSG:9062 'SearsChain': 20.11676512155 / SuperMap.METERS_PER_INCH, // EPSG:9042 'ClarkeLink': 0.201166194976 / SuperMap.METERS_PER_INCH, // EPSG:9039 'GunterLink': 0.2011684023368047 / SuperMap.METERS_PER_INCH, // EPSG:9034 'BenoitLink': 0.20116782494375872 / SuperMap.METERS_PER_INCH, // EPSG:9063 'SearsLink': 0.2011676512155 / SuperMap.METERS_PER_INCH, // EPSG:9043 'Rod': 5.02921005842012 / SuperMap.METERS_PER_INCH, 'IntnlChain': 20.1168 / SuperMap.METERS_PER_INCH, // EPSG:9097 'IntnlLink': 0.201168 / SuperMap.METERS_PER_INCH, // EPSG:9098 'Perch': 5.02921005842012 / SuperMap.METERS_PER_INCH, 'Pole': 5.02921005842012 / SuperMap.METERS_PER_INCH, 'Furlong': 201.1684023368046 / SuperMap.METERS_PER_INCH, 'Rood': 3.778266898 / SuperMap.METERS_PER_INCH, 'CapeFoot': 0.3047972615 / SuperMap.METERS_PER_INCH, 'Brealey': 375.00000000000000000000 / SuperMap.METERS_PER_INCH, 'ModAmFt': 0.304812252984505969011938 / SuperMap.METERS_PER_INCH, 'Fathom': 1.8288 / SuperMap.METERS_PER_INCH, 'NautM-UK': 1853.184 / SuperMap.METERS_PER_INCH, '50kilometers': 50000.0 / SuperMap.METERS_PER_INCH, '150kilometers': 150000.0 / SuperMap.METERS_PER_INCH }) // unit abbreviations supported by PROJ.4 SuperMap.Util.extend(SuperMap.INCHES_PER_UNIT, { 'mm': SuperMap.INCHES_PER_UNIT['Meter'] / 1000.0, 'cm': SuperMap.INCHES_PER_UNIT['Meter'] / 100.0, 'dm': SuperMap.INCHES_PER_UNIT['Meter'] * 100.0, 'km': SuperMap.INCHES_PER_UNIT['Meter'] * 1000.0, 'kmi': SuperMap.INCHES_PER_UNIT['nmi'], // International Nautical Mile 'fath': SuperMap.INCHES_PER_UNIT['Fathom'], // International Fathom 'ch': SuperMap.INCHES_PER_UNIT['IntnlChain'], // International Chain 'link': SuperMap.INCHES_PER_UNIT['IntnlLink'], // International Link 'us-in': SuperMap.INCHES_PER_UNIT['inches'], // U.S. Surveyor's Inch 'us-ft': SuperMap.INCHES_PER_UNIT['Foot'], // U.S. Surveyor's Foot 'us-yd': SuperMap.INCHES_PER_UNIT['Yard'], // U.S. Surveyor's Yard 'us-ch': SuperMap.INCHES_PER_UNIT['GunterChain'], // U.S. Surveyor's Chain 'us-mi': SuperMap.INCHES_PER_UNIT['Mile'], // U.S. Surveyor's Statute Mile 'ind-yd': SuperMap.INCHES_PER_UNIT['IndianYd37'], // Indian Yard 'ind-ft': SuperMap.INCHES_PER_UNIT['IndianFt37'], // Indian Foot 'ind-ch': 20.11669506 / SuperMap.METERS_PER_INCH // Indian Chain }) /** * @memberOf SuperMap * @description 分辨率与比例尺之间转换的常量,默认值96。 * @type {Object} * @default 96 */ SuperMap.DOTS_PER_INCH = 96 /** * @param scale - {number} * @return {number} 返回正常的scale值 */ SuperMap.Util.normalizeScale = function (scale) { var normScale = (scale > 1.0) ? (1.0 / scale) : scale return normScale } /** * @param scale - {number} 比例尺。 * @param units - {string} 比例尺单位。 * @return {number} 分辨率。 */ SuperMap.Util.getResolutionFromScale = function (scale, units) { var resolution if (scale) { if (units == null) { units = 'degrees' } var normScale = SuperMap.Util.normalizeScale(scale) resolution = 1 / (normScale * SuperMap.INCHES_PER_UNIT[units] * SuperMap.DOTS_PER_INCH) } return resolution } /** * @description 分辨率转比例尺。 * @param resolution - {number} 分辨率。 * @param units - {string} 分辨率单位。 * @return {number} 比例尺。 */ SuperMap.Util.getScaleFromResolution = function (resolution, units) { if (units == null) { units = 'degrees' } var scale = resolution * SuperMap.INCHES_PER_UNIT[units] * SuperMap.DOTS_PER_INCH return scale } /** * @memberOf SuperMap * @description 如果userAgent捕获到浏览器使用的是Gecko引擎则返回true。 * @constant */ SuperMap.IS_GECKO = (function () { var ua = navigator.userAgent.toLowerCase() return ua.indexOf('webkit') === -1 && ua.indexOf('gecko') !== -1 })() /** * @memberOf SuperMap * @description 浏览器名称,依赖于userAgent属性,BROWSER_NAME可以是空,或者以下浏览器: * * "opera" -- Opera * * "msie" -- Internet Explorer * * "safari" -- Safari * * "firefox" -- Firefox * * "mozilla" -- Mozilla * @constant */ SuperMap.Browser = (function () { var name = '' var version = '' var device = 'pc' var uaMatch // 以下进行测试 var ua = navigator.userAgent.toLowerCase() if (ua.indexOf('msie') > -1 || (ua.indexOf('trident') > -1 && ua.indexOf('rv') > -1)) { name = 'msie' uaMatch = ua.match(/msie ([\d.]+)/) || ua.match(/rv:([\d.]+)/) } else if (ua.indexOf('chrome') > -1) { name = 'chrome' uaMatch = ua.match(/chrome\/([\d.]+)/) } else if (ua.indexOf('firefox') > -1) { name = 'firefox' uaMatch = ua.match(/firefox\/([\d.]+)/) } else if (ua.indexOf('opera') > -1) { name = 'opera' uaMatch = ua.match(/version\/([\d.]+)/) } else if (ua.indexOf('safari') > -1) { name = 'safari' uaMatch = ua.match(/version\/([\d.]+)/) } version = uaMatch ? uaMatch[1] : '' if (ua.indexOf('ipad') > -1 || ua.indexOf('ipod') > -1 || ua.indexOf('iphone') > -1) { device = 'apple' } else if (ua.indexOf('android') > -1) { uaMatch = ua.match(/version\/([\d.]+)/) version = uaMatch ? uaMatch[1] : '' device = 'android' } return {name: name, version: version, device: device} })() /** * @description 获取浏览器相关信息。支持的浏览器包括:Opera,Internet Explorer,Safari,Firefox。 * @return {Object} 获取浏览器名称、版本、设备名称。对应的属性分别为 name, version, device。 */ SuperMap.Util.getBrowser = function () { return SuperMap.Browser } /** * @description 浏览器是否支持Canvas。 * @return {boolean} 获取当前浏览器是否支持 HTML5 Canvas 。 */ SuperMap.Util.isSupportCanvas = (function () { var checkRes = true var broz = SuperMap.Util.getBrowser() if (document.createElement('canvas').getContext) { if (broz.name === 'firefox' && parseFloat(broz.version) < 5) { checkRes = false } if (broz.name === 'safari' && parseFloat(broz.version) < 4) { checkRes = false } if (broz.name === 'opera' && parseFloat(broz.version) < 10) { checkRes = false } if (broz.name === 'msie' && parseFloat(broz.version) < 9) { checkRes = false } } else { checkRes = false } return checkRes })() /** * @description 判断;浏览器是否支持Canvas。 * @return {boolean} 获取当前浏览器是否支持 HTML5 Canvas 。 */ SuperMap.Util.supportCanvas = function () { return SuperMap.Util.isSupportCanvas } // 将服务端的地图单位转成SuperMap的地图单位 SuperMap.INCHES_PER_UNIT['degree'] = SuperMap.INCHES_PER_UNIT.dd SuperMap.INCHES_PER_UNIT['meter'] = SuperMap.INCHES_PER_UNIT.m SuperMap.INCHES_PER_UNIT['foot'] = SuperMap.INCHES_PER_UNIT.ft SuperMap.INCHES_PER_UNIT['inch'] = SuperMap.INCHES_PER_UNIT.inches SuperMap.INCHES_PER_UNIT['mile'] = SuperMap.INCHES_PER_UNIT.mi SuperMap.INCHES_PER_UNIT['kilometer'] = SuperMap.INCHES_PER_UNIT.km SuperMap.INCHES_PER_UNIT['yard'] = SuperMap.INCHES_PER_UNIT.yd /** * @description 判断一个 URL 请求是否在当前域中。 * @param url - {string} URL 请求字符串。 * @return {boolean} URL请求是否在当前域中。 */ SuperMap.Util.isInTheSameDomain = function (url) { if (!url) { return true } var index = url.indexOf('//') var documentUrl = document.location.toString() var documentIndex = documentUrl.indexOf('//') if (index === -1) { return true } else { var protocol var substring = protocol = url.substring(0, index) var documentSubString = documentUrl.substring(documentIndex + 2) documentIndex = documentSubString.indexOf('/') var documentPortIndex = documentSubString.indexOf(':') var documentDomainWithPort = documentSubString.substring(0, documentIndex) // var documentPort var documentprotocol = document.location.protocol if (documentPortIndex !== -1) { // documentPort = +documentSubString.substring(documentPortIndex, documentIndex) } else { documentDomainWithPort += ':' + (documentprotocol.toLowerCase() === 'http:' ? 80 : 443) } if (documentprotocol.toLowerCase() !== substring.toLowerCase()) { return false } substring = url.substring(index + 2) var portIndex = substring.indexOf(':') index = substring.indexOf('/') var domainWithPort = substring.substring(0, index) var domain if (portIndex !== -1) { domain = substring.substring(0, portIndex) } else { domain = substring.substring(0, index) domainWithPort += ':' + (protocol.toLowerCase() === 'http:' ? 80 : 443) } var documentDomain = document.domain if (domain === documentDomain && domainWithPort === documentDomainWithPort) { return true } } return false } /** * @description 计算iServer服务的REST图层的显示分辨率,需要从iServer的REST图层表述中获取viewBounds、viewer、scale、coordUnit、datumAxis 五个参数,来进行计算。 * @param viewBounds - {SuperMap.Bounds} 地图的参照可视范围,即地图初始化时默认的地图显示范围。 * @param viewer - {SuperMap.Size} 地图初始化时默认的地图图片的尺寸。 * @param scale - {number} 地图初始化时默认的显示比例尺。 * @param coordUnit - {string} 投影坐标系统的地图单位。 * @param datumAxis - {number} 地理坐标系统椭球体长半轴。用户自定义地图的Options时,若未指定该参数的值,则系统默认为WGS84参考系的椭球体长半轴6378137。 * @return {number} 返回图层显示分辨率。 */ SuperMap.Util.calculateDpi = function (viewBounds, viewer, scale, coordUnit, datumAxis) { // 10000 是 0.1毫米与米的转换。DPI的计算公式:Viewer / DPI * 0.0254 * 10000 = ViewBounds * scale ,公式中的10000是为了提高计算结果的精度,以下出现的ratio皆为如此。 if (!viewBounds || !viewer || !scale) { return } var ratio = 10000 var rvbWidth = viewBounds.getWidth() var rvbHeight = viewBounds.getHeight() var rvWidth = viewer.w var rvHeight = viewer.h // 用户自定义地图的Options时,若未指定该参数的值,则系统默认为6378137米,即WGS84参考系的椭球体长半轴。 datumAxis = datumAxis || 6378137 coordUnit = coordUnit || 'degrees' var dpi if (coordUnit.toLowerCase() === 'degree' || coordUnit.toLowerCase() === 'degrees' || coordUnit.toLowerCase() === 'dd') { let num1 = rvbWidth / rvWidth let num2 = rvbHeight / rvHeight let resolution = num1 > num2 ? num1 : num2 dpi = 0.0254 * ratio / resolution / scale / ((Math.PI * 2 * datumAxis) / 360) / ratio } else { let resolution = rvbWidth / rvWidth dpi = 0.0254 * ratio / resolution / scale / ratio } return dpi } /** * @description 将对象转换成 JSON 字符串。 * @param obj - {Object} 要转换成 JSON 的 Object 对象。 * @return {string} 返回转换后的 JSON 对象。 */ SuperMap.Util.toJSON = function (obj) { var objInn = obj if (objInn == null) { return null } switch (objInn.constructor) { case String: // s = "'" + str.replace(/(["\\])/g, "\\$1") + "'" string含有单引号出错 objInn = '"' + objInn.replace(/(["\\])/g, '\\$1') + '"' objInn = objInn.replace(/\n/g, '\\n') objInn = objInn.replace(/\r/g, '\\r') objInn = objInn.replace('<', '&lt') objInn = objInn.replace('>', '&gt') objInn = objInn.replace(/%/g, '%25') objInn = objInn.replace(/&/g, '%26') return objInn case Array: var arr = [] for (var i = 0, len = objInn.length; i < len; i++) { arr.push(SuperMap.Util.toJSON(objInn[i])) } return '[' + arr.join(',') + ']' case Number: return isFinite(objInn) ? String(objInn) : null case Boolean: return String(objInn) case Date: var dateStr = '{' + "'__type':\"System.DateTime\"," + "'Year':" + objInn.getFullYear() + ',' + "'Month':" + (objInn.getMonth() + 1) + ',' + "'Day':" + objInn.getDate() + ',' + "'Hour':" + objInn.getHours() + ',' + "'Minute':" + objInn.getMinutes() + ',' + "'Second':" + objInn.getSeconds() + ',' + "'Millisecond':" + objInn.getMilliseconds() + ',' + "'TimezoneOffset':" + objInn.getTimezoneOffset() + '}' return dateStr default: if (objInn['toJSON'] != null && typeof objInn['toJSON'] === 'function') { return objInn.toJSON() } if (typeof objInn === 'object') { if (objInn.length) { let arr = [] for (let i = 0, len = objInn.length; i < len; i++) { arr.push(SuperMap.Util.toJSON(objInn[i])) } return '[' + arr.join(',') + ']' } let arr = [] for (let attr in objInn) { // 为解决SuperMap.Geometry类型头json时堆栈溢出的问题,attr == "parent"时不进行json转换 if (typeof objInn[attr] !== 'function' && attr !== 'CLASS_NAME' && attr !== 'parent') { arr.push("'" + attr + "':" + SuperMap.Util.toJSON(objInn[attr])) } } if (arr.length > 0) { return '{' + arr.join(',') + '}' } else { return '{}' } } return objInn.toString() } } /** * @description 根据比例尺和dpi计算屏幕分辨率。 * @param scale - {number} 比例尺。 * @param dpi - {number} 图像分辨率,表示每英寸内的像素个数。 * @param coordUnit - {string} 投影坐标系统的地图单位。 * @param datumAxis - {number} 地理坐标系统椭球体长半轴。用户自定义地图的Options时,若未指定该参数的值,则DPI默认按照WGS84参考系的椭球体长半轴6378137来计算。 * @return {number} 返回当前比例尺下的屏幕分辨率。 */ SuperMap.Util.getResolutionFromScaleDpi = function (scale, dpi, coordUnit, datumAxis) { var resolution = null var ratio = 10000 // 用户自定义地图的Options时,若未指定该参数的值,则系统默认为6378137米,即WGS84参考系的椭球体长半轴。 datumAxis = datumAxis || 6378137 coordUnit = coordUnit || '' if (scale > 0 && dpi > 0) { scale = SuperMap.Util.normalizeScale(scale) if (coordUnit.toLowerCase() === 'degree' || coordUnit.toLowerCase() === 'degrees' || coordUnit.toLowerCase() === 'dd') { // scale = SuperMap.Util.normalizeScale(scale) resolution = 0.0254 * ratio / dpi / scale / ((Math.PI * 2 * datumAxis) / 360) / ratio return resolution } else { resolution = 0.0254 * ratio / dpi / scale / ratio return resolution } } return -1 } /** * @description 根据resolution、dpi、coordUnit和datumAxis计算比例尺。 * @param resolution - {number} 用于计算比例尺的地图分辨率。 * @param dpi - {number} 图像分辨率,表示每英寸内的像素个数。 * @param coordUnit - {string} 投影坐标系统的地图单位。 * @param datumAxis - {number} 地理坐标系统椭球体长半轴。用户自定义地图的Options时,若未指定该参数的值,则DPI默认按照WGS84参考系的椭球体长半轴6378137来计算。 * @return {number} 返回当前屏幕分辨率下的比例尺。 */ SuperMap.Util.getScaleFromResolutionDpi = function (resolution, dpi, coordUnit, datumAxis) { var scale = null var ratio = 10000 // 用户自定义地图的Options时,若未指定该参数的值,则系统默认为6378137米,即WGS84参考系的椭球体长半轴。 datumAxis = datumAxis || 6378137 coordUnit = coordUnit || '' if (resolution > 0 && dpi > 0) { if (coordUnit.toLowerCase() === 'degree' || coordUnit.toLowerCase() === 'degrees' || coordUnit.toLowerCase() === 'dd') { scale = 0.0254 * ratio / dpi / resolution / ((Math.PI * 2 * datumAxis) / 360) / ratio return scale } else { scale = 0.0254 * ratio / dpi / resolution / ratio return scale } } return -1 } /** * @description 转换查询结果。 * @param result - {Object} 查询结果。 * @return {Object} 转换后的查询结果。 */ SuperMap.Util.transformResult = function (result) { if (result.responseText && typeof result.responseText === 'string') { result = JSON.parse(result.responseText) } return result } /** * @description 属性拷贝,不拷贝方法类名(CLASS_NAME)等。 * @param destination - {Object} 拷贝目标。 * @param source - {Object} 源对象。 * */ SuperMap.Util.copyAttributes = function (destination, source) { destination = destination || {} if (source) { for (var property in source) { var value = source[property] if (value !== undefined && property !== 'CLASS_NAME' && typeof value !== 'function') { destination[property] = value } } } return destination } /** * @description 将源对象上的属性拷贝到目标对象上。(不拷贝 CLASS_NAME 和方法) * @param destination - {Object} 目标对象。 * @param source - {Object} 源对象。 * @param clip - {Array<string>} 源对象中禁止拷贝到目标对象的属性,目的是防止目标对象上不可修改的属性被篡改。 * */ SuperMap.Util.copyAttributesWithClip = function (destination, source, clip) { destination = destination || {} if (source) { for (var property in source) { // 去掉禁止拷贝的属性 var isInClip = false if (clip && clip.length) { for (var i = 0, len = clip.length; i < len; i++) { if (property === clip[i]) { isInClip = true break } } } if (isInClip === true) { continue } var value = source[property] if (value !== undefined && property !== 'CLASS_NAME' && typeof value !== 'function') { destination[property] = value } } } return destination } /** * @description 克隆一份Object对象 * @param obj - {Object} 需要克隆的对象。 * @return {Object} 返回对象的拷贝对象,注意是新的对象,不是指向。 */ SuperMap.Util.cloneObject = function (obj) { // Handle the 3 simple types, and null or undefined if (obj === null || typeof obj !== 'object') { return obj } // Handle Date if (obj instanceof Date) { let copy = new Date() copy.setTime(obj.getTime()) return copy } // Handle Array if (obj instanceof Array) { let copy = obj.slice(0) return copy } // Handle Object if (obj instanceof Object) { let copy = {} for (var attr in obj) { if (obj.hasOwnProperty(attr)) { copy[attr] = SuperMap.Util.cloneObject(obj[attr]) } } return copy } throw new Error("Unable to copy obj! Its type isn't supported.") } /** * @description 判断两条线段是不是有交点。 * @param a1 - {SuperMap.Geometry.Point} 第一条线段的起始节点。 * @param a2 - {SuperMap.Geometry.Point} 第一条线段的结束节点。 * @param b1 - {SuperMap.Geometry.Point} 第二条线段的起始节点。 * @param b2 - {SuperMap.Geometry.Point} 第二条线段的结束节点。 * @return {Object} 如果相交返回交点,如果不相交返回两条线段的位置关系。 */ SuperMap.Util.lineIntersection = function (a1, a2, b1, b2) { var intersectValue = null var k1 var k2 var b = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x) var a = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x) var ab = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y) // ab==0代表两条线断的斜率一样 if (ab !== 0) { k1 = b / ab k2 = a / ab if (k1 >= 0 && k2 <= 1 && k1 <= 1 && k2 >= 0) { intersectValue = new SuperMap.Geometry.Point(a1.x + k1 * (a2.x - a1.x), a1.y + k1 * (a2.y - a1.y)) } else { intersectValue = 'No Intersection' } } else { if (b === 0 && a === 0) { var maxy = Math.max(a1.y, a2.y) var miny = Math.min(a1.y, a2.y) var maxx = Math.max(a1.x, a2.x) var minx = Math.min(a1.x, a2.x) if (((b1.y >= miny && b1.y <= maxy) || (b2.y >= miny && b2.y <= maxy)) && (b1.x >= minx && b1.x <= maxx) || (b2.x >= minx && b2.x <= maxx)) { intersectValue = 'Coincident'// 重合 } else { intersectValue = 'Parallel'// 平行 } } else { intersectValue = 'Parallel'// 平行 } } return intersectValue } /** * @description 获取文本外接矩形宽度与高度。 * @param style - {SuperMap.Style} 文本样式。 * @param text - {string} 文本内容。 * @param element - {Object} DOM元素。 * @return {Object} 返回裁剪后的宽度,高度信息。 */ SuperMap.Util.getTextBounds = function (style, text, element) { document.body.appendChild(element) element.style.width = 'auto' element.style.height = 'auto' if (style.fontSize) { element.style.fontSize = style.fontSize } if (style.fontFamily) { element.style.fontFamily = style.fontFamily } if (style.fontWeight) { element.style.fontWeight = style.fontWeight } element.style.position = 'relative' element.style.visibility = 'hidden' // fix 在某些情况下,element内的文本变成竖起排列,导致宽度计算不正确的bug element.style.display = 'inline-block' element.innerHTML = text var textWidth = element.clientWidth var textHeight = element.clientHeight document.body.removeChild(element) return { textWidth: textWidth, textHeight: textHeight } }