openlayers第二天
目录
openlayers第二天,点选查询
需求:点击地图上的某个点如一个商店,返回这个商店的属性信息。
架构:postgresql存储商店的属性信息和空间位置数据,geoserver连接上数据库发布wms和wfs服务,前端用openlayers显示。推荐一个博客,我是看着它一步一步搭建好框架的。
废话少说,先上代码,以下代码中非js部分是从官网拷贝,官网也有诸多例子可供学习。
<!DOCTYPE html>
<html>
<head>
<title>Accessible Map</title>
<link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
<script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script>
</head>
<body>
<div id="map" class="map" tabindex="0"></div>
<script>
var baseGaodeMap = new ol.layer.Tile({//标准地图
source: new ol.source.XYZ({
crossOrigin: 'anonymous',
url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
})
});
var myLayer = new ol.layer.Image({
source: new ol.source.ImageWMS({
ratio: 1,
//自己的服务url
url: 'http://[IP]:[端口]/geoserver/[工作区]/wms',
//设置服务参数
params: {
'FORMAT': 'image/png',
'VERSION': '1.1.0',
STYLES: '',
//图层信息
LAYERS: '[工作区]:[图层名]',
}
})
});
var bounds = [116.38657515099074, 39.90773664369626, 116.41161625435377, 39.92026792421384];
var projection = new ol.proj.Projection({
code: 'EPSG:4326',
units: 'degrees',
axisOrientation: 'neu'
});
var view = new ol.View({
projection: projection,
maxZoom: 20
});
var map = new ol.Map({
target: 'map',
layers: [
baseGaodeMap,
myLayer
],
view: view
});
map.getView().fit(bounds, map.getSize());
map.on('click', function (evt) {
console.log(evt.coordinate);
var viewResolution = (map.getView().getResolution());
var url = myLayer.getSource().getGetFeatureInfoUrl(
evt.coordinate, viewResolution, 'EPSG:4326',
{'INFO_FORMAT': 'application/json'});
if (url) {
console.log(url);
$.ajax("http://[IP]:[端口]/[自定义]", {
type: 'GET',
data: {
token: token,
url: url
},
dataType: 'jsonp',
jsonpCallback: 'callback:myCallback',
jsonp: 'format_options'
});
}
});
function myCallback(json) {
console.log(json);
}
</script>
</body>
</html>
搭建geoserver发布图层可以参照我推荐的博客,服务发布后直接复制链接到代码中即可直接运行。
下面研究一下点击地图后查询的代码:
map.on('click', function (evt) {
console.log(evt.coordinate);
var viewResolution = (map.getView().getResolution());
console.log(viewResolution);
var url = outworkMap.getSource().getGetFeatureInfoUrl(
evt.coordinate, viewResolution, 'EPSG:4326',
{'INFO_FORMAT': 'application/json'});
...
}
可以看到,通过map
的单击事件返回的evt.coordinate
,可以取得当前点击位置的经纬度坐标。
图层的数据源+经纬度坐标+当前的分辨率+坐标系类型+请求返回类型—–>生成返回的url
直接访问这个url,就能返回当前点击位置的商店的信息。
出现的问题:
- 多图层查询
- 点击精度
- 跨域
多图层查询以后再说,点击精度是通过viewResolution
来控制的,直接用地图放大到最大时的分辨率,应该就能达到最精准的效果。
接下来主要讲讲跨域的问题。
关于geoserver跨域的解决方法网上有很多,但是要么没用要么就是太麻烦,我使用的方案是本地不直接请求geoserver,而是请求后台并带上这里生成的url
作为参数,后台去访问这个url
然后返回结果,这里后台相当于是一个代理,也可以记录下访问日志。
当然,最简单的方式是部署到同一个服务器的同一个端口下,就没跨域什么事了。
后台的代码简单贴一下
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
@RestController
@RequestMapping(produces = "application/json")
public class RedirectController {
@GetMapping("/redirect")
public String redirect(@RequestParam String url) throws IOException, URISyntaxException {
RequestConfig config = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(15000).build();
HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
URL tempUrl = new URL(url);
URI uri = new URI(tempUrl.getProtocol(), null, tempUrl.getHost(), tempUrl.getPort(), tempUrl.getPath(), tempUrl.getQuery(), null);
HttpGet httpGet = new HttpGet(uri);
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, "UTF-8");
return callback(result);
}
private String callback(String str) {
return "myCallback('" + str + "')";
}
}
openlayers第二天,从点选查询开始
转载自:https://blog.csdn.net/m0_37659871/article/details/80530053