UNPKG

@mint-ui/map

Version:

- React map library - Control various map with one interface - Google, Naver, Kakao map supported now - Typescript supported - Canvas marker supported

740 lines (604 loc) 26.2 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var tslib = require('tslib'); var log = require('../core/util/log.js'); var status = require('../core/util/status.js'); var MintMapController = require('../core/MintMapController.js'); var waiting = require('../core/util/waiting.js'); var MapEventTypes = require('../types/MapEventTypes.js'); var MapTypes = require('../types/MapTypes.js'); require('../core/MintMapCore.js'); require('react'); require('../types/MapDrawables.js'); require('../core/provider/MintMapProvider.js'); require('react-dom'); require('../core/util/animation.js'); require('../core/util/geo.js'); var polygon = require('../core/util/polygon.js'); require('../naver/NaverMintMapController.js'); require('../core/advanced/MapLoadingComponents.js'); require('../core/wrapper/MapControlWrapper.js'); var GoogleMintMapController = /** @class */ function (_super) { tslib.__extends(GoogleMintMapController, _super); function GoogleMintMapController(props) { var _a; var _this = _super.call(this, props) || this; _this.type = 'google'; _this.map = null; _this.scriptUrl = 'https://maps.googleapis.com/maps/api/js'; _this.scriptModules = ['marker']; //'drawing' , 'geometry' , 'journeySharing' , 'localContext' , 'places' , 'visualization'] _this.mapEvent = new MapEventTypes.MapEvent(); _this.mapUIEvent = new MapEventTypes.MapUIEvent(); _this.polylineEvents = ['mouseover', 'mouseout']; _this.polygonEvents = ['mouseover', 'mouseout']; _this.markerEvents = ['click', 'mouseover', 'mouseout']; _this.dragged = false; _this.lastMousePosition = null; _this.destroyMap = function () { try { _this.removeAllEventListener(); _this.map && google.maps.event.clearInstanceListeners(_this.map); } catch (e) { console.log('google map destroy error', e); } // console.log(`${this.type} map destroyed`); }; _this.eventMap = new Map(); //scriptModules 병합 if (props.scriptModules) { (_a = _this.scriptModules).push.apply(_a, props.scriptModules); } //google 은 zoomstart 가 없으므로 zoom_changed 로 대체 (하지만 zooming 되는 내내 여러번 호출됨) //나중에 naver 와 마찬가지로 zoomstart 1번 zoom_changed 1번 호출되도록 바꾸는것 고려중 _this.mapEvent.ZOOMSTART = 'zoom_changed'; Object.freeze(_this.mapEvent); Object.freeze(_this.mapUIEvent); return _this; // console.log(`${this.type} controller loadded`); } GoogleMintMapController.prototype.createPolyline = function (polyline) { var _this = this; var _a = polyline.options, position = _a.position, _b = _a.lineColor, lineColor = _b === void 0 ? 'blue' : _b, _c = _a.lineSize, lineSize = _c === void 0 ? 1 : _c, _d = _a.lineOpacity, lineOpacity = _d === void 0 ? 1 : _d, _e = _a.visible, visible = _e === void 0 ? true : _e, _f = _a.editable, editable = _f === void 0 ? false : _f, event = _a.event; //console.log('polyline', polyline); if (this.map && Array.isArray(position)) { var path = position.map(function (elem) { return Array.isArray(elem) ? new MapTypes.Position(elem[1], elem[0]) : elem; }); //console.log('polyline path',path); var pol_1 = new google.maps.Polyline({ map: this.map, path: path, strokeColor: lineColor, strokeWeight: lineSize, strokeOpacity: lineOpacity, clickable: true, visible: visible, editable: editable }); //console.log('google polyline created', polyline); polyline.native = pol_1; event && event.forEach(function (handler, key) { if (_this.polylineEvents.includes(key)) { pol_1.addListener(key, handler); } }); } }; GoogleMintMapController.prototype.updatePolyline = function (polyline, options) { //console.log('controller updatePolyline', options); if (polyline && polyline.native && polyline.native instanceof google.maps.Polyline) { var polylineOption = this.getValidOptions(options); //console.log('controller updatePolyline start', polylineOption); if (this.map && Array.isArray(options.position)) { var path = options.position.map(function (elem) { return Array.isArray(elem) ? new MapTypes.Position(elem[1], elem[0]) : elem; }); polylineOption.path = path; } polyline.native.setOptions(polylineOption); } }; GoogleMintMapController.prototype.createPolygon = function (polygon) { var _this = this; var _a = polygon.options, position = _a.position, innerPositions = _a.innerPositions, _b = _a.lineColor, lineColor = _b === void 0 ? 'green' : _b, _c = _a.lineSize, lineSize = _c === void 0 ? 1 : _c, _d = _a.lineOpacity, lineOpacity = _d === void 0 ? 1 : _d, _e = _a.fillColor, fillColor = _e === void 0 ? 'lightgreen' : _e, _f = _a.fillOpacity, fillOpacity = _f === void 0 ? 0.5 : _f, _g = _a.visible, visible = _g === void 0 ? true : _g, _h = _a.editable, editable = _h === void 0 ? false : _h, event = _a.event; //console.log('polygon', polygon); if (this.map && Array.isArray(position)) { var outLine = position.map(function (elem) { return Array.isArray(elem) ? new MapTypes.Position(elem[1], elem[0]) : elem; }); var paths = [outLine]; innerPositions && paths.push.apply(paths, innerPositions); var pol_2 = new google.maps.Polygon({ map: this.map, paths: paths, strokeColor: lineColor, strokeWeight: lineSize, strokeOpacity: lineOpacity, fillColor: fillColor, fillOpacity: fillOpacity, clickable: true, visible: visible, editable: editable }); //console.log('google polygon created', polygon); polygon.native = pol_2; event && event.forEach(function (handler, key) { if (_this.polygonEvents.includes(key)) { pol_2.addListener(key, handler); } }); } }; GoogleMintMapController.prototype.updatePolygon = function (polygon, options) { //console.log('controller updatePolygon', options); if (polygon && polygon.native && polygon.native instanceof google.maps.Polygon) { var polygonOption = this.getValidOptions(options); //console.log('controller updatePolygon start', polygonOption); if (this.map && Array.isArray(options.position)) { var outLine = options.position.map(function (elem) { return Array.isArray(elem) ? new MapTypes.Position(elem[1], elem[0]) : elem; }); var paths = [outLine]; options.innerPositions && paths.push.apply(paths, options.innerPositions); polygonOption.paths = paths; } polygon.native.setOptions(polygonOption); } }; GoogleMintMapController.prototype.getValidOptions = function (options) { //console.log('getValidOptions DrawableOptions',options) var target = {}; for (var _i = 0, _a = Object.getOwnPropertyNames(options); _i < _a.length; _i++) { var name_1 = _a[_i]; //@ts-ignore if (options[name_1] !== undefined) { //@ts-ignore target[name_1] = options[name_1]; } } return target; }; GoogleMintMapController.prototype.createMarker = function (marker) { var _this = this; var _a, _b; if (this.map) { var googleMarker_1; if (marker.element && marker.element instanceof Element) { var options = { map: this.map, position: marker.options.position }; options.content = marker.element; googleMarker_1 = new google.maps.marker.AdvancedMarkerView(options); } else { var options = { map: this.map, position: marker.options.position, visible: marker.options.visible === undefined || marker.options.visible, anchorPoint: marker.options.anchor }; googleMarker_1 = new google.maps.Marker(options); } log.log(this.mapProps.debug || marker.options.debug, marker.options.debugLabel, this.type + ' marker created'); status.Status.setMarker(1, marker.options.debugLabel); marker.native = googleMarker_1; ((_a = marker.options) === null || _a === void 0 ? void 0 : _a.event) && marker.options.event.forEach(function (handler, key) { if (_this.markerEvents.includes(key)) { googleMarker_1.addListener(key, handler); } }); if (!((_b = marker.options) === null || _b === void 0 ? void 0 : _b.event) || !marker.options.event.get('click')) { googleMarker_1.addListener('click', function () {}); } } }; GoogleMintMapController.prototype.updateMarker = function (marker, options) { //console.log('controller updateMarker', options); var _a, _b; if (marker && marker.native) { if (marker.native instanceof google.maps.Marker) { var map = marker.native.getMap(); if (map) { marker.native.setOptions({ map: map, position: options.position instanceof MapTypes.Position ? options.position : marker.native.getPosition(), visible: options.visible === undefined || options.visible // icon:{...marker.native.getIcon(), anchor:options.anchor} }); } } else if (marker.native instanceof google.maps.marker.AdvancedMarkerView) { if (options.visible !== undefined && marker.native.element) { marker.native.element.style.visibility = options.visible ? 'visible' : 'hidden'; } if (options.position instanceof MapTypes.Position && (((_a = marker.native.position) === null || _a === void 0 ? void 0 : _a.lat) != options.position.lat || ((_b = marker.native.position) === null || _b === void 0 ? void 0 : _b.lng) != options.position.lng)) { marker.native.position = options.position; } } log.log(this.mapProps.debug || options.debug, marker.options.debugLabel, this.type + ' marker updated'); } }; GoogleMintMapController.prototype.getMaxZIndex = function (increment, parent) { if (increment === void 0) { increment = 0; } if (this.map) { var targetPane = parent.parentElement; var max = 0; if (targetPane) { for (var i = 0; i < targetPane.childElementCount; i++) { var elem = targetPane.children[i]; if (elem instanceof HTMLElement) { var index = Number(elem.style.zIndex); if (!isNaN(index) && index > max) { max = index; } } } } this.markerMaxZIndex = max + increment; return this.markerMaxZIndex; } else { return this.markerMaxZIndex || 1; } }; GoogleMintMapController.prototype.setMarkerZIndex = function (marker, zIndex) { var _a; if (this.map && marker.element && marker.element instanceof HTMLElement) { var parent_1 = (_a = marker.element.parentElement) === null || _a === void 0 ? void 0 : _a.parentElement; if (parent_1) { parent_1.style.zIndex = String(zIndex); } } }; GoogleMintMapController.prototype.markerToTheTop = function (marker) { var _a; if (this.map && marker.element && marker.element instanceof HTMLElement) { var parent_2 = (_a = marker.element.parentElement) === null || _a === void 0 ? void 0 : _a.parentElement; if (parent_2) { this.setMarkerZIndex(marker, this.getMaxZIndex(1, parent_2)); } } }; GoogleMintMapController.prototype.clearDrawable = function (drawable) { if (drawable && drawable.native) { if (drawable.native instanceof google.maps.Marker || drawable.native instanceof google.maps.Polygon || drawable.native instanceof google.maps.Polyline) { google.maps.event.clearInstanceListeners(drawable.native); drawable.native.setMap(null); return true; } else if (drawable.native instanceof google.maps.marker.AdvancedMarkerView) { google.maps.event.clearInstanceListeners(drawable.native); drawable.native.map = null; log.log(this.mapProps.debug || drawable.options.debug, drawable.options.debugLabel, this.type + ' marker cleared'); status.Status.setMarker(-1, drawable.options.debugLabel); return true; } } return false; }; GoogleMintMapController.prototype.isMapDragged = function () { return this.dragged; }; GoogleMintMapController.prototype.setMapDragged = function (value) { this.dragged = value; }; GoogleMintMapController.prototype.checkLoaded = function () { var _a, _b, _c; return ((_c = (_b = (_a = window.google) === null || _a === void 0 ? void 0 : _a.maps) === null || _b === void 0 ? void 0 : _b.marker) === null || _c === void 0 ? void 0 : _c.AdvancedMarkerView) ? true : false; }; GoogleMintMapController.prototype.loadMapApi = function () { return tslib.__awaiter(this, void 0, void 0, function () { var _this = this; return tslib.__generator(this, function (_a) { return [2 /*return*/ , new Promise(function (resolve) { return tslib.__awaiter(_this, void 0, void 0, function () { var callbackName, loaded, params, callbackExecFlag, ok; return tslib.__generator(this, function (_a) { switch (_a.label) { case 0: callbackName = this.getRandomFunctionName('load_google'); loaded = false; //@ts-ignore window[callbackName] = function () { // console.log('google api loaded'); loaded = true; //@ts-ignore delete window[callbackName]; }; params = tslib.__assign({ key: this.mapProps.mapKey, libraries: this.scriptModules.join(','), v: 'beta', callback: callbackName }, this.mapProps.scriptParams); return [4 /*yield*/ , this.loadScript(this.buildUrl(this.scriptUrl, params), 'google_map_script', this.checkLoaded)]; case 1: callbackExecFlag = _a.sent(); if (!callbackExecFlag) { // console.log('google api loaded 222222'); loaded = true; //@ts-ignore delete window[callbackName]; } return [4 /*yield*/ , waiting.waiting(function () { return loaded; })]; case 2: ok = _a.sent(); if (!ok) { throw new Error('google script api load failed!!'); } this.mapApiLoaded = true; resolve(true); return [2 /*return*/ ]; } }); }); })]; }); }); }; GoogleMintMapController.prototype.initializingMap = function (divElement) { return tslib.__awaiter(this, void 0, void 0, function () { var _this = this; return tslib.__generator(this, function (_a) { //div element this.mapDivElement = divElement; return [2 /*return*/ , new Promise(function (resolve) { return tslib.__awaiter(_this, void 0, void 0, function () { var map; var _this = this; var _a, _b, _c, _d, _e, _f; return tslib.__generator(this, function (_g) { switch (_g.label) { case 0: //이미 생성했으면 //1. divElement 가 그대로인 경우 기존 map 객체 리턴 //2. divElement 가 바뀐경우 기존 map 객체 destroy 하고 새로 생성 if (this.mapInitialized && this.map) { if (this.map.getDiv() === divElement) { resolve(this.map); return [2 /*return*/ ]; } } if (!!this.mapApiLoaded) return [3 /*break*/ , 2]; return [4 /*yield*/ , this.loadMapApi()]; case 1: _g.sent(); _g.label = 2; case 2: map = new google.maps.Map(divElement, { mapId: this.mapProps.mapId || 'TEMP_MAP_ID', center: (_a = this.mapProps.base) === null || _a === void 0 ? void 0 : _a.center, maxZoom: (_b = this.mapProps.base) === null || _b === void 0 ? void 0 : _b.maxZoomLevel, minZoom: (_c = this.mapProps.base) === null || _c === void 0 ? void 0 : _c.minZoomLevel, zoom: ((_d = this.mapProps.base) === null || _d === void 0 ? void 0 : _d.zoomLevel) || this.getBaseToMapZoom(15), disableDefaultUI: true, gestureHandling: this.mapProps.draggable === false ? 'none' : 'greedy', keyboardShortcuts: this.mapProps.keyboardShortcuts === false ? false : true, clickableIcons: false }); this.map = map; //맵 커서 초기화 ((_e = this.mapProps.base) === null || _e === void 0 ? void 0 : _e.mapCursor) && this.setMapCursor((_f = this.mapProps.base) === null || _f === void 0 ? void 0 : _f.mapCursor); //@ts-ignore map.addListener('mousedown', function () { _this.dragged = false; // console.log('map mousedown / dragged => ', this.dragged); }); //@ts-ignore map.addListener('dragstart', function () { _this.dragged = true; // console.log('map dragstart / dragged => ', this.dragged); }); //@ts-ignore map.addListener('idle', function () { //onBoundsChanged event _this.checkBoundsChangeThrottleTime() && _this.mapProps.onBoundsChanged && _this.mapProps.onBoundsChanged(_this.getCurrBounds()); }); map.addListener('zoom_changed', function () { //onZoomChanged event // console.log('zoom_changed'); _this.map && _this.mapProps.onZoomChanged && _this.mapProps.onZoomChanged(_this.map.getZoom() || 10); }); //@ts-ignore map.addListener('click', function (e) { // console.log('map click', e) if (!_this.mapProps.onClick) return; var pos = new MapTypes.Position(e.latLng.lat(), e.latLng.lng()); pos.offset = new MapTypes.Offset(e.pixel.x, e.pixel.y); _this.mapProps.onClick(pos); }); //@ts-ignore map.addListener('mousedown', function (e) { // console.log('map click', e) var pos = new MapTypes.Position(e.latLng.lat(), e.latLng.lng()); pos.offset = new MapTypes.Offset(e.pixel.x, e.pixel.y); _this.lastMousePosition = pos; }); //@ts-ignore map.addListener('mouseup', function (e) { // console.log('map click', e) var pos = new MapTypes.Position(e.latLng.lat(), e.latLng.lng()); pos.offset = new MapTypes.Offset(e.pixel.x, e.pixel.y); _this.lastMousePosition = pos; }); map.addListener('mousemove', function (e) { if (!_this.mapProps.onMouseMove) return; var pos = new MapTypes.Position(e.latLng.lat(), e.latLng.lng()); pos.offset = new MapTypes.Offset(e.pixel.x, e.pixel.y); // console.log('mousemove', pos) _this.mapProps.onMouseMove(pos); }); this.mapInitialized = true; // console.log(`${this.type} map script initialized`, divElement); resolve(map); return [2 /*return*/ ]; } }); }); })]; }); }); }; GoogleMintMapController.prototype.fromGoogleBounds = function (bounds) { return MapTypes.Bounds.fromNESW(new MapTypes.Position(bounds.getNorthEast().lat(), bounds.getNorthEast().lng()), new MapTypes.Position(bounds.getSouthWest().lat(), bounds.getSouthWest().lng())); }; GoogleMintMapController.prototype.getCurrBounds = function () { if (!this.map) { throw new Error('Map is not initialized!!'); } var bounds = this.map.getBounds(); if (bounds) { return this.fromGoogleBounds(bounds); } else { throw new Error('bounds is not found!!!'); //return new Bounds(new Position(0,0), new Position(0,0)) } }; GoogleMintMapController.prototype.panningTo = function (targetCenter) { var _a; (_a = this.map) === null || _a === void 0 ? void 0 : _a.panTo(targetCenter); }; GoogleMintMapController.prototype.getZoomLevel = function () { var _a; return ((_a = this.map) === null || _a === void 0 ? void 0 : _a.getZoom()) || 13; }; GoogleMintMapController.prototype.setZoomLevel = function (zoom) { var _a; (_a = this.map) === null || _a === void 0 ? void 0 : _a.setZoom(zoom); }; GoogleMintMapController.prototype.getCenter = function () { return this.getCurrBounds().getCenter(); }; GoogleMintMapController.prototype.setCenter = function (position) { var _a; (_a = this.map) === null || _a === void 0 ? void 0 : _a.setCenter(position); }; GoogleMintMapController.prototype.setMapCursor = function (cursor) { var _a; (_a = this.map) === null || _a === void 0 ? void 0 : _a.setOptions({ draggingCursor: cursor, draggableCursor: cursor }); }; GoogleMintMapController.prototype.focusPositionsToFitViewport = function (positions, spacing) { var _a; var markerBounds = polygon.PolygonCalculator.getRegionInfo(positions); if (!markerBounds.maxLat || !markerBounds.minLat || !markerBounds.maxLng || !markerBounds.minLng) { throw new Error('markerBounds is invalid! in focusPositionsToFitViewport'); } var pointBounds = new google.maps.LatLngBounds(new google.maps.LatLng(markerBounds.minLat, markerBounds.minLng), new google.maps.LatLng(markerBounds.maxLat, markerBounds.maxLng)); (_a = this.map) === null || _a === void 0 ? void 0 : _a.fitBounds(pointBounds, spacing); }; GoogleMintMapController.prototype.addEventListener = function (eventName, callback) { var _this = this; if (!this.map) { return; } var googleEventName = this.mapEvent.get(eventName) || this.mapUIEvent.get(eventName); if (!googleEventName) { console.warn("MapEventName ".concat(eventName, " is not supported")); return; } // console.log(`${eventName} add`); var map = this.eventMap.get(eventName); if (!map) { map = new Map(); this.eventMap.set(eventName, map); } var wrappingCallback = function (e) { if (eventName in _this.mapEvent) { var bounds = _this.getCurrBounds(); var param = { name: eventName, mapType: 'google', vendorEventName: googleEventName, param: { bounds: bounds, center: bounds.getCenter(), zoomLevel: _this.getZoomLevel() } }; callback(param); } else if (eventName in _this.mapUIEvent) { var position = null; if (e) { position = new MapTypes.Position(e.latLng.lat(), e.latLng.lng()); position.offset = new MapTypes.Offset(e.pixel.x, e.pixel.y); } else { position = _this.lastMousePosition; } var param = { name: eventName, mapType: 'google', vendorEventName: googleEventName, param: { position: position, offset: position === null || position === void 0 ? void 0 : position.offset, pointerEvent: e.domEvent } }; callback(param); } }; var googleEventListener = this.map.addListener(googleEventName, wrappingCallback); map.set(callback, googleEventListener); }; GoogleMintMapController.prototype.removeEventListener = function (eventName, callback) { var map = this.eventMap.get(eventName); if (map) { var listenerMap = this.eventMap.get(eventName); if (listenerMap) { var googleEventListener = listenerMap.get(callback); if (googleEventListener) { // console.log(`${eventName} remove`); google.maps.event.removeListener(googleEventListener); listenerMap.delete(callback); } } } }; GoogleMintMapController.prototype.removeAllEventListener = function (eventName) { var _this = this; if (eventName) { this.clearEventListener(eventName); } else { this.eventMap.forEach(function (_map, eventName) { _this.clearEventListener(eventName); }); this.eventMap.clear(); } }; GoogleMintMapController.prototype.clearEventListener = function (eventName) { var map = this.eventMap.get(eventName); if (map) { map.forEach(function (googleEventListener) { // console.log(`${eventName} remove`); google.maps.event.removeListener(googleEventListener); }); this.eventMap.delete(eventName); } }; return GoogleMintMapController; }(MintMapController.MintMapController); exports.GoogleMintMapController = GoogleMintMapController;