首页 > 解决方案 > 等高线数据到 DEM 数据

问题描述

我只是想知道是否有一种方法可以使用免费的军械测量等高线数据并使用它生成 DEM 数据。我见过很多人将 DEM 数据转换为等高线数据,但反之则不然,有人可以帮我吗?

我也会为这个问题添加更多相关标签,虽然我没有声誉,标签也不存在

标签: mapstiles

解决方案


OS Terrain 50 可用作 ASCII 网格和等高线。这个 OpenLayers 示例直接读取解压缩的 ASCII 文件以生成单个缩放级别 EPSG:27700 平铺 DEM(使用 Mapbox RGB 编码方法),但您可以在 VB 中使用类似的逻辑来创建和保存 PNG 平铺网格。

<!doctype html>
<html lang="en">

<head>
  <link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v6.5.0/css/ol.css" type="text/css">
  <style>
    html, body, .map {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
    }
    .map {
        width: 100%;
        height: calc(100% - 20px);
    }
  </style>
  <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v6.5.0/build/ol.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.6.0/proj4.js"></script>
</head>

<body>
  <div id="map" class="map"></div>
  <div>
    <label>
      Elevation
      <span id="info">0.0</span> meters
    </label>
  </div>
  <script type="text/javascript">

      proj4.defs('EPSG:27700', '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs ');

      ol.proj.proj4.register(proj4);

      var canvas = document.createElement('canvas');
      canvas.width = 200;
      canvas.height = 200;
      var ctx = canvas.getContext('2d');
      var imgData = ctx.createImageData(200, 200);

      var layer = new ol.layer.Tile({
        source: new ol.source.XYZ({
          projection: 'EPSG:27700',
          tileGrid: new ol.tilegrid.TileGrid({
            tileSize: 200,
            resolutions: [50],
            extent: [0, 0, 700000, 1300000],
            origin: [0, 0]
          }),
          crossOrigin: '',
          imageSmoothing: false,
          tileUrlFunction: function (tileCoord, pixelRatio, projection) {
            var bounds = this.getTileGrid().getTileCoordExtent(tileCoord);
            var x = (Math.round(bounds[0]/10)/10) + 10000;
            var y = (Math.round(bounds[1]/10)/10) + 5000;
                var a1y = (4 - (Math.floor(y/5000)%5))*5;
                var a2y = (4 - (Math.floor(y/1000)%5))*5;
                var y1 = Math.floor(y/100)%10;
                a1y += (Math.floor(x/5000)%5);
                a2y += (Math.floor(x/1000)%5);
                var x1 = Math.floor(x/100)%10;
                var tile500km = String.fromCharCode(a1y + Math.floor((a1y+17)/25) + "A".charCodeAt(0));
                var tile100km = tile500km + String.fromCharCode(a2y + Math.floor((a2y+17)/25) + "A".charCodeAt(0));
                var tile10km = tile100km + x1 + y1;
            return 'https://mikenunn.net/data/terr50/grid/' + tile100km.toLowerCase() + '/' + tile10km + '.asc';
          },
          tileLoadFunction: function(tile, src) {
            var xhr = new XMLHttpRequest();
            xhr.addEventListener('loadend', function (evt) {
              var data = this.response;
              if (data !== undefined) {
                var rows = data.split('\n');
                if (rows.length >= 205) {
                  for (var j = 0; j < 200; j++) {
                    var values = rows[j + 5].split(' ');
                    for (var i = 0; i < 200; i++) {
                      var pixel = (parseFloat(values[i]) * 10) + 100000;
                      var index = (j * 200 + i) * 4;
                      imgData.data[index] = (pixel >> 16) & 0xFF;
                      imgData.data[index+1] = (pixel >> 8) & 0xFF;
                      imgData.data[index+2] = (pixel >> 0) & 0xFF;
                      imgData.data[index+3] = 0xFF;
                    }
                  }
                  ctx.putImageData(imgData, 0, 0);
                  tile.getImage().src = canvas.toDataURL();
                }
              } else {
                tile.setState(3);
              }
            });
            xhr.addEventListener('error', function () {
              tile.setState(3);
            });
            xhr.open('GET', src);
            xhr.send(); 
          }
        })
      });

      var map = new ol.Map({
        target: 'map',
        layers: [layer],
        view: new ol.View({
          projection: 'EPSG:27700',
          center: ol.proj.fromLonLat([0, 51.5], 'EPSG:27700'),
          zoom: 14
        })
      });

      var showElevations = function(evt) {
        if (evt.dragging) {
          return;
        }
        map.forEachLayerAtPixel(
          evt.pixel,
          function(layer, pixel) {
            var height = -10000 + (pixel[0] * 256 * 256 + pixel[1] * 256 + pixel[2]) * 0.1;
            info.innerHTML = height.toFixed(1);
          },
          {
            layerFilter: function(candidate) {
              return layer === candidate;
            }
          }
        );
      };

      map.on('pointermove', showElevations);

  </script>
</body>

</html>


推荐阅读