ol-extent
Version:
a JavaScript library for openlayers extent
295 lines (269 loc) • 7.5 kB
JavaScript
/**
* Created by FDD on 2017/10/12.
* @desc 坐标实时拾取
*/
import '../assets/scss/mousePosition.scss'
import ol from 'openlayers'
import {BASE_CLASS_NAME} from '../constants'
import {create, on} from '../utils';
class MousePosition extends ol.control.Control {
static Property_ = {
PROJECTION: 'projection',
COORDINATE_FORMAT: 'coordinateFormat',
UNITS: ['经度', '纬度']
};
static render = function (mapEvent) {
let frameState = mapEvent.frameState
if (!frameState) {
this.mapProjection_ = null
} else {
if (this.mapProjection_ !== frameState.viewState.projection) {
this.mapProjection_ = frameState.viewState.projection
this.transform_ = null
}
}
if (this.getMap() && this.lastMouseMovePixel_) {
if (this.followMouse_) {
this.followMousePopver_(this.lastMouseMovePixel_)
} else {
this.updateHTML_(this.lastMouseMovePixel_)
}
}
};
static identityTransform = function (input, output, dimension) {
if (output !== undefined && input !== output) {
for (let i = 0, ii = input.length; i < ii; ++i) {
output[i] = input[i];
}
input = output;
}
return input;
};
constructor (options = {}) {
const className_ = options.className !== undefined ? options.className : 'ole-mouse-position';
const element = create('div', (className_ + ' ' + BASE_CLASS_NAME.CLASS_UNSELECTABLE));
const render = options.render ? options.render : MousePosition.render;
super({
element: element,
render: render,
target: options.target
});
this.on('change:' + MousePosition.Property_.PROJECTION, this.handleProjectionChanged_, this);
if (options.coordinateFormat) {
this.setCoordinateFormat(options.coordinateFormat);
}
if (options.projection) {
this.setProjection(options.projection);
}
if (options.units) {
this.setUnits(options.units);
}
/**
* @private
* @type {string}
*/
this.undefinedHTML_ = options.undefinedHTML !== undefined ? options.undefinedHTML : '';
/**
* @private
* @type {string}
*/
this.renderedHTML_ = element.innerHTML;
/**
* @private
* @type {ol.proj.Projection}
*/
this.mapProjection_ = null;
/**
* @private
* @type {?ol.TransformFunction}
*/
this.transform_ = null;
/**
* @private
* @type {ol.Pixel}
*/
this.lastMouseMovePixel_ = null;
/**
* 是否显示跟随气泡(同步开启点击锚坐标)
* @type {boolean}
* @private
*/
this.followMouse_ = options['followMouse'] === true ? options['followMouse'] : false;
/**
* 当前气泡
* @type {null}
* @private
*/
this.popver_ = null;
/**
* 容器边界
* @type {null}
* @private
*/
this._bounds = null;
/**
* className
* @type {string}
* @private
*/
this.className_ = className_;
}
/**
* 处理投影变化事件
* @private
*/
handleProjectionChanged_ () {
this.transform_ = null
}
/**
* 获取投影转换函数
* @returns {ol.CoordinateFormatType|undefined}
*/
getCoordinateFormat () {
return (this.get(MousePosition.Property_.COORDINATE_FORMAT))
}
/**
* 获取投影
* @returns {ol.proj.Projection|undefined}
*/
getProjection () {
return (this.get(MousePosition.Property_.PROJECTION));
}
/**
* 处理鼠标移动事件
* @param event
*/
handleMouseMove (event) {
let map = this.getMap();
if (map) {
this.lastMouseMovePixel_ = map.getEventPixel(event);
if (this.lastMouseMovePixel_) {
if (this.followMouse_) {
this.followMousePopver_(event);
} else {
this.updateHTML_(this.lastMouseMovePixel_);
}
}
}
}
/**
* 显示气泡
* @private
*/
followMousePopver_ () {
let html = this.getHTML_(this.lastMouseMovePixel_);
let map = this.getMap();
let coordinates = map.getCoordinateFromPixel(this.lastMouseMovePixel_);
if (!this.popver_) {
let ele = create('div', this.className_ + '_overlay');
ele.innerHTML = html;
this.popver_ = new ol.Overlay({
element: ele,
offset: [10, 0],
position: coordinates,
positioning: 'center-left'
});
map.addOverlay(this.popver_);
map.render();
} else {
let _ele = this.popver_.getElement();
_ele.innerHTML = html;
if (_ele.offsetWidth >= this._bounds.width - this.lastMouseMovePixel_[0]) {
this.popver_.setPositioning('center-right');
this.popver_.setOffset([-10, 0]);
} else {
this.popver_.setPositioning('center-left');
this.popver_.setOffset([10, 0]);
}
this.popver_.setPosition(coordinates);
this.popver_.setElement(_ele);
}
}
/**
* 处理鼠标移出视图事件
* @param event
*/
handleMouseOut (event) {
this.updateHTML_(null);
this.lastMouseMovePixel_ = null;
}
/**
* setMap
* @param map
*/
setMap (map) {
super.setMap.call(this, map);
if (map) {
let viewport = map.getViewport();
this._bounds = map.getTargetElement().getBoundingClientRect();
on(viewport, 'mousemove', this.handleMouseMove, this);
on(viewport, 'mouseout', this.handleMouseOut, this);
}
}
/**
* 设置坐标格式化函数
* @param format
*/
setCoordinateFormat (format) {
this.set(MousePosition.Property_.COORDINATE_FORMAT, format);
}
/**
* 设置投影转换
* @param projection
*/
setProjection (projection) {
this.set(MousePosition.Property_.PROJECTION, ol.proj.get(projection));
}
/**
* 设置显示单位
* @param units
*/
setUnits (units) {
this.set(MousePosition.Property_.PROJECTION, units)
}
/**
* 更新页面控件
* @param pixel
* @private
*/
updateHTML_ (pixel) {
const html = this.getHTML_(pixel);
if (!this.renderedHTML_ || html !== this.renderedHTML_) {
this.element.innerHTML = html;
this.renderedHTML_ = html;
}
}
/**
* 获取dom
* @param pixel
* @returns {string|*}
* @private
*/
getHTML_ (pixel) {
let html = this.undefinedHTML_;
if (pixel && this.mapProjection_) {
if (!this.transform_) {
let projection = this.getProjection();
if (projection) {
this.transform_ = ol.proj.getTransformFromProjections(this.mapProjection_, projection);
} else {
this.transform_ = MousePosition.identityTransform;
}
}
let map = this.getMap();
let coordinate = map.getCoordinateFromPixel(pixel);
if (coordinate) {
this.transform_(coordinate, coordinate);
let coordinateFormat = this.getCoordinateFormat();
if (coordinateFormat) {
html = coordinateFormat(coordinate)
} else {
html = MousePosition.Property_.UNITS[0] + ':' + coordinate[0] +
' ' + MousePosition.Property_.UNITS[1] + ':' + coordinate[1]
}
}
}
return html
}
}
export default MousePosition