HTML关键代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>水利信息在线分析服务系统</title>
<link href="Libs/jquery-ui-1.11.4/jquery-ui.min.css" rel="stylesheet" type="text/css" />
<link href="Styles/style.css" rel="stylesheet" type="text/css" />
<!-- jQuery库 -->
<script src="Libs/jquery-1.11.2.min.js" type="text/javascript"></script>
<!--OL3库-->
<!--<script src="Libs/ol/ol.js" type="text/javascript"></script>-->
<script src="Libs/ol/ol-debug.js" type="text/javascript"></script>
<link href="Libs/ol/ol.css" rel="stylesheet" type="text/css" />
<!--OL3扩展库-->
<script src="Libs/ol/source/GoogleMapSource.js" type="text/javascript"></script>
<script src="Libs/ol/layer/GoogleMapLayer.js" type="text/javascript"></script>
<!-- 第三方插件库 统计图插件 -->
<script src="Libs/FusionCharts.js" type="text/javascript"></script>
<!-- 第三方插件库 -->
<script src="Libs/jquery-ui-1.11.4/jquery-ui.min.js" type="text/javascript"></script>
<script src="Libs/jquery.ui.datepicker-zh-CN.js" type="text/javascript"></script>
</head>
<body>
<div class="backgroundDiv">
</div>
<!-- 地图底图切换列表 -->
<select class="layerSwitcherDiv" id="layerSwitcherBtn" onchange="onlayerSwitcherBtn()">
<option value="terrain">谷歌地形图</option>
<option value="vector">谷歌矢量图</option>
<option value="raster">谷歌遥感图</option>
<option value="road">谷歌交通图</option>
</select>
<!-- 地图容器-->
<div id="map">
<!-- Popup -->
<div id="popup" class="ol-popup" >
<div id="popup-closer" class="ol-popup-closer"></div>
<div id="popup-content">
</div>
</div>
</div>
<!-- 系统功能库 -->
<script src="Scripts/SLSysFun.js" type="text/javascript"></script>
</body>
</html>

SLSysFun.js

/************************************************************************/
/* 水利信息在线分析服务系统
*@author fmm 2015-06-09/ wjl 2015-10-10
/************************************************************************/
var map; //地图容器
var labelType; //当前显示哪一个div
var winHeight; //屏幕当前高度
var winWidth; //屏幕当前宽度

var popup; //弹出的Popup
var popupElement = $("#popup");
var popupContent = $("#popup-content");
var popupCloser = $("#popup-closer");

var preFeature = null; //鼠标选中的前一要素

/*
* 页面初始化,在页面加载完成之后执行
*/
$(function () {
/**
* 添加关闭按钮的单击事件(隐藏popup)
* @return {boolean} Don't follow the href.
*/
popupCloser.bind("click", function () {
popup.setPosition(undefined); //未定义popup位置
popupCloser.blur(); //失去焦点
return false;
});

initMap(); //初始化地图容器

winWidth = $(window).width();
winHeight = $(window).height();
});

/*
* 页面尺寸发生变化回调函数
*@author fmm 2015-07-17
*/
window.onresize = function () {
winWidth = $(window).width();
winHeight = $(window).height();
}

/*
* 地图容器初始化
*/
var googleLayer; //加载的Google图层
var projection = ol.proj.get('EPSG:3857');

function initMap() {
//初始化Google图层
googleLayer = new ol.layer.GoogleMapLayer({
layerType: ol.source.GoogleLayerType.TERRAIN
});
//初始化地图容器
map = new ol.Map({
layers: [googleLayer],
target: 'map', //地图容器div的ID
view: new ol.View({
projection: projection, //投影坐标系
center: [12308196.042592192, 2719935.2144997073],
minZoom: 2,
zoom:6
})
});

/**
* 为map添加鼠标移动事件监听,当指向标注时改变鼠标光标状态
*/
map.on('pointermove', function (e) {
var pixel = map.getEventPixel(e.originalEvent);
var hit = map.hasFeatureAtPixel(pixel);
map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});

/**
* 在地图容器中创建一个Overlay
*/
popup = new ol.Overlay(/** @type {olx.OverlayOptions} */({
element: popupElement,
autoPan: true,
positioning: 'bottom-center',
stopEvent: false,
autoPanAnimation: {
duration: 250
}
}));
map.addOverlay(popup);

/**
* 为map添加点击事件监听,渲染弹出popup
*/
map.on('singleclick', function (evt) {
var coordinate = evt.coordinate;
//判断当前单击处是否有要素,捕获到要素时弹出popup
var feature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) { return feature; });
if (feature) {
popupContent.innerHTML = ''; //清空popup的内容容器
var type = feature.get('type');
if (type == "river" || type == "Rver") {
showDetailsInfo(feature); //为水情要素点添加popup的信息内容
}
else if (type == "sq") {
showSsyqDetailInfo(feature); //为雨情要素点添加popup的信息内容
}
else if (type == "typhoon") {
showTFDetailsInfo(feature);
}
else {
return;
}
}
});

/**
* 为map添加move事件监听,变更图标大小实现选中要素的动态效果
*/
map.on('pointermove', function (evt) {
var coordinate = evt.coordinate;
//判断当前鼠标悬停位置处是否有要素,捕获到要素时设置图标样式
var feature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) { return feature; });
if (feature) {
var type = feature.get('type');
if ((type == undefined) || (type == "tfMarker") || (type == "tfCircle")) {
return;
}
if ((preFeature != null) && (preFeature !== feature)) { //如果当前选中要素与前一选中要素不同,恢复前一要素样式,放大当前要素图标
var curImgURL = feature.get('imgURL');
var preImgURL = preFeature.get('imgURL');
feature.setStyle(createLabelStyle(feature, curImgURL, 1.2));
preFeature.setStyle(createLabelStyle(preFeature, preImgURL, 0.8));
preFeature = feature;
}
if (preFeature == null) { //如果前一选中要素为空,即当前选中要素为首次选中要素,放大当前要素图标
var curImgURL = feature.get('imgURL');
feature.setStyle(createLabelStyle(feature, curImgURL, 1.2));
preFeature = feature;
}
}
else {
if (preFeature != null) { //如果鼠标移出前一要素,恢复要素图标样式
var imgURL = preFeature.get('imgURL');
preFeature.setStyle(createLabelStyle(preFeature, imgURL, 0.8));
preFeature = null;
}
}
});
}

/*
* 根据图层类型加载Google地图
*/
function loadGoogleMap(mapType) {
switch (mapType) {
case "terrain": //地形
googleLayer = new ol.layer.GoogleMapLayer({
layerType: ol.source.GoogleLayerType.TERRAIN
});
break;
case "vector": //矢量
googleLayer = new ol.layer.GoogleMapLayer({
layerType: ol.source.GoogleLayerType.VEC
});
break;
case "raster": //影像
googleLayer = new ol.layer.GoogleMapLayer({
layerType: ol.source.GoogleLayerType.RASTER
});
break;
case "road": //道路
googleLayer = new ol.layer.GoogleMapLayer({
layerType: ol.source.GoogleLayerType.ROAD
});
default:
}
map.addLayer(googleLayer); //添加Google地图图层
}

/*
* 初始化图层切换控件
*@ahthor fmm 2015-07-10
*/
function onlayerSwitcherBtn() {
var layerType = $("#layerSwitcherBtn option:selected").val();
map.removeLayer(googleLayer); //移除Google图层
loadGoogleMap(layerType); //根据图层类型重新加载Google图层
}

GoogleMapSource.js

goog.provide('ol.source.GoogleMapSource');
goog.provide('ol.source.GoogleType');
goog.require('ol.source.TileImage');


ol.source.GoogleLayerType = {
VEC: 'vector', //Google矢量数据
RASTER: 'raster', //Google影像数据
ROAD: 'road', //Google道路数据
TERRAIN: 'terrain' //Google地形数据
};
/**
* @classdesc
* @constructor
* @param {options} options Google地图参数.
* @api
*/
ol.source.GoogleMapSource = function (options) {

this.ip = goog.isDef(options.ip) ? options.ip : null;

this.port = goog.isDef(options.port) ? options.port : null;

//图层类型,默认为矢量图
this.layerType = goog.isDef(options.layerType) ? options.layerType : ol.source.GoogleLayerType.VEC,
/**
* @public
* @type {number}
* 最大分辨率
*/
this.maxResolution = null;
//根据投影获取地图范围
var tileProjection = goog.isDef(options.projection) ? options.projection : null;
//瓦片范围
this.tileExtent = [-20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892];
if (tileProjection != null) {
this.tileExtent = tileProjection.getExtent();
}

//设置地图范围
this.extent = goog.isDef(options.extent) ? options.extent : this.tileExtent;

/**
* @public
* @type {Array.<number>}
* 地图的原点,可由外部指定,默认左下角
*/
this.origin = goog.isDef(options.origin) ? options.origin : ol.extent.getCorner(this.extent, ol.extent.Corner.TOP_LEFT);
/**
* @public
* @type {number}
* 瓦片地图总级数
*/
this.maxZoom = goog.isDef(options.maxZoom) ? (options.maxZoom <= 24 ? options.maxZoom : 24) : 24;

/**
* @public
* @type {number}
* 地图图片大小
*/
this.tileSize = goog.isDef(options.tileSize) ? options.tileSize : 256;
//分辨率数组,根据传入的分辨率或范围计算得到
this.resolutions = this.getResolutions();

this.baseURL = goog.isDef(options.baseURL) ? options.baseURL :this.getBaseURL();
/**
* @private
* @type {Array.<number>}
* 创建网格(内部调用)
*/
this.tileGrid = new ol.tilegrid.TileGrid({
origin: this.origin, //数组类型,如[0,0],
resolutions: this.resolutions, //分辨率
tileSize: this.tileSize //瓦片图片大小
});

goog.base(this, {
attributions: options.attributions,
extent: this.extent,
tileExtent: this.tileExtent,
ip: this.ip,
port: this.port,
layerType: this.layerType,
logo: options.logo,
opaque: options.opaque,
projection: options.projection,
state: goog.isDef(options.state) ?
/** @type {ol.source.State} */(options.state) : undefined,
tileGrid: this.tileGrid,
tilePixelRatio: options.tilePixelRatio,
crossOrigin: goog.isDef(options.crossOrigin) ? options.crossOrigin : null //"anonymous"为跨域调用,
});

this.tileUrlFunction = goog.isDef(options.tileUrlFunction) ?
options.tileUrlFunction :
this.tileUrlFunctionExtend;

};
goog.inherits(ol.source.GoogleMapSource, ol.source.TileImage);

/**
* 创建基地址
*/
ol.source.GoogleMapSource.prototype.getBaseURL = function () {
var url_base = "";
switch (this.layerType) {
case ol.source.GoogleLayerType.VEC:
url_base = "http://mt" + Math.round(Math.random() * 3) + ".google.cn/vt/lyrs=m@207000000&hl=zh-CN&gl=CN&src=app&s=Galile";
break;
case ol.source.GoogleLayerType.RASTER:
url_base = "http://mt" + Math.round(Math.random() * 3) + ".google.cn/vt?lyrs=s@173&hl=zh-Hans-CN&gl=CN&token=63145";
break;
case ol.source.GoogleLayerType.ROAD:
url_base = "http://mt" + Math.round(Math.random() * 3) + ".google.cn/vt/imgtp=png32&lyrs=h@248000000,highlight:0x342eaef8dd85f26f:0x39c2c9ac6c582210@1%7Cstyle:maps&hl=zh-CN&gl=CN&src=app&s=Galileo";
break;
case ol.source.GoogleLayerType.TERRAIN:
// url_base = "http://mt" + Math.round(Math.random() * 3) + ".google.cn/vt/lyrs=t@132,r@248000000&hl=zh-CN&src=app&s=Galileo";
url_base = "http://mt" + Math.round(Math.random() * 3) + ".google.cn/vt/lyrs=t@132,r@249000000&hl=zh-CN&src=app&s=Galileo";
// url_base = "http://mt" + Math.round(Math.random() * 3) + ".google.cn/vt?lyrs=t&scale=1";
break;
}
return url_base;
}
/**
* 创建分辨率数组
*/
ol.source.GoogleMapSource.prototype.getResolutions = function () {
if (this.maxResolution == null) {
var width = ol.extent.getWidth(this.tileExtent);
var height = ol.extent.getHeight(this.tileExtent);
this.maxResolution = (width <= height ? height : width) / (this.tileSize);
}
var opt_resolutions = new Array(this.maxZoom);
for (z = 0; z < this.maxZoom; ++z) {
opt_resolutions[z] = this.maxResolution / Math.pow(2, z);
}
return opt_resolutions;
};


/**
* 拼接url取图地址
* @param {Array.<number>} tileCoord 数据格式包含级数、行号、列号.
* @param {string} pixelRatio 像素比率
* @param {ol.proj.Projection} projection 投影
*/
ol.source.GoogleMapSource.prototype.tileUrlFunctionExtend = function (tileCoord, pixelRatio, projection) {
//判断返回的当前级数的行号和列号是否包含在整个地图范围内
if (this.tileGrid != null) {
var tileRange = this.tileGrid.getTileRangeForExtentAndZ(this.extent, tileCoord[0], tileRange);
if (!tileRange.contains(tileCoord)) {
return;
}
}
var urlTemplate = "";
switch (this.layerType) {
case ol.source.GoogleLayerType.VEC:
case ol.source.GoogleLayerType.RASTER:
case ol.source.GoogleLayerType.ROAD:
case ol.source.GoogleLayerType.TERRAIN:
urlTemplate = this.baseURL + "&x=" + '{x}' + "&y=" + '{y}' + "&z=" + '{z}';
break;
}
var z = tileCoord[0];
var x = tileCoord[1];
var y = -(tileCoord[2] + 1);
//var y = Math.pow(2, z) - 1 - tileCoord[2];

return new goog.Uri(urlTemplate.replace('{x}', x.toString()).replace('{y}', y.toString()).replace('{z}', z.toString()));
};

GoogleMapLayer.js

goog.provide('ol.layer.GoogleMapLayer');
goog.require('ol.layer.Tile');
goog.require('ol.source.GoogleMapSource');


/**
* @constructor
* @extends {ol.layer.Tile}
* @fires ol.render.Event
* @param opt_options: Layer options.
* @opt_options: extent(图层范围),origin(瓦片原点)默认情况下都不需要赋值,则默认取图层范围的左下角
* @opt_options: layerType(图层类型),默认情况下为"vector"
* @api stable
*/
ol.layer.GoogleMapLayer = function (opt_options) {
var options = goog.isDef(opt_options) ? opt_options : {};
goog.base(this, /** @type {olx.layer.LayerOptions} */(options));

var source = goog.isDef(options.source) ? options.source : null;

if (source == null) {
source = new ol.source.GoogleMapSource(options);
}
this.setSource(source);
};
goog.inherits(ol.layer.GoogleMapLayer, ol.layer.Tile);

实现效果:

OpenLayers3加载谷歌地图_图层

具体实现代码在上面已经贴出来了,如果要完整Demo可以下载。