提供 URL 和特征字符串时的不同结果

Different result when providing a URL and features string

我正在使用 Openlayers 4.6 和打字稿。

当我创建一个简单的矢量图层来渲染地图上的普通黑点时,我可能会提供一个 url 像:

export interface Options {
    features: string;
    url: string;
    text: string;
    font: string;
    textBaseline: string;
    fillColor: string;
}
...
constructor(private options: Options) {
    const { features, url, text, font, textBaseline, fillColor } = this.options;
    const format = new ol.format.GeoJSON();
    this._layer = new ol.layer.Vector({
        source: new ol.source.Vector({
            format,
            url
        }),
        style: new ol.style.Style({
            text: new ol.style.Text({
                text,
                font,
                textBaseline,
                fill: new ol.style.Fill({
                    color: fillColor
                })
            })
        })
    });    
 ...

而且效果很好:

但是,我想以纯字符串格式提供(相同的)数据,可以将其解析为实际的 GeoJSON 对象,如下所示:

export interface Options {
    features: string;
    url: string;
    text: string;
    font: string;
    textBaseline: string;
    fillColor: string;
}
...
constructor(private options: Options) {
    const { features, url, text, font, textBaseline, fillColor } = this.options;
    const format = new ol.format.GeoJSON();
    this._layer = new ol.layer.Vector({
        source: new ol.source.Vector({
            features: new ol.format.GeoJSON().readFeatures(features)
        }),
        style: new ol.style.Style({
            text: new ol.style.Text({
                text,
                font,
                textBaseline,
                fill: new ol.style.Fill({
                    color: fillColor
                })
            })
        })
    });    
 ...

通过调用

读取传入features的字符串
private readTextFile(file: string): string {
    let rawFile = new XMLHttpRequest();
    let result: string = '';
    rawFile.open('GET', file, false);
    rawFile.onreadystatechange = () => {
        if (rawFile.readyState === 4) {
            if (rawFile.status === 200 || rawFile.status === 0) {
                result = rawFile.responseText;
            }
        }
    };
    rawFile.send(null);
    return result;
}

提供 url 作为 file 参数。

按预期工作。使用 chrome 调试器逐步执行构造函数会导致以正确的格式等读取正确的数据。

在可视化方面,地图看起来像这样:

这显然是错误的...缩小后,可以在非洲海岸附近找到这些点。再次放大时(很多!),点再次分开:

现在我在 SO 和其他论坛上阅读了几篇帖子,我可能需要给出 data/feature 投影。所以我尝试了:

export interface Options {
    features: string;
    url: string;
    text: string;
    font: string;
    textBaseline: string;
    fillColor: string;
}
...
constructor(private options: Options) {
    const { features, url, text, font, textBaseline, fillColor } = this.options;
    const format = new ol.format.GeoJSON();
    this._layer = new ol.layer.Vector({
        source: new ol.source.Vector({
            features: new ol.format.GeoJSON().readFeatures(features, {
                dataProjection: 'EPSG:3857',
                featureProjection: 'EPSG:3857'
            })
        }),
        style: new ol.style.Style({
            text: new ol.style.Text({
                text,
                font,
                textBaseline,
                fill: new ol.style.Fill({
                    color: fillColor
                })
            })
        })
    });    
 ...

但是结果还是一样。该视图也具有相同的投影。

我在这里错过了什么?为什么您通过 url 提供的数据正确,而通过字符串提供的相同数据却错误?

数据是Lat Long,即EPSG 4326。你需要告诉你的应用程序以4326读取并以3857显示。就像现在一样,你声明数据已经在3857中,所以所有点在坐标 0;0 的 +-180m(不是度数)范围内。

尝试更改这部分代码:

features: new ol.format.GeoJSON().readFeatures(features, {
            dataProjection: 'EPSG:4326',
            featureProjection: 'EPSG:3857'
        })

当您使用 URL 获取数据时,数据投影和视图投影之间的这种投影变化由 OL 处理,如 Vector.url 文档中所述。