google 地图

获取地图

获取地址 http://maps.googleapis.com/maps/api/jshttps://maps.googleapis.com/maps/api/js

参数 描述
key 在Google申请的API key
sensor 用于指明应用程序是否使用一个传感器 (类似 GPS 导航) 来定位用户的位置。参数值可以设置为 true 或者 false。
callback 加载后的回调方法

例:

<!DOCTYPE html>
<html>
<head>
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDJW4jsPlNKgv6jFm3B5Edp5ywgdqLWdmc&callback=initMap" async defer></script>
    <script>
        function initMap() {
            let map = new google.maps.Map(document.getElementById("googleMap"), {
                center: new google.maps.LatLng(51.508742, -0.120850),
                zoom: 5,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            });
        }
        // 窗口载入后通过执行 initialize() 函数来初始化 Map 对象,这样可以确保在页面完全载入后再加载 Google 地图:
        google.maps.event.addDomListener(window, 'load', initMap);
    </script>
</head>
<body>
    <!-- 地图容器 -->
    <div id="googleMap" style="width:500px;height:380px;"></div>
</body>
</html>

同样我们也可以在页面完全载入后再加载 Google 地图 API。
以下实例使用了 window.onload 来实现页面完全载入后加载 Google 地图 。 loadScript() 函数创建了加载 Google 地图 API <script> 标签。此外在标签的末尾添加了 callback=initialize 参数, initialize()作为回调函数会在API完全载入后执行:

function loadScript() {
  var script = document.createElement("script");
  script.type = "text/javascript";
  script.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyBzE9xAESye6Kde-3hT-6B90nfwUkcS8Yw&sensor=false&callback=initialize";
  document.body.appendChild(script);
}

window.onload = loadScript;

地图 API Map() 构造器

Map() 构造器创建了一个新的地图并插入到指定的HTML元素中(

元素)。

语法:

// HTMLElement 规定要把地图放置在那个 HTML 元素中。
// MapOptions 带有地图初始化变量/选项的 MapOptions 对象。
new google.maps.Map(HTMLElement, MapOptions)

MapOptions

属性 类型 描述
backgroundColor string 规定 Map
的背景颜色。
center LatLng 中心点,指定了地图的中心,该中心通过坐标(纬度,经度)在地图上创建一个中心点。如:new google.maps.LatLng(51.508742,-0.120850)
disableDefaultUI boolean 是否关闭默认控件集, truefalse
disableDoubleClickZoom boolean 双击时启用/禁用缩放并居中。
draggable boolean 当设置为 False 时,阻止地图被拖拽。默认是 True。
draggableCursor string 规定要显示在可拖拽对象上的光标的名称/URL。
draggingCursor string 规定当对象被拖拽时要显示的光标的名称/URL。
keyboardShortcuts boolean 当设置为 False 时,阻止地图被键盘控制。默认是 True。
mapMaker boolean 如果要使用 Map Maker 图块代替常规图块,则设置为 True。
mapTypeControl boolean 规定 Map 类型控件的默认启用/禁用状态。
mapTypeControlOptions MapTypeControlOptions Map 类型控件的默认显示选项。
mapTypeId MapTypeId 指定了地图的初始类型:卫星图像的主要街道透明层HYBRID、普通的街道地图ROADMAP、卫星图像SATELLITE、带有自然特征(如地形和植被)的地图TERRAIN
noClear boolean 如果设置为 True,则不清空 Map <div> 的内容。
overviewMapControl boolean Overview Map 控件的启用/禁用状态。
overviewMapControlOptions OverviewMapControlOptions Overview Map 控件的显示选项。
panControl boolean Pan 控件的启用/禁用状态。
panControlOptions PanControlOptions Pan 控件的显示选项。
rotateControl boolean Rotate 控件的启用/禁用状态。
rotateControlOptions RotateControlOptions Rotate 控件的显示选项。
scaleControl boolean Scale 控件的默认启用/禁用状态。
scaleControlOptions ScaleControlOptions Scale 控件的默认显示选项。
scrollwheel boolean 当设置为 False 时,禁用地图上的滚轮缩放。默认是 True。
streetView StreetViewPanorama 当地图上的 Street View pegman 街景人形图标被投下时,要显示的 StreetViewPanorama。
streetViewControl boolean Street View Pegman 控件的默认启用/禁用状态。
streetViewControlOptions StreetViewControlOptions Street View Pegman 控件的默认显示选项
styles Array. 要应用到每个默认地图类型的样式。在线配置地址:https://mapstyle.withgoogle.com/
heading number 规定航拍图像的航向度数。
zoom number 缩放等级,zoom: 0 显示了整个地球地图的完全缩放。
maxZoom number 地图的最大缩放级别。
minZoom number 地图的最小缩放级别。
tilt number 从视口平面到地图平面的地图的入射角,以度为单位进行测量(0 和 45)。

Map() 的方法

方法 返回值 描述
fitBounds(LatLngBounds[, padding]) None 设置要包含给定边界的视口。padding值越小放大的比例越大,可以为负值
getBounds() LatLng,LatLng 返回当前视口的西南纬度/经度和东北纬度/经度。
getCenter() LatLng 返回地图的中心的纬度/经度。
getDiv() Node 返回包含地图的 DOM 对象。
getHeading() number 返回航拍图像的罗盘航向(支持 SATELLITE 和 HYBRID 地图类型)。
getMapTypeId() HYBRID ROADMAP SATELLITE TERRAIN 返回当前地图类型。
getProjection() Projection 返回当前 Projection(投影)。
getStreetView() StreetViewPanorama 返回绑定到地图的默认的 StreetViewPanorama。
getTilt() number 返回航拍图像的入射角度数(支持 SATELLITE 和 HYBRID 地图类型)。
getZoom() number 返回地图的当前缩放级别。
panBy(xnumber,ynumber None 通过以像素计的给定距离改变地图的中心。
panTo(LatLng) None 改变地图的中心为给定的 LatLng。自带过渡效果
panToBounds(LatLngBounds) None 将地图平移所需的最小距离以包含给定的 LatLngBounds。
setCenter(LatLng) None 直接定位到地图中心,无过渡效果
setHeading(number) None 设置航拍图像的罗盘方向(以度为单位进行测量),基本方向为北方。
setMapTypeId(MapTypeId) None 改变要显示的地图类型。
setOptions(MapOptions) None
setStreetView(StreetViewPanorama) None 绑定一个 StreetViewPanorama 到地图上。
setTilt(number) None 设置航拍图像的入射角度数(支持 SATELLITE 和 HYBRID 地图类型)。
setZoom(number) None
LatLngBounds

api详见:https://developers.google.com/maps/documentation/javascript/reference/coordinates#LatLng

实例代码片段:根据当前所有所要标记的点计算出中心点及最适合的zoom

... ...
let latlngbounds = new google.maps.LatLngBounds();

markers.forEach((item) => {
    let LatLng = new google.maps.LatLng(...item.LatLng);
    latlngbounds.extend(LatLng);
});

map.setCenter(latlngbounds.getCenter());
map.fitBounds(latlngbounds, -2);

Map() 的属性

属性 类型 描述
controls Array.<MVCArray.> 要附加到地图上的额外控件。
mapTypes MapTypeRegistry 按字符串 ID 划分的 MapType 实例的注册表。
overlayMapTypes MVCArray. 要叠加的额外地图类型。

Map() 的事件

事件 参数 描述
bounds_changed None 当可视区域范围更改时会触发此事件。
center_changed None 当地图 center(中心)属性更改时会触发此事件。
click MouseEvent 当用户点击地图(但不是点击标记或信息窗口)时会触发此事件。
dblclick MouseEvent 当用户双击地图时会触发此事件。请注意,触发此事件前还会触发点击事件。
drag None 当用户拖动地图时会反复触发此事件。
dragend None 当用户停止拖动地图时会触发此事件。
dragstart None 当用户开始拖动地图时会触发此事件。
heading_changed None 当地图 heading(方向)属性更改时会触发此事件。
idle None 当地图在平移或缩放之后变为闲置状态时会触发此事件。
maptypeid_changed None 当 mapTypeId 属性更改时会触发此事件。
mousemove MouseEvent 只要用户的鼠标在地图容器上移动,就会触发此事件。
mouseout MouseEvent 当用户的鼠标从地图容器上退出时会触发此事件。
mouseover MouseEvent 当用户的鼠标进入地图容器时会触发此事件。
projection_changed None 当投影更改时会触发此事件。
resize None 当地图(div)更改尺寸时会触发此事件。
rightclick MouseEvent 当用户右击地图时会触发此事件。
tilesloaded None 当可见图块载入完成后会触发此事件。
tilt_changed None 当地图 tilt(倾斜)属性更改时会触发此事件。
zoom_changed None 当地图 zoom(缩放)属性更改时会触发此事件。

叠加层

叠加层是地图上绑定到经度/纬度坐标的对象,会随您拖动或缩放地图而移动。
Google 地图 API 有如下几种叠加层:

  • 地图上的点使用标记来显示,通常显示自定义图标。标记是 GMarker 类型的对象,并且可以利用 GIcon 类型的对象来自定义图标。
  • 地图上的线使用折线(表示点的集合)来显示。线是类型为 GPolyline 的对象。
  • 地图上的区域显示为多边形(如果是任意形状的区域)或底面叠加层(如果是矩形区域)。多边形类似于闭合的折线,因此可以是任何形状。地面叠加层通常用于地图上与图块有直接或间接关联的区域。
  • 地图本身使用图块叠加层显示。如果您有自己的系列图块,可以使用 GTileLayerOverlay 类来改变地图上已有的图块,甚至可以使用 GMapType 来创建您自己的地图类型。
  • 信息窗口也是一种特殊的叠加层。但是请注意,信息窗口会自动添加到地图中,并且地图只能添加一个类型为 GInfoWindow 的对象。

事件

构造函数/对象 描述
MapsEventListener It has no methods and no constructor. Its instances are returned from addListener(), addDomListener() and are eventually passed back to removeListener()
event Adds/Removes/Trigger event listeners
MouseEvent Returned from various mouse events on the map and overlays

标记

详见:Marker

记标识地图上的点。默认情况下,它们使用 G_DEFAULT_ICON(您也可以指定自定义图标)。GMarker 构造函数将 GLatLng 和 GMarkerOptions(可选)对象作为参数。标记设计为可交互。例如,默认情况下它们接收 "click" 事件,常用于在事件侦听器中打开信息窗口。在定义marker时直接传入map实例或通过 setMap() 方法在地图上添加标记:

var marker = new google.maps.Marker({
    // map: map
    position: new google.maps.LatLng(52.395715,4.888916), // position: {lat: 59.327, lng: 18.067}
    draggable: true, // 是否可以拖拽
    animation: google.maps.Animation.BOUNCE, // 使用 animation 属性来拖动标记/
    label: 'A', // 当前点标签,是一个字符串
    icon: 'pinkball.png' // 标记可以用自定义的新图标来显示,以替代默认图标
});

marker.setMap(map);
// marker.setMap(null);

折线

GPolyline 对象可在地图上创建线性叠加层。GPolyline 包括一系列点,并创建一系列有序连接这些点的线段。折线支持以下属性:

let polyline = new google.maps.Polyline({
    path: [ // 指定了多个直线的纬度/经度坐标
        new google.maps.LatLng(58.983991,5.734863),
        new google.maps.LatLng(52.395715,4.888916),
        new google.maps.LatLng(53.508742,-0.120850)
    ],
    strokeColor: "#0000FF", // 指定直线的十六进制颜色值(格式: "#FFFFFF")
    strokeOpacity: 0.8, //  指定直线的透明度(该值为 0.0 到 1.0)
    strokeWeight: 2, // 定义线的宽度,以像素为单位。
    editable: false // 定义用户是否可编辑直线(true/false)
});

polyline.setMap(map);

多边形

GPolygon 对象类似于 GPolyline 对象,因为它们都包括一系列有序的点。但是,多边形不像折线一样有两个端点,而是设计为定义形成闭环的区域。和折线一样,您可以自定义多边形边(线)的颜色、粗细和透明度,以及封闭的填充区域的颜色和透明度。颜色应是十六进制数字 HTML 样式。

let polyline = new google.maps.Polygon({
    path: [ // 指定了多个直线的纬度/经度坐标
        new google.maps.LatLng(58.983991,5.734863),
        new google.maps.LatLng(52.395715,4.888916),
        new google.maps.LatLng(53.508742,-0.120850)
    ],
    strokeColor: "#0000FF", // 指定直线的十六进制颜色值(格式: "#FFFFFF")
    strokeOpacity: 0.8, //  指定直线的透明度(该值为 0.0 到 1.0)
    strokeWeight: 2, // 定义线的宽度,以像素为单位。
    editable: false, // 定义用户是否可编辑直线(true/false)
    fillColor: "#0000FF", // 指定闭合区域的十六进制颜色值 (格式: "#FFFFFF")
    fillOpacity: 0.4 // 指定填充颜色的透明度 (该值为 0.0 到 1.0)
});

polyline.setMap(map);

new google.maps.Circle({
  center: new google.maps.LatLng(52.395715,4.888916), // 指定圆的中心点参数
  radius: 20000, // 指定圆的半径,以米为单位
  strokeColor: "#0000FF", // 指定弧线的十六进制颜色值(格式: "#FFFFFF")
  strokeOpacity: 0.8, // 指定弧线的透明度(该值为 0.0 到 1.0)
  strokeWeight: 2, // 定义线的宽度,以像素为单位。
  fillColor: "#0000FF", // 指定圆的十六进制颜色值填充值 (格式: "#FFFFFF")
  fillOpacity: 0.4 // 指定填充颜色的透明度 (该值为 0.0 到 1.0)
  editable: false, // 定义用户是否可编辑(true/false)
})

信息窗口

var marker = new google.maps.Marker({
    position: new google.maps.LatLng(52.395715,4.888916),
    animation: google.maps.Animation.BOUNCE, // 使用 animation 属性来拖动标记
    icon: 'pinkball.png' // 标记可以用自定义的新图标来显示,以替代默认图标
});

marker.setMap(map);

var infowindow = new google.maps.InfoWindow({
   maxWidth: 600,
  content:"Hello World!"
});

infowindow.open(map,marker);
自定义popup

官方示例: overlay-popup

代码片段:

.page-wrap
    .map-container(ref="mapContainer")
    div(ref="popup")
        p hello-world
.page-wrap
    width: 100%
    height: 100%
    position: relative
.map-container
    width: 100%
    height: 100%
// popup
.popup-container
    cursor: auto
    position: absolute
    height: 0
    width: 280px
.popup-bubble-anchor
    position: absolute
    bottom: 8px
    left: 0
    right: 0
    &::after, &::before
        content: ""
        position: absolute
        top: 0
        left: 0
        transform: translate(-50%, 0)
        width: 0
        height: 0
        border-left: 6px solid transparent
        border-right: 6px solid transparent
        border-top: 8px solid #019B91
    &::before
        top: -3px
        border-top: 8px solid rgba(23,74,85,0.999)
        z-index: 1
.popup-bubble
    position: absolute
    top: 0
    left: 0
    width: 280px
    transform: translate(-50%, -100%)
    padding: 5px
    border-radius: 5px
    font-family: sans-serif
    overflow-y: auto
    background: rgba(23,74,85,0.80)
    border: 2px solid #019B91
    box-shadow: 0 2px 10px 1px rgba(0,0,0,0.5)
// add Custom Popups
init () {
    ... ...
    const Popup = this.createPoputClasss();
    let popup = new Popup(new google.maps.LatLng(...CENTER), this.$refs['popup']);
    popup.setMap(map);
},
createPoputClasss () {
    class Popup extends google.maps.OverlayView {
        constructor (position, content) {
            super();
            this.position = position;

            content.classList.add('popup-bubble');

            // This zero-height div is positioned at the bottom of the bubble.
            let bubbleAnchor = document.createElement('div');
            bubbleAnchor.classList.add('popup-bubble-anchor');
            bubbleAnchor.appendChild(content);

            // This zero-height div is positioned at the bottom of the tip.
            this.containerDiv = document.createElement('div');
            this.containerDiv.classList.add('popup-container');
            this.containerDiv.appendChild(bubbleAnchor);

            // Optionally stop clicks, etc., from bubbling up to the map.
            google.maps.OverlayView.preventMapHitsAndGesturesFrom(this.containerDiv);
        }
        onAdd () {
            this.getPanes().floatPane.appendChild(this.containerDiv);
        }
        onRemove () {
            if (this.containerDiv.parentElement) {
                this.containerDiv.parentElement.removeChild(this.containerDiv);
            }
        }
        draw () {
            let divPosition = this.getProjection().fromLatLngToDivPixel(this.position);

            // Hide the popup when it is far out of view.
            let display =
                Math.abs(divPosition.x) < 4000 && Math.abs(divPosition.y) < 4000 ?
                    'block' :
                    'none';

            if (display === 'block') {
                this.containerDiv.style.left = divPosition.x + 'px';
                this.containerDiv.style.top = divPosition.y + 'px';
            }
            if (this.containerDiv.style.display !== display) {
                this.containerDiv.style.display = display;
            }
        }
    }
    return Popup;
}

地图事件

点击标记缩放地图

// 使用 addListener() 事件处理程序来注册事件的监听。该方法使用一个对象,一个事件来监听,当指定的事件发生时 函数将被调用。
google.maps.event.addListener(marker,'click',function() {
  map.setZoom(9); // // Zoom to 9 when clicking on marker
  map.setCenter(marker.getPosition());
});

平滑放大地图

/**
* params {map:map实例, max: 最大值也是目标值, cnt: 当前值}
*/
smoothZoom (map, max, cnt) {
    if (cnt >= max) {
        return;
    } else {
        let z = google.maps.event.addListener(map, 'zoom_changed', () => {
            google.maps.event.removeListener(z);
            this.smoothZoom(map, max, cnt + 1);
        });
        let timer = setTimeout(function(){
            map.setZoom(cnt);
            clearTimeout(timer);
        }, 80);
    }
}

重置标记

// 通过给地图添加事件处理程序来改变 'center' 属性,以下代码使用 center_changed 事件在3秒后标记移会中心点
google.maps.event.addListener(map,'center_changed',function() {
  window.setTimeout(function() {
    map.panTo(marker.getPosition());
  },3000);
});

点击标记时打开信息窗口

var infowindow = new google.maps.InfoWindow({
  content:"Hello World!"
});

google.maps.event.addListener(marker, 'click', function() {
  infowindow.open(map,marker);
});

设置标记及打开每个标记的信息窗口

当用户点击地图时执行一个窗口用户点击地图某个位置时使用 placeMarker() 函数在指定位置上放置一个标记,并弹出信息窗口:

google.maps.event.addListener(map, 'click', function(event) {
  placeMarker(event.latLng);
});

function placeMarker(location) {
  var marker = new google.maps.Marker({
    position: location,
    map: map,
  });
  var infowindow = new google.maps.InfoWindow({
    content: 'Latitude: ' + location.lat() +
    '<br>Longitude: ' + location.lng()
  });
  infowindow.open(map,marker);
}

地图控件集

控件 描述
panControl 默认开启,地图上显示的是一个平底碗样的控件,点击4个角平移地图
zoomControl 默认开启,显示一个滑动条来控制map的Zoom级别
mapTypeControl 默认开启,允许用户在map types(roadmap 和 satallite)之间切换
streetViewControl 默认开启,显示为一个街景小人图标,可拖拽到地图上某个点来打开街景
fullscreenControl 默认开启,全屏
scaleControl 显示地图比例尺
overviewMapControl 从一个广域的视角俯视地图
rotateControl 显示一个小的圆周图标,可以转动地图
new google.maps.Map(document.getElementById("googleMap"), {
    center: new google.maps.LatLng(51.508742, -0.120850),
    zoom: 5,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    // disableDefaultUI: true, // 关闭默认控件集
    rotateControl: true, // 开启对应控件
    zoomControl:true, // 如果需要修改一个控件,首先开启控件(设置其为true)。
    zoomControlOptions: { // 修改控件
        style: google.maps.ZoomControlStyle.SMALL // SMALL-最小化控件、LARGE-标准滑动控件、DEFAULT-基于设备和地图大小,选择最合适的控件
    },
    mapTypeControl:true,
    mapTypeControlOptions: {
        // DROPDOWN_MENU,用于显示单个按钮控件,以便从下拉菜单中选择地图类型
        // HORIZONTAL_BAR,用于在水平栏中将一组控件显示为如 Google Maps 中所示按钮。
        // DEFAULT,用于显示"默认"的行为,该行为取决于屏幕尺寸,并且可能会在 API 以后的版本中有所变化。
        style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
        // 同样可以使用ControlPosition属性指定控件的位置:
        position:google.maps.ControlPosition.TOP_CENTER
    }
});

自定义控件集

<html>
<head>
<script src="//maps.googleapis.com/maps/api/js?key=AIzaSyDJW4jsPlNKgv6jFm3B5Edp5ywgdqLWdmc&sensor=false">
</script>

<script>
var map;
var london = new google.maps.LatLng(51.508742,-0.120850);

// Add a Home control that returns the user to London
function HomeControl(controlDiv, map) {
  controlDiv.style.padding = '5px';
  var controlUI = document.createElement('div');
  controlUI.style.backgroundColor = 'yellow';
  controlUI.style.border='1px solid red';
  controlUI.style.cursor = 'pointer';
  controlUI.style.textAlign = 'center';
  controlUI.title = 'Set map to London';
  controlDiv.appendChild(controlUI);
  var controlText = document.createElement('div');
  controlText.style.fontFamily='Arial,sans-serif';
  controlText.style.fontSize='12px';
  controlText.style.paddingLeft = '4px';
  controlText.style.paddingRight = '4px';
  controlText.innerHTML = '<b>Home<b>'
  controlUI.appendChild(controlText);

  // Setup click-event listener: simply set the map to London
  google.maps.event.addDomListener(controlUI, 'click', function() {
    map.setCenter(london)
  });
}

function initialize() {
  var mapDiv = document.getElementById('googleMap');
  var myOptions = {
    zoom: 12,
    center: london,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  map = new google.maps.Map(mapDiv, myOptions);
  // Create a DIV to hold the control and call HomeControl()
  var homeControlDiv = document.createElement('div');
  var homeControl = new HomeControl(homeControlDiv, map);
//  homeControlDiv.index = 1;
  map.controls[google.maps.ControlPosition.TOP_RIGHT].push(homeControlDiv);
}

google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>

<body>
    <div id="googleMap" style="width:500px;height:380px;"></div>
</body>
</html>

去掉log信息

a[title^=Open]
    display: none !important
.gmnoprint
    display: none !important

像素坐标转为地图坐标

fromPointToLatLng ({ x, y }) {
    let { map } = this;
    let ne = map.getBounds().getNorthEast();
    let sw = map.getBounds().getSouthWest();
    let projection = map.getProjection();
    let topRight = projection.fromLatLngToPoint(ne);
    let bottomLeft = projection.fromLatLngToPoint(sw);
    let scale = 1 << map.getZoom();
    return projection.fromPointToLatLng(new google.maps.Point(x / scale + bottomLeft.x, y / scale + topRight.y));
}

地图坐标转为像素坐标

function LatLng2Pixel(latLng) {
    let { map } = this;
    let scale = Math.pow(2, map.getZoom());
    let projection = map.getProjection();
    let bounds = map.getBounds();
    let nw = projection.fromLatLngToPoint(new google.maps.LatLng(bounds.getNorthEast().lat(), bounds.getSouthWest().lng()));
    let point = projection.fromLatLngToPoint(latLng);
    return new google.maps.Point(Math.floor((point.x - nw.x) * scale), Math.floor((point.y - nw.y) * scale));
}
posted @ 2020-05-17 18:37  fanlinqiang  阅读(658)  评论(0)    收藏  举报