123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566 |
- import Feature from 'ol/Feature'
- import Point from 'ol/geom/Point'
- import * as proj from 'ol/proj'
- import Style from 'ol/style/Style'
- import Text from 'ol/style/Text'
- import Fill from 'ol/style/Fill'
- import Stroke from 'ol/style/Stroke'
- import Icon from 'ol/style/Icon'
- import Overlay from 'ol/Overlay'
- import Common from './Common'
- import KBaseObject from './KBaseObject'
- import LngLat from './LngLat'
- import InfoWindow from './InfoWindow'
- /**
- * @description KMap.Marker 点标记类
- */
- class Marker extends KBaseObject{
- /**
- * @description 初始化Marker构造函数
- * @param {number} lng lng 经度 必填
- * @param {number} lat lat 纬度 必填
- * @param {String} markerImgUrl 点标记图标路径 必填
- * @param {number} offsetX X方向偏移量(正向右,负向左) 必填
- * @param {number} offsetY Y方向偏移量(正向下,负向上) 必填
- * @param {number} width 点标记尺寸宽度 必填
- * @param {number} height 点标记尺寸高度 必填
- * @param {JSON} param param.source 指定source 选填
- * @param {KMap.Map} [mapInstance=null] map对象,单地图的时候可不传,多地图时候需要传
- * @constructor
- */
- constructor(lng,lat,url,offsetX,offsetY,width,height,param,mapInstance = null){
- super(mapInstance)
- const vm = this
- //对于必填的参数进行验证
- let lnglat = [lng,lat];
- if(vm.map.getView().getProjection() == proj.get("EPSG:3857")){
- lnglat = proj.fromLonLat([lng,lat]);
- }
- vm.point = new Point(lnglat)
- let marker = new Feature({
- geometry: vm.point,
- properties: null
- })
- vm.marker = marker
- vm.source = vm.mapInstance.markerLayer.getSource()
- if(param && param.source){
- vm.source = param.source
- }
- vm.source.addFeature(marker)
- Common.notEmpty("url",url)
- vm.url = url
- vm.style = vm.initSyle(vm.url,offsetX,offsetY,width,height)
- vm.image = vm.style.getImage()
- vm.contentInfo = {}
- Common.checkLngLat(lng,lat)
- vm.lngLat = [lng,lat]
- }
- /**
- * @description 初始化Marker样式
- * @param {String} url marker 图片地址
- * @param {number} offsetX X方向偏移量(正向右,负向左) 必填
- * @param {number} offsetY Y方向偏移量(正向下,负向上) 必填
- * @param {number} width 点标记尺寸宽度 必填
- * @param {number} height 点标记尺寸高度 必填
- * @memberof Marker
- */
- initSyle(url,offsetX,offsetY,width,height){
- const vm = this
- offsetX = -offsetX/width
- offsetY = -offsetY/height
- let style = new Style({
- image: new Icon({
- src: url,
- anchor: [offsetX,offsetY] //点标记偏移
- }),
- zIndex: 0
- })
- vm.marker.setStyle(style)
- return style
- }
- /**
- * @description 获取点标记id
- * @returns {String} 点标记id
- */
- getId() {
- const vm = this
- let id = vm.marker.getId()
- return id
- }
- /**
- * @description 设置点标记id
- * @param {String}id 点标记id 必填
- */
- setId(id) {
- const vm = this
- vm.marker.setId(id)
- }
- /**
- * 点标记添加文本
- * @param {JSON} param json对象,文本参数,必填
- * param.text 文本内容,必填
- * param.font 字体大小,默认为13px sans-serif,选填
- * param.offsetX X轴偏移(正向右,负向左),选填,默认为0
- * param.offsetY Y轴偏移(正向下,负向上),选填,默认为25
- * param.rotation 旋转角度,选填,默认0
- * param.fill 填充颜色,选填,默认black
- * param.backgroundColor 背景色,选填,默认#fff
- * param.backgroundStroke 边框颜色,选填,默认black
- * param.padding padding值,选填,默认[2,5,2,5]
- */
- setText(param) {
- const vm = this
- let text = (param.text)? param.text : ""
- let font = (param.font)? param.font : '13px sans-serif'
- let offsetX = (param.offsetX)? param.offsetX : 0
- let offsetY = (param.offsetY)? param.offsetY : 25
- let rotation = (param.rotation)? param.rotation : 0
- let fill = (param.fill)? param.fill : "black"
- let backgroundColor = (param.backgroundColor)? param.backgroundColor : "#fff"
- let backgroundStroke = (param.backgroundStroke)? param.backgroundStroke : "black"
- let padding = (param.padding)? param.padding : [2,5,2,5]
- text = new Text({
- text: text,
- font: font,
- offsetX: offsetX,
- offsetY: offsetY,
- rotateWithView: false,//文本是否可旋转
- rotation: rotation,
- fill: new Fill({
- color: fill
- }),
- backgroundFill: new Fill({
- color: backgroundColor
- }),
- backgroundStroke: new Stroke({
- color: backgroundStroke
- }),
- padding: padding
- })
- if(text){
- vm.style.setText(text)
- }
- }
- /**
- * @description 显示点标记
- */
- show(){
- const vm = this
- if(!vm.source.hasFeature(vm.marker)) {
- vm.source.addFeature(vm.marker)
- if(vm.markerPopup){
- vm.map.removeOverlay(vm.markerPopup)
- }
- vm.showContent()
- }
- }
- /**
- * @description 隐藏点标记
- */
- hide(){
- const vm = this
- if(vm.source.hasFeature(vm.marker)) {
- vm.source.removeFeature(vm.marker);
- if(vm.markerPopup){
- vm.map.removeOverlay(vm.markerPopup)
- }
- vm.hideContent()
- }
- }
- /**
- * @description 删除点标记
- */
- remove(){
- const vm = this
- if(vm.source.hasFeature(vm.marker)) {
- vm.source.removeFeature(vm.marker)
- if(vm.markerPopup){
- vm.map.removeOverlay(vm.markerPopup)
- }
- vm.hideContent()
- }
- }
- /**
- * @description 设置点标记为透明样式
- */
- setHideStyle(){
- const vm = this
- let hideStyle = new Style({
- stroke: new Stroke({
- color: "transparent",
- width: 1
- })
- })
- vm.marker.setStyle(hideStyle)
- }
- /**
- * @description 获取点标记图标地址
- * @returns {String} 点标记图标地址
- */
- getIcon(){
- const vm = this
- let icon = vm.image.iconImage_.src_
- return icon
- }
- /**
- * @description 设置点标记图标
- * @param {String} url 点标记图标地址,必填
- */
- setIcon(url,offsetX,offsetY){
- const vm = this
- let style = new Style({
- image: new Icon({
- src: url,
- anchor: [offsetX,offsetY] //点标记偏移
- }),
- zIndex: 0
- })
- vm.marker.setStyle(style)
- }
- /**
- * @description 获取点标记坐标
- * @returns {KMap.LngLat} 返回KMap.LngLat格式的经纬度
- */
- getPosition() {
- const vm = this
- let position = proj.toLonLat(vm.point.getCoordinates())
- position = Common.MapLngLat2KMapLngLat(position)
- return position
- }
- /**
- * @description 设置点标记坐标
- * @param {KMap.LngLat} lnglat 格式的点标记经纬度,必填
- */
- setPosition(lnglat) {
- const vm = this
- lnglat = Common.KMapLngLat2MapLngLat(lnglat)
- let position = proj.fromLonLat(lnglat)
- vm.point.setCoordinates(position)
- // console.log(vm.source.getState())
- if(vm.markerPopup){
- vm.markerPopup.setPosition(vm.point.getCoordinates())
- }
- }
- /**
- * @description 获取点标记缩放值
- * @returns 点标记缩放值
- */
- getScale() {
- const vm = this
- let scale = vm.image.getScale()
- return scale
- }
- /**
- * @description 设置点标记缩放值
- * @param {number}scale 缩放值,必填
- */
- setScale(scale) {
- const vm = this
- vm.image.setScale(scale)
- }
- /**
- * @description 获取点标记旋转弧度
- * @returns 点标记旋转弧度
- */
- getAngle() {
- const vm = this
- let angle = vm.image.getRotation()
- return angle
- }
- /**
- * @description 设置点标记旋转弧度
- * @param {number} rotation 旋转弧度,必填
- */
- setAngle(rotation) {
- const vm = this
- vm.image.setRotation(rotation)
- }
- /**
- * @description 获取点标记叠加顺序
- * @returns 点标记叠加顺序
- */
- getZIndex() {
- const vm = this
- let index = vm.style.getZIndex()
- return index
- }
- /**
- * @description 设置点标记叠加顺序
- * @param {number} index 叠加顺序,必填,index值较大的点标记显示在上方 ,值相同时后创建的点标记显示在上方
- */
- setZIndex(index) {
- const vm = this
- vm.style.setZIndex(index)
- }
- /**
- * @description 设置点标记置顶,当地图有多个marker时,当isTop为true时marker将显示在最上层;当isTop为false时取消置顶
- * @param {boolean} isTop 必填,true:显示在最上层,false:取消置顶
- */
- setTop(isTop) {
- const vm = this
- let markers = vm.source.getFeatures()
- let maxIndex = 0
- for(let i=0; i<markers.length; i++) {
- if(markers[i].getStyle().getZIndex() > maxIndex)
- maxIndex = markers[i].getStyle().getZIndex()
- }
- if(isTop == true) {
- vm.style.setZIndex(++maxIndex)
- }
- else if(isTop == false) {
- vm.style.setZIndex(0)
- }
- }
- /**
- * @description 获取用户自定义属性
- * @returns {number,String,JSON} 用户自定义属性(支持数字,字符串,json)
- */
- getExtData() {
- const vm = this
- let extData = vm.marker.values_.properties
- return extData
- }
- /**
- * @description 设置用户自定义属性
- * @param {number/String/JSON} extData 用户自定义属性(支持数字,字符串,json),必填
- */
- setExtData(extData) {
- const vm = this
- extData = (extData)? extData : null
- if(extData != null) {
- vm.marker.values_.properties = extData
- }
- }
- /**
- * @description 获取点标记地图对象
- * @returns 地图对象
- */
- getMap() {
- const vm = this
- return vm.mapInstance
- }
- /**
- * @description 设置点标记地图对象,传入null时,移除点标记,
- * 建议不使用此API,使用remove方法
- * @param {KMap.Map} map 传入null,移除点标记
- */
- setMap(mapInstance){
- const vm = this
- mapInstance = (mapInstance)? mapInstance : null
- if(mapInstance == null) { //当map为null时,删除点标记
- if(vm.source.hasFeature(vm.marker)) {
- vm.source.removeFeature(vm.marker)
- if(vm.markerPopup){
- vm.map.removeOverlay(vm.markerPopup)
- }
- vm.hideContent()
- }
- }else{
- if(mapInstance != vm.mapInstance){
- vm.mapInstance = mapInstance
- }
- }
- }
- /**
- * @description 注册点标记事件
- * @param {String} eventName 鼠标事件
- * "click":鼠标点击事件 "mousemove":鼠标悬停事件
- * @param {function} callback 选中点标记时触发函数
- */
- on(eventName,callback){
- const vm = this
- if(eventName == "dblclick"){
- vm.map.on(eventName,function(e){
- let feature = vm.map.forEachFeatureAtPixel(e.pixel,function(feature) {
- return feature
- },{
- layerFilter:function(e){
- if(e.values_.name == "defaultMarkerLayer"){
- return true
- }else{
- return false
- }
- }
- })
- if(feature && feature == vm.marker){
- callback(e)
- }
- })
- }else{
- vm.marker.on(eventName,function(e) {
- if(eventName == "mousemove"){
- if(vm.marker.ol_uid != vm.mapInstance.InfowindowmoveUID)
- {
- vm.mapInstance.InfowindowmoveUID = vm.marker.ol_uid
- callback(e)
- }
- }
- else
- {
- callback(e)
- }
- })
- }
- }
- /**
- * @description 设置鼠标悬停时,点标记显示内容
- * @param {title} title 鼠标悬停内容(支持div模块/字符串格式),必填
- * @param {number} offsetX X轴方向偏移量(正向右,负向左),选填参数,默认为0
- * @param {number} offsetY Y轴方向偏移量(正向下,负向上),选填参数,默认为-25
- */
- setTitle(title,offsetX,offsetY) {
- const vm = this
- title = (title != undefined)? title : ""
- let lnglat = vm.getPosition()
- vm.on("mousemove",function(){
- let content
- //if(title.indexOf("div")<0) { content = "<div class='olText'>"+title+"</div>" }
- if(title.indexOf("div")<0) {
- content = "<div class='olText'><p class='olTextP' title='"+title+"'>"+title+"</p></div>"
- }else {
- content = title
- }
- let infoWindow = new InfoWindow({
- content: content,
- position: lnglat,
- offsetX: offsetX,
- offsetY: offsetY,
- type: "mousemove"
- })
- infoWindow.open(false) //显示标题内容
- })
- }
- /**
- * @description 设置挂载Label
- * @param {DOM} content DOM元素
- * @param {number} offsetX DOM元素X偏移,向左为负,向右为正
- * @param {number} offsetY DOM元素X偏移,向上为负,向下为正
- * @memberof Marker
- */
- setLabel(content,offsetX,offsetY){
- const vm = this
- let contentParent = document.createElement('div')
- contentParent.insertAdjacentHTML('beforeend',content)
- let offset = [0,0]
- if(offsetX){
- offset[0] = offsetX
- }
- if(offsetY){
- offset[1] = offsetY
- }
- vm.markerPopup = new Overlay({
- element: contentParent,
- position: proj.fromLonLat([vm.lng,vm.lat]),
- offset: offset//图片偏移量
- })
- vm.map.addOverlay(vm.markerPopup)
- }
- /**
- * @description 移除
- * @memberof Marker
- */
- removeLabel(){
- const vm = this
- if(vm.markerPopup){
- vm.map.removeOverlay(vm.markerPopup)
- }
- }
- /**
- * @description 隐藏挂载dom元素
- */
- hideContent(){
- const vm = this
- if(vm.contentInfo.overlay && vm.contentInfo.show){
- vm.contentInfo.show = false
- vm.map.removeOverlay(vm.contentInfo.overlay)
- }
- }
- /**
- * @description 显示挂载dom元素
- */
- showContent(){
- const vm = this
- if(vm.contentInfo.overlay && !vm.contentInfo.show){
- vm.contentInfo.show = true
- vm.map.addOverlay(vm.contentInfo.overlay)
- }
- }
- /**
- * @description 设设置挂载的DOM,
- * @param {DOM} content 挂载到Map的DOM元素
- * @param {number} offsetX DOM元素在地图上X偏移,向左为负,向右为正
- * @param {number} offsetY DOM元素在地图上Y偏移,向上为负,向下为正
- * @memberof Marker
- */
- setContent(content,offsetX,offsetY){
- const vm = this
- let overlay = new Overlay({
- element: content,
- offset:[offsetX,offsetY]
- })
- vm.contentInfo.content = content
- vm.contentInfo.offsetX = offsetX
- vm.contentInfo.offsetY = offsetY
- vm.contentInfo.overlay = overlay
- vm.contentInfo.show = true
- vm.map.addOverlay(overlay)
- let coordinate = vm.lngLat
- overlay.setPosition(proj.fromLonLat(coordinate))
- }
- /**
- * @description 设置挂载的DOM可变长度的,
- * @param {DOM} content DOM 挂载到Map的DOM元素
- * @param {number} offsetY DOM元素在地图上Y偏移,向上为负,向下为正
- * @memberof Marker
- */
- setContentChangeAbleWidth(content,offsetY){
- const vm = this
- let overlay = new Overlay({
- element: content,
- positioning:"bottom-center",
- offset:[0,offsetY]
- })
- vm.contentInfo.content = content
- vm.contentInfo.offsetX = 0
- vm.contentInfo.offsetY = offsetY
- vm.contentInfo.overlay = overlay
- vm.contentInfo.show = true
- vm.map.addOverlay(overlay)
- let coordinate = vm.lngLat
- overlay.setPosition(proj.fromLonLat(coordinate))
- }
- }
- export default Marker
|