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

You may also like...