使用基于本地geojson文件的mapbox进行3D挤出

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用基于本地geojson文件的mapbox进行3D挤出相关的知识,希望对你有一定的参考价值。

我在网上看过这个例子,data-driven building extrusion但根本没有提供代码。

我非常想实现同样的目标。我有一个geojson文件,其中包含某些属性,我想将其映射到建筑物的高度。你知道这怎么可能吗?

I have considered the recommended alternative:在已根据我的数据生成的圆上进行3D挤压。没有提供this blog post上的代码,所以我起诉了这个SO post的代码。

代码如下:

<html>
<head>
    <meta charset='utf-8' />
    <title>Display buildings in 3D</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.css' rel='stylesheet' />
    <script src='https://npmcdn.com/@turf/turf/turf.min.js'></script> 
    <style>
        body {
          margin: 0;
          padding: 0;
        }

        #map {
          position: absolute;
          top: 0;
          bottom: 0;
          width: 100%;
        }
    </style>
</head>
<body>

<div id='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoicXVlMzIxNiIsImEiOiJjaWhxZmMxMDUwMDBzdXhsdWh0ZDkyMzVqIn0.sz3lHuX9erctIPE2ya6eCw';

var map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/light-v9',
  center: [8.538961, 47.372476],
  zoom: 16,
  pitch: 40,
  hash: true
});

var url = 'http://127.0.0.1:62940/test2.json';

mapboxgl.accessToken = 'pk.eyJ1IjoicXVlMzIxNiIsImEiOiJjaWhxZmMxMDUwMDBzdXhsdWh0ZDkyMzVqIn0.sz3lHuX9erctIPE2ya6eCw';

var map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/light-v9',
  center: [8.538961, 47.372476],
  zoom: 16,
  pitch: 40,
  hash: true
});

map.on('load', function() {

  map.addLayer({
    'id': 'extrusion',
    'type': 'fill-extrusion',
    "source": {
      "type": "geojson",
      "data": {
        "type": "FeatureCollection",
        "features": []
      }
    },
    'paint': {
      'fill-extrusion-color': '#00f',
      'fill-extrusion-height': ['get', 'frequency'],
      'fill-extrusion-base': 0,
      'fill-extrusion-opacity': 0.9
    }
  });

  map.addLayer({
    "id": "total",
    'type': 'circle',
    'paint': {
      'circle-radius': {
        'base': 1.75,
        'stops': [
          [12, 2],
          [22, 180]
        ]
      },
      'circle-color': '#ff7770'
    },
    "source": {
      "type": "geojson",
      "data": {
        "type": "FeatureCollection",
        "features": [{
            "type": "Feature",
            "geometry": {
              "type": "Point",
              "coordinates": [8.538961, 47.372476]
            },
            "properties": {
              "frequency": 100
            }
          },
          {
            "type": "Feature",
            "geometry": {
              "type": "Point",
              "coordinates": [8.539961, 47.372476]
            },
            "properties": {
              "frequency": 44
            }
          }
        ]
      }
    }
  });


  map.on('sourcedata', function(e) {
    if (e.sourceId !== 'total') return
    if (e.isSourceLoaded !== true) return

    var data = {
      "type": "FeatureCollection",
      "features": []
    }
    e.source.data.features.forEach(function(f) {
      var object = turf.centerOfMass(f)
      var center = object.geometry.coordinates
      var radius = 10;
      var options = {
        steps: 16,
        units: 'meters',
        properties: object.properties
      };
      data.features.push(turf.circle(center, radius, options))
    })
    map.getSource('extrusion').setData(data);
  })
});


</script>

所以这很好用。

但是,当我尝试使用包含完全相同数据的本地geojson文件获取相同的内容时,它根本不起作用。

这是我的json:

{"type": "FeatureCollection", "features": [{"id": 1, "type": "Feature", "properties": {"frequency":44}, "geometry": {"type": "Point", "coordinates": [8.538961, 47.372476]}}, {"id": 2, "type": "Feature", "properties": {"frequency":200}, "geometry": {"type": "Point", "coordinates": [8.539961, 47.372476]}}]}

这是我的代码:

<html>
<head>
    <meta charset='utf-8' />
    <title>Display buildings in 3D</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.css' rel='stylesheet' />
    <script src='https://npmcdn.com/@turf/turf/turf.min.js'></script> 
    <style>
        body {
          margin: 0;
          padding: 0;
        }

        #map {
          position: absolute;
          top: 0;
          bottom: 0;
          width: 100%;
        }
    </style>
</head>
<body>

<div id='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoicXVlMzIxNiIsImEiOiJjaWhxZmMxMDUwMDBzdXhsdWh0ZDkyMzVqIn0.sz3lHuX9erctIPE2ya6eCw';

var map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/light-v9',
  center: [8.538961, 47.372476],
  zoom: 16,
  pitch: 40,
  hash: true
});

var url = 'http://127.0.0.1:62940/test2.json';

mapboxgl.accessToken = 'pk.eyJ1IjoicXVlMzIxNiIsImEiOiJjaWhxZmMxMDUwMDBzdXhsdWh0ZDkyMzVqIn0.sz3lHuX9erctIPE2ya6eCw';

var url = 'http://127.0.0.1:62940/test2.json';

var map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/light-v9',
  center: [8.538961, 47.372476],
  zoom: 16,
  pitch: 40,
  hash: true
});

map.on('load', function() {

  map.addLayer({
    'id': 'extrusion',
    'type': 'fill-extrusion',
    "source": {
      "type": "geojson",
      "data": {
        "type": "FeatureCollection",
        "features": []
      }
    },
    'paint': {
      'fill-extrusion-color': '#00f',
      'fill-extrusion-height': ['get', 'frequency'],
      'fill-extrusion-base': 0,
      'fill-extrusion-opacity': 0.9
    }
  }); 

 map.addSource("data", {
        type: "geojson",
        data: url,
    });

  map.addLayer({
    "id": "total",
    'type': 'circle',
    'paint': {
      'circle-radius': {
        'base': 1.75,
        'stops': [
          [12, 2],
          [22, 180]
        ]
      },
      'circle-color': '#ff7770'
    },
    "source": "data",
    /*"source": {
      "type": "geojson",
      "data": {
        "type": "FeatureCollection",
        "features": [{
            "type": "Feature",
            "geometry": {
              "type": "Point",
              "coordinates": [8.538961, 47.372476]
            },
            "properties": {
              "frequency": 100
            }
          },
          {
            "type": "Feature",
            "geometry": {
              "type": "Point",
              "coordinates": [8.539961, 47.372476]
            },
            "properties": {
              "frequency": 44
            }
          }
        ]
      }
    }*/
  });


  map.on('sourcedata', function(e) {
    if (e.sourceId !== 'total') return
    if (e.isSourceLoaded !== true) return

    var data = {
      "type": "FeatureCollection",
      "features": []
    }
    e.source.data.features.forEach(function(f) {
      var object = turf.centerOfMass(f)
      var center = object.geometry.coordinates
      var radius = 10;
      var options = {
        steps: 16,
        units: 'meters',
        properties: object.properties
      };
      data.features.push(turf.circle(center, radius, options))
    })
    map.getSource('extrusion').setData(data);
  })
});


</script>

我想在使用草皮处理数据的回调中有一些我不理解的东西,但我无法弄清楚什么,我找不到很多mapbox示例来配合文档来提供帮助。

这是预期的输出:image_expected output

这是我的输出:my_output

任何帮助将不胜感激。

答案

由于您添加了远程geojson文件,因此需要更改检查以及获取和处理数据的方式:

  map.on('sourcedata', function(e) {

    // if (e.sourceId !== 'total') return
    if (e.sourceId !== 'data') return
    if (e.isSourceLoaded !== true) return

    var data = {
      "type": "FeatureCollection",
      "features": []
    }

    // e.source.data.features.forEach(function(f) {
    map.querySourceFeatures('data').forEach(function(f) {
      var object = turf.centerOfMass(f)
      var center = object.geometry.coordinates
      var radius = 10;
      var options = {
        steps: 16,
        units: 'meters',
        properties: object.properties
      };
      data.features.push(turf.circle(center, radius, options))
    })
    map.getSource('extrusion').setData(data);
  })

[Qazxswpoi]

以上是关于使用基于本地geojson文件的mapbox进行3D挤出的主要内容,如果未能解决你的问题,请参考以下文章

没有GeoJSON文件的Mapbox聚类。

从 MySql 在 php 中创建 GeoJson 以与 MapBox javascript API 一起使用

我可以像在(mapbox-gl-js 文档)中那样使用 react-map-gl 添加 GeoJSON 行吗?

在 Plotly Density_Mapbox 上添加 GeoJSON 等高线作为图层

Mapbox源码分析(2)url解析

Mapbox GL Js:添加和删除 GeoJSON 源和图层