Mapbox GL JS本地化實踐

Mapbox GL JS 設(shè)計淺析中我們知道Mapbox GL JS使用的樣式是在線的弓候,比如官網(wǎng)中第一個例子:

  <script>
    mapboxgl.accessToken = 'pk.eyJ1IjoiYW56aGlodW4iLCJhIjoiY2lsdnhjdjN5MDFvMHVia3NpYTlnbmUzaSJ9.twlExCjpR7uwH2IiFC7aDA';
    var map = new mapboxgl.Map({
      container: 'map', // container id
      style: 'mapbox://styles/mapbox/streets-v9', //stylesheet location
      center: [-74.50, 40], // starting position
      zoom: 9 // starting zoom
    });
  </script>

代碼里面需要設(shè)置accessToken,而且mapboxgl.Map的配置style設(shè)置的是一個mapbox網(wǎng)站特有的樣式url:mapbox://styles/mapbox/streets-v9钓账。通常毁渗,我們一看到這樣的情況灌诅,基本就放棄本地化的打算了芳来。但Mapbox GL JS確實太誘人了,我最終也沒有抵御住它的誘惑猜拾,想要本地化來使用即舌。經(jīng)過幾乎一天的努力,終于基本搞定挎袜。

另一種style配置

通過官網(wǎng)Style Reference顽聂,可以看到style除了可以設(shè)置為一個url之外,還可以配置為一個如下的對象:

{
    "version": 8,
    "name": "Mapbox Streets",
    "sprite": "mapbox://sprites/mapbox/streets-v8",
    "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
    "sources": {...},
    "layers": [...]
}

從而我們就可以分開配置 sprite盯仪,glyphs紊搪,sourceslayers,這樣或許還有一些希望全景。

自定義source耀石,加載OSM在線瓦片

spriteglyphs看起來比較麻煩,那么我們先解決sources爸黄,看有沒有可能加載本地瓦片滞伟,或者在線瓦片,反正不要加載mapbox的在線瓦片炕贵。Mapbox GL JS針對Raster Tile提供了一種Source類型:raster梆奈。經(jīng)過**聰明伶俐一休桑 **的嘗試和驗證,用下面這種方式:

"sources": {
  "osm-tiles": {
    "type": "raster",
    'tiles': [
          "http://c.tile.openstreetmap.org/{z}/{x}/{y}.png"
      ],
    'tileSize': 256
  }
}

是可以加載在線的OSM瓦片的鲁驶, 既然這樣可以鉴裹,那么本地瓦片,其他在線瓦片钥弯,或者自己服務(wù)器上的瓦片也是可以加載的。我們不需要修改任何的地方督禽,就能加載第三方的瓦片脆霎,從而實現(xiàn)了第一步。

加載一些feature

瓦片地圖加載后狈惫,我們嘗試往地圖上加載一些矢量的feature睛蛛,如果這一步不能達(dá)到鹦马,自然就沒辦法使用了。Mapbox GL JS提供了geojson的數(shù)據(jù)源類型忆肾,我們就使用這個:

// 添加數(shù)據(jù)源
map.addSource("points", {
  "type": "geojson",
  "data": {
    "type": "FeatureCollection",
    "features": [{
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-77.03238901390978, 38.913188059745586]
      },
      "properties": {
        "title": "Mapbox DC 中國文字",
        "icon": "monument"
      }
      }, {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-122.414, 37.776]
      },
      "properties": {
        "title": "Mapbox SF",
        "icon": "harbor"
      }
      }]
  }
});

// 添加圖層荸频,使得上面的數(shù)據(jù)源里面的數(shù)據(jù)可視化
map.addLayer({
  "id": "points",
  "type": "symbol",
  "source": "points",
  "layout": {
    "icon-image": "{icon}-15",
    "text-field": "{title}",
    "text-font": ["Open Sans Regular"],
    "text-offset": [0, 0.6],
    "text-anchor": "top"
  }
});

上面這段代碼,添加一個geojson的矢量數(shù)據(jù)源客冈,同時添加一個對應(yīng)的symbol的圖層旭从。并通過layout定義要素的樣式。這段代碼出自官網(wǎng)例子Draw GeoJSON points场仲。通過上面的代碼和悦,我們發(fā)現(xiàn)icon-imagetext-font的設(shè)置,不同于其他的webgis渠缕。一般icon-image會設(shè)置為一個圖片的url鸽素,或者HTMLImage對象。text-font我們也不能隨意設(shè)定亦鳞。添加上這段代碼后馍忽,我們可以在地圖上看到圖標(biāo)和文字,如下:

mapbox-example.png

基本達(dá)到我們的要求燕差。

圖標(biāo)從哪兒來的舵匾?

我們僅僅通過"icon-image": "{icon}-15", 這個設(shè)置,就在地圖上出現(xiàn)了圖標(biāo)谁不, 它們來自于哪里坐梯? 帶著這個疑問,快速打開控制面板看了一下HTTP請求刹帕,發(fā)現(xiàn)圖標(biāo)來源于"sprite": "mapbox://sprites/mapbox/streets-v8",這個配置吵血。如果去掉這個配置,頁面顯示時偷溺,就會報錯:Error: layers.points.layout.icon-image: use of "icon-image" requires a style "sprite" property 蹋辅。看來要想本地化挫掏,就得解決這個sprite的問題侦另。

本地化sprite

通過HTTP請求可以發(fā)現(xiàn),sprite的配置尉共,會導(dǎo)致兩個請求褒傅,一個sprite.png的請求,一個是sprite.json的請求袄友。sprite.png請求的結(jié)果如下:

sprite.png

通過上圖殿托,基本可以看出來這是圖標(biāo)的集合,通過把所有的圖標(biāo)放在一起剧蚣,減少了HTTP請求次數(shù)支竹,從而起到優(yōu)化作用旋廷。Mapbox肯定很精通這種方式。既然是集合圖片礼搁,獲取其中的某一個圖片饶碘,自然就需要坐標(biāo)位置,圖片大小等信息馒吴,為此不難猜測sprite.json里面存儲的是什么信息了:

{"us-highway-alternate-2":{"width":20,"height":38,"x":0,"y":0,"pixelRatio":1},"us-highway-alternate-3":{"width":26,"height":38,"x":0,"y":38,"pixelRatio":1},"us-highway-business-2":{"width":20,"height":38,"x":20,"y":0,"pixelRatio":1},"us-highway-business-3":{"width":26,"height":38,"x":40,"y":0,"pixelRatio":1},"us-highway-bypass-2":{"width":20,"height":38,"x":26,"y":38,"pixelRatio":1},"us-highway-bypass-3":{"width":26,"height":38,"x":46,"y":38,"pixelRatio":1},"us-highway-truck-2":{"width":20,"height":38,"x":0,"y":76,"pixelRatio":1},"us-highway-truck-3":{"width":26,"height":38,"x":20,"y":76,"pixelRatio":1},"gb-national-rail.london-dlr.london-overground.london-tfl-rail.london-underground":{"width":60,"height":34,"x":0,"y":114,"pixelRatio":1},"de-s-bahn-01":{"width":17,"height":32,"x":60,"y":114,"pixelRatio":1},"de-s-bahn.de-u-bahn":{"width":17,"height":32,"x":46,"y":76,"pixelRatio":1},"pe-national-2":{"width":18,"height":26,"x":77,"y":114,"pixelRatio":1},"pe-national-3":{"width":22,"height":26,"x":95,"y":114,"pixelRatio":1}
......

由于圖片比較多扎运,暫且放置一部分內(nèi)容在上面。通過上面的內(nèi)容可以看出募书,基本和我們猜想的一樣绪囱。既然Mapbox GL JS采用這種方式加載圖標(biāo),那么我們準(zhǔn)守這種約定莹捡,在本地提供圖標(biāo)合集和信息鬼吵,基本上也能解決問題。所以我們大膽的嘗試一下修改sprite為本地路徑: "sprite": "./"篮赢, 修改之后測試一下齿椅,發(fā)現(xiàn)請求的地址確實變成本地的了:http://127.0.0.1:3209/.json, http://127.0.0.1:3209/.png。我們還需要取一個名字启泣,比如這樣設(shè)置涣脚,"sprite": "./sprite"。在本地準(zhǔn)備好sprite.png和sprite.json這兩個文件就好了寥茫。 Okay遣蚀,這樣圖標(biāo)的問題解決了。 那么還剩下glyphs的本地化了纱耻。

本地化字體

通過上面排查圖標(biāo)的方式芭梯,我們可以發(fā)現(xiàn)字體也是從Mapbox網(wǎng)站上請求的,每一個漢字都會請求一次弄喘。想必我們也是有辦法在本地搭建一個本地化的服務(wù)器來提供漢字請求服務(wù)的玖喘。同樣的,我們修改為本地的地址試試:"glyphs": "./font/{fontstack}/{range}.pbf", 蘑志。確認(rèn)這次請求的地址是本地累奈,而fontstackrange會被具體的字體類型和這個字在字體中所處的實際范圍給替換了。完成了第一步之后急但,我們需要處理的是怎么提供這種字體服務(wù)器澎媒, 由于Mapbox GL JS使用的SDF的方式繪制字體,Mapbox團(tuán)隊也開源了一個工具羊始,將普通的ttf和otf字體轉(zhuǎn)換成Mapbox GL渲染需要的字體的工具:node-fontnik旱幼。轉(zhuǎn)換后的字體就像下面這樣:

sdf font.png

這樣我們就可以把他們?nèi)糠旁诒镜亓恕?/p>

最終代碼

最后,我們的代碼也不需要設(shè)置accessToken了突委,并沒有使用任何Mapbox的地圖樣式和地圖資源服務(wù)柏卤,可以這樣:

var map = new mapboxgl.Map({
      container: 'map', // container id
      style: {
        "version": 8,
        //      style: 'mapbox://styles/mapbox/basic-v9',
        //      "sprite": "mapbox://sprites/mapbox/streets-v8",
        "sprite": "./sprite",
        "glyphs": "./font/{fontstack}/{range}.pbf",
        "sources": {
          "osm-tiles": {
            "type": "raster",
            'tiles': [
                  "http://c.tile.openstreetmap.org/{z}/{x}/{y}.png"
              ],
            'tileSize': 256
          }
        },
        "layers": [{
          "id": "simple-tiles",
          "type": "raster",
          "source": "osm-tiles",
          "minzoom": 0,
          "maxzoom": 22
        }]
      },
      center: [-96, 37.8],
      zoom: 3
    });

Okay,完成收工匀油!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缘缚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子敌蚜,更是在濱河造成了極大的恐慌桥滨,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弛车,死亡現(xiàn)場離奇詭異齐媒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)纷跛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門喻括,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贫奠,你說我怎么就攤上這事唬血。” “怎么了唤崭?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵拷恨,是天一觀的道長。 經(jīng)常有香客問我谢肾,道長腕侄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任芦疏,我火速辦了婚禮冕杠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘眯分。我一直安慰自己拌汇,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布弊决。 她就那樣靜靜地躺著噪舀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪飘诗。 梳的紋絲不亂的頭發(fā)上与倡,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機(jī)與錄音昆稿,去河邊找鬼纺座。 笑死,一個胖子當(dāng)著我的面吹牛溉潭,可吹牛的內(nèi)容都是我干的净响。 我是一名探鬼主播少欺,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼馋贤!你這毒婦竟也來了赞别?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤配乓,失蹤者是張志新(化名)和其女友劉穎仿滔,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體犹芹,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡崎页,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了腰埂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片飒焦。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖盐固,靈堂內(nèi)的尸體忽然破棺而出荒给,到底是詐尸還是另有隱情,我是刑警寧澤刁卜,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布志电,位于F島的核電站,受9級特大地震影響蛔趴,放射性物質(zhì)發(fā)生泄漏挑辆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一孝情、第九天 我趴在偏房一處隱蔽的房頂上張望鱼蝉。 院中可真熱鬧,春花似錦箫荡、人聲如沸魁亦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洁奈。三九已至,卻和暖如春绞灼,著一層夾襖步出監(jiān)牢的瞬間利术,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工低矮, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留印叁,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像轮蜕,于是被迫代替她去往敵國和親昨悼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫肠虽、插件幔戏、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,029評論 4 62
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,519評論 25 707
  • 一場秋雨玛追,一層涼税课, 勾起了感嘆, 勾起了憂傷痊剖。 四季的更迭韩玩,如同你我的生活, 有時像夏花一般炫麗燦爛陆馁, 有時似秋葉...
    猴子1980閱讀 150評論 0 0
  • 冷雨浸窗泠雙目找颓,浮光劃空掠只影。 若曉鳴蟬驚夏夢叮贩,
    茜沙流影閱讀 192評論 1 0