【三維地圖】開發攻略 —— 詳解「GeoJSON」技術和應用場景

2022-08-29 15:01:55

GeoJSON ,一個用於儲存地理資訊的資料格式。GoeJSON物件可以表示幾何、特徵或特徵集合,支援:點、線、面、多點、多線、多面和幾何集合。在基於平面地圖,三維地圖中都需要用到的一種資料型別。
由於這種格式在三維地圖中的優秀屬性,使用它我們不僅可以輕鬆實現地圖類功能,更重要的是在3D效果展示上也具有不凡的表現。

GeoJSON資料結構圖

念介紹:

  • GeoJSON是一種對各種地理資料結構進行編碼的格式。
  • GeoJSON物件可以表示幾何(Geometry)、特徵(Feature)或者特徵集合(FeatureCollection)。
  • GeoJSON支援下面幾何型別:點(Point)、線(LineString)、面(Polygon)多點(MultiPoint)、多線(MultiLineString)、多面(MultiPolygon)和幾何集合(GeometryCollection)。
  • GeoJSON裡的特徵包含一個幾何物件和其他屬性,特徵集合表示一系列特徵。

一個完整的GeoJSON資料結構可以稱為一個物件。在GeoJSON裡,物件由名/值對–也稱作成員的集合組成。
瞭解了概念之後,我們對GeoJSON的神祕面紗更神祕了,它究竟可以做什麼?上面我們提到,GeoJSON就是一個地理資訊的資料結構,那麼這個資料如何記錄的?
接下來給大家詳細介紹一下,GeoJSON的整個資料結構。

一個標準的GeoJSON結構:

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1]
  },
  "properties": {
    "name": "Dinagat Islands"
  }
}

最外層:

  • type:"Feature"表示一個特徵要素,"FeatureCollection"表示為特徵要素的集合
  • geometry:儲存該特徵要素的實際形狀描述
  • properties:儲存該要素的屬性

geometry:

  • type:儲存要素型別(Point(點),LineString,Polygon,MultiPoint(多點),MultiLineString(多線)和MultiPolygon(多面))
  • coordinates:座標(儲存圖形座標)

GeoJSON的基礎結構瞭解清楚,接下來就是如何在實際案例中用的。先看看其中的幾個實現效果:
動畫鏡頭

貼地點圖

飛線

熱力圖

點圖

立體面圖

海量點圖示

通過以上效果,可以看到基於地圖實現非常多並且非常酷炫的顯示效果。對於GeoJSON的應用領域有了新的瞭解。而這些特性是基於地圖基礎之上的。接下來就介紹一下從基礎領域到顯示領域的技術應用。
GeoJSON的基礎應用:地圖
GeoJSON的高階應用:webGL

技術應用解決方案

基於我們已經瞭解的基礎知識,GeoJSON是由點線面組成,因此目前高德地圖,百度地圖等地圖類軟體也都推出了對應的api,用來解析GeoJSON。做的相對成熟。
這裡就以高德地圖為例,介紹一下技術人員基於高德地圖應用GeoJSON的技術方案。
以上功能基於高德地圖的Loca 資料視覺化,是一個基於高德地圖JS API 2.0的高效能地圖資料視覺化庫。

高階視覺化實現

Loca.GeoJSONSource:繫結geojson 格式的資料來源,一個資料來源可以給多個圖層同時提供資料。一個geojson資料來源可以同時擁有點、線、面的資料型別,每個圖層繪製的時候會自動獲取 合適的資料型別進行渲染。
顯示效果:

範例程式碼:

<script>
        var map =  new AMap.Map('map', {
            zooms: [4, 8],
            zoom: 4.5,
            showLabel: false,
            viewMode: '3D',
            center: [105.425968, 35.882505],
            mapStyle: 'amap://styles/45311ae996a8bea0da10ad5151f72979',
        });

        var loca = new Loca.Container({
            map,
            opacity:0,
        });

        var geo = new Loca.GeoJSONSource({
            url: 'https://a.amap.com/Loca/static/loca-v2/demos/mock_data/cuisine.json',
        });

        var pl = window.pl = new Loca.PointLayer({
            zIndex: 10,
            blend: 'lighter',
        });

        var style = {
            radius: 3.5,
            unit: 'px',
            color: '#3C1FA8',
            borderWidth: 0,
            blurWidth: 3.5,
        }
        pl.setSource(geo);
        pl.setStyle(style);
        loca.add(pl);

        var dat = new Loca.Dat();
        dat.addLayer(pl);
    </script> 

通過範例程式碼可以看到:解析GeoJson,只需要呼叫 Loca. GeoJSONSource即可,是需要簡單幾句程式碼,就可以實現酷炫效果。已經大大降低了對於底層技術的瞭解。
接下來再看另一個範例:區域覆蓋。

範例程式碼:

<script type="text/javascript">
    var map = new AMap.Map('container', {
        center: [107.943579, 30.131735],
        zoom: 7
    });
    
    ajax('../chongqing.json', function(err, geoJSON) {
        if (!err) {
            var geojson = new AMap.GeoJSON({
                geoJSON: geoJSON,
                getPolygon: function(geojson, lnglats) {
                    return new AMap.Polygon({
                        path: lnglats,
                        fillOpacity: 1,	
                        strokeColor: 'white',
                        fillColor: 'red'
                    });
                }
            });
            map.add(geojson);
            log.success('GeoJSON 資料載入完成')
        } else {
            log.error('GeoJSON 服務請求失敗')
         }
    })
</script>
其中載入GeoJson關鍵程式碼部分為:
var geojson = new AMap.GeoJSON({
                geoJSON: geoJSON,
                getPolygon: function(geojson, lnglats) { 
                    return new AMap.Polygon({
                        path: lnglats,
                        fillOpacity: 1,	// 透明度
                        strokeColor: 'white',
                        fillColor: 'red'
                    });
                }
            });
            map.add(geojson);

範例中,已經將程式碼量降到了最低,只需要瞭解基礎的前端程式碼,就可以實現。
此案例中所參照的GeoJson程式碼摘取:

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "id": "500242",
                "name": "酉陽土家族苗族自治縣",
                "cp": [
                    108.8196,
                    28.8666
                ],
                "childNum": 1
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            108.3142,
                            28.9984
                        ],
                        [
                            108.3252,
                            29.0039
                        ],
                        [
                            108.3142,
                            28.9984
                        ]………………………
                    ]
                ]
            }
        }
    ]
}

這段程式碼的自述:我是一段區域程式碼,其中包括了好幾個子項集合,作為頂頭上司的我,type為 FeatureCollection ,我的小兄弟都在features 節點中,這裡定義著每個人的個性,他們的頭標籤包括一下幾個type為 Feature ,properties 節點中,有他們的身份證,名稱,以及位置資訊,當然也包括他們有幾個手下。基礎地圖中的GeoJson基本內容就是這麼簡單。

每個小兄弟的geometry節點,為他們的活動區域, type 為 Polygon ,coordinates 這裡就代表著活動區域。
所以按照方法,繫結GeoJson,就可以顯示在地圖中。
地圖,是GeoJson的戰場,目前市面上所有的地圖都是基於GeoJson的格式來完成的。
通過解析,發現其實GeoJson也不是那麼神祕。

前面介紹的,都是基於二維層面的地圖,接下來介紹一下GeoJson的高階用法,帶有高度的格式如何實現和應用。
3D效果範例

程式碼範例:

var geo = new Loca.GeoJSONSource({
            url: 'geo.json',
        });
var pl = new Loca.PolygonLayer({
            zIndex: 120,
            shininess: 10,
            hasSide: true,
            cullface: 'back',
            depth: true,
        });
pl.setSource(geo);


對應GeoJson格式:
{
    "type": "FeatureCollection",
    "name": "sh_building_center",
    "crs": {
        "type": "name",
        "properties": {
            "name": "urn"
        }
    },
    "features": [
        {
            "type": "Feature",
            "properties": {
                "mainKey": 50001,
                "h": 18
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            121.480519,
                            31.250787
                        ],
                        [
                            121.480127,
                            31.250616
                        ],
                        [
                            121.480132,
                            31.25061
                        ],
                        [
                            121.480374,
                            31.25061
                        ],
                        [
                            121.480578,
                            31.250707
                        ],
                        [
                            121.480519,
                            31.250787
                        ]
                    ]
                ]
            }
        }
    ]
}


在features 節點中的properties
看了程式碼後,發現3D跟平面地圖處理過程幾乎一致,這也從側面反應了,其實在目前階段的GeoJson使用中,都是基於地圖所開放的api來實現的。技術的革新,讓我們基礎開發者,也可以實現高階的地圖應用功能。總是一句話,GeoJson的誕生,就是為了讓地圖應用開發更加簡單易用。

應用場景

我們基於GetJSON 開發地圖外掛往往不是獨立的去顯示一個地圖動效就結束了,而是需要實現「地圖視覺化」, 將地理資料轉換成視覺化形態,通過將具有地域特徵的資料或者資料分析結果形象地表現在地圖上,使得使用者可以更加容易理解資料規律和趨勢。地圖視覺化可以將業務資料顯示在相關地理資料中,更直白地展現出業務資料。

很多BI 工具解決資料視覺化大屏展示的功能,但在地圖視覺化展示時提供的原生樣式會有很多樣式,功能的限制,因此也BI工具開放了視覺化的外掛開發,供開發人員基於外掛開發機制,來實現滿足專案需求的視覺化外掛開發。

此外大家如果感興趣可以嘗試體驗線上demo:
https://www.grapecity.com.cn/solutions/wyn/demo