iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 4
0
Modern Web

《你的地圖會說話? WebGIS與JavaScript的情感交織》系列 第 4

[2-1] 點資料圖徵 X 瀏覽器定位 X 地址定位

本系列文章已出版實體書籍:
「你的地圖會說話?WebGIS 與 JavaScript 的情感交織」(博碩文化)
WebGIS啟蒙首選✖五家地圖API✖近百個程式範例✖實用簡易口訣✖學習難度分級✖補充ES6小知識

網格與向量

在GIS中的資料呈現模式分為網格模式與向量模式兩種。

  • 網格模式可以想像成地圖是用一個一個正方形的格子所組成,
    網格越小,解析度也就越高,適用於對資料的精確度要求較低,如衛星影像、航照圖等。
  • 向量模式則直接紀錄精確的座標,線及面的表示方法則由一堆點所組成,
    精確度較高,適用於作為地理空間分析。
  • 在WebGIS中,向量資料呈現過多可能會有圖台效能問題。

點資料圖徵

    <div id="gmap"></div>
    <script>
        var gMap = new google.maps.Map(document.getElementById('gmap'), {
            center: { lat: 23.5, lng: 121 },
            zoom: 7
        });
    </script>

↑ 先初始化地圖

        var marker = new google.maps.Marker({
            position: { lat: 23.5, lng: 121 },
            map: gMap,
            title: '你好!我是點資料圖徵!'
        });

↑ 再來,新增一個點資料圖徵。

        var infowindow = new google.maps.InfoWindow({
            content: `lat: 23.5, lng: 121`
        });

↑ 我們想為點加上一些註釋,我們可以新增一個資訊視窗(InfoWindow),

        marker.addListener('click', function () {
            infowindow.open(gMap, marker);
        });

↑ 對marker新增一個click事件,點擊後打開資訊視窗。
並且把Infowindow綁在marker上面,讓它相對於marker顯示在地圖上。
https://ithelp.ithome.com.tw/upload/images/20200919/20130604etzGvws1vp.jpg

瀏覽器定位

那要怎麼在WebGIS上找到自己的位置呢?
別擔心!HTML5提供了geolocation API可以進行定位!

        var x = document.getElementById("demo");
        function getLocation() {
            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(showPosition);
            } else {
                x.innerHTML = "Geolocation is not supported by this browser.";
            }
        }

        function showPosition(position) {
            x.innerHTML = "Latitude: " + position.coords.latitude +
                "<br>Longitude: " + position.coords.longitude;
        }

↑ 這是w3schools上面的一個範例: https://www.w3schools.com/html/html5_geolocation.asp

看到這裡應該會有幾個疑問:

  1. navigator是什麼?
  2. showPosition這個參數為什麼可以放function?
  • navigator是瀏覽器BOM的一個JS物件,用以存取客戶端瀏覽器資訊。
    ↓ 在chrome按F12(開發者工具),console中直接打navigator
    https://ithelp.ithome.com.tw/upload/images/20200919/20130604glIbTLfRom.jpg

navigator常見功能

  • navigator.cookieEnabled 可以檢查瀏覽器的cookie是否有開啟
  • navigator.appVersion 可以取得瀏覽器的版本
  • navigator.language 可以取得瀏覽器所設定的語系
  • navigator.geolocation 可以取得客戶端使用瀏覽器的位置

geolocation API可以取得客戶端使用瀏覽器的位置,其原理有二:

  1. GPS (必須有GPS功能之裝置)
  2. IP (必須連上網路,有對外IP)

因此,如果我們在自家電腦用geolocation API,通常誤差都蠻大的,
因為少了GPS的輔助,一樣的位置使用手機定位,會精確許多。
https://ithelp.ithome.com.tw/upload/images/20200919/2013060433l49T3ZQY.jpg
此外,geolocation API不支援http連線,所以網站需要申請SSL憑證,
轉成https再使用吧!不然也可以找憑證產生的外掛程式(誤

定位 X 標記點

接著我們把showPosition加入剛剛寫的點資料圖徵的方式顯示在地圖上。

       var marker;
       var infowindow;
       function showPosition(position) {
            var lng = position.coords.longitude;
            var lat = position.coords.latitude

            marker = new google.maps.Marker({
                position: { lat: lat, lng: lng },
                map: gMap,
                title: `lat: ${ lat }, lng: ${ lng }`
            });
            infowindow = new google.maps.InfoWindow({
                content: `lat: ${ lat }, lng: ${ lng }`
            });
            marker.addListener('click', function () {
                infowindow.open(gmap, marker);
            });
        }

在這邊,showPosition是作為navigator.geolocation.getCurrentPosition(callback);
的callback function,也就是geolocation定位完後,才會呼叫這個function,
並且把定位結果資訊傳入callback function中。

        getLocation();

↑ 呼叫getLocation方法定位。
https://ithelp.ithome.com.tw/upload/images/20200919/20130604TGW03YEE0N.jpg
這裡就是我家的位置啦!

同場加映~

全國門牌地址定位服務

內政部TGOS圖台提供的門牌地址定位服務,可以依地址比對取得座標。
官網上有ASP.NET後端呼叫的範例、以及TGOS API呼叫的範例
這裡直接附上寫好的function給大家使用! 其實是我懶得一步一步解釋
(記得要先引用TGOS Map API)

        function Locate() {
            if (!(this instanceof Locate)) {  
                return new Locate();
            }
        }

        Locate.prototype.ByAddress = function (address, callback) {
            var locator = new TGOS.TGLocateService();
            var result = {
                x: undefined,
                y: undefined,
                pointList: [],
                errorMessage: ''
            }
            callback = callback || function () { }

            locator.locateWGS84({ address: address }, function (e, status) {
                if (status === TGOS.TGLocatorStatus.OK) {
                    result.x = e[0].geometry.location.x;
                    result.y = e[0].geometry.location.y;
                    result.pointList.push({
                        county: e[0].addressComponents.county,
                        town: e[0].addressComponents.town,
                        addressComponents: e[0].addressComponents,
                        address: e[0].formattedAddress,
                        x: e[0].geometry.location.x,
                        y: e[0].geometry.location.y
                    });

                } else if (status === TGOS.TGLocatorStatus.TOO_MANY_RESULTS) {
                    result.pointList = e.map(function (item) {
                        return {
                            county: item.addressComponents.county,
                            town: item.addressComponents.town,
                            addressComponents: item.addressComponents,
                            address: item.formattedAddress,
                            x: item.geometry.location.x,
                            y: item.geometry.location.y
                        }
                    });
                    result.errorMessage = '地址查詢結果過多!';

                } else {
                    console.log('查無地址!');
                    result.errorMessage = '查無地址!';
                }

                callback(result);
            });

            this.result = result;
        }

↑ 這邊把TGOS.TGLocateService()封裝,自定義callback回傳參數,
看不懂的朋友別擔心!未來會有一篇專門講callback & promise!

        var locate = new Locate();
        locate.ByAddress('臺北市信義區市府路45號', function (result) {
            console.log(result);
        });

↑ 呼叫的方式只需要兩行。
https://ithelp.ithome.com.tw/upload/images/20200919/20130604gELZX4osfA.jpg
↑ 回傳的結果
雖然跟實際的經緯度還是有一點點誤差,不過也算是很好用的服務了!難的是申請API Key


今天講了Html5 geolocation API,以及TGOS 全國門牌地址定位服務 API,
如果今天研究一個從來沒用過的API,除了看API文件以外,要怎麼去Try?
下一篇,會深入講解JS的Function以及Arguments教你怎麼一下就上手別人的API
也會順便講一些ES6的寫法。

欲知後事如何,且聽下回分解。/images/emoticon/emoticon28.gif


上一篇
[1-2] 地圖的工廠 - 以 簡單工廠模式 Simple Factory Design Pattern 產出地圖
下一篇
[2-2] JS 的 Function X Arguments 與 ES6寫法介紹
系列文
《你的地圖會說話? WebGIS與JavaScript的情感交織》30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言