小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

數(shù)據(jù)可視化:地圖使用案例

 東西二王 2023-01-11 發(fā)布于重慶

原創(chuàng)2022-02-09 19:38·鏡心的小樹屋

推薦技術(shù)棧

  • amap + g2/ amap + L7

  • mapbox + deck.gl/echarts.gl

地理相關(guān)庫

amap
mapbox
Leaflet
Cesium
deck.gl
g2 map類
turfjs

工具

http:///#map=2/20.0...
地圖選擇器

地圖3D


https:///AlexZ33/pe...
點擊預(yù)覽

https:///AlexZ33/pe...
點擊預(yù)覽
北京市居住人口3D分布

https://github.com/zhu18/visualcontrols

樓宇


https:///AlexZ33/pe...
點擊預(yù)覽  用css實現(xiàn)太累

城市統(tǒng)計

上海城市統(tǒng)計

圖層

Mapv - 地理信息可視化開源庫

https://github.com/chengquan2...

高德地圖api

百度地圖api

http://lbsyun.baidu.com/index...
http://mapv.baidu.com/gallery...
vue-baidu-map

注意
百度地圖webapi接口文檔
百度地圖javascript api文檔

使用百度地圖的服務(wù),需使用BD09坐標(biāo)。

若使用非BD09坐標(biāo)、未經(jīng)過坐標(biāo)轉(zhuǎn)換(非BD09轉(zhuǎn)成BD09)直接疊加在地圖上,地圖展示位置會偏移,因此通過其他坐標(biāo)(WGS84、GCJ02)調(diào)用服務(wù)時,需先將其他坐標(biāo)轉(zhuǎn)換為BD09。

非百度坐標(biāo)系,如何轉(zhuǎn)換成百度坐標(biāo)系?

http://lbsyun.baidu.com/index...


http://lbsyun.baidu.com/index...

圖吧地圖api

Mapbox api

地圖API和工具

坐標(biāo)拾取器械


https:///AlexZ33/pe...
點擊預(yù)覽
另外,百度地圖api的開發(fā)文檔下的工具支持中有很多類似的工具
Vue Baidu Map

地圖選擇器

GeoJSON

turf.js

坐標(biāo)系統(tǒng)說明


高德地圖: GCJ-02 
我國地圖坐標(biāo)系統(tǒng) 
百度地圖: BD-09 (BD-09II/bd09mc)

  • 普通GPS定位出來的數(shù)值都是基于WSG-84坐標(biāo)系標(biāo)準,這是世界通用的坐標(biāo)系。(美國的)

  • GCJ-02和WSG-84之間的坐標(biāo)系轉(zhuǎn)換算法是保密的。

“中國政府為了國家安全在國內(nèi) GPS 定位時人為加入一定偏移”這種說法是不正確的。
應(yīng)該是“我國所發(fā)行的地圖類產(chǎn)品強制性加入偏移算法,使原本標(biāo)準的坐標(biāo)系統(tǒng)(WSG-84)變?yōu)閲冶C艿淖远x坐標(biāo)系統(tǒng)(GCJ-02)”。

坐標(biāo)系說明

在進行地圖開發(fā)過程中,我們一般能接觸到以下三種類型的地圖坐標(biāo)系:

1.WGS-84原始坐標(biāo)系,一般用國際GPS紀錄儀記錄下來的經(jīng)緯度,通過GPS定位拿到的原始經(jīng)緯度,Google和高德地圖定位的的經(jīng)緯度(國外)都是基于WGS-84坐標(biāo)系的;但是在國內(nèi)是不允許直接用WGS84坐標(biāo)系標(biāo)注的,必須經(jīng)過加密后才能使用;

2.GCJ-02坐標(biāo)系,又名“火星坐標(biāo)系”,是我國國測局獨創(chuàng)的坐標(biāo)體系,由WGS-84加密而成,在國內(nèi),必須至少使用GCJ-02坐標(biāo)系,或者使用在GCJ-02加密后再進行加密的坐標(biāo)系,如百度坐標(biāo)系。高德和Google在國內(nèi)都是使用GCJ-02坐標(biāo)系,可以說,GCJ-02是國內(nèi)最廣泛使用的坐標(biāo)系;

3.百度坐標(biāo)系:bd-09,百度坐標(biāo)系是在GCJ-02坐標(biāo)系的基礎(chǔ)上再次加密偏移后形成的坐標(biāo)系,只適用于百度地圖。(目前百度API提供了從其它坐標(biāo)系轉(zhuǎn)換為百度坐標(biāo)系的API,但卻沒有從百度坐標(biāo)系轉(zhuǎn)為其他坐標(biāo)系的API)

three.js地圖


http://blog.csdn.net/u0125393...

Three.js - 用100行javascript代碼創(chuàng)建一座城市

https://github.com/doter1995/earthquakes

G2地圖

地圖數(shù)據(jù)

通常情況下,地理數(shù)據(jù)的可視化會包含多份數(shù)據(jù):一份是用于繪制地圖的經(jīng)緯度數(shù)據(jù),一份是用戶真正想要可視化的用戶數(shù)據(jù)。

  • 實例 中國地圖-省市下鉆只有經(jīng)緯度數(shù)據(jù),但是特殊的是,這個實例中,我們從amap api獲得數(shù)據(jù),在左側(cè)繪制地圖(其中中國地圖直接得到的geoJSON數(shù)據(jù),行政區(qū)劃得到的是TopoJSON數(shù)據(jù)),在右側(cè)用g2繪制處理行政區(qū)劃數(shù)據(jù)(geojson -> json數(shù)組 --> dataset) 繪制地圖

  • 實例 帶氣泡的地圖 需要在世界地圖上標(biāo)注各個國家的男女比例情況,這個時候就可以使用多視圖的可視化方案:詳情 戳 --->這

地圖數(shù)據(jù)一般保存為JSON格式,G2和D3常用的有兩種:

  • GeoJSON 描述地理信息的一種基本格式 例——> world.geo.json

  • TopoJSOND3作者Mike Bostock制定的格式,符合JSON規(guī)范

我們以這個g2 中國地圖-省市下鉆為例

g2/demos/map-drill-down.html

<!doctype html><html lang="en"><head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>中國地圖-省市下鉆</title>
    <link rel="stylesheet" />
    <style>
        .button-group{            position: fixed;            bottom:50%;            left: 0px;            width: 70%;
        }    </style>
    <script type="text/javascript" src="http://cache.amap.com/lbs/static/addToolbar.js"></script></head><body>
  <div id="mountNode"></div>
  <div class='button-group' style="background-color: #fff">
      <input type='radio' onclick='refresh(this.value)' checked name='mapStyle' value='normal'>標(biāo)準      <input type='radio' onclick='refresh(this.value)' name='mapStyle' value='dark'>幻影黑      <input type='radio' onclick='refresh(this.value)' name='mapStyle' value='light'>月光銀      <input type='radio' onclick='refresh(this.value)' name='mapStyle' value='fresh'>草色青      <input type='radio' onclick='refresh(this.value)' name='mapStyle' value='grey'>雅士灰<br>
      <input type='radio' onclick='refresh(this.value)' name='mapStyle' value='graffiti'>涂鴉      <input type='radio' onclick='refresh(this.value)' name='mapStyle' value='whitesmoke'>遠山黛      <input type='radio' onclick='refresh(this.value)' name='mapStyle' value='macaron'>馬卡龍      <input type='radio' onclick='refresh(this.value)' name='mapStyle' value='blue'>靛青藍      <input type='radio' onclick='refresh(this.value)' name='mapStyle' value='darkblue'>極夜藍<br>
      <input type='radio' onclick='refresh(this.value)' name='mapStyle' value='wine'>醬籽  </div>
  <script>/*Fixing iframe window.innerHeight 0 issue in Safari*/document.body.clientHeight;</script>
  <script src="https://gw./os/antv/assets/g2/3.0.4-beta.2/g2.min.js"></script>
  <script src="https://gw./os/antv/assets/data-set/0.8.3/data-set.min.js"></script>
  <script src="https://gw./os/antv/assets/lib/jquery-3.2.1.min.js"></script>
  <script src="https://gw./os/antv/assets/lib/lodash-4.17.4.min.js"></script>
  <script src="https://webapi.amap.com/maps?v=1.4.1&key=8c8c021990b332b22254f2f8289a62ef"></script>
  <script src="https://webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script>
  <script>
      $('#mountNode').html(          '<div style="position:relative;">'+              '<div id="china" style="width:50%;height:400px;position:absolute;left:0;top:0"></div>' +              '<div id="province" style="width:50%;height:400px;position:absolute;right:0;top:0;"></div>'+          '</div>'
      );      //調(diào)用高德api繪制底圖以及geo數(shù)據(jù)

      const map = new AMap.Map('china',{        resizeEnable: true,          zoom:4
      });      function refresh(enName) {
        map.setMapStyle('amap://styles/'+enName);
      }      const colors = [ "#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499", "#22aa99", "#aaaa11", "#6633cc", "#e67300", "#8b0707", "#651067", "#329262", "#5574a6", "#3b3eac" ];      // 當(dāng)前聚焦的區(qū)域
      let currentAreaNode;


      AMapUI.load(['ui/geo/DistrictExplorer', 'lib/$'], function(DistrictExplorer) {        //創(chuàng)建一個實例
        const districtExplorer = window.districtExplorer = new DistrictExplorer({          eventSupport: true, //打開事件支持
          map
        });//        //創(chuàng)建一個輔助Marker,提示鼠標(biāo)內(nèi)容//        var tipMarker = new AMap.Marker({//          //啟用冒泡,否則click事件會被marker自己攔截//          bubble:true//        });//
        // feature 被點擊
        districtExplorer.on('featureClick', function(e, feature) {          const props = feature.properties;          //如果存在子節(jié)點
          console.log(props);          if(props.childrenNum > 0) {            //切換聚焦區(qū)域
            switch2AreaNode(props.adcode);
          }
        });        //外部區(qū)域被點擊
        districtExplorer.on('outsideClick', function(e) {
          districtExplorer.locatePosition(e.originalEvent.lnglat, function(error,routeFeatures) {            if(routeFeatures && routeFeatures.length > 1) {              //切換到省級區(qū)域
              switch2AreaNode(routeFeatures[1].properties.adcode);
            }else{              //切換到全國
              switch2AreaNode(100000)
            }
          },{            levelLimit:2
          });
        });        //繪制某個區(qū)域的邊界
        function renderAreaPolygons(areaNode) {          const node = _.cloneDeep(areaNode);

          districtExplorer.clearFeaturePolygons();

          districtExplorer.renderSubFeatures(node, function(feature, i) {            const fillColor = colors[i % colors.length];            const strokeColor = colors[colors.length - 1 -i % colors.length];            return {              cursor: 'default',              bubble:true,
              strokeColor,//線顏色
              strokeOpacity:1,//線透明度
              strokeWeight:1, //線寬
              fillOpacity: 0.35 //填充透明度
            };
          });          //繪制父區(qū)域
          districtExplorer.renderParentFeature(node, {            cursor: 'default',            bubble: true,            strokeColor: 'black',//線顏色
            strokeOpacity: 1, //線透明度
            strokeWeight: 1, //線寬
            fillColor: null, //填充色
            fillOpacity: 0.35 //填充透明度
          });
        }        //切換區(qū)域后刷新顯示內(nèi)容
        function refreshAreaNode(areaNode) {
          districtExplorer.setHoverFeature(null);
          renderAreaPolygons(areaNode)

        }        //切換區(qū)域
        function switch2AreaNode(adcode, callback) {          if (currentAreaNode && ('' + currentAreaNode.getAdcode() === '' + adcode)) {            return;
          }

          loadAreaNode(adcode, function(error, areaNode) {            if (error) {              if (callback) {
                callback(error);
              }              return;
            }
            currentAreaNode = window.currentAreaNode = areaNode;
            refreshAreaNode(areaNode);            if (callback) {
              callback(null, areaNode);
            }
          });
        }        //加載區(qū)域
        function loadAreaNode(adcode, callback) {
          districtExplorer.loadAreaNode(adcode, function(error, areaNode) {            if(error) {              if(callback) {
                callback(error);
              }              return;
            }
            renderG2Map(areaNode); //使用 G2 繪制地圖

            if(callback) {
              callback(null, areaNode);
            }
          });
        }        //浙江
        switch2AreaNode(330000);
      });      //開始使用G2繪制地圖
      let provinceChart;      function renderG2Map(areaNode) {        const adcode = areaNode.getAdcode();        const geoJSON = areaNode.getSubFeatures(); // 獲取 geoJSON 數(shù)據(jù)
        const name = areaNode.getName();

        provinceChart && provinceChart.destroy();
        provinceChart = null;        if (!geoJSON || currentAreaNode && ('' + currentAreaNode.getAdcode() === '' + adcode)) {          return;
        }        const dv = processData(geoJSON);        // start: 計算地圖的最佳寬高
        const longitudeRange = dv.range('longitude');        const lantitudeRange = dv.range('lantitude');        const ratio = (longitudeRange[1] - longitudeRange[0]) / (lantitudeRange[1] - lantitudeRange[0]);        let width;        let height;        if (ratio > 1) {
          width = $('#province').width();
          height = width / ratio;
        } else {
          width = 300 * ratio;
          height = $('#province').height();
        }        // end: 計算地圖的最佳寬高
        provinceChart = new G2.Chart({          container: 'province',
          width,
          height,          padding: 0
        });
        provinceChart.source(dv);
        provinceChart.axis(false);
        provinceChart.tooltip({          showTitle: false
        });
        provinceChart
            .polygon()
            .position('longitude*lantitude')
            .label('name', {              textStyle: {                fill: '#fff',                fontSize: 10,                shadowBlur: 2,                shadowColor: 'rgba(0, 0, 0, .45)'
              }
            })
            .style({              stroke: '#fff',              lineWidth: 1
            })
            .color('value', '#BAE7FF-#1890FF-#0050B3');
        provinceChart.guide().text({          position: [ 'min', 'max' ],          offsetY: 20,          content: name,          style: {            fontSize: 14,            fontWeight: 'bold'
          }
        });
        provinceChart.render();
      }      function processData(geoJSON) {        console.log("---------------------geoJSON---------------------------");        console.log(geoJSON);        const mapData = {          type: 'FeatureCollection',          features: geoJSON
        };        // 構(gòu)造虛擬數(shù)據(jù)
        const userData = [];        for (let i = 0; i < geoJSON.length; i++) {          const name = geoJSON[i].properties.name;
          userData.push({
            name,            value: Math.round(Math.random() * 1000)
          });
        }         console.log("----------------userData----------------");        console.log(userData);        const ds = new DataSet();        const geoDataView = ds.createView().source(mapData, {          type: 'GeoJSON'
        }); // geoJSON 經(jīng)緯度數(shù)據(jù)

        // 用戶數(shù)據(jù)
        const dvData = ds.createView().source(userData);
        dvData.transform({          type: 'geo.region',          field: 'name',
          geoDataView,          as: [ 'longitude', 'lantitude' ]
        });        console.log('---------------------dvData-------------');        console.log(dvData);        return dvData;
      }  </script></body></html>

這里的代碼

AMapUI.load(['ui/geo/DistrictExplorer', 'lib/$'], function(DistrictExplorer) {

}

是對高德地圖ui的組件調(diào)用,DistrictExplorer是行政區(qū)劃瀏覽

  • 自有組件還有:參考組件 UI組件庫

  • 我們還可以自定義組件模塊,AMapUI組件庫的擴展 ,詳情戳這里————> AMapUI組件庫高級功能

  • ui/geo/DistrictExplorer是擴展的模塊路徑

  • lib/$, 即DomLibrary(jQuery或者Zepto)


這里load的json數(shù)據(jù)是這樣的,其中的topo內(nèi)的就是TopoJSON數(shù)據(jù)
geo/DistrictExplorer.json

  • type 是Topology,表示文件類型

  • transform用于描述縮放量和平移量,分別用一個只有兩項的數(shù)組來表示

  • objects里存有幾何體模塊,此處只有浙江省parent 是全省sub 是各市縣arcs表示如何從最外層的數(shù)組arcs里提取地形.

注意 :
相比GeoJSON直接使用Polygon、Point之類的幾何體來表示圖形的方法,TopoJSON中的每一個幾何體都是通過將共享邊(被稱為arcs)整合后組成
TopoJSON消除了冗余,文件大小縮小了80%,因為:

  • 邊界線只記錄一次

  • 地理坐標(biāo)使用整數(shù),不使用浮點數(shù)

地圖投影

我們再看一看 g2的另一個實例 : 帶氣泡的地圖

const dv = ds.createView('back')
                           .source(mapData,{                               type: 'GeoJSON'
                           })
                           .transform({                               type:'geo.projection',
                               projection: 'geoMercator',                               as:['x','y','centroidX','centroidY']
                           });

這里的 projection: 'geoMecator',表示投影是墨卡托投影

墨卡托投影、高斯-克呂格投影、UTM投影

我們可以看看d3里面關(guān)于地圖的投影api,看看有哪些地圖投影:
d3.js Azimuthal Projections

繪制過程


相比2.0版本 3.0版本的container是支持string 也支持dom對象的

從上面兩個例子我們可以看出來,在載入地圖時候我們可以

  • 調(diào)用amap api地圖

  • 本地GeoJSON或TopoJSON生成

這里我們說一說如何載入數(shù)據(jù)
如何裝載數(shù)據(jù)

這里我們可以看到 g2中繪制地圖時候需要 傳入一個JSON數(shù)組
所以上面例子中國地圖-省市下鉆 的 const dv = processData(geoJSON); processData函數(shù)應(yīng)該有這樣一個轉(zhuǎn)換過程 GeoJSON --> JSON數(shù)組 --> DataSet,我們來看一看是不是這樣(即userData應(yīng)該是JSON數(shù)組,dvData應(yīng)該是DataSet)

const geoDataView = ds.createView().source(mapData, {      type: 'GeoJSON'
    }); // geoJSON 經(jīng)緯度數(shù)據(jù)

為什么是轉(zhuǎn)換為Dataset?

自 G2 3.0 版本開始,原先內(nèi)置的數(shù)據(jù)處理模塊 frame 從 G2 包中抽離出來,獨立成為 DataSet 包。DataSet 的目標(biāo)是為數(shù)據(jù)可視化場景提供狀態(tài)驅(qū)動(state driven)的 -->DataSet

<script src="https://gw./os/antv/assets/data-set/0.8.1/data-set.js"></script>

在DataSet包中

  • 我們把數(shù)據(jù)處理分為兩個大的步驟:數(shù)據(jù)連接(Connector)和數(shù)據(jù)轉(zhuǎn)換(Transform)。Connector 負責(zé)導(dǎo)入和歸一化數(shù)據(jù)(譬如導(dǎo)入 CSV 數(shù)據(jù),導(dǎo)入 GeoJSON 數(shù)據(jù)等),Transform 負責(zé)進行各種數(shù)據(jù)轉(zhuǎn)換操作(譬如圖布局、數(shù)據(jù)統(tǒng)計、數(shù)據(jù)補全等)。

想要了解G2中數(shù)據(jù)的處理流程直接點擊

常用實例

基于baidu、google、arcgis、高德地圖、canvas數(shù)據(jù)可視化
GeoHey gallery

文章

基于WebGL的大數(shù)據(jù)二三維可視化--uber的deck.gl介紹
deck.gl example
可視化篇:mapbox + echarts-gl 展示血脈交通
從Mapbox的開源工具看Web GIS的發(fā)展
ECharts 地圖博客
echarts結(jié)合高德API進行地圖下鉆

參考

一站式解決echarts實現(xiàn)區(qū)域地圖

Map Projection Overview
[python處理地理數(shù)據(jù)-geopandas和pyshp]()
mapbox/node-fontnik工具使用介紹
Mapbox GL JS本地化實踐
GIS文章集
Geomatics(GIS,GPS,RS,Surveying)
地圖應(yīng)用API(GIS+LBS)
antv g2的理解總結(jié)
Maps
inMap

https:///stevepeppl...


https:///AlexZ33/pe...
點擊預(yù)覽

https:///pbeshai/pr...


https:///jakealbaug...


https://github.com/LylaYuKako...

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多