openlayers+geoserver
从发布地图到点击查询
安装geoserver
1.安装geoserver,我这里提供了geoserver2.19.2版本的下载链接 geoserver.
2.下载以后解压,点击bin目录中的startup.bat启动服务。
3.注意8080端口不要被占用,很多vue项目的端口也是8080,注意改为8081。
4.进入localhost:8080/geoserver/web,初始账户/密码为admin/geoserver,后期可修改。
打开geoserver跨域权限
如果使用本机,请求geoserver访问时会报跨域问题,解决方法为找到geoserver文件中的webapps\geoserver\WEB-INF\web.xml,打开后使用查询,搜索cross-origin打开代码
<filter>
<filter-name>cross-origin</filter-name>
<filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
<init-param>
<param-name>chainPreflight</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>allowedOrigins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>allowedMethods</param-name>
<param-value>GET,POST,PUT,DELETE,HEAD,OPTIONS</param-value>
</init-param>
<init-param>
<param-name>allowedHeaders</param-name>
<param-value>*</param-value>
</init-param>
</filter>
//下面还有一段代码
<filter-mapping>
<filter-name>cross-origin</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
最好是将geoserver放在服务器上,其他文章所说的下载一些jar文件放入webapps\geoserver\WEB-INF\lib其实并没有什么用。
发布shp要素地图
发布图层前要先将shp文件准备好,尽量不要放在桌面即可
1.创建工作区
name可以随便取,命名空间url也是,命名空间url只是方便后面使用图层时建立连接
2.添加数据
选择Shapefile发布数据,工作区,选择自己刚才创建的,在DBF的字符集首选UTF-8,不然之后查询属性时,会显示乱码。点击保存以后点击发布,会来到图层页面
3.发布图层
注意使用的坐标系,如果不是4326,可能在openlayers中显示会出现错误。
在发布中可以修改图例的样式
4.查看图层
在Layer Preview中点击对应图层就可查看样式,点和线的wms可能在openlayers中显示没有,如果属性中出现乱码就是在添加数据的时候没有选择UTF-8,我参考其他博主可能也是(GBK,GN2312)
属性查询
属性查询首选openlayers官网wfs-getfeature.,主要使用的图层为VectorLayer ,数据层为vectorSource
//先创建一个查询条件
const featureRequest = new WFS().writeGetFeature({
srsName: "EPSG:3857", //这里的EPSG不要改为4326,可能无法显示
featureNS: "www.test.com", //这里是工作空间中的命名空间url
featurePrefix: "osm", //这里是oms是为了能够访问属性
featureTypes: ["test"], //你要查询的图层
outputFormat: "application/json", //数据返回格式
filter: equalToFilter("LANDOWNER", 's') //查询的属性与查询的值
});
//发送请求,使用fetch和axios都可以
fetch("http://59.110.136.223:8080/geoserver/xhk/wfs", {
method: "POST",
body: new XMLSerializer().serializeToString(featureRequest)
}).then(function(response) {
return response.json();
}).then(json => {
const features = new GeoJSON().readFeatures(json);
this.vectorSource.clear()//第二次查询清楚第一次查询结果
this.vectorSource.addFeatures(features);
this.map.getView().fit(this.vectorSource.getExtent()); //查询出数据以后跳转到目标位置
});
点击查询
先要绑定map的点击事件,我采用的vue,所以将map绑定在this上,使用时注意作用域。
this.map.on("click", this.mapClick);
//下面是点击触发的函数
mapClick(evt) {
console.log("mapClick");
var viewResolution = this.map.getView().getResolution();
var url = this.tileLayer
.getSource()
.getFeatureInfoUrl(evt.coordinate, viewResolution, "EPSG:3857", {
INFO_FORMAT: "application/json"
});
// 使用getFeatureInfoUrl获取点击层的要素
fetch(url, {
method: "GET"
})
.then(function(response) {
return response.json();
})
.then(json => {
// 此处添加用户信息弹窗
if (json.numberReturned) {
console.log(json.features[0].properties);
}
});
}