Openlayers+GeoServer+MySql获得JSON、GML数据的兼容性问题

2 篇文章 0 订阅
2 篇文章 0 订阅

问题

在使用OpenLayers4获得GeoServer数据时出现的一个问题:

if (currentSource.getGetFeatureInfoUrl) {
                    url = currentSource.getGetFeatureInfoUrl(evt.coordinate, viewResolution, viewProjection, {
                        'INFO_FORMAT': 'application/json'//vnd.ogc.gml
                    });

                    //向服务器发送请求,获得返回数据
                    $.get(url, function (data) {
                        var geoJSONReader = new ol.format.GeoJSON();
                        var feature = geoJSONReader.readFeatures(data)[0];

......

GeoServer连接的MySql数据库,空间数据包含Date类型的属性(如:'2017-11-2')。

获得的feature的Date属性产生了错误:'2017-11-2Z',多了一个Z

经过检查,发现get到的data中已经产生了该错误。

分析问题过程

既然json格式对Date的支持不好,那就改变数据格式。查询GeoServer官网,发现getFeatureInfo方法支持的格式有:

经过测试GML2支持Date类型数据(GML3出现同样的错误)。因此改为使用GML2:

 

if (currentSource.getGetFeatureInfoUrl) {
                    url = currentSource.getGetFeatureInfoUrl(evt.coordinate, viewResolution, viewProjection, {
                        'INFO_FORMAT': 'application/vnd.ogc.gml'//vnd.ogc.gml
                    });

                    //向服务器发送请求,获得返回数据
                    $.get(url, function (data) {
                        var gml2Reader = new ol.format.GML2();
                        var feature = gml2Reader.readFeatures(data)[0];

......

获取的data没有问题,但是经过ol.format.GML2解析后的feature出现了经纬度颠倒的情况:

查看OL4中有关ol.format.GML2读取数据的源码:

https://github.com/openlayers/openlayers/blob/2eea8df75af5f548cad4e8e0d0597e487d90a06b/src/ol/format/gml2.js#L59
https://github.com/openlayers/openlayers/blob/2eea8df75af5f548cad4e8e0d0597e487d90a06b/src/ol/format/gml2.js#L59
ol.format.GML2.prototype.readFlatCoordinates_ = function(node, objectStack) {
ol.format.GML2.prototype.readFlatCoordinates_ = function(node, objectStack) {
ol.format.GML2.prototype.readFlatCoordinates_ = function(node, objectStack) {
  var s = ol.xml.getAllTextContent(node, false).replace(/^\s*|\s*$/g, '');
  var context = /** @type {ol.XmlNodeStackItem} */ (objectStack[0]);
  var containerSrs = context['srsName'];
  var axisOrientation = 'enu';
  if (containerSrs) {
    var proj = ol.proj.get(containerSrs);
    if (proj) {
      axisOrientation = proj.getAxisOrientation();
    }
  }
  var coordsGroups = s.trim().split(/\s+/);
  var x, y, z;
  var flatCoordinates = [];
  for (var i = 0, ii = coordsGroups.length; i < ii; i++) {
    var coords = coordsGroups[i].split(/,+/);
    x = parseFloat(coords[0]);
    y = parseFloat(coords[1]);
    z = (coords.length === 3) ? parseFloat(coords[2]) : 0;
    if (axisOrientation.substr(0, 2) === 'en') {
      flatCoordinates.push(x, y, z);
    } else {
      flatCoordinates.push(y, x, z);
    }
  }
  return flatCoordinates;
};enu';
  if (containerSrs) {
    var proj = ol.proj.get(containerSrs);
    if (proj) {
      axisOrientation = proj.getAxisOrientation();
    }
  }
  var coordsGroups = s.trim().split(/\s+/);
  var x, y, z;
  var flatCoordinates = [];
  for (var i = 0, ii = coordsGroups.length; i < ii; i++) {
    var coords = coordsGroups[i].split(/,+/);
    x = parseFloat(coords[0]);
    y = parseFloat(coords[1]);
    z = (coords.length === 3) ? parseFloat(coords[2]) : 0;
    if (axisOrientation.substr(0, 2) === 'en') {
      flatCoordinates.push(x, y, z);
    } else {
      flatCoordinates.push(y, x, z);
    }
  }
  return flatCoordinates;
};

可以看到,在使用ol.format.GML2解析gml数据时,OL会优先使用gml数据携带的坐标系统的axis(坐标顺序)。那么再查看一下待解析的gml数据是什么样子:

<?xml version="1.0" encoding="utf-8"?>
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs" xmlns="http://www.opengis.net/wfs" xmlns:wireless="wireless.dimpt.com" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="wireless.dimpt.com http://10.220.97.179:8080/geoserver/wireless/wfs?service=WFS&amp;version=1.0.0&amp;request=DescribeFeatureType&amp;typeName=wireless%3Aview_rundata_cd http://www.opengis.net/wfs http://10.220.97.179:8080/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd">
  <gml:boundedBy>
    <gml:null>unknown</gml:null>
  </gml:boundedBy>
  <gml:featureMember>
    <wireless:view_rundata_cd fid="view_rundata_cd.fid--75fad491_163438c7a48_-466d">
      <wireless:provinceid>JS</wireless:provinceid>
      <wireless:cityid>320100</wireless:cityid>
      <wireless:number>南京0860</wireless:number>
      <wireless:modeid>03</wireless:modeid>
      <wireless:mode>4G</wireless:mode>
      <wireless:the_geom>
        <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
          <gml:coordinates decimal="." cs="," ts=" ">118.53192755,31.99111585</gml:coordinates>
        </gml:Point>
      </wireless:the_geom>
    </wireless:view_rundata_cd>
  </gml:featureMember>
</wfs:FeatureCollection>

可以看到,gml数据的坐标系统的名称(code)是http://www.opengis.net/gml/srs/epsg.xml#4326。这是WGS84坐标系统的code,意味着数据的坐标系统是WGS84(这与GeoServer发布的图层坐标系统吻合)。OL中默认包含该坐标系统。并且可以看到,该feature是一个点类型,其坐标顺序是(经度,纬度)。

那么再看一下OL中有关WGS84坐标系统的定义:

ol.proj.EPSG4326.PROJECTIONS = [
  new ol.proj.EPSG4326.Projection_('CRS:84'),
  new ol.proj.EPSG4326.Projection_('EPSG:4326', 'neu'),
  new ol.proj.EPSG4326.Projection_('urn:ogc:def:crs:EPSG::4326', 'neu'),
  new ol.proj.EPSG4326.Projection_('urn:ogc:def:crs:EPSG:6.6:4326', 'neu'),
  new ol.proj.EPSG4326.Projection_('urn:ogc:def:crs:OGC:1.3:CRS84'),
  new ol.proj.EPSG4326.Projection_('urn:ogc:def:crs:OGC:2:84'),
  new ol.proj.EPSG4326.Projection_('http://www.opengis.net/gml/srs/epsg.xml#4326', 'neu'),
  new ol.proj.EPSG4326.Projection_('urn:x-ogc:def:crs:EPSG:4326', 'neu')
];

同一个坐标系统可以有许多不同的code代号,以上列出的是OL中有关WGS84的所有默认code。可以看到code为http://www.opengis.net/gml/srs/epsg.xml#4326的坐标系统带了一个参数:'neu'。该参数指明了数据的坐标顺序为(纬度,经度,高度)。

可以看出这和gml中数据的坐标顺序不一样!

下面捋一捋:使用OL的getGetFeatureInfoUrl获得的gml数据,携带有坐标系统,code为http://www.opengis.net/gml/srs/epsg.xml#4326;另外,gml数据中坐标的顺序是(经度,纬度)。

之后使用ol.format.GML2对象读取该gml数据:OL在解析的过程中,检测到了gml数据的坐标系统,因此使用了该坐标系统,即code为http://www.opengis.net/gml/srs/epsg.xml#4326的WGS84坐标系统,其axis为'neu'(纬度,经度,高度),如此,OL把gml的坐标数据(经度,纬度)当成了(纬度,经度,高度)进行处理!这导致OL最终解析出的feature的坐标出现了经纬度颠倒的情况。

解决方法

参考github上大神的方法:

it is neu according to the EPSG database

you will need to override the axis order, code sample I've used before:

// override the axis orientation for WMS GetFeatureInfo
var proj = new ol.proj.Projection({
  code: 'http://www.opengis.net/gml/srs/epsg.xml#4326',
  axis: 'enu'
});
ol.proj.addEquivalentProjections([ol.proj.get('EPSG:4326'), proj]);//也可以使用ol.proj.addProjection(proj)将新的坐标系统添加进来即可,会自动覆盖原坐标系统

解决思路就是重写(override)坐标系统的axis属性。但是需要注意的是覆盖的一定得是与gml具有相同code的坐标系统,即code为http://www.opengis.net/gml/srs/epsg.xml#4326的坐标系统。

这里附上axis的可能值及其含义

axis可能值:enu,qnu,neu。

含义如下:

> The +axis switch takes three character arguments defining the axis
> orientation of the coordinate system.  The possible values are:
> 
> 'e' - easting
> 'w' - westing - an x/longitude with the opposite sign to normal.
> 'n' - northing
> 's' - southing - a y/latitude with the opposite sign to the normal.
> 'u' - up - normal z
> 'd' - down - a z/elevation with the opposite sign to the normal.
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
路径分析是指在地理信息系统中,根据给定的起点和终点,在网络数据中找到最佳或最短的路径。在本例中,我们将使用PostgreSQL数据库、GeoServerOpenLayers来实现路径分析。 首先,我们需要将网络数据导入PostgreSQL数据库。我们可以使用PostGIS插件来处理空间数据,它提供了丰富的空间分析功能。将网络数据导入数据库后,我们可以使用SQL查询进行路径分析。 接下来,我们需要将数据库中的数据发布到GeoServer中。GeoServer是一个开源的地理信息服务器,它可以将数据库中的空间数据发布为Web服务。通过GeoServer,我们可以将网络数据以WMS或WFS的形式发布出去,供OpenLayers进行可视化展示和交互。 最后,我们可以使用OpenLayers来在Web页面中显示地图,并实现路径分析的可视化。OpenLayers是一个开源的JavaScript库,它提供了丰富的地图显示和交互功能。我们可以使用OpenLayers的API来加载GeoServer发布的网络数据,并通过JavaScript代码来实现路径分析的功能。例如,我们可以在地图上绘制起点和终点,并使用OpenLayers的路线计算函数来找到最佳路径,并将其显示在地图上。 在整个过程中,PostgreSQL提供了数据存储和查询的功能,GeoServer提供了数据发布的功能,而OpenLayers提供了地图的可视化和交互功能。通过这些工具的结合,我们可以实现路径分析的功能,从而为用户提供最佳或最短路径的查询和展示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值