首页 > 解决方案 > 无法将 topojson 对象加载为 openlayers 层

问题描述

我正在使用开放图层并且无法直接从 topojson 对象(而不是 URL)加载地图图层。

地图应该有一个代表墨西哥的蓝色矢量图层,但由于某种原因,该图层没有添加到地图中。它不会抛出任何错误。我不认为这是一个投影问题。

我有一种情况,我已经在 Open Layers 之外加载了 topojson 对象,所以我想直接使用它,而不是从 URL 重新加载。

  //Create a background layer
    var raster = new ol.layer.Tile({
      source: new ol.source.TileJSON({
        url: 'https://api.tiles.mapbox.com/v3/mapbox.world-dark.json?secure'
      })
    });


    //create a vector layer for the US using a a topojson URL as the input
    var style_world_RedBorder = new ol.style.Style({
      fill: new ol.style.Fill({
        color: 'rgba(0,0,0,0)'
      }),
      stroke: new ol.style.Stroke({
        color: 'rgba(255,0,0,1)',
        width: 1
      })
    });
    var vector_world = new ol.layer.Vector({
      source: new ol.source.Vector({
        url: 'https://openlayers.org/en/v4.6.5/examples/data/topojson/world-110m.json',
        format: new ol.format.TopoJSON({
          layers: ['countries']
        }),
        overlaps: false
      }),
      style: style_world_RedBorder
    });


    //create a vector layer for mexico using a topojson object as the input
    var style_mexico = new ol.style.Style({
      fill: new ol.style.Fill({
        color: 'rgba(0,255,0,0.25)'
      }),
      stroke: new ol.style.Stroke({
        color: 'rgba(0,255,0,1)',
        width: 1
      })
    });
    var mexicoData = {
      "type": "Topology",
      "arcs": [
        [
          [315, 1244],
          [121, -48],
          [171, 0],
          [110, 31],
          [90, -87],
          [21, -67],
          [84, -52],
          [29, 57],
          [76, 2],
          [115, -164],
          [24, -84],
          [118, -38],
          [-33, -124],
          [-5, -160],
          [41, -115],
          [77, -136],
          [82, -44],
          [182, 52],
          [42, 39],
          [23, 122],
          [142, 44],
          [70, -13],
          [-54, -137],
          [-2, -87],
          [-83, -45],
          [-111, 0],
          [32, -129],
          [-77, 0],
          [-29, -61],
          [-59, 16],
          [-101, 71],
          [-97, -59],
          [-194, 80],
          [-228, 121],
          [-93, 77],
          [-39, 78],
          [29, 76],
          [-38, 91],
          [-159, 194],
          [-48, 93],
          [-65, 50],
          [-110, 133],
          [-108, 200],
          [-53, -6],
          [11, -103],
          [108, -131],
          [132, -270],
          [-91, 6],
          [-11, 99],
          [-127, 75],
          [25, 97],
          [-99, 92],
          [-86, 206],
          [140, -2],
          [105, -40]
        ]
      ],
      "transform": {
        "scale": [0.016598932212296365, 0.013431657853810241],
        "translate": [-118.28916899999996, 15.262220000000072]
      },
      "objects": {
        "mexico": {
          "type": "GeometryCollection",
          "geometries": [{
            "arcs": [
              [0]
            ],
            "type": "Polygon",
            "properties": {
              "FIPS": "MX",
              "ISO2": "MX",
              "ISO3": "MEX",
              "UN": 484,
              "NAME": "Mexico",
              "AREA": 190869,
              "POP2005": 104266392,
              "REGION": 19,
              "SUBREGION": 13,
              "LON": -102.535,
              "LAT": 23.951
            }
          }]
        }
      }
    }
    var features = (new ol.format.TopoJSON({
      layers: ['mexico']
    })).readFeatures(mexicoData);
    var source = new ol.source.Vector({
      features: features,
      overlaps: false
    });
    var vector_mexico = new ol.layer.Vector({
      source: source,
      style: style_mexico
    });


    //Add all layers to the map
    var map = new ol.Map({
      layers: [raster, vector_world, vector_mexico],
      target: 'map',
      view: new ol.View({
        center: [0, 0],
        zoom: 1
      })
    });
<!DOCTYPE html>
<html>

<head>
  <title>TopoJSON</title>
  <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
  <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
  <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
  <script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script>


</head>

<body>
  <div id="map" class="map"></div>

</body>

</html>

标签: openlayerstopojson

解决方案


当你读入你的特征时,你必须告诉 OL 数据的投影,然后是你显示特征的投影。所以,在这部分代码中:

var features = (new ol.format.TopoJSON({
  layers: ['mexico']
})).readFeatures(mexicoData);

你需要添加这个:

var features = (new ol.format.TopoJSON({
  layers: ['mexico']
})).readFeatures(mexicoData,{
  dataProjection: 'EPSG:4326',
  featureProjection: 'EPSG:3857'
});

我复制了你的源代码并尝试了它,它按预期工作。顺便说一句,如果不进行此修改,您的多边形确实会绘制,但它在 EPSG:3857 0,0 坐标处非常小,您可以在那里看到一个小的蓝色“点”。如果你放大很多,你会看到墨西哥的轮廓。


推荐阅读