import { AutocompleteSearchCallback, AutocompleteSelectCallback, ClickOptions, DrivingSearchCallback, EventCallback, HtmlRender, IAutocomplete, ICircle, IDriving, IInfoWindow, ILayer, ILngLat, IMap, IMapOptions, IMarker, IMarkerCluster, IMarkOptions, IMouseTool, IPixel, IPlaceSearch, IRenderClusterMarker, ISelf, ITileLayer, PixelRender, PlaceSearchCallback } from './map' import { SearchDownList } from './component/SearchDownListPlugins/SearchDownList'; import { SearchService } from '@src/app/searchComponent.service'; import * as ObjectID from 'bson-objectid'; import * as global from 'globals'; declare var KMap: any; class KedaBasic implements ISelf { self: any; discriminator: string = "ISelf"; } const cityPosition: number[] = [121.469167918, 31.232262275]; //上海市 坐标 const beforCity: string = "上海市"; //当前城市 const cityCode: string = "310000"; //当前城市 行政编码 export class KeDaMap extends KedaBasic implements IMap { constructor(container: string, options: IMapOptions) { //地图初始化 super(); let that = this let opt = Object.assign({}, { containerId: container }, options) as any; opt.configUrl = "/assets/kmap/Kmap.config.json"; opt.targetCoordinateType = "WGS84"; opt.center = cityPosition; opt.zoom === undefined ? opt.zoom = 9 : opt.zoom = opt.zoom - 2 let mapLayer = function () { if (opt.viewMode && opt.viewMode == "3D") { let data = { type: 'FeatureCollection', features: [ { type: 'Feature', geometry: { type: 'Point', coordinates: cityPosition }, properties: { height: 30 } } ] }; that.self.add3DLayer({ data: data }); } } opt.onLoadMap = mapLayer this.self = new KMap(opt); } containerToLngLat(e: IPixel): ILngLat { let d = null; this.self.getGeoPointByPixel({ ePoint: e.self, callback: (e) => { d = new KeDaLngLat(e.data.lng, e.data.lat); } }) return d; } setAdministrativeAreaStyle(component: any, getData?: Function, setData?: Function) { //自定义 行政区划 样式 let beforeCode = cityCode //当前 城市行政编码 let setTime //延时器 let initMap = ()=>{ //绘制地图 this.self.getGeometryByAdminCode({ code: beforeCode, callback: function (res) { this.self.highlightPolygon({ color: 'rgba(255,0,0,0.5)', area:res.data }); } }); } //function let clickMap = (e)=>{ //点击地图 console.log(e,'点击map') this.self.getAdminInfoByPoint({ point: e.position, callback: (res)=>{ if (res.status === 10) { if (res.data.adminId != beforeCode && res.data.parentId === cityCode) { //当前点击位置已改动 window.clearTimeout(setTime) beforeCode = res.data.adminId setTime = window.setTimeout(()=>{ initMap() },100) let name = { properties:{name: res.data.cityName } } getData && getData.call(component,name); return } else if (res.data.adminId != beforeCode || res.data.parentId != cityCode) { window.clearTimeout(setTime) beforeCode = cityCode setTime = window.setTimeout(()=>{ initMap() },100) setData && setData.call(component); } } else { if (beforeCode != cityCode) { window.clearTimeout(setTime) beforeCode = cityCode setTime = window.setTimeout(()=>{ initMap() },100) setData && setData.call(component); } } } }); } this.self.addEventOnMap({ event: "load", handler: ()=>{ initMap() let level = Number(sessionStorage.getItem("level")) if (level < 3) { this.self.addEventOnMap({ event: "click", handler: clickMap }); } } }); } clearMap() { this.self.clear() } distance(a: number[], b: number[]) { let num this.self.distancePoints({ startPoint: a, endPoint: b, units: "meters", callback: (res) => { num = res.data } }) return num } setZoomAndCenter(zoom: number, pos: number[]) { this.self.flyTo({ zoom: zoom, point: pos, }); } getBounds() { let bounds this.self.getBounds({ callback: (res) => { bounds = res.data console.log(res.data) } }) return bounds } add(obj: any) { if (obj && obj.typeName === "KeDaMarker") { let _marker = (obj as KeDaMarker); _marker.map = this; this.self.addMarkers(_marker.self) } else if (obj == "卫星图层") { this.self.setImageLayer({ display: true }) } else if (obj == "路网图层") { this.self.setMapStyle({ solution: '8888' }); } } remove(obj: any) { if (obj && obj.typeName === "KeDaMarker") { this.self.removeMarkersByType({ markerType: obj.id }) } else if (obj && obj.typeName === "KeDaInfoWindow") { this.self.removeAllPopups() } else if (obj && obj.typeName === "KeDaCircle") { this.self.removeLayer({ layerId: obj.id }) } else if (obj == "卫星图层") { this.self.setImageLayer({ display: false }) } else if (obj == "路网图层") { this.self.setMapStyle({ solution: '9999' }); } } setCity(city: string) { let that = this if (city.includes("上海") && this.self.flyTo instanceof Function) { that.self.flyTo({ zoom: 9, point: cityPosition }); } } getCity(callback: Function) { return callback } setZoom(zoom: number) { this.self.zoomTo({ zoom: zoom }); } getZoom(): number { let num this.self.getZoom({ callback: (e) => { num = e.data; } }) return num } setCenter(pos: number[] | ILngLat) { let position = [] if (pos instanceof Array) { position = pos } else { position = pos.getArray(); } this.self.flyTo({ point: position }) } getCenter() { let center this.self.getCenter({ callback: function (res) { center = res.data console.log(res); } }); return center } on(eventName: string, callback: EventCallback, component?: any) { let eventMapProfile = { complete: "load", click: "click", rightclick: "contextmenu" }; if (eventName == "click") { this.self.addEventOnMap({event: "click", handler: (res)=>{ console.log(res,'地图点击') var d:ClickOptions = res.data.map(); callback.call(component,d); } }); } else { this.self.addEventOnMap({ event: eventMapProfile[eventName], handler: callback }); } } } export class KeDaPixel extends KedaBasic implements IPixel { constructor(x: number, y: number) { super(); this.x = x; this.y = y; this.self = [x, y]; } getArray(): number[] { return this.self; } x: number; y: number; } export class KeDaMarker extends KedaBasic implements IMarker { public map: KeDaMap; public typeName: string = "KeDaMarker"; constructor(options: IMarkOptions) { super(); let pos = [] if (options.position instanceof Array) { pos = options.position } else { pos = options.position.getArray() } let points = [{ point: pos, htmlText: null, }] let marker = { data: points, url: '/assets/images/dingwei.png', offset: options.offset ? options.offset.self : null, markerType: "KedaMarker", ended: (res) => { this.id = res.data; } }; this.self = marker; this._position = pos if (options.map) { this.map = options.map as KeDaMap this.map.self.addMarkers(this.self); } } _position: number[]; setContent(html: string) { //marker 添加 DOM元素 this.map.self.setMarkerProperty({ type: "markerType", markerType: "KedaMarker", points: [ { htmlText: html } ] }) } setPosition(position: number[]) { this.map.self.setMarkerProperty({ type: "markerType", markerType: "KedaMarker", points: [position] }) } setMap() { this.map.self.removeMarkersByType({ markerType: this.id }) } get id(): string { return this.self.id } set id(str: string) { this.self.id = str } public bindObj = []; // event on(eventName: string, callback: EventCallback, component?: any) { this.bindObj.push({ eventName: eventName, callback: callback, component: component, }); this.startBindEvent(); } startBindEvent() { if (this.map !== undefined) { this.bindObj.forEach((item, index) => { this.map.self.addEventOnMarkers({ selector: `.${this.id}`, event: item.eventName, handler: (res) =>{ console.log(res,'marker点击') var d:ClickOptions = res.data.map(); d.target.id = this.self.id item.callback.call(item.component,d) } }); }) this.bindObj = []; } } } export class KeDaLngLat extends KedaBasic implements ILngLat { constructor(lng: number, lat: number) { super(); this.lng = lng this.lat = lat this.self = this; } offset(x: number, y: number): ILngLat { return x = 2 * Math.asin(Math.sin(Math.round(x) / 12756274) / Math.cos(this.kT * Math.PI / 180)), x = this.KL + 180 * x / Math.PI, y = 2 * Math.asin(Math.round(y) / 12756274), new KeDaLngLat(x, y); } typeName = "LngLat"; lng: number; lat: number; get KL(): number { return this.lng; } get kT(): number { return this.lat; } getArray(): number[] { return [this.lng, this.lat]; } } export class KedaDriving extends KedaBasic implements IDriving { //路线导航 public map: KeDaMap; public policy: number; // 0:快捷模式, 4:躲避拥堵 public id: string; constructor(options: any) { super(); this.map = options.map as KeDaMap options.policy === undefined ? this.policy = 0 : this.policy = options.policy } search(component: any, posStart: ILngLat, posEnd: ILngLat, callback: DrivingSearchCallback) { let params = { startPoint: posStart.getArray(), endPoint: posEnd.getArray(), error: () => { alert('路线规划失败!') }, ended: (res) => { this.id = res.data let router = { routes:[] } console.log(res.data) callback.call(component,'complete',router) } } if (this.policy === 0) { //快捷模式 this.map.self.createMinDistanceRoutePlanning(params) } else { //躲避拥堵 this.map.self.createMinTimeRoutePlanning(params) } } clear() { this.map.self.removeRoutePlanning({ id: this.id }) } } export class KedaAutocomplete extends KedaBasic implements IAutocomplete { //Autocomplete 关键字搜索 private component: any; private searchDownList: SearchDownList; private $input: any; constructor(options: any, component: any) { super(); this.component = component if (options && options.input != undefined) { //绑定input框 搜索事件 this.searchDownList = global.injector.get(SearchService).appendComponentToBody(SearchDownList).instance; this.$input = document.getElementById(options.input); this.searchDownList.init(this.$input) this.$input.oninput = (e) =>{ //监听 input事件 (this.component.map as KeDaMap).self.queryInfoByType({ code: cityCode, keyword: this.$input.value, searchType: [], callback: (res) => { let list = res.data this.searchDownList.searchList = list || [] } }) // search } } } on(eventName: string, callback: AutocompleteSelectCallback) { this.searchDownList.setClickHander(e => { console.log(e+'Keda') callback.call(this.component,e); }); } search(address: string, callback: AutocompleteSearchCallback) { (this.component.map as KeDaMap).self.queryInfoByType({ code: cityCode, keyword: address, searchType: [], callback: (res) => { console.log(res) callback.call(this.component,'complete',res); } }) } } export class KedaPlaceSearch extends KedaBasic implements IPlaceSearch { //PlaceSearch 关键字搜索 private component: any constructor(component: any) { super(); this.component = component } search(address: string, callback: PlaceSearchCallback) { (this.component.map as KeDaMap).self.queryInfoByType({ code: cityCode, keyword: address, searchType: [], callback: (res) => { console.log(res) callback.call(this.component,'complete',res); } }) } } export class KedaCircle extends KedaBasic implements ICircle { //圆形 图层 public typeName: string = "KeDaCircle"; public id: string; constructor(options: any) { super(); let circle = { data: { type: 'FeatureCollection', features: [ { type: 'Feature', geometry: { type: 'Point', coordinates: cityPosition }, properties: { id: ObjectID.default.generate() } } ] }, defaultStyles: { "line-dasharray": options.strokeDasharray, "line-opacity": options.strokeOpacity, "fill-color": options.fillColor, "fill-opacity": options.fillOpacity, }, radius: 0, draggable: false, updateHandler: (res) => { console.log(res) }, end: (res) => { this.id = res } } this.self = circle } setRadius(num: number) { //设置圆的半径 this.self.radius = num / 1000 } setCenter(pos: number[]) {//设置圆的中心 this.self.center = pos } setMap(map: IMap) {//把圆添加到 map map.self.addGeometryCircleLayer(this.self) } } export class KedaMarkerCluster extends KedaBasic implements IMarkerCluster { //Marker 聚合物 constructor(map: IMap, list: Object[], options: any) { super(); } on(eventName: string, callback: Function): void { throw new Error('Method not implemented.'); } setData(list: any[]) { throw new Error('Method not implemented.'); } } export class KedaRenderClusterMarkerr extends KedaBasic implements IRenderClusterMarker { //Marker 聚合物 配置项 constructor() { super(); } getFirstImages(context: any): string { throw new Error('Method not implemented.'); } contentRender: HtmlRender; contentNonRender: HtmlRender; pixelRender: PixelRender; pixelNonRender: PixelRender; } export class KedaInfoWindow extends KedaBasic implements IInfoWindow { //信息窗体 public typeName: string = "KeDaInfoWindow"; constructor(options) { super(); let opt = { htmlText: options.content, anchor: 'bottom', point: options.position, closeButton: true, } this.self = opt } open(map: IMap) { map.self.addPopup(this.self); } listen(html: any, event: string, callback: Function) { html.addEventListener(event, callback) } } export class KedaLayer extends KedaBasic implements ILayer { //mapInit 配置项 constructor(options: any) { super(); } } export class KedaTileLayer extends KedaBasic implements ITileLayer { //图层切换 constructor() { super(); } Satellite() { //卫星图层 return "卫星图层" } RoadNet() { //路网图层 return "路网图层" } } export class KedaMouseTool extends KedaBasic implements IMouseTool { //地图工具 constructor(map: IMap) { super(); this.self = map.self } layerIds = []; layerIdAreas = []; rule(options: any) { let that = this this.self.measureDistance({ units: 'kilometers', callback: (result) => { var startText, sClass = that.self.mapType === 'AG' ? 'ag-popup-tools' : 'mm-popup-tools'; var result = result.data; if (!result.isEnd) { if (result.isStart) { that.self.addTexts({ points: [{ point: result.point, htmlText: '起点', class: sClass }], anchor: 'left', ended: function (res) { console.log(res); that.layerIds.push(res.data); startText = res.data; } }); } else { that.self.addTexts({ points: [{ point: result.point, htmlText: result.distance.toFixed(4) + 'km', class: sClass }], anchor: 'left', ended: function (res) { console.log(res); that.layerIds.push(res.data); } }); } } else { if (result.index >= 1) { if (result.isFailure) { that.layerIds.forEach((layerId) => { that.self.removeTextsByType({ textType: layerId }); }); return; } that.layerIds.push(result.layerId); if (that.self.mapType === 'BM') { that.self.addTexts({ points: [{ point: result.point, htmlText: '总距离:' + result.distance.toFixed(4) + 'km', class: sClass }], anchor: 'left', ended: function (res) { console.log(res); that.layerIds.push(res.data); } }); } } else { that.layerIds.forEach((layerId) => { that.self.removeTextsByType({ textType: layerId }); }); } } } }); } measureArea(options: any) { let that = this this.self.measureArea({ units: 'meters', callback: (result) => { var sClass = that.self.mapType === 'AG' ? 'ag-popup-tools' : 'mm-popup-tools'; var result = result.data; if (!result.isEnd) { if (result.index >= 2) { that.self.addTexts({ points: [{ point: result.point, htmlText: result.area + '平方米', class: sClass }], anchor: 'left', ended: function (res) { console.log(res); that.layerIdAreas.push(res.data); } }); } } else { if (result.index >= 2) { if (result.isFailure) { that.layerIdAreas.forEach((layerId) => { that.self.removeTextsByType({ textType: layerId }); }); return; } that.layerIdAreas.push(result.layerId); if (that.self.mapType === 'BM') { that.self.addTexts({ points: [{ point: result.point, htmlText: '总面积:' + result.area + '平方米', class: sClass }], anchor: 'left', ended: function (res) { console.log(res); that.layerIdAreas.push(res.data); } }); } } } } }); } close(isTrue: boolean) { if (isTrue) { this.self.clear(); for (var i in this.layerIds) { this.self.removeTextsByType({ textType: this.layerIds[i] }); } for (var i in this.layerIdAreas) { this.self.removeTextsByType({ textType: this.layerIdAreas[i] }); } this.layerIdAreas = []; this.layerIds = []; } } }