diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2014-03-12 15:27:20 +0100 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2014-03-14 11:36:10 +0100 |
commit | d9589573bc9b437b55ee27f4746627a427aedb69 (patch) | |
tree | ad94dfba2aa96c5306040ad91ca801865a64d6d4 /src | |
parent | df56f9fbcefa28295992c99096ebc82d3543194f (diff) | |
download | qtlocation-mapboxgl-d9589573bc9b437b55ee27f4746627a427aedb69.tar.gz |
extract label shaping
Diffstat (limited to 'src')
-rw-r--r-- | src/map/tile_data.cpp | 12 | ||||
-rw-r--r-- | src/platform/platform.cpp | 4 | ||||
-rw-r--r-- | src/renderer/text_bucket.cpp | 55 | ||||
-rw-r--r-- | src/style/resources.cpp | 2 | ||||
-rw-r--r-- | src/style/style.cpp | 10 | ||||
-rw-r--r-- | src/style/style_parser.cpp | 13 |
6 files changed, 81 insertions, 15 deletions
diff --git a/src/map/tile_data.cpp b/src/map/tile_data.cpp index 5ca0e817af..7110297ead 100644 --- a/src/map/tile_data.cpp +++ b/src/map/tile_data.cpp @@ -5,6 +5,7 @@ #include <llmr/geometry/fill_buffer.hpp> #include <llmr/geometry/line_buffer.hpp> #include <llmr/geometry/point_buffer.hpp> +#include <llmr/geometry/text_buffer.hpp> #include <llmr/geometry/elements_buffer.hpp> #include <llmr/renderer/fill_bucket.hpp> #include <llmr/renderer/line_bucket.hpp> @@ -24,6 +25,7 @@ TileData::TileData(Tile::ID id, const Style& style) fillVertexBuffer(std::make_shared<FillVertexBuffer>()), lineVertexBuffer(std::make_shared<LineVertexBuffer>()), pointVertexBuffer(std::make_shared<PointVertexBuffer>()), + textVertexBuffer(std::make_shared<TextVertexBuffer>()), triangleElementsBuffer(std::make_shared<TriangleElementsBuffer>()), lineElementsBuffer(std::make_shared<LineElementsBuffer>()), pointElementsBuffer(std::make_shared<PointElementsBuffer>()), @@ -157,7 +159,7 @@ std::shared_ptr<Bucket> TileData::createBucket(const VectorTile& tile, const Buc } else if (bucket_desc.type == BucketType::Text) { return createTextBucket(tile, layer, bucket_desc); } else { - // TODO: create other bucket types. + throw std::runtime_error("unknown bucket type"); } } else { // The layer specified in the bucket does not exist. Do nothing. @@ -206,7 +208,7 @@ std::shared_ptr<Bucket> TileData::createTextBucket(const VectorTile& tile, const } // TODO: currently hardcoded to use the first font stack. - const std::map<Value, std::vector<VectorTilePlacement>>& stack = layer.shaping.begin()->second; + const std::map<Value, std::vector<VectorTilePlacement>>& shaping = layer.shaping.begin()->second; std::vector<const VectorTileFace *> faces; for (const std::string& face : layer.faces) { @@ -221,11 +223,9 @@ std::shared_ptr<Bucket> TileData::createTextBucket(const VectorTile& tile, const std::shared_ptr<TextBucket> bucket = std::make_shared<TextBucket>(textVertexBuffer, triangleElementsBuffer, bucket_desc); FilteredVectorTileLayer filtered_layer(layer, bucket_desc); - for (pbf feature_pbf : filtered_layer) { + for (const pbf& feature_pbf : filtered_layer) { if (state == State::obsolete) return nullptr; - - const VectorTileFeature feature(feature_pbf, layer); - std::cerr << feature; + bucket->addFeature({ feature_pbf, layer }, faces, shaping); } return bucket; diff --git a/src/platform/platform.cpp b/src/platform/platform.cpp index ebe65184ae..e2d6d828cf 100644 --- a/src/platform/platform.cpp +++ b/src/platform/platform.cpp @@ -1,4 +1,4 @@ #include <llmr/platform/platform.hpp> -const char *llmr::kTileURL = "http://a.gl-api-us-east-1.tilestream.net/v3/mapbox.mapbox-streets-v4/%d/%d/%d.gl.pbf"; -const char *llmr::kSpriteURL = "https://dl.dropboxusercontent.com/u/575564/sprite"; +const char *llmr::kTileURL = "http://localhost:3333/v3/mapbox.mapbox-streets-v4/%d/%d/%d.gl.pbf"; +const char *llmr::kSpriteURL = "http://localhost:3333/images/sprite"; diff --git a/src/renderer/text_bucket.cpp b/src/renderer/text_bucket.cpp index dd646794b7..0b9b865b81 100644 --- a/src/renderer/text_bucket.cpp +++ b/src/renderer/text_bucket.cpp @@ -11,12 +11,12 @@ #include <llmr/util/math.hpp> #include <llmr/platform/gl.hpp> +#include <iostream> + #define BUFFER_OFFSET(i) ((char *)nullptr + (i)) #include <cassert> -struct geometry_too_long_exception : std::exception {}; - using namespace llmr; TextBucket::TextBucket(const std::shared_ptr<TextVertexBuffer>& vertexBuffer, @@ -26,12 +26,55 @@ TextBucket::TextBucket(const std::shared_ptr<TextVertexBuffer>& vertexBuffer, vertexBuffer(vertexBuffer), triangleElementsBuffer(triangleElementsBuffer), vertex_start(vertexBuffer->index()), - triangle_elements_start(triangleElementsBuffer->index()) -{ + triangle_elements_start(triangleElementsBuffer->index()) { } -void TextBucket::addGeometry(pbf& geom) { - // noop +void TextBucket::addFeature(const VectorTileFeature& feature, + const std::vector<const VectorTileFace *>& faces, + const std::map<Value, std::vector<VectorTilePlacement>>& shaping) { + auto it_prop = feature.properties.find(geometry.text_field); + if (it_prop == feature.properties.end()) { + // feature does not have the correct property + return; + } + const Value& value = it_prop->second; + + + auto it_shaping = shaping.find(value); + if (it_shaping == shaping.end()) { + // we lack shaping information for this label + return; + } + const std::vector<VectorTilePlacement>& placements = it_shaping->second; + + // std::cerr << "we have shaping for " << value << std::endl; + + // Decode all lines. + std::vector<Coordinate> line; + Geometry::command cmd; + + Coordinate coord; + pbf geom = feature.geometry; + Geometry geometry(geom); + int32_t x, y; + while ((cmd = geometry.next(x, y)) != Geometry::end) { + if (cmd == Geometry::move_to) { + if (!line.empty()) { + addLabel(line, faces, placements); + line.clear(); + } + } + line.emplace_back(x, y); + } + if (line.size()) { + addLabel(line, faces, placements); + } +} + +void TextBucket::addLabel(const std::vector<Coordinate>& line, + const std::vector<const VectorTileFace *>& faces, + const std::vector<VectorTilePlacement>& placements) { + // TODO } void TextBucket::render(Painter& painter, const std::string& layer_name, const Tile::ID& id) { diff --git a/src/style/resources.cpp b/src/style/resources.cpp index 58cf8265f6..9e06afc6d7 100644 --- a/src/style/resources.cpp +++ b/src/style/resources.cpp @@ -3,5 +3,5 @@ using namespace llmr; -const unsigned char resources::style[] = R"JSON({"buckets":{"water":{"source":"streets","layer":"water","type":"fill"},"road_large":{"source":"streets","layer":"road","field":"class","value":["motorway","main"],"type":"line","cap":"round","join":"round"},"road_regular":{"source":"streets","layer":"road","field":"class","value":"street","type":"line","cap":"round","join":"round"},"road_limited":{"source":"streets","layer":"road","field":"class","value":"street_limited","type":"line","cap":"round","join":"round"},"park":{"source":"streets","layer":"landuse","field":"class","value":"park","type":"fill"},"wood":{"source":"streets","layer":"landuse","field":"class","value":"wood","type":"fill"},"school":{"source":"streets","layer":"landuse","field":"class","value":"school","type":"fill"},"cemetery":{"source":"streets","layer":"landuse","field":"class","value":"cemetery","type":"fill"},"industrial":{"source":"streets","layer":"landuse","field":"class","value":"industrial","type":"fill"},"building":{"source":"streets","layer":"building","type":"fill"},"alcohol_poi":{"source":"streets","layer":"poi_label","field":"type","value":["Alcohol"],"type":"point"},"cafe_poi":{"source":"streets","layer":"poi_label","field":"type","value":["Cafe"],"type":"point"},"embassy_poi":{"source":"streets","layer":"poi_label","field":"type","value":["Embassy"],"type":"point"},"park_poi":{"source":"streets","layer":"poi_label","field":"type","value":["Park"],"type":"point"},"restaurant_poi":{"source":"streets","layer":"poi_label","field":"type","value":["Restaurant"],"type":"point"}},"sprite":"img/maki-sprite","constants":{"park":"#c8df9f"},"structure":[{"name":"park","bucket":"park"},{"name":"wood","bucket":"wood"},{"name":"water","bucket":"water"},{"name":"building","bucket":"building"},{"name":"road_limited","bucket":"road_limited"},{"name":"road_regular","bucket":"road_regular"},{"name":"road_large","bucket":"road_large"},{"name":"alcohol_poi","bucket":"alcohol_poi"},{"name":"cafe_poi","bucket":"cafe_poi"},{"name":"embassy_poi","bucket":"embassy_poi"},{"name":"park_poi","bucket":"park_poi"},{"name":"restaurant_poi","bucket":"restaurant_poi"}],"classes":[{"name":"default","layers":{"background":{"type":"background","color":"#FFFFFF"},"park":{"type":"fill","color":"park","antialias":true,"image":"park"},"wood":{"type":"fill","color":"#33AA66","antialias":true,"opacity":0.1},"water":{"type":"fill","color":"#bae0e9","stroke":"#73b6e6","antialias":true,"image":"water_etsy"},"building":{"type":"fill","color":"#000000","antialias":true,"opacity":["linear",13,0,0.1,0,0.1]},"road_limited":{"type":"line","color":"#BBBBBB","width":["stops",{"z":0,"val":1},{"z":30,"val":1}]},"road_regular":{"type":"line","color":"#999999","width":["stops",{"z":0,"val":0.5},{"z":13,"val":0.5},{"z":16,"val":2},{"z":20,"val":32},{"z":30,"val":32}]},"road_large":{"type":"line","color":"#666666","width":["stops",{"z":0,"val":0.5},{"z":11,"val":0.5},{"z":13,"val":1},{"z":16,"val":4},{"z":20,"val":64},{"z":30,"val":64}]},"alcohol_poi":{"type":"point","color":"#cccccc","size":18,"image":"alcohol-shop","opacity":["linear",15,0,1,0,0.75]},"cafe_poi":{"type":"point","color":"#cccccc","size":18,"image":"cafe","opacity":["linear",15,0,1,0,0.75]},"embassy_poi":{"type":"point","color":"#cccccc","size":18,"image":"embassy","opacity":["linear",15,0,1,0,0.75]},"park_poi":{"type":"point","color":"#cccccc","size":18,"image":"park","opacity":["linear",15,0,1,0,0.75]},"restaurant_poi":{"type":"point","color":"#cccccc","size":18,"image":"restaurant","opacity":["linear",15,0,1,0,0.75]}}}]})JSON"; +const unsigned char resources::style[] = R"JSON({"buckets":{"water":{"source":"streets","layer":"water","type":"fill"},"road_large":{"source":"streets","layer":"road","field":"class","value":["motorway","main"],"type":"line","cap":"round","join":"round"},"road_regular":{"source":"streets","layer":"road","field":"class","value":"street","type":"line","cap":"round","join":"round"},"road_limited":{"source":"streets","layer":"road","field":"class","value":"street_limited","type":"line","cap":"round","join":"round"},"park":{"source":"streets","layer":"landuse","field":"class","value":"park","type":"fill"},"wood":{"source":"streets","layer":"landuse","field":"class","value":"wood","type":"fill"},"school":{"source":"streets","layer":"landuse","field":"class","value":"school","type":"fill"},"cemetery":{"source":"streets","layer":"landuse","field":"class","value":"cemetery","type":"fill"},"industrial":{"source":"streets","layer":"landuse","field":"class","value":"industrial","type":"fill"},"building":{"source":"streets","layer":"building","type":"fill"},"alcohol_poi":{"source":"streets","layer":"poi_label","field":"type","value":["Alcohol"],"type":"point"},"cafe_poi":{"source":"streets","layer":"poi_label","field":"type","value":["Cafe"],"type":"point"},"embassy_poi":{"source":"streets","layer":"poi_label","field":"type","value":["Embassy"],"type":"point"},"park_poi":{"source":"streets","layer":"poi_label","field":"type","value":["Park"],"type":"point"},"restaurant_poi":{"source":"streets","layer":"poi_label","field":"type","value":["Restaurant"],"type":"point"},"country_label":{"source":"streets","type":"text","layer":"country_label","feature_type":"point","padding":10,"text_field":"name","path":"horizontal","font":"Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS","fontSize":16}},"sprite":"img/maki-sprite","constants":{"park":"#c8df9f","text":"#000000"},"structure":[{"name":"park","bucket":"park"},{"name":"wood","bucket":"wood"},{"name":"water","bucket":"water"},{"name":"building","bucket":"building"},{"name":"road_limited","bucket":"road_limited"},{"name":"road_regular","bucket":"road_regular"},{"name":"road_large","bucket":"road_large"},{"name":"alcohol_poi","bucket":"alcohol_poi"},{"name":"cafe_poi","bucket":"cafe_poi"},{"name":"embassy_poi","bucket":"embassy_poi"},{"name":"park_poi","bucket":"park_poi"},{"name":"restaurant_poi","bucket":"restaurant_poi"},{"name":"country_label","bucket":"country_label"}],"classes":[{"name":"default","layers":{"background":{"type":"background","color":"#FFFFFF"},"park":{"type":"fill","color":"park","antialias":true,"image":"park"},"wood":{"type":"fill","color":"#33AA66","antialias":true,"opacity":0.1},"water":{"type":"fill","color":"#bae0e9","stroke":"#73b6e6","antialias":true,"image":"water_etsy"},"building":{"type":"fill","color":"#000000","antialias":true,"opacity":["linear",13,0,0.1,0,0.1]},"road_limited":{"type":"line","color":"#BBBBBB","width":["stops",{"z":0,"val":1},{"z":30,"val":1}]},"road_regular":{"type":"line","color":"#999999","width":["stops",{"z":0,"val":0.5},{"z":13,"val":0.5},{"z":16,"val":2},{"z":20,"val":32},{"z":30,"val":32}]},"road_large":{"type":"line","color":"#666666","width":["stops",{"z":0,"val":0.5},{"z":11,"val":0.5},{"z":13,"val":1},{"z":16,"val":4},{"z":20,"val":64},{"z":30,"val":64}]},"alcohol_poi":{"type":"point","color":"#cccccc","size":18,"image":"alcohol-shop","opacity":["linear",15,0,1,0,0.75]},"cafe_poi":{"type":"point","color":"#cccccc","size":18,"image":"cafe","opacity":["linear",15,0,1,0,0.75]},"embassy_poi":{"type":"point","color":"#cccccc","size":18,"image":"embassy","opacity":["linear",15,0,1,0,0.75]},"park_poi":{"type":"point","color":"#cccccc","size":18,"image":"park","opacity":["linear",15,0,1,0,0.75]},"restaurant_poi":{"type":"point","color":"#cccccc","size":18,"image":"restaurant","opacity":["linear",15,0,1,0,0.75]},"country_label":{"type":"text","stroke":[1,1,1,0.7],"color":"text"}}}]})JSON"; const unsigned long resources::style_size = sizeof(resources::style); diff --git a/src/style/style.cpp b/src/style/style.cpp index 03656e8f40..9ecf59e702 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -76,6 +76,16 @@ void Style::cascade(float z) { point.image = layer.image; } + for (const auto& text_pair : sheetClass.text) { + const std::string& layer_name = text_pair.first; + const llmr::TextClass& layer = text_pair.second; + + // TODO: This should be restricted to point styles that have actual + // values so as to not override with default values. + llmr::TextProperties& text = computed.texts[layer_name]; + text.color = layer.color; + } + // Cascade background computed.background.color = sheetClass.background.color; } diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index 82e2b5153d..f9e294f972 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -233,6 +233,8 @@ void StyleParser::parseClass(const std::string& name, JSVal value, ClassDescript class_desc.line.insert({ name, std::forward<LineClass>(parseLineClass(value)) }); } else if (type_name == "point") { class_desc.point.insert({ name, std::forward<PointClass>(parsePointClass(value)) }); + } else if (type_name == "text") { + class_desc.text.insert({ name, std::forward<TextClass>(parseTextClass(value)) }); } else if (type_name == "background") { class_desc.background = parseBackgroundClass(value); } else { @@ -471,6 +473,17 @@ PointClass StyleParser::parsePointClass(JSVal value) { return klass; } + +TextClass StyleParser::parseTextClass(JSVal value) { + TextClass klass; + + if (value.HasMember("color")) { + klass.color = parseColor(value["color"]); + } + + return klass; +} + BackgroundClass StyleParser::parseBackgroundClass(JSVal value) { BackgroundClass klass; |