WebGIS 开发中,对于数据量不是很大的场景,可以直接从数据库读取数据,通过创建点线面要素(Feature),然后添加到矢量图层(vectorLayer)中,在地图上展示。添加点线面的方法可以封装一下,方便使用。
WebGIS 数据最好符合标准,这里介绍 WKT WKB GeoJson 三种常见格式数据。
2022年10月23日 已修改示例,增加数据转换工具。
<html lang="en">
<head>
<meta charset="utf-8">
<!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
<link rel="stylesheet" href="http://openlayers.vip/examples/css/ol.css" type="text/css">
<style>
/* 注意:这里必须给高度,否则地图初始化之后不显示;一般是计算得到高度,然后才初始化地图 */
.map {
height: 400px;
width: 100%;
float:left;
}
</style>
<!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
<script src="http://openlayers.vip/examples/resources/ol.js"></script>
<script src="./tiandituLayers.js"></script>
<title>OpenLayers example</title>
</head>
<body>
<h2>Feature Layer</h2>
<!--地图容器,需要指定 id -->
<div id="map" class="map"></div>
<script type="text/javascript">
var map = new ol.Map({
// 地图容器
target: 'map',
// 地图图层,比如底图、矢量图等
layers: [
getIMG_CLayer(),
getIBO_CLayer(),
getCIA_CLayer(),
],
// 地图视野
view: new ol.View({
// 设置投影
projection: "EPSG:4326",
// 定位
center: [116, 39],
// 缩放
zoom: 4,
maxZoom: 18,
minZoom: 1,
})
});
var layer = initVectorLayer();
addFeatures();
// 添加点线面
function addFeatures() {
var features = [];
// 添加 WKT 数据
features.push(getFeatureByWKT("POINT(116.17983834030585 39.98298600752048)"));
// 添加 geojson 数据
var geojson = {"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[116.09129344901807,39.976463050783],[116.12802898368604,39.986934394777144],[116.14845668754346,39.970454902589644],[116.14365016898877,39.952945442140425],[116.11069118461377,39.95037052148613],[116.09129344901807,39.976463050783]]]},"properties":null};
features.push(getFeatureByGeoJson(geojson));
// 添加 WKB 数据
features.push(getFeatureByWKB("0102000020E6100000040000004AB6DE424F095D4024548C542D0144404AB6DE42E10D5D4024548CD46D0444404AB6DE022D115D4024548CD4DBFF43404AB6DE42DB135D4024548CD46D044440"));
// 将 features 添加到图层中
layer.getSource().addFeatures(features);
// 地图定位
var extent = layer.getSource().getExtent();
map.getView().fit(extent, {
duration: 1,//动画的持续时间,
callback: null,
});
}
/**
* @todo 矢量图层
* @returns {VectorLayer}
* @constructor
*/
function initVectorLayer() {
//实例化一个矢量图层Vector作为绘制层
let source = new ol.source.Vector();
//创建一个图层
let customVectorLayer = new ol.layer.Vector({
source: source,
zIndex: 2,
//设置样式
style: new ol.style.Style({
//边框样式
stroke: new ol.style.Stroke({
color: 'red',
width: 5,
lineDash: [3, 5]
}),
//填充样式
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.3)',
}),
// 点的样式
image: new ol.style.Circle({
// 点半径
radius: 9,
// 点颜色
fill: new ol.style.Fill({
color: 'red',
})
})
}),
});
//将绘制层添加到地图容器中
map.addLayer(customVectorLayer);
return customVectorLayer;
}
/**
* @todo wkt格式数据转化成图形对象
* @param {string} wkt "POINT(112.7197265625,39.18164062499999)" 格式数据
* @param {string|Projection} sourceCode 源投影坐标系
* @param {string|Projection} targetCode 目标投影坐标系
* @returns {Feature}
*/
function getFeatureByWKT(wkt, sourceCode, targetCode) {
try {
let view = map.getView();
if (!wkt) {
return null;
}
// 数据格式类型
let format = new ol.format.WKT();
let feature;
feature = format.readFeature(wkt, {
featureProjection: targetCode || view.getProjection(),
dataProjection: sourceCode || view.getProjection(),
});
return feature;
} catch (e) {
console.log(e);
return null;
}
}
/**
* @todo 图形对象转化成GeoJson格式数据(postgis)
* @param {string|object} geojson geojson字符串或者对象
* @param {string|Projection} sourceCode 源投影坐标系
* @param {string|Projection} targetCode 目标投影坐标系
* @returns {Feature}
*/
function getFeatureByGeoJson(geojson, sourceCode, targetCode) {
let view = map.getView();
if (!geojson) {
return null;
}
let feature;
if ((typeof geojson) == 'string') {
// 替换 null 字符
while (geojson.indexOf('null') != -1) {
// geojson = geojson
geojson = geojson.replace("null", "");
}
}
feature = (new ol.format.GeoJSON()).readFeature(geojson, {
dataProjection: sourceCode || view.getProjection(), // 设定JSON数据使用的坐标系
featureProjection: targetCode || view.getProjection() // 设定当前地图使用的feature的坐标系
});
return feature;
}
/**
* @todo WKB格式数据转化成图形对象
* @param {string} coordinate 0101000020E610000063B48EAA26105D404E7FF623451C4440 格式数据
* @param {string|Projection} sourceCode 源投影坐标系
* @param {string|Projection} targetCode 目标投影坐标系
* @returns {Feature}
*/
function getFeatureByWKB(coordinate, sourceCode, targetCode) {
try {
let view = map.getView();
if (!coordinate) {
return null;
}
// 数据格式类型
let format = new ol.format.WKB();
let feature;
// 判断收尾,是否为 WKB 格式
if (coordinate.indexOf('010') == 0) {
// 判断字符结尾
let confirmEnding = function (str, target) {
// 请把你的代码写在这里
var start = str.length - target.length;
var arr = str.substr(start, target.length);
if (arr == target) {
return true;
}
return false;
}
if (confirmEnding(coordinate, '40')) {
feature = (format).readFeature(coordinate, {
dataProjection: sourceCode || view.getProjection(), // 设定JSON数据使用的坐标系
featureProjection: targetCode || view.getProjection() // 设定当前地图使用的feature的坐标系
});
}
}
return feature;
} catch (e) {
console.log(e);
return null;
}
}
</script>
</body>
</html>
Openlayers 添加 WKT WKB GeoJson 格式点线面数据:Openlayers feature