提交 23648f85 编写于 作者: DCloud-WZF's avatar DCloud-WZF 💬

feat(h5 map): map 组件支持高德地图

上级 42fe6a65
...@@ -2,6 +2,9 @@ import { inject, onUnmounted, watch } from 'vue' ...@@ -2,6 +2,9 @@ import { inject, onUnmounted, watch } from 'vue'
import { defineSystemComponent, useCustomEvent } from '@dcloudio/uni-components' import { defineSystemComponent, useCustomEvent } from '@dcloudio/uni-components'
import { Maps, Map, Circle, CircleOptions } from './maps' import { Maps, Map, Circle, CircleOptions } from './maps'
import { hexToRgba } from '../../../helpers/hexToRgba' import { hexToRgba } from '../../../helpers/hexToRgba'
import { getIsAMap } from '../../../helpers/location'
import { QQMaps } from './maps/qq/types'
import { GoogleMaps } from './maps/google/types'
const props = { const props = {
latitude: { type: [Number, String], require: true }, latitude: { type: [Number, String], require: true },
...@@ -39,7 +42,12 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -39,7 +42,12 @@ export default /*#__PURE__*/ defineSystemComponent({
addCircle(option) addCircle(option)
} }
function addCircle(option: Props) { function addCircle(option: Props) {
const center = new maps.LatLng(option.latitude, option.longitude) const center = getIsAMap()
? [option.longitude, option.latitude]
: new (maps as QQMaps | GoogleMaps).LatLng(
option.latitude,
option.longitude
)
const circleOptions: CircleOptions = { const circleOptions: CircleOptions = {
map: map as any, map: map as any,
center: center as any, center: center as any,
...@@ -48,18 +56,27 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -48,18 +56,27 @@ export default /*#__PURE__*/ defineSystemComponent({
strokeWeight: Number(option.strokeWidth) || 1, strokeWeight: Number(option.strokeWidth) || 1,
strokeDashStyle: 'solid', strokeDashStyle: 'solid',
} }
const { r: fr, g: fg, b: fb, a: fa } = hexToRgba(option.fillColor) if (getIsAMap()) {
const { r: sr, g: sg, b: sb, a: sa } = hexToRgba(option.color) circleOptions.strokeColor = option.color
if ('Color' in maps) { circleOptions.fillColor = option.fillColor || '#000'
circleOptions.fillColor = new maps.Color(fr, fg, fb, fa) as any circleOptions.fillOpacity = 1
circleOptions.strokeColor = new maps.Color(sr, sg, sb, sa) as any
} else { } else {
circleOptions.fillColor = `rgb(${fr}, ${fg}, ${fb})` const { r: fr, g: fg, b: fb, a: fa } = hexToRgba(option.fillColor)
circleOptions.fillOpacity = fa const { r: sr, g: sg, b: sb, a: sa } = hexToRgba(option.color)
circleOptions.strokeColor = `rgb(${sr}, ${sg}, ${sb})` if ('Color' in maps) {
circleOptions.strokeOpacity = sa circleOptions.fillColor = new maps.Color(fr, fg, fb, fa) as any
circleOptions.strokeColor = new maps.Color(sr, sg, sb, sa) as any
} else {
circleOptions.fillColor = `rgb(${fr}, ${fg}, ${fb})`
circleOptions.fillOpacity = fa
circleOptions.strokeColor = `rgb(${sr}, ${sg}, ${sb})`
circleOptions.strokeOpacity = sa
}
} }
circle = new maps.Circle(circleOptions) circle = new maps.Circle(circleOptions)
if (getIsAMap()) {
;(map as AMap.Map).add(circle as any)
}
} }
addCircle(props as Props) addCircle(props as Props)
watch(props, updateCircle) watch(props, updateCircle)
......
import { inject, onUnmounted, watch, PropType } from 'vue' import { inject, onUnmounted, watch, PropType } from 'vue'
import { getRealPath } from '@dcloudio/uni-platform' import { getRealPath } from '@dcloudio/uni-platform'
import { defineSystemComponent, useCustomEvent } from '@dcloudio/uni-components' import { defineSystemComponent, useCustomEvent } from '@dcloudio/uni-components'
import { Maps, Map } from './maps' import { Maps, Map, QQMap, GoogleMap } from './maps'
import { getIsAMap } from '../../../helpers/location'
import { QQMaps } from './maps/qq/types'
import { GoogleMaps } from './maps/google/types'
interface Position { interface Position {
left: number | string left: number | string
...@@ -15,6 +18,7 @@ const props = { ...@@ -15,6 +18,7 @@ const props = {
position: { type: Object as PropType<Position>, require: true }, position: { type: Object as PropType<Position>, require: true },
iconPath: { type: String, require: true }, iconPath: { type: String, require: true },
clickable: { type: [Boolean, String], default: '' }, clickable: { type: [Boolean, String], default: '' },
rootRef: { type: Object, default: null },
} }
export type Props = Partial<Record<keyof typeof props, any>> export type Props = Partial<Record<keyof typeof props, any>>
...@@ -51,6 +55,8 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -51,6 +55,8 @@ export default /*#__PURE__*/ defineSystemComponent({
style.position = 'absolute' style.position = 'absolute'
style.width = '0' style.width = '0'
style.height = '0' style.height = '0'
style.top = '0'
style.left = '0'
img.onload = () => { img.onload = () => {
if (option.position.width) { if (option.position.width) {
img.width = option.position.width img.width = option.position.width
...@@ -72,7 +78,13 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -72,7 +78,13 @@ export default /*#__PURE__*/ defineSystemComponent({
}) })
} }
} }
map.controls[maps.ControlPosition.TOP_LEFT].push(control) if (getIsAMap()) {
props.rootRef.value && props.rootRef.value.appendChild(control)
} else {
;(map as QQMap | GoogleMap).controls[
(maps as QQMaps | GoogleMaps).ControlPosition.TOP_LEFT
].push(control)
}
} }
addControl(props as Props) addControl(props as Props)
watch(props, updateControl) watch(props, updateControl)
......
...@@ -3,12 +3,13 @@ import { isFunction } from '@vue/shared' ...@@ -3,12 +3,13 @@ import { isFunction } from '@vue/shared'
import { getRealPath } from '@dcloudio/uni-platform' import { getRealPath } from '@dcloudio/uni-platform'
import { defineSystemComponent, useCustomEvent } from '@dcloudio/uni-components' import { defineSystemComponent, useCustomEvent } from '@dcloudio/uni-components'
import { Maps, Map, LatLng, Callout, CalloutOptions } from './maps' import { Maps, Map, LatLng, Callout, CalloutOptions } from './maps'
import { getIsAMap } from '../../../helpers/location'
import { import {
Map as GMap,
LatLng as GLatLng, LatLng as GLatLng,
Marker as GMarker, Marker as GMarker,
Label as GLabel, Label as GLabel,
Icon, Icon,
GoogleMaps,
} from './maps/google/types' } from './maps/google/types'
import { import {
Map as QMap, Map as QMap,
...@@ -16,6 +17,7 @@ import { ...@@ -16,6 +17,7 @@ import {
Marker as QMarker, Marker as QMarker,
Label as QLabel, Label as QLabel,
MarkerImage, MarkerImage,
QQMaps,
} from './maps/qq/types' } from './maps/qq/types'
const props = { const props = {
...@@ -114,7 +116,8 @@ interface MarkerExt { ...@@ -114,7 +116,8 @@ interface MarkerExt {
} }
interface GMarkerExt extends GMarker, MarkerExt {} interface GMarkerExt extends GMarker, MarkerExt {}
interface QMarkerExt extends QMarker, MarkerExt {} interface QMarkerExt extends QMarker, MarkerExt {}
type Marker = GMarkerExt | QMarkerExt interface AMarkerExt extends AMap.Marker, MarkerExt {}
type Marker = GMarkerExt | QMarkerExt | AMarkerExt
type MarkerLabelStyle = Partial< type MarkerLabelStyle = Partial<
Pick< Pick<
CSSStyleDeclaration, CSSStyleDeclaration,
...@@ -172,15 +175,30 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -172,15 +175,30 @@ export default /*#__PURE__*/ defineSystemComponent({
;(marker.label as QLabel).setMap(null) ;(marker.label as QLabel).setMap(null)
} }
if (marker.callout) { if (marker.callout) {
marker.callout.setMap(null) removeMarkerCallout(marker.callout)
} }
marker.setMap(null) marker.setMap(null)
} }
} }
function removeMarkerCallout(callout: Marker['callout']) {
if (getIsAMap()) {
callout!.removeAMapText()
} else {
callout!.setMap(null)
}
}
onMapReady((map, maps, trigger) => { onMapReady((map, maps, trigger) => {
function updateMarker(option: Props) { function updateMarker(option: Props) {
const title = option.title const title = option.title
const position = new maps.LatLng(option.latitude, option.longitude) const position = getIsAMap()
? new (maps as AMap.NameSpace).LngLat(
option.longitude,
option.latitude
)
: new (maps as QQMaps | GoogleMaps).LatLng(
option.latitude,
option.longitude
)
const img = new Image() const img = new Image()
img.onload = () => { img.onload = () => {
const anchor = option.anchor || {} const anchor = option.anchor || {}
...@@ -203,14 +221,22 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -203,14 +221,22 @@ export default /*#__PURE__*/ defineSystemComponent({
img.src, img.src,
null, null,
null, null,
new maps.Point(x * w, y * h), new (maps as QQMaps).Point(x * w, y * h),
new maps.Size(w, h) new (maps as QQMaps).Size(w, h)
) )
} else if ('Icon' in maps) {
// 高德
icon = new (maps as AMap.NameSpace).Icon({
image: img.src,
size: new (maps as AMap.NameSpace).Size(w, h),
imageSize: new (maps as AMap.NameSpace).Size(w, h),
imageOffset: new (maps as AMap.NameSpace).Pixel(x * w, y * h),
})
} else { } else {
icon = { icon = {
url: img.src, url: img.src,
anchor: new maps.Point(x, y), anchor: new (maps as GoogleMaps).Point(x, y),
size: new maps.Size(w, h), size: new (maps as GoogleMaps).Size(w, h),
} }
} }
marker.setPosition(position as any) marker.setPosition(position as any)
...@@ -247,13 +273,33 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -247,13 +273,33 @@ export default /*#__PURE__*/ defineSystemComponent({
}) })
marker.label = label marker.label = label
} else if ('setLabel' in marker) { } else if ('setLabel' in marker) {
const className = updateMarkerLabelStyle(labelStyle) if (getIsAMap()) {
marker.setLabel({ const content = `<div style="
text: labelOpt.content, margin-left:${labelStyle.marginLeft};
color: labelStyle.color, margin-top:${labelStyle.marginTop};
fontSize: labelStyle.fontSize, padding:${labelStyle.padding};
className, background-color:${labelStyle.backgroundColor};
}) border-radius:${labelStyle.borderRadius};
line-height:${labelStyle.lineHeight};
color:${labelStyle.color};
font-size:${labelStyle.fontSize};
">
${labelOpt.content}
<div>`
marker.setLabel({
content,
direction: 'bottom-right',
} as any)
} else {
const className = updateMarkerLabelStyle(labelStyle)
;(marker as GMarker).setLabel({
text: labelOpt.content,
color: labelStyle.color,
fontSize: labelStyle.fontSize,
className,
})
}
} }
} }
const calloutOpt = option.callout || {} const calloutOpt = option.callout || {}
...@@ -266,6 +312,8 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -266,6 +312,8 @@ export default /*#__PURE__*/ defineSystemComponent({
position, position,
map, map,
top, top,
// handle AMap callout offset
offsetY: -option.height / 2,
content: calloutOpt.content, content: calloutOpt.content,
color: calloutOpt.color, color: calloutOpt.color,
fontSize: calloutOpt.fontSize, fontSize: calloutOpt.fontSize,
...@@ -279,26 +327,42 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -279,26 +327,42 @@ export default /*#__PURE__*/ defineSystemComponent({
position, position,
map, map,
top, top,
// handle AMap callout offset
offsetY: -option.height / 2,
content: title, content: title,
boxShadow, boxShadow,
} }
if (callout) { if (callout) {
callout.setOption(calloutStyle) callout.setOption(calloutStyle)
} else { } else {
callout = marker.callout = new maps.Callout(calloutStyle) if (getIsAMap()) {
callout.div.onclick = function ($event) { const callback = (id: number | string) => {
if (id !== '') { if (id !== '') {
trigger('callouttap', $event, { trigger('callouttap', {} as Event, {
markerId: Number(id), markerId: Number(id),
}) })
}
}
callout = marker.callout = new maps.Callout(
calloutStyle,
callback
)
} else {
callout = marker.callout = new maps.Callout(calloutStyle)
callout.div!.onclick = function ($event: Event) {
if (id !== '') {
trigger('callouttap', $event, {
markerId: Number(id),
})
}
$event.stopPropagation()
$event.preventDefault()
} }
$event.stopPropagation()
$event.preventDefault()
} }
} }
} else { } else {
if (callout) { if (callout) {
callout.setMap(null) removeMarkerCallout(callout)
delete marker.callout delete marker.callout
} }
} }
...@@ -311,24 +375,34 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -311,24 +375,34 @@ export default /*#__PURE__*/ defineSystemComponent({
} }
function addMarker(props: Props) { function addMarker(props: Props) {
marker = new maps.Marker({ marker = new maps.Marker({
map: map as GMap & QMap, map: map as any,
flat: true, flat: true,
autoRotation: false, autoRotation: false,
}) })
updateMarker(props) updateMarker(props)
maps.event.addListener(marker, 'click', () => { const MapsEvent =
(maps as QQMaps | GoogleMaps).event || (maps as AMap.NameSpace).Event
MapsEvent.addListener(marker, 'click', () => {
const callout = marker.callout const callout = marker.callout
if (callout) { if (callout && !callout.alwaysVisible) {
const div = callout.div if (getIsAMap()) {
const parent = div.parentNode as HTMLElement callout.visible = !callout.visible
if (!callout.alwaysVisible) { if (callout.visible) {
marker.callout!.createAMapText()
} else {
marker.callout!.removeAMapText()
}
} else {
callout.set('visible', !callout.visible) callout.set('visible', !callout.visible)
} if (callout.visible) {
if (callout.visible) { const div = callout.div!
parent.removeChild(div) const parent = div.parentNode!
parent.appendChild(div) parent.removeChild(div)
parent.appendChild(div)
}
} }
} }
if (id) { if (id) {
trigger('markertap', {} as Event, { trigger('markertap', {} as Event, {
markerId: Number(id), markerId: Number(id),
...@@ -361,20 +435,23 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -361,20 +435,23 @@ export default /*#__PURE__*/ defineSystemComponent({
rotation = marker.getRotation() rotation = marker.getRotation()
} }
const a = marker.getPosition() const a = marker.getPosition()
const b = new maps.LatLng( const b = new (maps as QQMaps | GoogleMaps).LatLng(
destination.latitude, destination.latitude,
destination.longitude destination.longitude
) )
const distance = const distance =
maps.geometry.spherical.computeDistanceBetween( (
a as any, maps as QQMaps | GoogleMaps
b as any ).geometry.spherical.computeDistanceBetween(a as any, b as any) /
) / 1000 1000
const time = const time =
(typeof duration === 'number' ? duration : 1000) / (typeof duration === 'number' ? duration : 1000) /
(1000 * 60 * 60) (1000 * 60 * 60)
const speed = distance / time const speed = distance / time
const movingEvent = maps.event.addListener( const MapsEvent =
(maps as QQMaps | GoogleMaps).event ||
(maps as AMap.NameSpace).Event
const movingEvent = MapsEvent.addListener(
marker, marker,
'moving', 'moving',
(e: any) => { (e: any) => {
...@@ -389,10 +466,10 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -389,10 +466,10 @@ export default /*#__PURE__*/ defineSystemComponent({
} }
} }
) )
const event = maps.event.addListener(marker, 'moveend', () => { const event = MapsEvent.addListener(marker, 'moveend', () => {
event.remove() event.remove()
movingEvent.remove() movingEvent.remove()
marker.lastPosition = a! marker.lastPosition = a as QLatLng
marker.setPosition(b as any) marker.setPosition(b as any)
const label = marker.label const label = marker.label
if (label) { if (label) {
...@@ -410,14 +487,18 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -410,14 +487,18 @@ export default /*#__PURE__*/ defineSystemComponent({
let lastRtate = 0 let lastRtate = 0
if (autoRotate) { if (autoRotate) {
if (marker.lastPosition) { if (marker.lastPosition) {
lastRtate = maps.geometry.spherical.computeHeading( lastRtate = (
maps as QQMaps | GoogleMaps
).geometry.spherical.computeHeading(
marker.lastPosition as any, marker.lastPosition as any,
a as any a as any
) )
} }
rotate = rotate =
maps.geometry.spherical.computeHeading(a as any, b as any) - (maps as QQMaps | GoogleMaps).geometry.spherical.computeHeading(
lastRtate a as any,
b as any
) - lastRtate
} }
if ('setRotation' in marker) { if ('setRotation' in marker) {
marker.setRotation(rotation + rotate) marker.setRotation(rotation + rotate)
...@@ -426,7 +507,7 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -426,7 +507,7 @@ export default /*#__PURE__*/ defineSystemComponent({
marker.moveTo(b as QLatLng, speed) marker.moveTo(b as QLatLng, speed)
} else { } else {
marker.setPosition(b as GLatLng) marker.setPosition(b as GLatLng)
maps.event.trigger(marker, 'moveend', {}) MapsEvent.trigger(marker, 'moveend', {})
} }
}) })
}, },
......
...@@ -2,6 +2,7 @@ import { inject, PropType, onUnmounted, watch } from 'vue' ...@@ -2,6 +2,7 @@ import { inject, PropType, onUnmounted, watch } from 'vue'
import { defineSystemComponent, useCustomEvent } from '@dcloudio/uni-components' import { defineSystemComponent, useCustomEvent } from '@dcloudio/uni-components'
import { Maps, Map, LatLng, Polyline, PolylineOptions } from './maps' import { Maps, Map, LatLng, Polyline, PolylineOptions } from './maps'
import { hexToRgba } from '../../../helpers/hexToRgba' import { hexToRgba } from '../../../helpers/hexToRgba'
import { getIsAMap } from '../../../helpers/location'
interface Point { interface Point {
latitude: number latitude: number
...@@ -56,9 +57,15 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -56,9 +57,15 @@ export default /*#__PURE__*/ defineSystemComponent({
addPolyline(option) addPolyline(option)
} }
function addPolyline(option: Props) { function addPolyline(option: Props) {
const path: LatLng[] = [] const path: LatLng | any[] = []
option.points.forEach((point: Point) => { option.points.forEach((point: Point) => {
path.push(new maps.LatLng(point.latitude, point.longitude)) const pointPosition = getIsAMap()
? [point.longitude, point.latitude]
: new (maps as typeof google.maps).LatLng(
point.latitude,
point.longitude
)
path.push(pointPosition)
}) })
const strokeWeight = Number(option.width) || 1 const strokeWeight = Number(option.width) || 1
const { r: sr, g: sg, b: sb, a: sa } = hexToRgba(option.color) const { r: sr, g: sg, b: sb, a: sa } = hexToRgba(option.color)
......
...@@ -15,9 +15,12 @@ import { ...@@ -15,9 +15,12 @@ import {
useSubscribe, useSubscribe,
useCustomEvent, useCustomEvent,
} from '@dcloudio/uni-components' } from '@dcloudio/uni-components'
import '@amap/amap-jsapi-types'
import { callOptions } from '@dcloudio/uni-shared' import { callOptions } from '@dcloudio/uni-shared'
import { Point } from '../../../helpers/location' import { Point } from '../../../helpers/location'
import { Maps, Map, loadMaps, LatLng } from './maps' import { Maps, Map, loadMaps, LatLng, QQMap, GoogleMap } from './maps'
import { QQMaps } from './maps/qq/types'
import { GoogleMaps } from './maps/google/types'
import MapMarker, { import MapMarker, {
Props as MapMarkerProps, Props as MapMarkerProps,
Context as MapMarkerContext, Context as MapMarkerContext,
...@@ -31,6 +34,7 @@ import MapLocation, { ...@@ -31,6 +34,7 @@ import MapLocation, {
} from './MapLocation' } from './MapLocation'
import MapPolygon from './map-polygon/index' import MapPolygon from './map-polygon/index'
import { Polygon } from './map-polygon/interface' import { Polygon } from './map-polygon/interface'
import { getIsAMap } from '../../../helpers/location'
const props = { const props = {
id: { id: {
...@@ -117,6 +121,26 @@ function getPoints(points: Point[]): Point[] { ...@@ -117,6 +121,26 @@ function getPoints(points: Point[]): Point[] {
return newPoints return newPoints
} }
function getAMapPosition(
maps: AMap.NameSpace,
latitude: number,
longitude: number
) {
return new maps.LngLat(longitude, latitude)
}
function getGoogleOrQQMapPosition(
maps: QQMaps | GoogleMaps,
latitude: number,
longitude: number
) {
return new maps.LatLng(latitude, longitude)
}
function getMapPosition(maps: Maps, latitude: number, longitude: number) {
return getIsAMap()
? getAMapPosition(maps as AMap.NameSpace, latitude, longitude)
: getGoogleOrQQMapPosition(maps as QQMaps | GoogleMaps, latitude, longitude)
}
function getLat(latLng: LatLng) { function getLat(latLng: LatLng) {
if ('getLat' in latLng) { if ('getLat' in latLng) {
return latLng.getLat() return latLng.getLat()
...@@ -195,7 +219,12 @@ function useMap( ...@@ -195,7 +219,12 @@ function useMap(
state.latitude = latitude state.latitude = latitude
state.longitude = longitude state.longitude = longitude
if (map) { if (map) {
map.setCenter(new maps.LatLng(latitude, longitude) as any) const centerPosition = getMapPosition(
maps,
state.latitude,
state.longitude
)
map.setCenter(centerPosition as any)
} }
} }
} }
...@@ -222,25 +251,40 @@ function useMap( ...@@ -222,25 +251,40 @@ function useMap(
return { return {
scale: map.getZoom(), scale: map.getZoom(),
centerLocation: { centerLocation: {
latitude: getLat(center), latitude: getLat(center as LatLng),
longitude: getLng(center), longitude: getLng(center as LatLng),
}, },
} }
} }
function updateCenter() { function updateCenter() {
map.setCenter(new maps.LatLng(state.latitude, state.longitude) as any) const centerPosition = getMapPosition(maps, state.latitude, state.longitude)
map.setCenter(centerPosition as any)
} }
function updateBounds() { function updateBounds() {
const bounds = new maps.LatLngBounds() if (getIsAMap()) {
state.includePoints.forEach(({ latitude, longitude }) => { const points: [number, number][] = []
const latLng = new maps.LatLng(latitude, longitude) state.includePoints.forEach((point) => {
bounds.extend(latLng as any) points.push([point.longitude, point.latitude])
}) })
map.fitBounds(bounds as any) const bounds = new (maps as AMap.NameSpace).Bounds(...points)
;(map as AMap.Map).setBounds(bounds)
} else {
const bounds = new (maps as QQMaps | GoogleMaps).LatLngBounds()
state.includePoints.forEach(({ latitude, longitude }) => {
const latLng = new (maps as QQMaps | GoogleMaps).LatLng(
latitude,
longitude
)
bounds.extend(latLng as any)
})
;(map as QQMap | GoogleMap).fitBounds(bounds as any)
}
} }
function initMap() { function initMap() {
const mapEl = mapRef.value as HTMLDivElement const mapEl = mapRef.value as HTMLDivElement
const center = new maps.LatLng(state.latitude, state.longitude) const center = getMapPosition(maps, state.latitude, state.longitude)
const event =
(maps as QQMaps | GoogleMaps).event || (maps as AMap.NameSpace).Event
const map = new maps.Map(mapEl, { const map = new maps.Map(mapEl, {
center: center as any, center: center as any,
zoom: Number(props.scale), zoom: Number(props.scale),
...@@ -271,26 +315,22 @@ function useMap( ...@@ -271,26 +315,22 @@ function useMap(
} }
}) })
// 需在 bounds_changed 后触发 BoundsReady // 需在 bounds_changed 后触发 BoundsReady
const boundsChangedEvent = maps.event.addListener( const boundsChangedEvent = event.addListener(map, 'bounds_changed', () => {
map, boundsChangedEvent.remove()
'bounds_changed', emitBoundsReady()
() => { })
boundsChangedEvent.remove() event.addListener(map, 'click', () => {
emitBoundsReady()
}
)
maps.event.addListener(map, 'click', () => {
// TODO 编译器将 tap 转换为 click // TODO 编译器将 tap 转换为 click
trigger('tap', {} as Event, {}) trigger('tap', {} as Event, {})
trigger('click', {} as Event, {}) trigger('click', {} as Event, {})
}) })
maps.event.addListener(map, 'dragstart', () => { event.addListener(map, 'dragstart', () => {
trigger('regionchange', {} as Event, { trigger('regionchange', {} as Event, {
type: 'begin', type: 'begin',
causedBy: 'gesture', causedBy: 'gesture',
}) })
}) })
maps.event.addListener(map, 'dragend', () => { event.addListener(map, 'dragend', () => {
trigger( trigger(
'regionchange', 'regionchange',
{} as Event, {} as Event,
...@@ -303,7 +343,7 @@ function useMap( ...@@ -303,7 +343,7 @@ function useMap(
) )
) )
}) })
maps.event.addListener(map, 'zoom_changed', () => { event.addListener(map, 'zoom_changed', () => {
emit('update:scale', map.getZoom()) emit('update:scale', map.getZoom())
trigger( trigger(
'regionchange', 'regionchange',
...@@ -317,15 +357,16 @@ function useMap( ...@@ -317,15 +357,16 @@ function useMap(
) )
) )
}) })
maps.event.addListener(map, 'center_changed', () => { event.addListener(map, 'center_changed', () => {
const center = map.getCenter()! const center = map.getCenter()!
const latitude = getLat(center) const latitude = getLat(center as LatLng)
const longitude = getLng(center) const longitude = getLng(center as LatLng)
emit('update:latitude', latitude) emit('update:latitude', latitude)
emit('update:longitude', longitude) emit('update:longitude', longitude)
}) })
return map return map
} }
try { try {
// TODO 支持在页面外使用 // TODO 支持在页面外使用
const id = useContextInfo() const id = useContextInfo()
...@@ -336,8 +377,8 @@ function useMap( ...@@ -336,8 +377,8 @@ function useMap(
onMapReady(() => { onMapReady(() => {
const center = map.getCenter()! const center = map.getCenter()!
callOptions(data, { callOptions(data, {
latitude: getLat(center), latitude: getLat(center as LatLng),
longitude: getLng(center), longitude: getLng(center as LatLng),
errMsg: `${type}:ok`, errMsg: `${type}:ok`,
}) })
}) })
...@@ -359,7 +400,12 @@ function useMap( ...@@ -359,7 +400,12 @@ function useMap(
state.latitude = latitude state.latitude = latitude
state.longitude = longitude state.longitude = longitude
if (map) { if (map) {
map.setCenter(new maps.LatLng(latitude, longitude) as any) const centerPosition = getMapPosition(
maps,
latitude,
longitude
)
map.setCenter(centerPosition as any)
} }
onMapReady(() => { onMapReady(() => {
callOptions(data, `${type}:ok`) callOptions(data, `${type}:ok`)
...@@ -402,12 +448,12 @@ function useMap( ...@@ -402,12 +448,12 @@ function useMap(
const northeast = latLngBounds.getNorthEast() const northeast = latLngBounds.getNorthEast()
callOptions(data, { callOptions(data, {
southwest: { southwest: {
latitude: getLat(southwest), latitude: getLat(southwest as LatLng),
longitude: getLng(southwest), longitude: getLng(southwest as LatLng),
}, },
northeast: { northeast: {
latitude: getLat(northeast), latitude: getLat(northeast as LatLng),
longitude: getLng(northeast), longitude: getLng(northeast as LatLng),
}, },
errMsg: `${type}:ok`, errMsg: `${type}:ok`,
}) })
...@@ -430,7 +476,7 @@ function useMap( ...@@ -430,7 +476,7 @@ function useMap(
onMounted(() => { onMounted(() => {
loadMaps(props.libraries, (result) => { loadMaps(props.libraries, (result) => {
maps = result maps = result
map = initMap() map = initMap() as Map
emitMapReady() emitMapReady()
trigger('updated', {} as Event, {}) trigger('updated', {} as Event, {})
}) })
...@@ -480,7 +526,7 @@ export default /*#__PURE__*/ defineBuiltInComponent({ ...@@ -480,7 +526,7 @@ export default /*#__PURE__*/ defineBuiltInComponent({
<MapCircle {...item} /> <MapCircle {...item} />
))} ))}
{props.controls.map((item) => ( {props.controls.map((item) => (
<MapControl {...item} /> <MapControl {...item} rootRef={rootRef} />
))} ))}
{props.showLocation && <MapLocation />} {props.showLocation && <MapLocation />}
{props.polygons.map((item) => ( {props.polygons.map((item) => (
......
...@@ -9,9 +9,11 @@ import { ...@@ -9,9 +9,11 @@ import {
CustomEventTrigger, CustomEventTrigger,
PolygonOptions, PolygonOptions,
} from './interface' } from './interface'
import { Map, Maps } from '../maps' import { GoogleMap, QQMap } from '../maps'
import { QQMaps } from '../maps/qq/types'
import { hexToRgba } from '../../../../helpers/hexToRgba' import { hexToRgba } from '../../../../helpers/hexToRgba'
import { getIsAMap } from '../../../../helpers/location'
import { QQMaps } from '../maps/qq/types'
import { GoogleMaps } from '../maps/google/types'
export default /*#__PURE__*/ defineSystemComponent({ export default /*#__PURE__*/ defineSystemComponent({
name: 'MapPolygon', name: 'MapPolygon',
...@@ -22,103 +24,111 @@ export default /*#__PURE__*/ defineSystemComponent({ ...@@ -22,103 +24,111 @@ export default /*#__PURE__*/ defineSystemComponent({
// 当地图准备好以后调用指定的回调函数 // 当地图准备好以后调用指定的回调函数
const onMapReady = inject<OnMapReady>('onMapReady') as OnMapReady const onMapReady = inject<OnMapReady>('onMapReady') as OnMapReady
onMapReady((map: Map, maps: Maps, trigger: CustomEventTrigger) => { onMapReady(
// 绘制区域 (
function drawPolygon() { map: QQMap | GoogleMap,
const { maps: QQMaps | GoogleMaps,
points, trigger: CustomEventTrigger
strokeWidth, ) => {
strokeColor, // 绘制区域
dashArray, function drawPolygon() {
fillColor, const {
zIndex, points,
} = props strokeWidth,
strokeColor,
const path = points.map((item: Point) => { dashArray,
const { latitude, longitude } = item fillColor,
return new maps.LatLng(latitude, longitude) zIndex,
}) } = props
const { r: fcR, g: fcG, b: fcB, a: fcA } = hexToRgba(fillColor) const path = points.map((item: Point) => {
const { r: scR, g: scG, b: scB, a: scA } = hexToRgba(strokeColor) const { latitude, longitude } = item
return getIsAMap()
const polygonOptions: PolygonOptions = { ? [longitude, latitude]
//多边形是否可点击。 : new (maps as QQMaps | GoogleMaps).LatLng(latitude, longitude)
clickable: true, })
//鼠标在多边形内的光标样式。 const { r: fcR, g: fcG, b: fcB, a: fcA } = hexToRgba(fillColor)
cursor: 'crosshair', const { r: scR, g: scG, b: scB, a: scA } = hexToRgba(strokeColor)
//多边形是否可编辑。 const polygonOptions: PolygonOptions = {
editable: false, //多边形是否可点击。
clickable: true,
// 地图实例,即要显示多边形的地图
// @ts-ignore //鼠标在多边形内的光标样式。
map, cursor: 'crosshair',
// 区域填充色 //多边形是否可编辑。
fillColor: '', editable: false,
//多边形的路径,以经纬度坐标数组构成。 // 地图实例,即要显示多边形的地图
path, // @ts-ignore
map,
// 区域边框
strokeColor: '', // 区域填充色
fillColor: '',
//多边形的边框样式。实线是solid,虚线是dash。
strokeDashStyle: dashArray.some((item: number) => item > 0) //多边形的路径,以经纬度坐标数组构成。
? 'dash' path,
: 'solid',
// 区域边框
//多边形的边框线宽。 strokeColor: '',
strokeWeight: strokeWidth,
//多边形的边框样式。实线是solid,虚线是dash。
//多边形是否可见。 strokeDashStyle: dashArray.some((item: number) => item > 0)
visible: true, ? 'dash'
: 'solid',
//多边形的zIndex值。
zIndex: zIndex, //多边形的边框线宽。
} strokeWeight: strokeWidth,
// 多边形的填充色、边框以及相应的透明度 //多边形是否可见。
if ((maps as QQMaps).Color) { visible: true,
// 说明是 腾讯地图,google map 实例没有 Color 属性
// 将类型转为两者共有的 string,避免 ts 报错 //多边形的zIndex值。
polygonOptions.fillColor = new (maps as QQMaps).Color( zIndex: zIndex,
fcR, }
fcG,
fcB, // 多边形的填充色、边框以及相应的透明度
fcA if ((maps as QQMaps).Color) {
) as unknown as string // 说明是 腾讯地图,google map 实例没有 Color 属性
polygonOptions.strokeColor = new (maps as QQMaps).Color( // 将类型转为两者共有的 string,避免 ts 报错
scR, polygonOptions.fillColor = new (maps as QQMaps).Color(
scG, fcR,
scB, fcG,
scA fcB,
) as unknown as string fcA
} else { ) as unknown as string
// google map polygonOptions.strokeColor = new (maps as QQMaps).Color(
polygonOptions.fillColor = `rgb(${fcR}, ${fcG}, ${fcB})` scR,
polygonOptions.fillOpacity = fcA scG,
polygonOptions.strokeColor = `rgb(${scR}, ${scG}, ${scB})` scB,
polygonOptions.strokeOpacity = scA scA
} ) as unknown as string
} else {
if (polygonIns) { // google & 高德 map
// 更新区域属性 polygonOptions.fillColor = `rgb(${fcR}, ${fcG}, ${fcB})`
polygonIns.setOptions(polygonOptions) polygonOptions.fillOpacity = fcA
return polygonOptions.strokeColor = `rgb(${scR}, ${scG}, ${scB})`
polygonOptions.strokeOpacity = scA
}
if (polygonIns) {
// 更新区域属性
polygonIns.setOptions(polygonOptions)
return
}
// 说明是新增区域
polygonIns = new maps.Polygon(polygonOptions)
} }
// 说明是新增区域 // 给地图添加区域
polygonIns = new maps.Polygon(polygonOptions) drawPolygon()
// 监听 props
watch(props, drawPolygon)
} }
)
// 给地图添加区域
drawPolygon()
// 监听 props
watch(props, drawPolygon)
})
onUnmounted(() => { onUnmounted(() => {
// 卸载时清除地图上绘制的 polygon // 卸载时清除地图上绘制的 polygon
......
import { Maps, Map } from '../maps' import { QQMap, GoogleMap } from '../maps'
import { import {
Polygon as QQPolygon, Polygon as QQPolygon,
PolygonOptions as QQPolygonOptions, PolygonOptions as QQPolygonOptions,
QQMaps,
} from '../maps/qq/types' } from '../maps/qq/types'
import { Polygon as GPolygon } from '../maps/google/types' import { GoogleMaps, Polygon as GPolygon } from '../maps/google/types'
import { useCustomEvent } from '@dcloudio/uni-components' import { useCustomEvent } from '@dcloudio/uni-components'
import props from './props' import props from './props'
...@@ -15,8 +16,8 @@ export interface Point { ...@@ -15,8 +16,8 @@ export interface Point {
export type CustomEventTrigger = ReturnType<typeof useCustomEvent> export type CustomEventTrigger = ReturnType<typeof useCustomEvent>
type OnMapReadyCallback = ( type OnMapReadyCallback = (
map: Map, map: QQMap | GoogleMap,
maps: Maps, maps: QQMaps | GoogleMaps,
trigger: CustomEventTrigger trigger: CustomEventTrigger
) => void ) => void
......
...@@ -3,7 +3,7 @@ import { Point } from './interface' ...@@ -3,7 +3,7 @@ import { Point } from './interface'
// MapPolygon 组件的 props 属性配置 // MapPolygon 组件的 props 属性配置
export default { export default {
// 边框虚线,腾讯地图支持,google 地图不支持,默认值为[0, 0] 为实线,非 [0, 0] 为虚线,H5 端无法像微信小程序一样控制虚线的间隔像素大小 // 边框虚线,腾讯地图支持,google 高德 地图不支持,默认值为[0, 0] 为实线,非 [0, 0] 为虚线,H5 端无法像微信小程序一样控制虚线的间隔像素大小
dashArray: { dashArray: {
type: Array as PropType<number[]>, type: Array as PropType<number[]>,
default: () => [0, 0], default: () => [0, 0],
......
import { getIsAMap } from '../../../../helpers/location'
import { QQMaps, Overlay, LatLng as QLatLng } from './qq/types' import { QQMaps, Overlay, LatLng as QLatLng } from './qq/types'
import { GoogleMaps, OverlayView, LatLng as GLatLng } from './google/types' import { GoogleMaps, OverlayView, LatLng as GLatLng } from './google/types'
export interface CalloutOptions { export interface CalloutOptions {
map?: any map?: any
position?: GLatLng | QLatLng position?: GLatLng | QLatLng | AMap.LngLat
display?: 'ALWAYS' display?: 'ALWAYS'
boxShadow?: string boxShadow?: string
content?: string content?: string
...@@ -13,100 +13,165 @@ export interface CalloutOptions { ...@@ -13,100 +13,165 @@ export interface CalloutOptions {
borderRadius?: number borderRadius?: number
bgColor?: string bgColor?: string
top?: number top?: number
offsetY?: number
} }
export function createCallout(maps: QQMaps | GoogleMaps) { export function createCallout(maps: QQMaps | GoogleMaps | AMap.NameSpace) {
const overlay: OverlayView | Overlay = new ((maps as GoogleMaps)
.OverlayView || (maps as QQMaps).Overlay)()
function onAdd(this: Callout) { function onAdd(this: Callout) {
const div = this.div const div = this.div
const panes = this.getPanes()! const panes = this.getPanes()!
panes.floatPane.appendChild(div) panes.floatPane.appendChild(div)
} }
function onRemove(this: Callout) { function onRemove(this: Callout) {
const parentNode = this.div.parentNode const parentNode = this.div!.parentNode
if (parentNode) { if (parentNode) {
parentNode.removeChild(this.div) parentNode.removeChild(this.div!)
}
}
function createAMapText(this: Callout) {
const option = this.option
this.Text = new (maps as AMap.NameSpace).Text({
text: option.content,
anchor: 'bottom-center', // 设置文本标记锚点
offset: new (maps as AMap.NameSpace).Pixel(0, option.offsetY!),
style: {
'margin-bottom': '1rem',
padding: (option.padding || 8) + 'px',
'line-height': (option.fontSize || 14) + 'px',
'border-radius': (option.borderRadius || 0) + 'px',
'border-color': `${option.bgColor || '#fff'} transparent transparent`,
'background-color': option.bgColor || '#fff',
'box-shadow': '0 2px 6px 0 rgba(114, 124, 245, .5)',
'text-align': 'center',
'font-size': (option.fontSize || 14) + 'px',
color: option.color || '#000',
},
position: option.position as any,
})
const event =
(maps as QQMaps | GoogleMaps).event || (maps as AMap.NameSpace).Event
event.addListener(this.Text, 'click', () => {
this.callback!()
})
this.Text.setMap(option.map)
}
function removeAMapText(this: Callout) {
if (this.Text) {
this.option.map.remove(this.Text)
} }
} }
class Callout implements OverlayView, Overlay { class Callout implements OverlayView, Overlay {
option: CalloutOptions option: CalloutOptions
position?: GLatLng | QLatLng position?: GLatLng | QLatLng | AMap.LngLat
index?: number index?: number
visible?: boolean visible?: boolean
alwaysVisible?: boolean alwaysVisible?: boolean
div: HTMLDivElement div?: HTMLDivElement
triangle: HTMLDivElement triangle?: HTMLDivElement
callback?: Function
Text?: AMap.Text
// @ts-ignore
setMap
// @ts-ignore
getMap
// @ts-ignore // @ts-ignore
setMap = overlay.setMap getPanes
// @ts-ignore // @ts-ignore
getMap = overlay.getMap getProjection
// @ts-ignore // @ts-ignore
getPanes = overlay.getPanes map_changed
// @ts-ignore // @ts-ignore
getProjection = overlay.getProjection set: (key: string, value: any) => void
map_changed = (overlay as any).map_changed
set = overlay.set
get = overlay.get
setOptions = overlay.setValues
bindTo = overlay.bindTo
bindsTo = (overlay as any).bindsTo
notify = overlay.notify
setValues = overlay.setValues
// @ts-ignore // @ts-ignore
unbind = overlay.unbind get: (key: string) => any
// @ts-ignore // @ts-ignore
unbindAll = overlay.unbindAll setOptions: (values?: object | null | undefined) => void
addListener = (overlay as any).addListener // @ts-ignore
bindTo
// @ts-ignore
bindsTo
// @ts-ignore
notify
// @ts-ignore
setValues
// @ts-ignore
unbind
// @ts-ignore
unbindAll
// @ts-ignore
addListener
set onclick(callback: any) { set onclick(callback: any) {
this.div.onclick = callback this.div!.onclick = callback
} }
get onclick(): any { get onclick(): any {
return this.div.onclick return this.div!.onclick
} }
constructor(option: CalloutOptions = {}) { constructor(option: CalloutOptions = {}, callback?: Function) {
this.option = option || {} this.option = option || {}
const map = option.map
this.position = option.position
this.index = 1
const visible = const visible =
(this.visible = (this.visible =
this.alwaysVisible = this.alwaysVisible =
option.display === 'ALWAYS') option.display === 'ALWAYS')
const div = (this.div = document.createElement('div'))
const divStyle = div.style if (getIsAMap()) {
divStyle.position = 'absolute' this.callback = callback
divStyle.whiteSpace = 'nowrap' if (this.visible) {
divStyle.transform = 'translateX(-50%) translateY(-100%)' this.createAMapText()
divStyle.zIndex = '1' }
divStyle.boxShadow = option.boxShadow || 'none' } else {
divStyle.display = visible ? 'block' : 'none' const map = option.map
const triangle = (this.triangle = document.createElement('div')) this.position = option.position
triangle.setAttribute( this.index = 1
'style', const div = (this.div = document.createElement('div'))
'position: absolute;white-space: nowrap;border-width: 4px;border-style: solid;border-color: #fff transparent transparent;border-image: initial;font-size: 12px;padding: 0px;background-color: transparent;width: 0px;height: 0px;transform: translate(-50%, 100%);left: 50%;bottom: 0;' const divStyle = div.style
) divStyle.position = 'absolute'
this.setStyle(option) divStyle.whiteSpace = 'nowrap'
div.appendChild(triangle) divStyle.transform = 'translateX(-50%) translateY(-100%)'
if (map) { divStyle.zIndex = '1'
this.setMap(map) divStyle.boxShadow = option.boxShadow || 'none'
divStyle.display = visible ? 'block' : 'none'
const triangle = (this.triangle = document.createElement('div'))
triangle.setAttribute(
'style',
'position: absolute;white-space: nowrap;border-width: 4px;border-style: solid;border-color: #fff transparent transparent;border-image: initial;font-size: 12px;padding: 0px;background-color: transparent;width: 0px;height: 0px;transform: translate(-50%, 100%);left: 50%;bottom: 0;'
)
this.setStyle(option)
div.appendChild(triangle)
if (map) {
this.setMap(map)
}
} }
} }
createAMapText = createAMapText
removeAMapText = removeAMapText
onAdd = onAdd onAdd = onAdd
construct = onAdd construct = onAdd
setOption(option: CalloutOptions) { setOption(option: CalloutOptions) {
this.option = option this.option = option
this.setPosition(option.position)
if (option.display === 'ALWAYS') { if (option.display === 'ALWAYS') {
this.alwaysVisible = this.visible = true this.alwaysVisible = this.visible = true
} else { } else {
this.alwaysVisible = false this.alwaysVisible = false
} }
this.setStyle(option)
if (getIsAMap()) {
if (this.visible) {
this.createAMapText()
}
} else {
this.setPosition(option.position)
this.setStyle(option)
}
} }
setStyle(option: CalloutOptions) { setStyle(option: CalloutOptions) {
const div = this.div const div = this.div!
const divStyle = div.style const divStyle = div.style
div.innerText = option.content || '' div.innerText = option.content || ''
divStyle.lineHeight = (option.fontSize || 14) + 'px' divStyle.lineHeight = (option.fontSize || 14) + 'px'
...@@ -116,11 +181,11 @@ export function createCallout(maps: QQMaps | GoogleMaps) { ...@@ -116,11 +181,11 @@ export function createCallout(maps: QQMaps | GoogleMaps) {
divStyle.borderRadius = (option.borderRadius || 0) + 'px' divStyle.borderRadius = (option.borderRadius || 0) + 'px'
divStyle.backgroundColor = option.bgColor || '#fff' divStyle.backgroundColor = option.bgColor || '#fff'
divStyle.marginTop = '-' + ((option.top || 0) + 5) + 'px' divStyle.marginTop = '-' + ((option.top || 0) + 5) + 'px'
this.triangle.style.borderColor = `${ this.triangle!.style.borderColor = `${
option.bgColor || '#fff' option.bgColor || '#fff'
} transparent transparent` } transparent transparent`
} }
setPosition(position?: GLatLng | QLatLng) { setPosition(position?: GLatLng | QLatLng | AMap.LngLat) {
this.position = position this.position = position
this.draw() this.draw()
} }
...@@ -137,11 +202,38 @@ export function createCallout(maps: QQMaps | GoogleMaps) { ...@@ -137,11 +202,38 @@ export function createCallout(maps: QQMaps | GoogleMaps) {
divStyle.top = pixel.y + 'px' divStyle.top = pixel.y + 'px'
} }
changed() { changed() {
const divStyle = this.div.style const divStyle = this.div!.style
divStyle.display = this.visible ? 'block' : 'none' divStyle.display = this.visible ? 'block' : 'none'
} }
onRemove = onRemove onRemove = onRemove
destroy = onRemove destroy = onRemove
} }
if (!getIsAMap()) {
const overlay: OverlayView | Overlay = new ((maps as GoogleMaps)
.OverlayView || (maps as QQMaps).Overlay)()
// @ts-ignore
Callout.prototype.setMap = overlay.setMap
// @ts-ignore
Callout.prototype.getMap = overlay.getMap
// @ts-ignore
Callout.prototype.getPanes = overlay.getPanes
// @ts-ignore
Callout.prototype.getProjection = overlay.getProjection
Callout.prototype.map_changed = (overlay as any).map_changed
Callout.prototype.set = overlay.set
Callout.prototype.get = overlay.get
Callout.prototype.setOptions = overlay.setValues
Callout.prototype.bindTo = overlay.bindTo
Callout.prototype.bindsTo = (overlay as any).bindsTo
Callout.prototype.notify = overlay.notify
Callout.prototype.setValues = overlay.setValues
// @ts-ignore
Callout.prototype.unbind = overlay.unbind
// @ts-ignore
Callout.prototype.unbindAll = overlay.unbindAll
Callout.prototype.addListener = (overlay as any).addListener
}
return Callout return Callout
} }
import { MapType, getMapInfo } from '../../../../helpers/location' import { MapType, getMapInfo, getIsAMap } from '../../../../helpers/location'
export * from './types' export * from './types'
import { QQMaps } from './qq/types' import { QQMaps } from './qq/types'
import { GoogleMaps } from './google/types' import { GoogleMaps } from './google/types'
...@@ -16,7 +16,12 @@ interface GoogleMapsWithCallout extends GoogleMaps, MapsWithCallout {} ...@@ -16,7 +16,12 @@ interface GoogleMapsWithCallout extends GoogleMaps, MapsWithCallout {}
interface QQMapsWithCallout extends QQMaps, MapsWithCallout {} interface QQMapsWithCallout extends QQMaps, MapsWithCallout {}
export type Maps = GoogleMapsWithCallout | QQMapsWithCallout interface AMapMapsWithCallout extends AMap.NameSpace, MapsWithCallout {}
export type Maps =
| GoogleMapsWithCallout
| QQMapsWithCallout
| AMapMapsWithCallout
let maps: Maps let maps: Maps
const callbacksMap: Partial<Record<MapType, Array<(maps: Maps) => void>>> = {} const callbacksMap: Partial<Record<MapType, Array<(maps: Maps) => void>>> = {}
...@@ -39,7 +44,9 @@ export function loadMaps(libraries: string[], callback: (maps: Maps) => void) { ...@@ -39,7 +44,9 @@ export function loadMaps(libraries: string[], callback: (maps: Maps) => void) {
(window as WindowExt)[mapInfo.type] && (window as WindowExt)[mapInfo.type] &&
(window as WindowExt)[mapInfo.type].maps (window as WindowExt)[mapInfo.type].maps
) { ) {
maps = (window as WindowExt)[mapInfo.type].maps maps = getIsAMap()
? (window as WindowExt)[mapInfo.type]
: (window as WindowExt)[mapInfo.type].maps
maps.Callout = maps.Callout || createCallout(maps) maps.Callout = maps.Callout || createCallout(maps)
callback(maps) callback(maps)
} else if (callbacks.length) { } else if (callbacks.length) {
...@@ -50,16 +57,21 @@ export function loadMaps(libraries: string[], callback: (maps: Maps) => void) { ...@@ -50,16 +57,21 @@ export function loadMaps(libraries: string[], callback: (maps: Maps) => void) {
const callbackName = GOOGLE_MAP_CALLBACKNAME + mapInfo.type const callbackName = GOOGLE_MAP_CALLBACKNAME + mapInfo.type
globalExt[callbackName] = function () { globalExt[callbackName] = function () {
delete globalExt[callbackName] delete globalExt[callbackName]
maps = (window as WindowExt)[mapInfo.type].maps maps = getIsAMap()
? (window as WindowExt)[mapInfo.type]
: (window as WindowExt)[mapInfo.type].maps
maps.Callout = createCallout(maps) maps.Callout = createCallout(maps)
callbacks.forEach((callback) => callback(maps)) callbacks.forEach((callback) => callback(maps))
callbacks.length = 0 callbacks.length = 0
} }
if (getIsAMap()) {
handleAMapSecurityPolicy(mapInfo)
}
const script = document.createElement('script') const script = document.createElement('script')
let src = let src = getScriptBaseUrl(mapInfo.type)
mapInfo.type === MapType.GOOGLE
? 'https://maps.googleapis.com/maps/api/js?'
: 'https://map.qq.com/api/js?v=2.exp&'
if (mapInfo.type === MapType.QQ) { if (mapInfo.type === MapType.QQ) {
libraries.push('geometry') libraries.push('geometry')
} }
...@@ -73,3 +85,20 @@ export function loadMaps(libraries: string[], callback: (maps: Maps) => void) { ...@@ -73,3 +85,20 @@ export function loadMaps(libraries: string[], callback: (maps: Maps) => void) {
document.body.appendChild(script) document.body.appendChild(script)
} }
} }
const getScriptBaseUrl = (mapType: string): string => {
const urlMap: any = {
qq: 'https://map.qq.com/api/js?v=2.exp&',
google: 'https://maps.googleapis.com/maps/api/js?',
AMap: 'https://webapi.amap.com/maps?v=2.0&',
}
return urlMap[mapType]
}
function handleAMapSecurityPolicy(mapInfo: AnyObject) {
;(window as any)._AMapSecurityConfig = {
securityJsCode: mapInfo.securityJsCode || '',
serviceHost: mapInfo.serviceHost || '',
}
}
...@@ -13,11 +13,17 @@ import { ...@@ -13,11 +13,17 @@ import {
PolylineOptions as QPolylineOptions, PolylineOptions as QPolylineOptions,
Circle as QCircle, Circle as QCircle,
CircleOptions as QCircleOptions, CircleOptions as QCircleOptions,
Point as QPoint,
} from './qq/types' } from './qq/types'
export type Map = GMap | QMap export type GoogleMap = GMap
export type QQMap = QMap
export type Map = GMap | QMap | AMap.Map
export type LatLng = GLatLng | QLatLng export type LatLng = GLatLng | QLatLng
export type Polyline = GPolyline | QPolyline export type Polyline = GPolyline | QPolyline | AMap.Polyline
export type PolylineOptions = GPolylineOptions & QPolylineOptions export type PolylineOptions = GPolylineOptions &
export type Circle = GCircle | QCircle QPolylineOptions &
export type CircleOptions = GCircleOptions & QCircleOptions AMap.PolylineOptions
export type Circle = GCircle | QCircle | AMap.Circle
export type CircleOptions = GCircleOptions & QCircleOptions & AMap.CircleOptions
export type Point = QPoint
...@@ -8,3 +8,14 @@ uni-map { ...@@ -8,3 +8,14 @@ uni-map {
uni-map[hidden] { uni-map[hidden] {
display: none; display: none;
} }
/* 处理高德地图 marker label 默认样式 */
.amap-marker-label{
padding:0;
border:none;
background-color: transparent;
}
/* 处理高德地图 open-location icon 被遮挡问题 */
.amap-marker>.amap-icon>img{
left:0!important;
top:0!important;
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册