国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

自定義mapbox插件 - 地圖快照下載(JS)

caikeal / 1067人閱讀

摘要:本次我開發的插件功能很簡單,下載地圖的快照,即將當前地圖顯示導出圖片。之后通過插件本身拿到的地圖上下文,開始下載。不加后兩個參數在下會報錯事件類型,是否冒泡,是否阻止瀏覽器的默認行為至此,一個下載地圖快照的插件就完成了。

效果預覽

mapbox 是一個非常好用的開源地圖引擎,他支持得平臺有android,ios,js,rn等等,功能多樣,但是對于地圖插件開發這一塊,沒找到具體的實施文檔。因此本文以js 為例,來把開發mapbox插件這一過程記錄下來。

mapbox
var map = new mapboxgl.Map({
    container: "map", // container id
    style: "mapbox://styles/mapbox/streets-v11", // stylesheet location
    center: [-74.50, 40], // starting position [lng, lat]
    zoom: 9, // starting zoom
    preserveDrawingBuffer: true // 這個需要開啟,才能獲取正確的base64
  });

在開發之前先簡述下mapbox的地圖。在顯示一張地圖時,有兩個屬性是必須的,一個就是container ,地圖的容器,接受一個dom的id,另一個就是style,地圖實際渲染所需的資源配置都在這里,mapbox是支持室內外地圖的,也就是在style的source屬性中去分別加載indoor,outdoor的資源(可以是瓦片,也可以是geojson),有了這兩個屬性,就可以將地圖顯示出來了,其余屬性不過多介紹。

mapbox 插件

mapbox 官方提供了很多插件,如線面繪制,地圖比較等等。本次我開發的插件功能很簡單,下載地圖的快照,即將當前地圖顯示導出圖片。mapbox 渲染完畢是一個canvas標簽,而canvas 可以直接轉成圖片的base64資源,然后轉成文件資源去進行下載。

本文重點放在開發一款mapbox插件,而非下載功能本身,所以具體下載流程在接下來的插件開發中插入。

插件開發流程

因為官方沒有提供開發插件的文檔(沒找到),因此從0到1這樣一步一步來。

map.addControl(new mapboxgl.NavigationControl()); // 官方代碼
// 插件的類
class Map2img {
  constructor() {
    
       }
  }
  map.addControl(new Map2img ()); 

上述代碼為mapbox的一個示例,mapbox 提供了addControl這個api 用于將插件引入地圖,在初始化好一個類(Map2img ),以同樣的方式引入map,此時出現報錯:

由此可知,一個可供map使用的插件類至少需要2個方法,onAdd ,onRemove。為了更詳細的了解這兩個方法的作用,直接去mapbox-gl-js里面搜索addControl。
mapbox-gl部分代碼:

 addControl(control: IControl, position?: ControlPosition) {
        if (position === undefined && control.getDefaultPosition) {
            position = control.getDefaultPosition();
        }
        if (position === undefined) {
            position = "top-right";
        }
        if (!control || !control.onAdd) {
            return this.fire(new ErrorEvent(new Error(
                "Invalid argument to map.addControl(). Argument must be a control with onAdd and onRemove methods.")));
        }
        const controlElement = control.onAdd(this);
        this._controls.push(control);

        const positionContainer = this._controlPositions[position];
        if (position.indexOf("bottom") !== -1) {
            positionContainer.insertBefore(controlElement, positionContainer.firstChild);
        } else {
            positionContainer.appendChild(controlElement);
        }
        return this;
    }

從源碼中不難看出,在把插件加入map之后,會觸發插件(control)上的onAdd方法,這個方法返回一個dom元素,元素被插入到mapbox 的控制器(插件中),相當于把插件放入一個插槽。
因此,首先將類增加一個onAdd 方法,并返回一個dom元素,然后讓他顯示至右上角(top-right)。
Map2img.js

class Map2img {
  constructor(html) {
    this._html = html; // 初始化接收要顯示的html
  }
       onAdd(map) {
    this._map = map;
    const el = document.createElement("div");
    el.innerHTML = this._html
    this.bindEvent(el) // 添加點擊事件
    return el // 返回這個傳入的html
  }
   onRemove(map) {
    this.container.parentNode.removeChild(this.container);
    this._map = null;
    return this
  }
  }

index.html

  let eltemp = `
插件
` var downloadCtrl=new Map2img(eltemp) map.addControl(downloadCtrl, "top-right");

這樣,就完成了插件的第一步,顯示嵌入地圖的問題。繼續在加入的dom節點上增加點擊監聽事件,再點擊之后通過在onAdd 方法中獲取的地圖上下文,進而獲取到地圖的canvas

 bindEvent(el) {
    el.addEventListener("click", () => {
      const base64 = this._map.getCanvas().toDataURL()
      this.downloadFile(this._map.getStyle().name, base64)
    })
  }

做到這一步后,發現并沒有按照預想的結果,點擊后觸發相關事件。在這里卡了很久,沒有找到原因,嘗試過更改dom的z-index等等,更改事件監聽方式等等,均沒有觸發點擊效果。最終去翻閱官方的插件代碼,發現官方的插件中,對于引入的dom,添加了一個mapboxgl-ctrl的樣式,去mapbox-gl中搜索這個樣式后,發現一個關鍵屬性。

在這個css 中,有一個控制很關鍵。pointer-events 當這個屬性為none時會阻止點擊事件的觸發(還有很多其他控制,不展開敘述),由此打開瀏覽器調試發現,果然插入dom的父級把這個屬性置為none。

在加入這個樣式之后,引入的插件成功的觸發了點擊方法。之后通過插件本身拿到的地圖上下文,開始下載。

downloadFile(fileName, content) {
    let aLink = document.createElement("a");
    let blob = this.base64ToBlob(content); //new Blob([content]);
    let evt = document.createEvent("HTMLEvents");
    evt.initEvent("click", true, true);//initEvent 不加后兩個參數在FF下會報錯  事件類型,是否冒泡,是否阻止瀏覽器的默認行為
    aLink.download = fileName;
    aLink.href = URL.createObjectURL(blob);
    aLink.dispatchEvent(new MouseEvent("click", {bubbles: true, cancelable: true, view: window}));
  }

  base64ToBlob(code) {
    let parts = code.split(";base64,");
    let contentType = parts[0].split(":")[1];
    let raw = window.atob(parts[1]);
    let rawLength = raw.length;

    let uInt8Array = new Uint8Array(rawLength);

    for (let i = 0; i < rawLength; ++i) {
      uInt8Array[i] = raw.charCodeAt(i);
    }
    return new Blob([uInt8Array], {type: contentType});
  }

至此,一個下載地圖快照的插件就完成了。

PS:

如果是室內外地圖,有分樓層下載地圖快照且不希望下載中去切換樓層,影響當前顯示的需求的話,我目前的做法是通過絕對定位,初始化一個新的地圖在下面,然后用這個新的地圖去切換樓層,然后將新地圖的快照截取出來,因為地圖下載只能是當前camera(視口)的圖象。還有一點需要注意的是,如果不是手動觸發,而是在地圖load時就下載地圖的話,需要主動延遲適當的時間,因為地圖onload的方法不包含地圖字體的顯示加載,即區域名稱,所以要有必要的延遲,以上是我目前解決問題的思路,有更好的方法歡迎交流分享!

項目地址:https://github.com/jiwenjiang...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106648.html

相關文章

  • 3D GIS 應用開發 —— 基于 Mapbox GL 的實踐總結

    摘要:最近在折騰的端的可視化項目,由于相關業務的需要,用到了這一地圖開發的神器。其技術奠基于與。分別指縮放級別地面法線偏移角地軸偏移角等,用以確定當前視窗所顯示的地圖區域和空間關系。個人認為其最大的亮點在于即使不了解內部實現,也不影響其使用。 最近在折騰的 web 端的可視化項目,由于相關業務的需要,用到了 Mapbox 這一地圖開發的神器。在此先奉上一個基于mapbox-gl實現的demo...

    YancyYe 評論0 收藏0
  • 入門Leaflet之小Demo

    入門 Leaflet 之小 Demo 寫在前面 ---- WebGIS 開發基礎之 Leaflet GIS 基本概念:GIS、Map、Layer、Feature、Geometry、Symbol、Data(Point、Polyline、Polygon)、Renderer、Scale、Project、Coordinates; GIS 開發概述:架構模式、常用平臺和 SDK、二維三維 使用 Lea...

    Eminjannn 評論0 收藏0
  • vue 地圖可視化 mapbox篇(2)

    MapBox 項目中用到MapBox也是偶然的機會,項目中需要采用3D地圖,當現有的工具(百度地圖)無法滿足我們的需求,我們肯定需要更高級開源的地圖,無奈谷歌地圖無法在國內使用,已是便找到Leafle,一開始驚艷于leafle的開源程度和其與眾不同的地圖風格,后來順藤摸瓜,找到一個商業性地圖,它便是我們的主角-MapBoxshowImg(https://segmentfault.com/img/b...

    _DangJin 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<