概述
在openlayers中直接加载海图会有偏移,这是因为海图的坐标是做了便宜的,所以需要定义海图的坐标,本文将讲述如何实现,并对比OSM和高德。
效果
实现
代码语言:javascript复制<!DOCTYPE html>
<html>
<head>
<title>XYZ</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
<style>
#map,
body,
html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
font-size: 16px;
}
.basemap {
position: absolute;
top: 20px;
right: 20px;
z-index: 99;
padding: 5px;
background: white;
}
</style>
<script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js"></script>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<div id="map" class="map">
<div class="basemap">
<input type="radio" name="baselayer" value="osm">OSM
<input type="radio" name="baselayer" value="nav" checked="checked">高德
<input type="radio" name="baselayer" value="sea">海图
</div>
</div>
<script>
// 定义海图坐标
proj4.defs(
'EPSG:3395',
' proj=merc lon_0=0 k=1 x_0=0 y_0=0 datum=WGS84 units=m no_defs'
);
const seaLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://m12.shipxy.com/tile.c?l=Na&m=o&y={y}&x={x}&z={z}',
projection: 'EPSG:3395',
tileGrid: ol.tilegrid.createXYZ({
extent: [
-20037508.342789244,
-20037508.342789244,
20037508.342789244,
20037508.342789244
]
})
}),
visible: false
});
const navLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8'
})
});
const osmLayer = new ol.layer.Tile({
source: new ol.source.OSM(),
visible: false
});
const vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
url: "data/china.json",
format: new ol.format.GeoJSON()
}),
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#f00',
width: 1
})
})
});
const map = new ol.Map({
target: 'map',
layers: [ navLayer, osmLayer, seaLayer, vectorLayer ],
view: new ol.View({
minZoom: 1,
maxZoom: 18,
center: [11278378, 4208063],
zoom: 4
})
});
const layerDict = {
sea: seaLayer,
osm: osmLayer,
nav: navLayer
}
$('input[type=radio][name=baselayer]').change(function() {
for (const k in layerDict) {
const isShow = this.value === k;
layerDict[k].setVisible(isShow);
}
});
</script>
</body>
</html>