Merge pull request #407 from mapbox/filesource
Use style.json directory as base path for loading sprite images
This commit is contained in:
@@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var mkdirp = require('./mkdirp');
|
||||
var name = 'style';
|
||||
var data = JSON.stringify(require(path.join(process.cwd(), process.argv[2])));
|
||||
|
||||
var out_path = path.join(process.argv[3], 'bin/style.min.js');
|
||||
mkdirp.sync(path.dirname(out_path));
|
||||
fs.writeFileSync(out_path, data);
|
||||
506
bin/style.js
506
bin/style.js
@@ -1,506 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"version": 4,
|
||||
"sprite": "https://www.mapbox.com/mapbox-gl-styles/sprites/sprite",
|
||||
"glyphs": "http://mapbox.s3.amazonaws.com/gl-glyphs-256/{fontstack}/{range}.pbf",
|
||||
"constants": {
|
||||
"@red": "#f00",
|
||||
"@land": "#eee",
|
||||
"@water": "#999",
|
||||
"@park": "#bda",
|
||||
"@road": "#fefefe",
|
||||
"@border": "#6d90ab",
|
||||
"@wood": "#33AA66",
|
||||
"@building": "#ddd",
|
||||
"@building_outline": "#ccc",
|
||||
"@text": "#000000",
|
||||
"@satellite_brightness_low": 0,
|
||||
"@satellite_brightness_high": 1,
|
||||
"@satellite_saturation": 0,
|
||||
"@satellite_spin": 0,
|
||||
"@satellite_contrast": 0,
|
||||
"@road_blur": 1,
|
||||
"@stroke_width": 0.25
|
||||
},
|
||||
"sources": {
|
||||
"mapbox": {
|
||||
"type": "vector",
|
||||
"url": "mapbox://mapbox.mapbox-streets-v5",
|
||||
"maxZoom": 14
|
||||
}
|
||||
},
|
||||
"layers": [{
|
||||
"id": "bg",
|
||||
"type": "background",
|
||||
"style": {
|
||||
"background-color": "@land",
|
||||
"transition-background-color": {
|
||||
"duration": 500
|
||||
}
|
||||
},
|
||||
"style.satellite": {
|
||||
"transition-fill-color": {
|
||||
"duration": 500,
|
||||
"delay": 500
|
||||
},
|
||||
"fill-opacity": 0,
|
||||
"fill-color": "rgba(255,0,0,0)"
|
||||
}
|
||||
}, {
|
||||
"id": "park",
|
||||
"source": "mapbox",
|
||||
"source-layer": "landuse",
|
||||
"filter": { "class": "park" },
|
||||
"type": "fill",
|
||||
"style": {
|
||||
"fill-color": "@park"
|
||||
},
|
||||
"style.satellite": {
|
||||
"transition-fill-color": {
|
||||
"duration": 500
|
||||
},
|
||||
"fill-color": "rgba(0,0,0,0)"
|
||||
}
|
||||
}, {
|
||||
"id": "wood",
|
||||
"source": "mapbox",
|
||||
"source-layer": "landuse",
|
||||
"filter": { "class": "wood" },
|
||||
"type": "fill",
|
||||
"style": {
|
||||
"fill-color": "@wood",
|
||||
"fill-opacity": 0.08
|
||||
}
|
||||
}, {
|
||||
"id": "water",
|
||||
"source": "mapbox",
|
||||
"source-layer": "water",
|
||||
"type": "fill",
|
||||
"style": {
|
||||
"fill-color": "@water"
|
||||
},
|
||||
"style.satellite": {
|
||||
"fill-opacity": 0
|
||||
}
|
||||
}, {
|
||||
"id": "waterway",
|
||||
"source": "mapbox",
|
||||
"source-layer": "waterway",
|
||||
"type": "line",
|
||||
"style": {
|
||||
"line-color": "@water",
|
||||
"line-width": {
|
||||
"base": 1.01,
|
||||
"stops": [[7, 0.5], [19, 6.5]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
// "id": "roads",
|
||||
// "layers": [{
|
||||
"id": "tunnel_large_casing",
|
||||
"source": "mapbox",
|
||||
"source-layer": "tunnel",
|
||||
"filter": { "class": ["motorway", "main"] },
|
||||
"type": "line",
|
||||
"style": {
|
||||
"line-color": "rgba(0,0,0,0.5)",
|
||||
"line-width": 1,
|
||||
"line-offset": {
|
||||
"stops": [[12.11458208048225, 1], [19, 93.2862864971161]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "tunnel_regular_casing",
|
||||
"source": "mapbox",
|
||||
"source-layer": "tunnel",
|
||||
"filter": { "class": ["street", "street_limited"] },
|
||||
"type": "line",
|
||||
"style": {
|
||||
"line-color": "rgba(0,0,0,0.5)",
|
||||
"line-width": 1,
|
||||
"line-offset": {
|
||||
"stops": [[11.637356828788917, 1], [19, 31.287358856201173]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "tunnel_large",
|
||||
"ref": "tunnel_large_casing",
|
||||
"style": {
|
||||
"line-color": "rgba(255,255,255,0.5)",
|
||||
"line-width": {
|
||||
"stops": [[12.11458208048225, 1], [19, 93.2862864971161]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "tunnel_regular",
|
||||
"ref": "tunnel_regular_casing",
|
||||
"style": {
|
||||
"line-color": "rgba(255,255,255,0.5)",
|
||||
"line-width": {
|
||||
"stops": [[14.11458208048225, 1], [19, 29.787358856201173]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "road_large_casing",
|
||||
"source": "mapbox",
|
||||
"source-layer": "road",
|
||||
"filter": { "class": ["motorway", "main"] },
|
||||
"type": "line",
|
||||
"render": {
|
||||
"line-cap": "round",
|
||||
"line-join": "bevel"
|
||||
},
|
||||
"style": {
|
||||
"line-color": "rgba(154,154,154,0.5)",
|
||||
"line-width": {
|
||||
"stops": [[12.751938909271168, 4], [19, 100.00060082197189]]
|
||||
},
|
||||
"line-opacity": {
|
||||
"base": 1.01,
|
||||
"stops": [[13, 0], [14, 1]]
|
||||
},
|
||||
"transition-line-width": {
|
||||
"duration": 500
|
||||
},
|
||||
"line-blur": "@road_blur"
|
||||
},
|
||||
"style.satellite": {
|
||||
"line-width": {
|
||||
"stops": [[13.751938909271168, 4], [19, 57.57177189826965]]
|
||||
},
|
||||
"transition-line-width": {
|
||||
"duration": 500,
|
||||
"delay": 1000
|
||||
}
|
||||
},
|
||||
"style.test": {
|
||||
"line-width": {
|
||||
"stops": [[11.751938909271168, 4], [19, 174.25105143845082]]
|
||||
},
|
||||
"line-color": "rgba(255,0,0,1)",
|
||||
"transition-line-width": {
|
||||
"duration": 500
|
||||
},
|
||||
"transition-line-color": {
|
||||
"duration": 2000,
|
||||
"delay": 500
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "road_regular_casing",
|
||||
"source": "mapbox",
|
||||
"source-layer": "road",
|
||||
"filter": { "class": "street" },
|
||||
"type": "line",
|
||||
"render": {
|
||||
"line-cap": "round",
|
||||
"line-join": "bevel"
|
||||
},
|
||||
"style": {
|
||||
"line-color": "rgba(154,154,154,0.5)",
|
||||
"line-width": {
|
||||
"stops": [[10.637356828788917, 1], [19, 54.377877998352055]]
|
||||
},
|
||||
"line-opacity": {
|
||||
"base": 1.01,
|
||||
"stops": [[14.5, 0], [15.5, 1]]
|
||||
},
|
||||
"line-blur": "@road_blur"
|
||||
},
|
||||
"style.satellite": {
|
||||
"transition-line-width": {
|
||||
"duration": 500,
|
||||
"delay": 1000
|
||||
},
|
||||
"line-width": {
|
||||
"stops": [[11.637356828788917, 1], [19, 31.287358856201173]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "road_limited",
|
||||
"source": "mapbox",
|
||||
"source-layer": "road",
|
||||
"filter": { "class": "street_limited" },
|
||||
"type": "line",
|
||||
"render": {
|
||||
"line-cap": "round",
|
||||
"line-join": "bevel",
|
||||
"line-round-limit": 0.7
|
||||
},
|
||||
"style": {
|
||||
"line-dasharray": [10, 2],
|
||||
"line-color": "@road",
|
||||
"line-blur": "@road_blur",
|
||||
"line-width": {
|
||||
"stops": [[13.11458208048225, 1], [19, 52.877877998352055]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "road_large",
|
||||
"ref": "road_large_casing",
|
||||
"style": {
|
||||
"line-color": "@road",
|
||||
"line-blur": "@road_blur",
|
||||
"line-width": {
|
||||
"stops": [[12.11458208048225, 1], [19, 93.2862864971161]]
|
||||
}
|
||||
},
|
||||
"style.satellite": {
|
||||
"transition-line-width": {
|
||||
"duration": 500,
|
||||
"delay": 1000
|
||||
},
|
||||
"line-width": {
|
||||
"stops": [[13.11458208048225, 1], [19, 52.877877998352055]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "road_regular",
|
||||
"ref": "road_regular_casing",
|
||||
"style": {
|
||||
"line-color": "@road",
|
||||
"line-blur": "@road_blur",
|
||||
"line-width": {
|
||||
"stops": [[13.11458208048225, 1], [19, 52.877877998352055]]
|
||||
}
|
||||
},
|
||||
"style.satellite": {
|
||||
"transition-line-width": {
|
||||
"duration": 500,
|
||||
"delay": 1000
|
||||
},
|
||||
"line-width": {
|
||||
"stops": [[14.11458208048225, 1], [19, 29.787358856201173]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "path",
|
||||
"source": "mapbox",
|
||||
"source-layer": "road",
|
||||
"filter": { "class": "path" },
|
||||
"type": "line",
|
||||
"render": {
|
||||
"line-cap": "round",
|
||||
"line-join": "bevel"
|
||||
},
|
||||
"style": {
|
||||
"line-color": "rgba(255,255,255,1)",
|
||||
"line-dasharray": [2, 2],
|
||||
"line-width": 2
|
||||
}
|
||||
}, {
|
||||
"id": "rail",
|
||||
"source": "mapbox",
|
||||
"source-layer": "road",
|
||||
"filter": { "class": "major_rail" },
|
||||
"type": "line",
|
||||
"render": {
|
||||
"line-cap": "round",
|
||||
"line-join": "bevel"
|
||||
},
|
||||
"style": {
|
||||
"line-color": "rgba(76,76,76,0.8)",
|
||||
"line-dasharray": [2, 1],
|
||||
"line-width": 3
|
||||
}
|
||||
}, {
|
||||
"id": "tunnel_rail",
|
||||
"source": "mapbox",
|
||||
"source-layer": "tunnel",
|
||||
"filter": { "class": ["minor_rail", "major_rail"] },
|
||||
"type": "line",
|
||||
"style": {
|
||||
"line-color": "rgba(76,76,76,0.3)",
|
||||
"line-dasharray": [2, 1],
|
||||
"line-width": 3
|
||||
}
|
||||
// }],
|
||||
// "type": "composite",
|
||||
// "style": {
|
||||
// "composite-opacity": 1,
|
||||
// "transition-composite-opacity": {
|
||||
// "duration": 500
|
||||
// }
|
||||
// },
|
||||
// "style.satellite": {
|
||||
// "transition-composite-opacity": {
|
||||
// "duration": 500,
|
||||
// "delay": 500
|
||||
// },
|
||||
// "composite-opacity": 0.5
|
||||
// }
|
||||
}, {
|
||||
"id": "building",
|
||||
"source": "mapbox",
|
||||
"source-layer": "building",
|
||||
"type": "fill",
|
||||
"style": {
|
||||
"fill-color": "@building",
|
||||
"transition-fill-opacity": {
|
||||
"duration": 500,
|
||||
"delay": 500
|
||||
},
|
||||
"fill-opacity": {
|
||||
"base": 1.01,
|
||||
"stops": [[13, 0], [14, 1]]
|
||||
},
|
||||
"fill-outline-color": "@building_outline"
|
||||
},
|
||||
"style.satellite": {
|
||||
"fill-opacity": 0,
|
||||
"transition-fill-opacity": {
|
||||
"duration": 500
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "borders",
|
||||
"source": "mapbox",
|
||||
"source-layer": "admin",
|
||||
"type": "line",
|
||||
"style": {
|
||||
"line-color": "rgba(0,0,0,0.3)",
|
||||
"line-width": 1
|
||||
}
|
||||
}, {
|
||||
"id": "bridge_large_casing",
|
||||
"source": "mapbox",
|
||||
"source-layer": "bridge",
|
||||
"filter": { "class": ["motorway", "main"] },
|
||||
"type": "line",
|
||||
"style": {
|
||||
"line-color": "rgba(0,0,0,0.4)",
|
||||
"line-width": {
|
||||
"stops": [[2.6468052936710817, 1.51], [19, 95.7862864971161]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "bridge_large",
|
||||
"ref": "bridge_large_casing",
|
||||
"style": {
|
||||
"line-color": "@road",
|
||||
"line-width": {
|
||||
"stops": [[12.11458208048225, 1], [19, 93.2862864971161]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "park_poi",
|
||||
"source": "mapbox",
|
||||
"source-layer": "poi_label",
|
||||
"filter": { "maki": "park" },
|
||||
"type": "symbol",
|
||||
"render": {
|
||||
"icon-image": "dot.sdf",
|
||||
"icon-allow-overlap": true,
|
||||
"icon-ignore-placement": true
|
||||
},
|
||||
"style": {
|
||||
"icon-color": "#8f8",
|
||||
"icon-halo-color": "#393",
|
||||
"icon-halo-width": 0,
|
||||
"icon-halo-blur": 5,
|
||||
"icon-opacity": 0,
|
||||
"icon-halo-opacity": 0.9,
|
||||
"icon-translate": [2, -1],
|
||||
"icon-size": 15
|
||||
}
|
||||
}, {
|
||||
"id": "country_label",
|
||||
"source": "mapbox",
|
||||
"source-layer": "country_label",
|
||||
"filter": { "$type": "Point" },
|
||||
"type": "symbol",
|
||||
"render": {
|
||||
"text-field": "{name}",
|
||||
"text-font": "Open Sans Regular, Arial Unicode MS Regular",
|
||||
"text-max-size": 16,
|
||||
"text-path": "horizontal",
|
||||
"text-padding": 10
|
||||
},
|
||||
"style": {
|
||||
"text-halo-color": "rgba(255,255,255,0.7)",
|
||||
"text-halo-width": "@stroke_width",
|
||||
"text-color": "@text"
|
||||
}
|
||||
}, {
|
||||
"id": "place_label",
|
||||
"source": "mapbox",
|
||||
"source-layer": "place_label",
|
||||
"filter": { "$type": "Point" },
|
||||
"type": "symbol",
|
||||
"render": {
|
||||
"text-field": "{name}",
|
||||
"text-font": "Open Sans Semibold, Arial Unicode MS Regular",
|
||||
"text-max-size": 18,
|
||||
"text-path": "horizontal",
|
||||
"text-max-width": 2
|
||||
},
|
||||
"style": {
|
||||
"text-halo-color": "rgba(255,255,255,0.7)",
|
||||
"text-halo-width": "@stroke_width",
|
||||
"text-color": "@text"
|
||||
}
|
||||
}, {
|
||||
"id": "road_label",
|
||||
"source": "mapbox",
|
||||
"source-layer": "road_label",
|
||||
"filter": { "$type": "LineString" },
|
||||
"type": "symbol",
|
||||
"min-zoom": 14,
|
||||
"render": {
|
||||
"symbol-placement": "line",
|
||||
"text-field": "{name}",
|
||||
"text-font": "Open Sans Regular, Arial Unicode MS Regular",
|
||||
"text-max-size": 12,
|
||||
"text-path": "curve",
|
||||
"text-min-distance": 250,
|
||||
"text-max-angle": 1.04
|
||||
},
|
||||
"style": {
|
||||
"text-color": "@text",
|
||||
"text-halo-color": "rgba(255,255,255,0.7)",
|
||||
"text-halo-width": "@stroke_width",
|
||||
"text-size": {
|
||||
"stops": [[4.770835839035499, 8.01], [15.477225251693334, 12]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "poi",
|
||||
"source": "mapbox",
|
||||
"source-layer": "poi_label",
|
||||
"type": "symbol",
|
||||
"min-zoom": 15,
|
||||
"render": {
|
||||
"icon-size": 12,
|
||||
"icon-image": "{maki}-12",
|
||||
"text-font": "Open Sans Regular, Arial Unicode MS Regular",
|
||||
"text-max-size": 10,
|
||||
"text-offset": [0, 0.8],
|
||||
"text-path": "horizontal",
|
||||
"text-max-width": 7,
|
||||
"text-optional": true,
|
||||
"text-vertical-align": "top",
|
||||
"text-field": "{name}"
|
||||
},
|
||||
"style": {
|
||||
"text-size": 10,
|
||||
"text-color": "#333",
|
||||
"text-halo-color": "#eee",
|
||||
"icon-rotate-anchor": "viewport"
|
||||
}
|
||||
}, {
|
||||
"id": "road_markers",
|
||||
"source": "mapbox",
|
||||
"source-layer": "road",
|
||||
"filter": { "oneway": 1, "$type": "LineString" },
|
||||
"type": "symbol",
|
||||
"min-zoom": 16,
|
||||
"render": {
|
||||
"symbol-placement": "line",
|
||||
"symbol-min-distance": 150,
|
||||
"icon-image": "triangle-stroked-12",
|
||||
"icon-rotate": 90
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -27,6 +27,7 @@ class StyleLayer;
|
||||
class StyleLayerGroup;
|
||||
class StyleSource;
|
||||
class Texturepool;
|
||||
class FileSource;
|
||||
class View;
|
||||
|
||||
class Map : private util::noncopyable {
|
||||
@@ -64,7 +65,8 @@ public:
|
||||
void toggleClass(const std::string &name);
|
||||
const std::vector<std::string> &getAppliedClasses() const;
|
||||
void setDefaultTransitionDuration(uint64_t duration_milliseconds = 0);
|
||||
void setStyleJSON(std::string newStyleJSON);
|
||||
void setStyleURL(const std::string &url);
|
||||
void setStyleJSON(std::string newStyleJSON, const std::string &base = "");
|
||||
std::string getStyleJSON() const;
|
||||
void setAccessToken(std::string access_token);
|
||||
std::string getAccessToken() const;
|
||||
@@ -111,6 +113,7 @@ public:
|
||||
|
||||
public:
|
||||
inline const TransformState &getState() const { return state; }
|
||||
inline std::shared_ptr<FileSource> getFileSource() const { return fileSource; }
|
||||
inline std::shared_ptr<Style> getStyle() const { return style; }
|
||||
inline std::shared_ptr<GlyphAtlas> getGlyphAtlas() { return glyphAtlas; }
|
||||
inline std::shared_ptr<GlyphStore> getGlyphStore() { return glyphStore; }
|
||||
@@ -150,6 +153,14 @@ private:
|
||||
void renderLayers(std::shared_ptr<StyleLayerGroup> group);
|
||||
void renderLayer(std::shared_ptr<StyleLayer> layer_desc, RenderPass pass);
|
||||
|
||||
private:
|
||||
bool async = false;
|
||||
std::shared_ptr<uv::loop> loop;
|
||||
uv_thread_t thread;
|
||||
uv_async_t *async_terminate = nullptr;
|
||||
uv_async_t *async_render = nullptr;
|
||||
uv_async_t *async_cleanup = nullptr;
|
||||
|
||||
private:
|
||||
// If cleared, the next time the render thread attempts to render the map, it will *actually*
|
||||
// render the map.
|
||||
@@ -170,6 +181,8 @@ private:
|
||||
Transform transform;
|
||||
TransformState state;
|
||||
|
||||
std::shared_ptr<FileSource> fileSource;
|
||||
|
||||
std::shared_ptr<Style> style;
|
||||
std::shared_ptr<GlyphAtlas> glyphAtlas;
|
||||
std::shared_ptr<GlyphStore> glyphStore;
|
||||
@@ -189,13 +202,6 @@ private:
|
||||
|
||||
std::set<std::shared_ptr<StyleSource>> activeSources;
|
||||
|
||||
private:
|
||||
bool async = false;
|
||||
std::shared_ptr<uv::loop> loop;
|
||||
uv_thread_t thread;
|
||||
uv_async_t *async_terminate = nullptr;
|
||||
uv_async_t *async_render = nullptr;
|
||||
uv_async_t *async_cleanup = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Map;
|
||||
class FileSource;
|
||||
|
||||
class SpritePosition {
|
||||
public:
|
||||
@@ -33,11 +33,11 @@ public:
|
||||
class Sprite : public std::enable_shared_from_this<Sprite>, private util::noncopyable {
|
||||
private:
|
||||
struct Key {};
|
||||
void load();
|
||||
void load(const std::shared_ptr<FileSource> &fileSource);
|
||||
|
||||
public:
|
||||
Sprite(const Key &, const std::string& base_url, float pixelRatio);
|
||||
static std::shared_ptr<Sprite> Create(const std::string& base_url, float pixelRatio);
|
||||
static std::shared_ptr<Sprite> Create(const std::string& base_url, float pixelRatio, const std::shared_ptr<FileSource> &fileSource);
|
||||
|
||||
const SpritePosition &getSpritePosition(const std::string& name) const;
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class FileSource;
|
||||
|
||||
class SDFGlyph {
|
||||
public:
|
||||
@@ -46,7 +47,7 @@ private:
|
||||
|
||||
class GlyphPBF {
|
||||
public:
|
||||
GlyphPBF(const std::string &glyphURL, const std::string &fontStack, GlyphRange glyphRange);
|
||||
GlyphPBF(const std::string &glyphURL, const std::string &fontStack, GlyphRange glyphRange, const std::shared_ptr<FileSource> &fileSource);
|
||||
|
||||
void parse(FontStack &stack);
|
||||
|
||||
@@ -62,7 +63,7 @@ private:
|
||||
// Manages Glyphrange PBF loading.
|
||||
class GlyphStore {
|
||||
public:
|
||||
GlyphStore();
|
||||
GlyphStore(const std::shared_ptr<FileSource> &fileSource);
|
||||
|
||||
// Block until all specified GlyphRanges of the specified font stack are loaded.
|
||||
void waitForGlyphRanges(const std::string &fontStack, const std::set<GlyphRange> &glyphRanges);
|
||||
@@ -81,6 +82,7 @@ public:
|
||||
std::string glyphURL;
|
||||
|
||||
private:
|
||||
const std::shared_ptr<FileSource> fileSource;
|
||||
std::unordered_map<std::string, std::map<GlyphRange, std::unique_ptr<GlyphPBF>>> ranges;
|
||||
std::unordered_map<std::string, std::unique_ptr<FontStack>> stacks;
|
||||
std::mutex mtx;
|
||||
|
||||
45
include/mbgl/util/filesource.hpp
Normal file
45
include/mbgl/util/filesource.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef MBGL_UTIL_FILESOURCE
|
||||
#define MBGL_UTIL_FILESOURCE
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
namespace uv {
|
||||
class loop;
|
||||
}
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace platform {
|
||||
struct Response;
|
||||
}
|
||||
|
||||
enum class ResourceType : uint8_t {
|
||||
Unknown,
|
||||
Tile,
|
||||
Glyphs,
|
||||
Image,
|
||||
JSON
|
||||
};
|
||||
|
||||
class FileSource {
|
||||
public:
|
||||
FileSource();
|
||||
|
||||
void setBase(const std::string &value);
|
||||
const std::string &getBase() const;
|
||||
|
||||
void load(ResourceType type, const std::string &url, std::function<void(platform::Response *)> callback, const std::shared_ptr<uv::loop> loop = nullptr);
|
||||
|
||||
private:
|
||||
// Stores a URL that is used as a base for loading resources with relative path.
|
||||
std::string base;
|
||||
|
||||
// Stores the absolute path to the cache directory.
|
||||
const std::string cache;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -16,9 +16,23 @@
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace uv {
|
||||
|
||||
inline std::string cwd() {
|
||||
size_t max = 0;
|
||||
std::string dir;
|
||||
do {
|
||||
max += 256;
|
||||
dir.resize(max);
|
||||
uv_cwd(const_cast<char *>(dir.data()), &max);
|
||||
} while (max == dir.size());
|
||||
dir.resize(max - 1);
|
||||
return dir;
|
||||
}
|
||||
|
||||
class loop {
|
||||
public:
|
||||
inline loop() {
|
||||
|
||||
@@ -45,15 +45,6 @@ int main(int argc, char *argv[]) {
|
||||
sigIntHandler.sa_flags = 0;
|
||||
sigaction(SIGINT, &sigIntHandler, NULL);
|
||||
|
||||
// read default stylesheet from disk
|
||||
std::ifstream stylefile("./style.min.js");
|
||||
if (!stylefile.good()) {
|
||||
fprintf(stderr, "Cannot read style file\n");
|
||||
return 1;
|
||||
}
|
||||
std::stringstream stylejson;
|
||||
stylejson << stylefile.rdbuf();
|
||||
|
||||
view = new GLFWView();
|
||||
mbgl::Map map(*view);
|
||||
|
||||
@@ -72,7 +63,8 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
// Load style
|
||||
map.setStyleJSON(stylejson.str());
|
||||
const std::string style = std::string("file://") + uv::cwd() + std::string("/styles/bright/style.json");
|
||||
map.setStyleURL(style);
|
||||
|
||||
int ret = view->run();
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
],
|
||||
'dependencies': [
|
||||
'../mapboxgl.gyp:mapboxgl',
|
||||
'../mapboxgl.gyp:copy_default_stylesheet',
|
||||
'../mapboxgl.gyp:copy_styles',
|
||||
'../mapboxgl.gyp:copy_certificate_bundle',
|
||||
],
|
||||
},
|
||||
|
||||
@@ -73,14 +73,17 @@ int main() {
|
||||
GLFWView view;
|
||||
mbgl::Map map(view);
|
||||
|
||||
URLHandler *handler = [[URLHandler alloc] init];
|
||||
[handler setMap:&map];
|
||||
NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
|
||||
[appleEventManager setEventHandler:handler andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
|
||||
|
||||
// Load settings
|
||||
mbgl::Settings_NSUserDefaults settings;
|
||||
map.setLonLatZoom(settings.longitude, settings.latitude, settings.zoom);
|
||||
map.setBearing(settings.bearing);
|
||||
map.setDebug(settings.debug);
|
||||
|
||||
URLHandler *handler = [[URLHandler alloc] init];
|
||||
[handler setMap:&map];
|
||||
|
||||
// Set access token if present
|
||||
NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"];
|
||||
@@ -88,15 +91,9 @@ int main() {
|
||||
if (accessToken) map.setAccessToken([accessToken cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
||||
|
||||
// Load style
|
||||
NSString *path = [[NSBundle mainBundle] pathForResource:@"style.min" ofType:@"js"];
|
||||
NSString *json = [NSString stringWithContentsOfFile:path
|
||||
encoding:[NSString defaultCStringEncoding]
|
||||
error:nil];
|
||||
map.setStyleJSON((std::string)[json cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
||||
|
||||
NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
|
||||
[appleEventManager setEventHandler:handler andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
|
||||
const std::string path([[[NSBundle mainBundle] pathForResource:@"style" ofType:@"json" inDirectory:@"styles/bright"] UTF8String]);
|
||||
|
||||
map.setStyleURL(std::string("file://") + path);
|
||||
|
||||
int ret = view.run();
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
'mac_bundle': 1,
|
||||
'mac_bundle_resources': [
|
||||
'Icon.icns',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/bin/style.min.js'
|
||||
],
|
||||
'xcode_settings': {
|
||||
'SDKROOT': 'macosx',
|
||||
@@ -40,7 +39,8 @@
|
||||
'CLANG_ENABLE_OBJC_ARC': 'YES'
|
||||
},
|
||||
'dependencies': [
|
||||
'../mapboxgl.gyp:mapboxgl'
|
||||
'../mapboxgl.gyp:bundle_styles',
|
||||
'../mapboxgl.gyp:mapboxgl',
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
33
mapboxgl.gyp
33
mapboxgl.gyp
@@ -34,37 +34,38 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
'target_name': 'build_stylesheet',
|
||||
'target_name': 'bundle_styles',
|
||||
'type': 'none',
|
||||
'hard_dependency': 1,
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'Build Stylesheet',
|
||||
'inputs': [
|
||||
'bin/style.js',
|
||||
],
|
||||
'outputs': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/bin/style.min.js'
|
||||
],
|
||||
'action': ['<@(node)', 'bin/build-style.js', '<@(_inputs)', '<(SHARED_INTERMEDIATE_DIR)']
|
||||
'action_name': 'Touch Stylesheet Directory',
|
||||
'inputs': ['styles'],
|
||||
'outputs': ['styles'],
|
||||
'action': ['touch', 'styles'], # required for xcode http://openradar.appspot.com/7232149
|
||||
}
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'sources': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/bin/style.min.js'
|
||||
'mac_bundle_resources': [
|
||||
'styles',
|
||||
],
|
||||
}
|
||||
},
|
||||
{
|
||||
'target_name': 'copy_default_stylesheet',
|
||||
'target_name': 'copy_styles',
|
||||
'type': 'none',
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'build_stylesheet'
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'Touch Stylesheet Directory',
|
||||
'inputs': ['styles'],
|
||||
'outputs': ['styles'],
|
||||
'action': ['touch', 'styles'], # required for xcode http://openradar.appspot.com/7232149
|
||||
}
|
||||
],
|
||||
'copies': [
|
||||
{
|
||||
'files': [ '<(SHARED_INTERMEDIATE_DIR)/bin/style.min.js' ],
|
||||
'files': [ 'styles' ],
|
||||
'destination': '<(PRODUCT_DIR)'
|
||||
}
|
||||
]
|
||||
@@ -86,7 +87,6 @@
|
||||
'type': 'static_library',
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'build_stylesheet',
|
||||
'shaders',
|
||||
],
|
||||
'sources': [
|
||||
@@ -154,7 +154,6 @@
|
||||
'type': 'static_library',
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'build_stylesheet',
|
||||
'shaders',
|
||||
],
|
||||
'sources': [
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <mbgl/style/style_bucket.hpp>
|
||||
#include <mbgl/util/texturepool.hpp>
|
||||
#include <mbgl/geometry/sprite_atlas.hpp>
|
||||
#include <mbgl/util/filesource.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
@@ -29,15 +31,16 @@
|
||||
using namespace mbgl;
|
||||
|
||||
Map::Map(View& view)
|
||||
: view(view),
|
||||
: loop(std::make_shared<uv::loop>()),
|
||||
view(view),
|
||||
transform(view),
|
||||
fileSource(std::make_shared<FileSource>()),
|
||||
style(std::make_shared<Style>()),
|
||||
glyphAtlas(std::make_shared<GlyphAtlas>(1024, 1024)),
|
||||
glyphStore(std::make_shared<GlyphStore>()),
|
||||
glyphStore(std::make_shared<GlyphStore>(fileSource)),
|
||||
spriteAtlas(std::make_shared<SpriteAtlas>(512, 512)),
|
||||
texturepool(std::make_shared<Texturepool>()),
|
||||
painter(*this),
|
||||
loop(std::make_shared<uv::loop>()) {
|
||||
painter(*this) {
|
||||
|
||||
view.initialize(this);
|
||||
|
||||
@@ -184,10 +187,29 @@ void Map::setup() {
|
||||
painter.setup();
|
||||
}
|
||||
|
||||
void Map::setStyleJSON(std::string newStyleJSON) {
|
||||
void Map::setStyleURL(const std::string &url) {
|
||||
fileSource->load(ResourceType::JSON, url, [&](platform::Response *res) {
|
||||
if (res->code == 200) {
|
||||
// Calculate the base
|
||||
const size_t pos = url.rfind('/');
|
||||
std::string base = "";
|
||||
if (pos != std::string::npos) {
|
||||
base = url.substr(0, pos + 1);
|
||||
}
|
||||
|
||||
this->setStyleJSON(res->body, base);
|
||||
} else {
|
||||
Log::Error(Event::Setup, "loading style failed: %d (%s)", res->code, res->error_message.c_str());
|
||||
}
|
||||
}, loop);
|
||||
}
|
||||
|
||||
|
||||
void Map::setStyleJSON(std::string newStyleJSON, const std::string &base) {
|
||||
styleJSON.swap(newStyleJSON);
|
||||
sprite.reset();
|
||||
style->loadJSON((const uint8_t *)styleJSON.c_str());
|
||||
fileSource->setBase(base);
|
||||
glyphStore->setURL(style->glyph_url);
|
||||
update();
|
||||
}
|
||||
@@ -208,7 +230,7 @@ std::shared_ptr<Sprite> Map::getSprite() {
|
||||
const float pixelRatio = state.getPixelRatio();
|
||||
const std::string &sprite_url = style->getSpriteURL();
|
||||
if (!sprite || sprite->pixelRatio != pixelRatio) {
|
||||
sprite = Sprite::Create(sprite_url, pixelRatio);
|
||||
sprite = Sprite::Create(sprite_url, pixelRatio, fileSource);
|
||||
}
|
||||
|
||||
return sprite;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
#include <mbgl/util/filesource.hpp>
|
||||
#include <mbgl/util/uv.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
|
||||
@@ -20,9 +21,9 @@ SpritePosition::SpritePosition(uint16_t x, uint16_t y, uint16_t width, uint16_t
|
||||
pixelRatio(pixelRatio) {
|
||||
}
|
||||
|
||||
std::shared_ptr<Sprite> Sprite::Create(const std::string& base_url, float pixelRatio) {
|
||||
std::shared_ptr<Sprite> Sprite::Create(const std::string& base_url, float pixelRatio, const std::shared_ptr<FileSource> &fileSource) {
|
||||
std::shared_ptr<Sprite> sprite(std::make_shared<Sprite>(Key(), base_url, pixelRatio));
|
||||
sprite->load();
|
||||
sprite->load(fileSource);
|
||||
return sprite;
|
||||
}
|
||||
|
||||
@@ -49,7 +50,7 @@ Sprite::operator bool() const {
|
||||
// Note: This is a separate function that must be called exactly once after creation
|
||||
// The reason this isn't part of the constructor is that calling shared_from_this() in
|
||||
// the constructor fails.
|
||||
void Sprite::load() {
|
||||
void Sprite::load(const std::shared_ptr<FileSource> &fileSource) {
|
||||
if (!valid) {
|
||||
// Treat a non-existent sprite as a successfully loaded empty sprite.
|
||||
loadedImage = true;
|
||||
@@ -60,7 +61,7 @@ void Sprite::load() {
|
||||
|
||||
std::shared_ptr<Sprite> sprite = shared_from_this();
|
||||
|
||||
platform::request_http(jsonURL, [sprite](platform::Response *res) {
|
||||
fileSource->load(ResourceType::JSON, jsonURL, [sprite](platform::Response *res) {
|
||||
if (res->code == 200) {
|
||||
sprite->body.swap(res->body);
|
||||
sprite->parseJSON();
|
||||
@@ -73,7 +74,7 @@ void Sprite::load() {
|
||||
}
|
||||
});
|
||||
|
||||
platform::request_http(spriteURL, [sprite](platform::Response *res) {
|
||||
fileSource->load(ResourceType::Image, spriteURL, [sprite](platform::Response *res) {
|
||||
if (res->code == 200) {
|
||||
sprite->image.swap(res->body);
|
||||
sprite->parseImage();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <mbgl/util/token.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/util/filesource.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
@@ -38,7 +39,7 @@ void TileData::request() {
|
||||
|
||||
// Note: Somehow this feels slower than the change to request_http()
|
||||
std::weak_ptr<TileData> weak_tile = shared_from_this();
|
||||
req = platform::request_http(url, [weak_tile](platform::Response *res) {
|
||||
map.getFileSource()->load(ResourceType::Tile, url, [weak_tile](platform::Response *res) {
|
||||
std::shared_ptr<TileData> tile = weak_tile.lock();
|
||||
if (!tile || tile->state == State::obsolete) {
|
||||
// noop. Tile is obsolete and we're now just waiting for the refcount
|
||||
@@ -55,7 +56,7 @@ void TileData::request() {
|
||||
fprintf(stderr, "[%s] tile loading failed: %d, %s\n", tile->url.c_str(), res->code, res->error_message.c_str());
|
||||
#endif
|
||||
}
|
||||
}, map.getLoop());
|
||||
});
|
||||
}
|
||||
|
||||
void TileData::cancel() {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/token.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
#include <mbgl/util/filesource.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
#include <uv.h>
|
||||
#include <algorithm>
|
||||
@@ -135,7 +136,7 @@ void FontStack::lineWrap(Shaping &shaping, const float lineHeight, const float m
|
||||
align(shaping, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, line);
|
||||
}
|
||||
|
||||
GlyphPBF::GlyphPBF(const std::string &glyphURL, const std::string &fontStack, GlyphRange glyphRange)
|
||||
GlyphPBF::GlyphPBF(const std::string &glyphURL, const std::string &fontStack, GlyphRange glyphRange, const std::shared_ptr<FileSource> &fileSource)
|
||||
: future(promise.get_future().share())
|
||||
{
|
||||
// Load the glyph set URL
|
||||
@@ -152,7 +153,7 @@ GlyphPBF::GlyphPBF(const std::string &glyphURL, const std::string &fontStack, Gl
|
||||
fprintf(stderr, "%s\n", url.c_str());
|
||||
#endif
|
||||
|
||||
platform::request_http(url, [&](platform::Response *res) {
|
||||
fileSource->load(ResourceType::Glyphs, url, [&](platform::Response *res) {
|
||||
if (res->code != 200) {
|
||||
// Something went wrong with loading the glyph pbf. Pass on the error to the future listeners.
|
||||
const std::string msg = util::sprintf<255>("[ERROR] failed to load glyphs (%d): %s\n", res->code, res->error_message.c_str());
|
||||
@@ -226,7 +227,7 @@ void GlyphPBF::parse(FontStack &stack) {
|
||||
data.clear();
|
||||
}
|
||||
|
||||
GlyphStore::GlyphStore() {}
|
||||
GlyphStore::GlyphStore(const std::shared_ptr<FileSource> &fileSource) : fileSource(fileSource) {}
|
||||
|
||||
void GlyphStore::setURL(const std::string &url) {
|
||||
glyphURL = url;
|
||||
@@ -269,7 +270,7 @@ std::shared_future<GlyphPBF &> GlyphStore::loadGlyphRange(const std::string &fon
|
||||
auto range_it = rangeSets.find(range);
|
||||
if (range_it == rangeSets.end()) {
|
||||
// We don't have this glyph set yet for this font stack.
|
||||
range_it = rangeSets.emplace(range, std::make_unique<GlyphPBF>(glyphURL, fontStack, range)).first;
|
||||
range_it = rangeSets.emplace(range, std::make_unique<GlyphPBF>(glyphURL, fontStack, range, fileSource)).first;
|
||||
}
|
||||
|
||||
return range_it->second->getFuture();
|
||||
|
||||
58
src/util/filesource.cpp
Normal file
58
src/util/filesource.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include <mbgl/util/filesource.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
FileSource::FileSource() {}
|
||||
|
||||
|
||||
void FileSource::setBase(const std::string &value) {
|
||||
base = value;
|
||||
}
|
||||
|
||||
const std::string &FileSource::getBase() const {
|
||||
return base;
|
||||
}
|
||||
|
||||
void FileSource::load(ResourceType type, const std::string &url, std::function<void(platform::Response *)> callback, const std::shared_ptr<uv::loop> loop) {
|
||||
// convert relative URLs to absolute URLs
|
||||
|
||||
const std::string absoluteURL = [&]() -> std::string {
|
||||
const size_t separator = url.find("://");
|
||||
if (separator == std::string::npos) {
|
||||
// Relative URL.
|
||||
return base + url;
|
||||
} else {
|
||||
return url;
|
||||
}
|
||||
}();
|
||||
|
||||
const size_t separator = absoluteURL.find("://");
|
||||
const std::string protocol = separator != std::string::npos ? absoluteURL.substr(0, separator) : "";
|
||||
|
||||
if (protocol == "file") {
|
||||
// load from disk
|
||||
const std::string path = absoluteURL.substr(separator + 3);
|
||||
std::ifstream file(path);
|
||||
|
||||
platform::Response response(callback);
|
||||
if (!file.good()) {
|
||||
response.error_message = "file not found (" + path + ")";
|
||||
} else {
|
||||
std::stringstream data;
|
||||
data << file.rdbuf();
|
||||
response.code = 200;
|
||||
response.body = data.str();
|
||||
}
|
||||
|
||||
callback(&response);
|
||||
} else {
|
||||
// load from the internet
|
||||
platform::request_http(absoluteURL, callback, loop);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
2818
styles/bright/img/sprite.json
Normal file
2818
styles/bright/img/sprite.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
styles/bright/img/sprite.png
Normal file
BIN
styles/bright/img/sprite.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
2818
styles/bright/img/sprite@2x.json
Normal file
2818
styles/bright/img/sprite@2x.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
styles/bright/img/sprite@2x.png
Normal file
BIN
styles/bright/img/sprite@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 266 KiB |
1336
styles/bright/style.json
Normal file
1336
styles/bright/style.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -189,8 +189,8 @@
|
||||
"dependencies": [
|
||||
"../deps/gtest/gtest.gyp:gtest",
|
||||
"../mapboxgl.gyp:mapboxgl",
|
||||
'../mapboxgl.gyp:bundle_styles',
|
||||
"link_gl",
|
||||
'../mapboxgl.gyp:copy_default_stylesheet',
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user