@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
JavaScript
'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;