diff --git a/.gitignore b/.gitignore index b3b9aabb1..5295ff95f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ .DS_Store -*.o *.xcodeproj *.o -/out /mapnik-packaging /macosx/build /ios/build @@ -11,7 +9,6 @@ /build /bin/node_modules /include/llmr/shader/shaders.hpp -/include/llmr/style/resources.hpp -/src/style/resources.cpp /src/shader/shaders_gl.cpp -/src/shader/shaders_gles2.cpp \ No newline at end of file +/src/shader/shaders_gles2.cpp +/bin/style.bin.js diff --git a/.gitmodules b/.gitmodules index 37a988d2b..e2d05b3e9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "ios/MVKMapKit"] - path = ios/MVKMapKit - url = git@github.com:mapbox/MVKMapKit.git +[submodule "ios/mapbox-gl-cocoa"] + path = ios/mapbox-gl-cocoa + url = git@github.com:mapbox/mapbox-gl-cocoa.git diff --git a/.travis.yml b/.travis.yml index ed5c26f03..d14985125 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,26 +20,26 @@ cache: - mapnik-packaging before_install: -- source ./scripts/install_build_deps_${TRAVIS_OS_NAME}.sh -- source ./setup-libraries.sh +- source ./scripts/setup_travis.sh install: -- rm -rf mapnik-packaging/out/packages +- make setup before_script: -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]] && [[ ${CXX} == "g++" ]]; then export CXX="g++-4.8" ; fi +- rm -rf mapnik-packaging/out/packages script: -- make llmr BUILDTYPE=${BUILDTYPE} -- make clean -- make ${TRAVIS_OS_NAME} BUILDTYPE=${BUILDTYPE} -- make clean +- make linux BUILDTYPE=${BUILDTYPE} - make run-tests BUILDTYPE=${BUILDTYPE} # TODO - port this test to linux - if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then make run-headless-test BUILDTYPE=${BUILDTYPE} ; fi notifications: -- hipchat: WB52YkcbCGMbNcStsGeaoRO7cyBSK4wX2ZHo2Y4b@GL + hipchat: + rooms: + secure: "ZKtTiFjXgXfrAO8eMU1nJBe46OBLgk0H7VAVmk84QwAb6DuoqT+mGMs+1yrWtjLwZI8vayZyaucupp1siM7lBWCOADx5GXA6GCCLOuE7fYLSNJFrXHa1u70IUBLOU8b5bDWRn8tcd5CM754R609l4ckTzBH3y4CIh9YNFrB0b+g=" + template: + - '%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}' git: submodules: false diff --git a/LICENSE.md b/LICENSE.md index 016ff7eaa..845f31169 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,26 +1,24 @@ -Copyright (c), Mapbox +mapbox-gl-native copyright (c) 2014, Mapbox. -All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. -- Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. -- Neither the name "Mapbox" nor the names of its contributors may be used to - endorse or promote products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile b/Makefile index b10cdbb7b..d48f62a85 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,12 @@ BUILDTYPE ?= Release PYTHON ?= python V ?= 1 -all: llmr +all: setup + +setup: config.gypi + +config.gypi: + ./setup-libraries.sh # Builds the regular library llmr: config.gypi llmr.gyp node @@ -28,14 +33,9 @@ run-tests: test $${FILE}; \ done -test/%: +test/%: build/test/Makefile $(MAKE) -C build/test BUILDTYPE=$(BUILDTYPE) V=$(V) $* - build/$(BUILDTYPE)/test_$* - -# Only runs headless test case -run-headless-test: build/test/Makefile - $(MAKE) -C build/test BUILDTYPE=$(BUILDTYPE) V=$(V) headless - build/$(BUILDTYPE)/test_headless + (cd build/$(BUILDTYPE) && ./test_$*) ##### Makefile builds ########################################################## @@ -48,7 +48,7 @@ linux: config.gypi linux/llmr-app.gyp node # Executes the Linux binary run-linux: linux - build/$(BUILDTYPE)/llmr + (cd build/$(BUILDTYPE) && ./mapbox-gl) @@ -95,11 +95,12 @@ lproj: config.gypi linux/llmr-app.gyp clear_xcode_cache node clean: clear_xcode_cache -find ./deps/gyp -name "*.pyc" -exec rm {} \; -rm -rf ./build/ - -rm -f ./include/llmr/shader/shaders.hpp - -rm -f ./include/llmr/style/resources.hpp - -rm -f ./src/style/resources.cpp + -rm -rf ./config.mk + -rm -rf ./config.gypi distclean: clean - -rm -rf ./build + -rm -rf ./config.mk + -rm -rf ./config.gypi + -rm -rf ./mapnik-packaging/osx/out/ .PHONY: llmr test linux diff --git a/README.md b/README.md index c94627b47..8eba4e664 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Travis](https://api.travis-ci.com/mapbox/llmr-native.svg?token=yZ9zvfZwYkJNWivRLoyX)](https://magnum.travis-ci.com/mapbox/llmr-native) +[![Travis](https://api.travis-ci.com/mapbox/mapbox-gl-native.svg?token=yZ9zvfZwYkJNWivRLoyX)](https://magnum.travis-ci.com/mapbox/mapbox-gl-native) An OpenGL renderer for [Mapbox vector tiles](https://www.mapbox.com/blog/vector-tiles), implemented in C++11, currently targeting iOS, OS X, and Ubuntu Linux. @@ -6,11 +6,13 @@ implemented in C++11, currently targeting iOS, OS X, and Ubuntu Linux. # Depends - Modern C++ compiler that supports `-std=c++11` + - Boost headers - `libpng` - `libuv` - - `libcurl` (depends on OpenSSL; Linux only) - `glfw3` - - Boost + - `libcurl` (depends on OpenSSL; Linux only) + - `libboost_regex` (Linux only) + - Homebrew (for build on OS X) - Python (for build only) - Node.js (for build only) @@ -19,23 +21,30 @@ implemented in C++11, currently targeting iOS, OS X, and Ubuntu Linux. We use [mapnik-packaging](https://github.com/mapnik/mapnik-packaging) to build static libraries of dependencies. +First off: if you hit problems during development try: + + make clean + +This will clear cached build data and update to the latest versions of dependencies. + ## OS X -Run `./setup-libraries.sh` +First run: -This downloads all required dependencies, builds them and creates universal libraries that can be -used on both OS X and iOS. + make setup + +This downloads all required dependencies, builds them and creates universal libraries that can be used on both OS X and iOS. To create projects, you can run: - `make xproj`: Creates an Xcode project with OS X-specific handlers for HTTP downloads and - settings storage. It uses GLFW for window handling. + settings storage. It uses [GLFW](http://www.glfw.org) for window handling. - `make lproj`: Creates an Xcode project with platform-independent handlers for downloads and settings storage. This is what is also being built on Linux. - `make linux`: Builds the Linux GLFW application with `make`. ## iOS -iOS makes use of a Cocoa-specific API currently housed in [MVKMapKit](https://github.com/mapbox/MVKMapKit), +iOS makes use of a Cocoa-specific API called [mapbox-gl-cocoa](https://github.com/mapbox/mapbox-gl-cocoa), which is included as a submodule and provides a `UIView` interface to the map view and some bundle resources. First, pull down the submodule(s): @@ -43,9 +52,11 @@ First, pull down the submodule(s): git submodule init git submodule update -Then, because `libpng` isn't included in the iOS SDK, you will need to build a cross-architecture version -yourself. Run `./setup-libraries.sh`, which is derived from Mapnik's cross-architecture build -scripts. This will also run `./configure`. +Then run: + + make setup + +This downloads all required dependencies, builds them and creates universal libraries that can be used on both OS X and iOS. Lastly, `make iproj` to create and open an Xcode project with an iOS-specific view controller housing. @@ -56,7 +67,7 @@ Target devices: iPhone 4 and above (4S, 5, 5c, 5s) and iPad 2 and above (3, 4, m Ensure you have git and other build essentials: sudo apt-get update - sudo apt-get install git cmake make pkg-config curl automake libtool xutils-dev + sudo apt-get install git build-essential zlib1g-dev automake libtool xutils-dev make cmake pkg-config nodejs-legacy Install a `-std=c++11` capable compiler @@ -68,21 +79,22 @@ Install glfw3 dependencies: sudo apt-get install libxi-dev libglu1-mesa-dev x11proto-randr-dev x11proto-xext-dev libxrandr-dev x11proto-xf86vidmode-dev libxxf86vm-dev libxcursor-dev -Build static dependencies: +Then run: - ./setup-libraries.sh + make setup -This will automatically run configure for you and set the correct paths. +This downloads all required dependencies, builds them and creates universal libraries that can be used on both OS X and iOS. -You can then proceed to build the library, tests, or a GLFW app itself. +You can then proceed to build the library like: + + make linux # Style -We're currently embedding the stylesheet JSON in the binary. To create the C++ -file and the associated header, run +The default stylesheet at `bin/style.js` is JSON and is processed into a minified version by the following script: ``` -bin/build-style.js +node bin/build-style.js ``` This is automatically taken care of as a build phase. @@ -106,3 +118,7 @@ This is automatically taken care of as a build phase. - Two-finger single-tap to zoom out one level - Single-tap to toggle the command palette visibility for resetting north & the transform, toggling debug, toggling styles, and locating the user - Double-tap, long-pressing the second, then pan up and down to "quick zoom" (iPhone only, meant for one-handed use) + +# Other notes + +Under early development, this project was called LLMR (Low-Level Map Renderer), in case you see any lingering references to it. diff --git a/bin/build-style.js b/bin/build-style.js index 932287b89..c69fcb8b4 100755 --- a/bin/build-style.js +++ b/bin/build-style.js @@ -7,36 +7,6 @@ var mkdirp = require('./mkdirp'); var name = 'style'; var data = JSON.stringify(require(path.join(process.cwd(), process.argv[2]))); - -var length = data.length; - -var header = '// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.\n\n'; -header += '#ifndef LLMR_STYLE_RESOURCES\n'; -header += '#define LLMR_STYLE_RESOURCES\n'; -header += '\n'; -header += 'namespace llmr {\n'; -header += 'namespace resources {\n'; -header += '\n'; -header += 'extern const unsigned char ' + name + '[];\n'; -header += 'extern const unsigned long ' + name + '_size;\n'; -header += '\n'; -header += '}\n'; -header += '}\n'; -header += '\n'; -header += '#endif\n'; - -var header_path = path.join(process.argv[3], 'include/llmr/style/resources.hpp'); -mkdirp.sync(path.dirname(header_path)); -fs.writeFileSync(header_path, header); - -var code = '// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.\n'; -code += '#include \n'; -code += '\n'; -code += 'using namespace llmr;\n'; -code += '\n'; -code += 'const unsigned char resources::' + name + '[] = R"JSON(' + data + ')JSON";\n'; -code += 'const unsigned long resources::' + name + '_size = sizeof(resources::' + name + ');\n'; - -var file_path = path.join(process.argv[3], 'src/style/resources.cpp'); -mkdirp.sync(path.dirname(file_path)); -fs.writeFileSync(file_path, code); +var out_path = path.join(process.argv[3], 'bin/style.min.js'); +mkdirp.sync(path.dirname(out_path)); +fs.writeFileSync(out_path, data); diff --git a/bin/style.js b/bin/style.js index 35f40beac..4157e1e8f 100644 --- a/bin/style.js +++ b/bin/style.js @@ -14,8 +14,11 @@ module.exports = { "admin_l2": { "source": "outdoors", "layer": "admin", - "field": "admin_level", - "value": 2, + "filter": [ + "and", + {"field": "admin_level", "value": 2}, + {"field": "maritime", "operator": "not", "value": 1} + ], "join": "round", "cap": "round", "type": "line" @@ -23,11 +26,10 @@ module.exports = { "admin_l3": { "source": "outdoors", "layer": "admin", - "field": "admin_level", - "value": [ - 3, - 4, - 5 + "filter": [ + "and", + {"field": "admin_level", "value": [3,4,5]}, + {"field": "maritime", "operator": "not", "value": 1} ], "join": "round", "type": "line" @@ -263,13 +265,18 @@ module.exports = { "contour_label": { "source": "outdoors", "layer": "contour", - "field": "index", - "value": 10, + "filter": [ + "and", + { "field": "index", "value": [ 5, 10 ] }, + { "field": "ele", "operator": "not", "value": 0 } + ], "path": "curve", - "text_field": "ele", + "text_field": "{{ele}} m", + "font": "Open Sans Regular, Arial Unicode MS Regular", "fontSize": 10, "feature_type": "line", - "type": "text" + "type": "text", + "maxAngleDelta": 0.5 }, "building": { "source": "outdoors", @@ -646,101 +653,185 @@ module.exports = { "country_label": { "source": "outdoors", "layer": "country_label", - "text_field": "name", + "text_field": "{{name_en}}", "path": "horizontal", + "font": "Open Sans Semibold, Arial Unicode MS Bold", "fontSize": 24, "feature_type": "point", - "type": "text" + "type": "text", + "maxWidth": 5, }, "country_label_line": { "source": "outdoors", "layer": "country_label_line", "type": "line" }, - "marine_label_line": { + "marine_label_line_1": { "source": "outdoors", "layer": "marine_label", "feature_type": "line", "type": "text", - "text_field": "name", + "field": "labelrank", + "value": 1, + "text_field": "{{name_en}}", "path": "curve", - "fontSize": 16 + "font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "fontSize": 30, + "letterSpacing": 0.4, + "maxAngleDelta": 0.5 + }, + "marine_label_line_2": { + "source": "outdoors", + "layer": "marine_label", + "feature_type": "line", + "field": "labelrank", + "value": 2, + "type": "text", + "text_field": "{{name_en}}", + "path": "curve", + "font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "fontSize": 24, + "letterSpacing": 0.2, + "maxAngleDelta": 0.5 + }, + "marine_label_line_3": { + "source": "outdoors", + "layer": "marine_label", + "feature_type": "line", + "type": "text", + "field": "labelrank", + "value": 3, + "text_field": "{{name_en}}", + "path": "curve", + "font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "fontSize": 18, + "letterSpacing": 0.1, + "maxAngleDelta": 0.5 + }, + "marine_label_line_other": { + "source": "outdoors", + "layer": "marine_label", + "feature_type": "line", + "type": "text", + "field": "labelrank", + "value": [4, 5, 6], + "text_field": "{{name_en}}", + "path": "curve", + "font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "fontSize": 16, + "letterSpacing": 0.1, + "maxAngleDelta": 0.5 }, "marine_label_point_1": { "source": "outdoors", "layer": "marine_label", "feature_type": "point", "type": "text", - "text_field": "name", + "text_field": "{{name_en}}", "path": "horizontal", "field": "labelrank", "value": 1, - "fontSize": 30 + "font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "fontSize": 30, + "maxWidth": 8, + "letterSpacing": 0.4, + "lineHeight": 2, }, "marine_label_point_2": { "source": "outdoors", "layer": "marine_label", "feature_type": "point", "type": "text", - "text_field": "name", + "text_field": "{{name_en}}", "path": "horizontal", "field": "labelrank", "value": 2, - "fontSize": 24 + "font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "fontSize": 24, + "maxWidth": 8, + "letterSpacing": 0.2, + "lineHeight": 1.5, + }, + "marine_label_point_3": { + "source": "outdoors", + "layer": "marine_label", + "feature_type": "point", + "type": "text", + "text_field": "{{name_en}}", + "path": "horizontal", + "field": "labelrank", + "value": 3, + "font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "fontSize": 18, + "maxWidth": 8, + "letterSpacing": 0.1, + "lineHeight": 1.3, }, "marine_label_point_other": { "source": "outdoors", "layer": "marine_label", "feature_type": "point", "type": "text", - "text_field": "name", + "text_field": "{{name_en}}", "path": "horizontal", "field": "labelrank", - "value": [3,4,5,6], - "fontSize": 18 + "value": [4,5,6], + "font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "fontSize": 16, + "maxWidth": 8, + "letterSpacing": 0.1, + "lineHeight": 1.2, }, "state_label": { "source": "outdoors", "layer": "state_label", - "text_field": "name", + "text_field": "{{name_en}}", "path": "horizontal", + "font": "Open Sans Regular, Arial Unicode MS Regular", "fontSize": 16, "feature_type": "point", "type": "text", - "enabled": 4 + "enabled": 4, + "maxWidth": 8 }, "place_label_city": { "source": "outdoors", "layer": "place_label", "field": "type", "value": "city", - "text_field": "name", + "text_field": "{{name_en}}", "path": "horizontal", + "font": "Open Sans Semibold, Arial Unicode MS Bold", "fontSize": 20, "feature_type": "point", - "type": "text" + "type": "text", + "maxWidth": 8 }, "place_label_town": { "source": "outdoors", "layer": "place_label", "field": "type", "value": "town", - "text_field": "name", + "text_field": "{{name_en}}", "path": "horizontal", + "font": "Open Sans Semibold, Arial Unicode MS Bold", "fontSize": 24, "feature_type": "point", - "type": "text" + "type": "text", + "maxWidth": 8 }, "place_label_village": { "source": "outdoors", "layer": "place_label", "field": "type", "value": "village", - "text_field": "name", + "text_field": "{{name_en}}", "path": "horizontal", + "font": "Open Sans Semibold, Arial Unicode MS Bold", "fontSize": 22, "feature_type": "point", - "type": "text" + "type": "text", + "maxWidth": 8 }, "place_label_other": { "source": "outdoors", @@ -751,20 +842,23 @@ module.exports = { "suburb", "neighbourhood" ], - "text_field": "name", + "text_field": "{{name_en}}", "path": "horizontal", + "font": "Open Sans Semibold, Arial Unicode MS Bold", "fontSize": 18, + "maxWidth": 6, "feature_type": "point", - "type": "text" + "type": "text", }, "road_label_1": { "source": "outdoors", "layer": "road_label", "field": "class", "value": ["motorway","main"], - "text_field": "name", + "text_field": "{{name_en}}", "path": "curve", "padding": 2, + "font": "Open Sans Regular, Arial Unicode MS Regular", "fontSize": 18, "feature_type": "line", "type": "text", @@ -775,9 +869,10 @@ module.exports = { "layer": "road_label", "field": "class", "value": ["street","street_limited"], - "text_field": "name", + "text_field": "{{name_en}}", "path": "curve", "padding": 2, + "font": "Open Sans Regular, Arial Unicode MS Regular", "fontSize": 16, "feature_type": "line", "type": "text", @@ -788,9 +883,10 @@ module.exports = { "layer": "road_label", "field": "class", "value": ["service","driveway","path"], - "text_field": "name", + "text_field": "{{name_en}}", "path": "curve", "padding": 2, + "font": "Open Sans Regular, Arial Unicode MS Regular", "fontSize": 14, "feature_type": "line", "type": "text", @@ -799,21 +895,24 @@ module.exports = { "water_label": { "source": "outdoors", "layer": "water_label", - "text_field": "name", + "text_field": "{{name_en}}", "path": "horizontal", + "font": "Open Sans Semibold Italic, Arial Unicode MS Bold", "fontSize": 12, "feature_type": "point", - "type": "text" + "type": "text", + "maxWidth": 8 }, "waterway_label": { "source": "outdoors", "layer": "waterway_label", - "text_field": "name", + "text_field": "{{name_en}}", "path": "curve", + "font": "Open Sans Semibold Italic, Arial Unicode MS Bold", "fontSize": 12, - "textMinDistance": 15, "feature_type": "line", - "type": "text" + "type": "text", + "maxAngleDelta": 0.5 }, "poi": { "source": "outdoors", @@ -833,11 +932,36 @@ module.exports = { "size": 12, "type": "point" }, - "poi_4": { + "poi_4_4": { "source": "outdoors", "layer": "poi_label", "icon": "maki", - "field": "scalerank", + "filter": [ + "and", + { "field": "scalerank", "value": 4 }, + { "field": "localrank", "operator": "<=", "value": 4 } + ], + "size": 12, + "type": "point" + }, + "poi_4_16": { + "source": "outdoors", + "layer": "poi_label", + "icon": "maki", + "filter": [ + "and", + { "field": "scalerank", "value": 4 }, + { "field": "localrank", "operator": "<=", "value": 16 }, + { "field": "localrank", "operator": ">", "value": 4 } + ], + "size": 12, + "type": "point" + }, + "poi_4_all": { + "source": "outdoors", + "layer": "poi_label", + "icon": "maki", + "field": "scalerank", "value": 4, "size": 12, "type": "point" @@ -859,36 +983,86 @@ module.exports = { 1, 2 ], - "text_field": "name", + "text_field": "{{name_en}}", "path": "horizontal", "padding": 2, - "fontSize": 11, + "maxWidth": 10, + "verticalAlignment": "top", + "translate": [0, -1], + "font": "Open Sans Semibold, Arial Unicode MS Bold", + "fontSize": 12, "feature_type": "point", - "type": "text" + "type": "text", }, "poi_label_3": { "source": "outdoors", "layer": "poi_label", "field": "scalerank", "value": 3, - "text_field": "name", + "text_field": "{{name_en}}", "path": "horizontal", "padding": 2, - "fontSize": 10, + "maxWidth": 8, + "verticalAlignment": "top", + "translate": [0, -1], + "font": "Open Sans Semibold, Arial Unicode MS Bold", + "fontSize": 11, "feature_type": "point", - "type": "text" + "type": "text", }, - "poi_label_4": { + "poi_label_4_4": { "source": "outdoors", "layer": "poi_label", - "field": "scalerank", - "value": 4, - "text_field": "name", + "filter": [ + "and", + { "field": "scalerank", "value": 4 }, + { "field": "localrank", "operator": "<=", "value": 4 } + ], + "text_field": "{{name_en}}", "path": "horizontal", "padding": 2, + "maxWidth": 8, + "verticalAlignment": "top", + "translate": [0, -1], + "font": "Open Sans Semibold, Arial Unicode MS Bold", "fontSize": 10, "feature_type": "point", - "type": "text" + "type": "text", + }, + "poi_label_4_16": { + "source": "outdoors", + "layer": "poi_label", + "filter": [ + "and", + { "field": "scalerank", "value": 4 }, + { "field": "localrank", "operator": "<=", "value": 16 } + ], + "text_field": "{{name_en}}", + "path": "horizontal", + "padding": 2, + "maxWidth": 8, + "verticalAlignment": "top", + "translate": [0, -1], + "font": "Open Sans Semibold, Arial Unicode MS Bold", + "fontSize": 10, + "feature_type": "point", + "type": "text", + }, + "poi_label_4_all": { + "source": "outdoors", + "layer": "poi_label", + "field": "scalerank", + "value": 4, + "text_field": "{{name_en}}", + "path": "horizontal", + "padding": 2, + "maxWidth": 8, + "verticalAlignment": "top", + "translate": [0, -1], + "font": "Open Sans Semibold, Arial Unicode MS Bold", + "fontSize": 10, + "feature_type": "point", + "type": "text", } }, "structure": [ @@ -984,18 +1158,6 @@ module.exports = { "name": "waterway_stream", "bucket": "waterway_stream" }, - { - "name": "contour_line_loud", - "bucket": "contour_line_10" - }, - { - "name": "contour_line_loud", - "bucket": "contour_line_5" - }, - { - "name": "contour_line_regular", - "bucket": "contour_line_other" - }, { "name": "building_shadow", "bucket": "building" @@ -1024,6 +1186,18 @@ module.exports = { "name": "hillshade_full_shadow", "bucket": "hillshade_full_shadow" }, + { + "name": "contour_line_loud", + "bucket": "contour_line_10" + }, + { + "name": "contour_line_loud", + "bucket": "contour_line_5" + }, + { + "name": "contour_line_regular", + "bucket": "contour_line_other" + }, { "name": "barrier_line_gate", "bucket": "barrier_line_gate" @@ -1156,6 +1330,10 @@ module.exports = { "name": "road_street_casing", "bucket": "street" }, + { + "name": "road_motorway_casing", + "bucket": "motorway" + }, { "name": "road_motorway_link", "bucket": "motorway_link" @@ -1172,10 +1350,6 @@ module.exports = { "name": "road_main", "bucket": "main" }, - { - "name": "road_motorway_casing", - "bucket": "motorway" - }, { "name": "road_motorway", "bucket": "motorway" @@ -1321,8 +1495,20 @@ module.exports = { "bucket": "country_label" }, { - "name": "marine_label_line", - "bucket": "marine_label_line" + "name": "marine_label_line_1", + "bucket": "marine_label_line_1" + }, + { + "name": "marine_label_line_2", + "bucket": "marine_label_line_2" + }, + { + "name": "marine_label_line_3", + "bucket": "marine_label_line_3" + }, + { + "name": "marine_label_line_other", + "bucket": "marine_label_line_other" }, { "name": "marine_label_point_1", @@ -1332,6 +1518,10 @@ module.exports = { "name": "marine_label_point_2", "bucket": "marine_label_point_2" }, + { + "name": "marine_label_point_3", + "bucket": "marine_label_point_3" + }, { "name": "marine_label_point_other", "bucket": "marine_label_point_other" @@ -1356,10 +1546,34 @@ module.exports = { "name": "place_label_other", "bucket": "place_label_other" }, + { + "name": "water_label", + "bucket": "water_label" + }, + { + "name": "poi_aerodrome", + "bucket": "poi_aerodrome" + }, + { + "name": "poi", + "bucket": "poi" + }, + { + "name": "poi_label_1-2", + "bucket": "poi_label_1-2" + }, { "name": "road_label_1", "bucket": "road_label_1" }, + { + "name": "poi_3", + "bucket": "poi_3" + }, + { + "name": "poi_label_3", + "bucket": "poi_label_3" + }, { "name": "road_label_2", "bucket": "road_label_2" @@ -1372,41 +1586,33 @@ module.exports = { "name": "contour_label", "bucket": "contour_label" }, - { - "name": "water_label", - "bucket": "water_label" - }, { "name": "waterway_label", "bucket": "waterway_label" }, { - "name": "poi", - "bucket": "poi" + "name": "poi_4_4", + "bucket": "poi_4_4" }, { - "name": "poi_label_1-2", - "bucket": "poi_label_1-2" + "name": "poi_label_4_4", + "bucket": "poi_label_4_4" }, { - "name": "poi_3", - "bucket": "poi_3" + "name": "poi_4_16", + "bucket": "poi_4_16" }, { - "name": "poi_label_3", - "bucket": "poi_label_3" + "name": "poi_label_4_16", + "bucket": "poi_label_4_16" }, { - "name": "poi_4", - "bucket": "poi_4" + "name": "poi_4_all", + "bucket": "poi_4_all" }, { - "name": "poi_label_4", - "bucket": "poi_label_4" - }, - { - "name": "poi_aerodrome", - "bucket": "poi_aerodrome" + "name": "poi_label_4_all", + "bucket": "poi_label_4_all" } ], "constants": { @@ -1433,7 +1639,7 @@ module.exports = { "street": "#fff", "text": "#666", "text_stroke": "rgba(255,255,255,0.8)", - "country_text": "#333", + "country_text": "#222", "marine_text": "#a0bdc0", "water_text": "#185869", @@ -1456,6 +1662,7 @@ module.exports = { "admin_night": "#ffb680", "text_night": "#fff", + "text_water_night": "#2a5b8a", "text_stroke_night": "#103", "text2_stroke_night": "rgba(1,69,89,0.8)", @@ -1685,6 +1892,28 @@ module.exports = { "stops", {"z": 1, "val": 14}, {"z": 12, "val": 24} + ], + "poi_label_1-2_size": [ + "stops", + {"z": 15, "val": 10}, + {"z": 16, "val": 11}, + {"z": 17, "val": 12} + ], + "poi_label_3_size": [ + "stops", + {"z": 16, "val": 10}, + {"z": 17, "val": 11} + ], + "hillshade_prerender": [ + "stops", + {"z": 11, "val": 0}, + {"z": 12, "val": 1} + ], + "hillshade_prerender_size": [ + "stops", + {"z": 11, "val": 1056}, + {"z": 12, "val": 512}, + {"z": 13, "val": 256} ] }, "classes": [ @@ -1838,53 +2067,61 @@ module.exports = { "hillshade_full_shadow": { "color": "#103", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", - {"z": 15, "val": 0.075}, + {"z": 15, "val": 0.08}, + {"z": 16, "val": 0.075}, {"z": 17, "val": 0.05}, - {"z": 18, "val": 0.025} + {"z": 18, "val": 0.05}, + {"z": 19, "val": 0.025} ] }, "hillshade_medium_shadow": { "color": "#206", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", - {"z": 15, "val": 0.075}, + {"z": 15, "val": 0.08}, + {"z": 16, "val": 0.075}, {"z": 17, "val": 0.05}, - {"z": 18, "val": 0.025} + {"z": 18, "val": 0.05}, + {"z": 19, "val": 0.025} ] }, "hillshade_full_highlight": { "color": "#fffff3", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", {"z": 15, "val": 0.3}, + {"z": 16, "val": 0.3}, {"z": 17, "val": 0.2}, - {"z": 18, "val": 0.1} + {"z": 18, "val": 0.2}, + {"z": 19, "val": 0.1} ] }, "hillshade_medium_highlight": { "color": "#ffd", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", {"z": 15, "val": 0.3}, + {"z": 16, "val": 0.3}, {"z": 17, "val": 0.2}, - {"z": 18, "val": 0.1} + {"z": 18, "val": 0.2}, + {"z": 19, "val": 0.1} ] }, "contour_line_loud": { @@ -1905,6 +2142,13 @@ module.exports = { {"z": 13, "val": 0.11} ] }, + "contour_label": { + "color": "text", + "stroke": "land", + "strokeWidth": 0.3, + "strokeBlur": 3, + "size": 10 + }, "water": { "color": "water", "stroke": "#a2bdc0" @@ -2232,7 +2476,7 @@ module.exports = { "country_label": { "color": "country_text", "stroke": "rgba(255,255,255,0.5)", - "strokeWidth": 0.4, + "strokeWidth": 0.5, "size": "country_label_size" }, "country_label_line": { @@ -2240,12 +2484,8 @@ module.exports = { "width": 0.5, "opacity": 0.5 }, - "marine_label_line": { + "marine_label_line_1": { "color": "marine_text", - "stroke": "water" - }, - "marine_label_point_1": { - "color": "#a9c4c7", "size": ["stops", {"z": 3, "val": 20}, {"z": 4, "val": 25}, @@ -2254,8 +2494,8 @@ module.exports = { ], "stroke": "water" }, - "marine_label_point_2": { - "color": "#a9c4c7", + "marine_label_line_2": { + "color": "marine_text", "size": ["stops", {"z": 3, "val": 13}, {"z": 4, "val": 14}, @@ -2265,8 +2505,8 @@ module.exports = { ], "stroke": "water" }, - "marine_label_point_other": { - "color": "#a9c4c7", + "marine_label_line_3": { + "color": "marine_text", "size": ["stops", {"z": 3, "val": 12}, {"z": 4, "val": 13}, @@ -2276,6 +2516,58 @@ module.exports = { ], "stroke": "water" }, + "marine_label_line_other": { + "color": "marine_text", + "size": ["stops", + {"z": 4, "val": 12}, + {"z": 5, "val": 14}, + {"z": 6, "val": 16}, + {"z": 22, "val": 16} + ], + "stroke": "water" + }, + "marine_label_point_1": { + "color": "marine_text", + "size": ["stops", + {"z": 3, "val": 20}, + {"z": 4, "val": 25}, + {"z": 5, "val": 30}, + {"z": 22, "val": 30} + ], + "stroke": "water" + }, + "marine_label_point_2": { + "color": "marine_text", + "size": ["stops", + {"z": 3, "val": 13}, + {"z": 4, "val": 14}, + {"z": 5, "val": 20}, + {"z": 6, "val": 24}, + {"z": 22, "val": 24} + ], + "stroke": "water" + }, + "marine_label_point_3": { + "color": "marine_text", + "size": ["stops", + {"z": 3, "val": 12}, + {"z": 4, "val": 13}, + {"z": 5, "val": 15}, + {"z": 6, "val": 18}, + {"z": 22, "val": 18} + ], + "stroke": "water" + }, + "marine_label_point_other": { + "color": "marine_text", + "size": ["stops", + {"z": 4, "val": 12}, + {"z": 5, "val": 14}, + {"z": 6, "val": 16}, + {"z": 22, "val": 16} + ], + "stroke": "water" + }, "state_label": { "color": "#333", "strokeWidth": 0.4, @@ -2378,11 +2670,19 @@ module.exports = { "antialias": false, "opacity": [ "stops", - {"z": 16.5, "val": 0}, - {"z": 16.75, "val": 1} + {"z": 17.5, "val": 0}, + {"z": 17.75, "val": 1} ] }, - "poi_4": { + "poi_4_4": { + "antialias": false, + "opacity": [ + "stops", + {"z": 18, "val": 0}, + {"z": 18.25, "val": 1} + ] + }, + "poi_4_16": { "antialias": false, "opacity": [ "stops", @@ -2390,39 +2690,68 @@ module.exports = { {"z": 18.75, "val": 1} ] }, + "poi_4_all": { + "antialias": false, + "opacity": [ + "stops", + {"z": 18.75, "val": 0}, + {"z": 19, "val": 1} + ] + }, "poi_label_1-2": { "color": "#444", - "size": 11, + "size": "poi_label_1-2_size", "stroke": "land", "strokeWidth": 0.3, "strokeBlur": 1, - "translate": [0, 14] }, "poi_label_3": { "color": "#444", - "size": 10, + "size": "poi_label_3_size", "stroke": "land", "strokeWidth": 0.3, "strokeBlur": 1, - "translate": [0, 14], "opacity": [ "stops", - {"z": 16.5, "val": 0}, - {"z": 16.75, "val": 1} + {"z": 17.5, "val": 0}, + {"z": 17.75, "val": 1} ] }, - "poi_label_4": { + "poi_label_4_4": { "color": "#444", "size": 10, "opacity": [ "stops", - {"z": 18.5, "val": 0}, + {"z": 18, "val": 0}, + {"z": 17.25, "val": 1} + ], + "stroke": "land", + "strokeWidth": 0.3, + "strokeBlur": 1, + }, + "poi_label_4_16": { + "color": "#444", + "size": 10, + "opacity": [ + "stops", + {"z": 18.25, "val": 0}, {"z": 18.75, "val": 1} ], "stroke": "land", "strokeWidth": 0.3, "strokeBlur": 1, - "translate": [0, 14] + }, + "poi_label_4_all": { + "color": "#444", + "size": 10, + "opacity": [ + "stops", + {"z": 18.75, "val": 0}, + {"z": 19, "val": 1} + ], + "stroke": "land", + "strokeWidth": 0.3, + "strokeBlur": 1, }, "poi_aerodrome": { "opacity": ["stops", @@ -2434,7 +2763,7 @@ module.exports = { } }, { - "name": "satellite", + "name": "night", "layers": { "background": { "color": "land_night" @@ -2590,54 +2919,58 @@ module.exports = { "hillshade_full_shadow": { "color": "#103", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", {"z": 16, "val": 0.3}, {"z": 17, "val": 0.2}, - {"z": 18, "val": 0.1} + {"z": 18, "val": 0.1}, + {"z": 19, "val": 0.05} ] }, "hillshade_medium_shadow": { "color": "#206", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", {"z": 16, "val": 0.3}, {"z": 17, "val": 0.2}, - {"z": 18, "val": 0.1} + {"z": 18, "val": 0.1}, + {"z": 19, "val": 0.05} ] }, "hillshade_full_highlight": { "color": "#fdfdad", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", {"z": 14, "val": 0.4}, {"z": 15, "val": 0.3}, {"z": 17, "val": 0.2}, - {"z": 18, "val": 0.1} + {"z": 18, "val": 0.1}, + {"z": 19, "val": 0.05} ] }, "hillshade_medium_highlight": { "color": "#ffe1b7", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", {"z": 15, "val": 0.3}, {"z": 17, "val": 0.2}, - {"z": 18, "val": 0.15} + {"z": 18, "val": 0.15}, + {"z": 19, "val": 0.05} ] }, "contour_line_loud": { @@ -2658,6 +2991,13 @@ module.exports = { {"z": 13, "val": 0.4} ] }, + "contour_label": { + "color": "contour_night", + "stroke": "land_night", + "strokeWidth": 0.3, + "strokeBlur": 3, + "size": 10 + }, "water": { "color": "water_night", "stroke": "water_dark_night" @@ -2982,6 +3322,7 @@ module.exports = { "color": "text_night", "stroke": "text2_stroke_night", "strokeWidth": 0.4, + "strokeBlur": 2, "size": "country_label_size" }, "country_label_line": { @@ -2989,8 +3330,46 @@ module.exports = { "width": 0.5, "opacity": 0.5 }, - "marine_label_line": { + "marine_label_line_1": { "color": "water_dark_night", + "size": ["stops", + {"z": 3, "val": 20}, + {"z": 4, "val": 25}, + {"z": 5, "val": 30}, + {"z": 22, "val": 30} + ], + "stroke": "water_night" + }, + "marine_label_line_2": { + "color": "water_dark_night", + "size": ["stops", + {"z": 3, "val": 13}, + {"z": 4, "val": 14}, + {"z": 5, "val": 20}, + {"z": 6, "val": 24}, + {"z": 22, "val": 24} + ], + "stroke": "water_night" + }, + "marine_label_line_3": { + "color": "water_dark_night", + "size": ["stops", + {"z": 3, "val": 12}, + {"z": 4, "val": 13}, + {"z": 5, "val": 15}, + {"z": 6, "val": 18}, + {"z": 22, "val": 18} + ], + "stroke": "water_night" + }, + "marine_label_line_other": { + "color": "water_dark_night", + "size": ["stops", + {"z": 4, "val": 12}, + {"z": 5, "val": 14}, + {"z": 6, "val": 16}, + {"z": 22, "val": 16} + ], "stroke": "water_night" }, "marine_label_point_1": { @@ -3014,8 +3393,8 @@ module.exports = { ], "stroke": "water_night" }, - "marine_label_point_other": { - "color": "#a9c4c7", + "marine_label_point_3": { + "color": "water_dark_night", "size": ["stops", {"z": 3, "val": 12}, {"z": 4, "val": 13}, @@ -3025,6 +3404,16 @@ module.exports = { ], "stroke": "water_night" }, + "marine_label_point_other": { + "color": "water_dark_night", + "size": ["stops", + {"z": 4, "val": 12}, + {"z": 5, "val": 14}, + {"z": 6, "val": 16}, + {"z": 22, "val": 16} + ], + "stroke": "water_night" + }, "state_label": { "color": "#fff", "strokeWidth": 0.4, @@ -3113,14 +3502,12 @@ module.exports = { "size": "road_label_3_size" }, "water_label": { - "color": "water_dark_night", - "strokeWidth": 0.8, - "stroke": "text2_stroke_night" + "color": "text_water_night", + "stroke": "water_night", }, "waterway_label": { - "color": "water_dark_night", - "strokeWidth": 0.8, - "stroke": "text2_stroke_night" + "color": "text_water_night", + "stroke": "water_night", }, "poi": { "color": "white", @@ -3130,11 +3517,19 @@ module.exports = { "antialias": false, "opacity": [ "stops", - {"z": 16.5, "val": 0}, - {"z": 16.75, "val": 1} + {"z": 17.5, "val": 0}, + {"z": 17.75, "val": 1} ] }, - "poi_4": { + "poi_4_4": { + "antialias": false, + "opacity": [ + "stops", + {"z": 18, "val": 0}, + {"z": 17.25, "val": 1} + ] + }, + "poi_4_16": { "antialias": false, "opacity": [ "stops", @@ -3142,28 +3537,46 @@ module.exports = { {"z": 18.75, "val": 1} ] }, + "poi_4_all": { + "antialias": false, + "opacity": [ + "stops", + {"z": 18.75, "val": 0}, + {"z": 19, "val": 1} + ] + }, "poi_label_1-2": { "color": "#fff", - "size": 11, + "size": "poi_label_1-2_size", "stroke": "text2_stroke_night", "strokeWidth": 0.3, - "strokeBlur": 1, - "translate": [0, 14] + "strokeBlur": 1 }, "poi_label_3": { "color": "#fff", - "size": 10, + "size": "poi_label_3_size", "stroke": "text2_stroke_night", "strokeWidth": 0.3, "strokeBlur": 1, - "translate": [0, 14], "opacity": [ "stops", - {"z": 16.5, "val": 0}, - {"z": 16.75, "val": 1} + {"z": 17.5, "val": 0}, + {"z": 17.75, "val": 1} ] }, - "poi_label_4": { + "poi_label_4_4": { + "color": "#fff", + "size": 10, + "opacity": [ + "stops", + {"z": 18, "val": 0}, + {"z": 18.25, "val": 1} + ], + "stroke": "text2_stroke_night", + "strokeWidth": 0.3, + "strokeBlur": 1 + }, + "poi_label_4_16": { "color": "#fff", "size": 10, "opacity": [ @@ -3173,8 +3586,19 @@ module.exports = { ], "stroke": "text2_stroke_night", "strokeWidth": 0.3, - "strokeBlur": 1, - "translate": [0, 14] + "strokeBlur": 1 + }, + "poi_label_4_all": { + "color": "#fff", + "size": 10, + "opacity": [ + "stops", + {"z": 18.75, "val": 0}, + {"z": 19, "val": 1} + ], + "stroke": "text2_stroke_night", + "strokeWidth": 0.3, + "strokeBlur": 1 }, "poi_aerodrome": { "opacity": ["stops", diff --git a/common.gypi b/common.gypi index b1ad46015..a9567d4d3 100644 --- a/common.gypi +++ b/common.gypi @@ -5,27 +5,33 @@ 'CLANG_CXX_LIBRARY': 'libc++', 'CLANG_CXX_LANGUAGE_STANDARD':'c++11', 'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0', + 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES', + 'GCC_ENABLE_CPP_RTTI':'YES', + 'OTHER_CPLUSPLUSFLAGS': [ '-Wall', '-Wextra' ], + 'GCC_WARN_PEDANTIC': 'YES', + 'GCC_WARN_UNINITIALIZED_AUTOS': 'YES_AGGRESSIVE' }, - 'cflags_cc': ['-std=c++11'], + 'cflags_cc': ['-std=c++11', '-Wall', '-Wextra'], 'configurations': { 'Debug': { - 'cflags': [ '-g', '-O0' ], + 'cflags_cc': [ '-g', '-O0', '-fno-omit-frame-pointer','-fwrapv', '-fstack-protector-all', '-fno-common' ], 'defines': [ 'DEBUG' ], 'xcode_settings': { 'GCC_OPTIMIZATION_LEVEL': '0', 'GCC_GENERATE_DEBUGGING_SYMBOLS': 'YES', - 'OTHER_CPLUSPLUSFLAGS': [ '-Wall', '-Wextra', '-pedantic' ] + 'DEAD_CODE_STRIPPING': 'NO', + 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'NO', + 'OTHER_CPLUSPLUSFLAGS': [ '-fno-omit-frame-pointer','-fwrapv', '-fstack-protector-all', '-fno-common'] } }, 'Release': { - 'cflags': [ '-O3' ], + 'cflags_cc': [ '-O3' ], 'defines': [ 'NDEBUG' ], 'xcode_settings': { 'GCC_OPTIMIZATION_LEVEL': '3', 'GCC_GENERATE_DEBUGGING_SYMBOLS': 'NO', 'DEAD_CODE_STRIPPING': 'YES', - 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES', - 'OTHER_CPLUSPLUSFLAGS': [ '-Wall', '-Wextra', '-pedantic' ] + 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES' } } } diff --git a/common/curl_request.cpp b/common/curl_request.cpp index 0702e1e72..e5edb5aba 100644 --- a/common/curl_request.cpp +++ b/common/curl_request.cpp @@ -89,7 +89,7 @@ class CURLRequest : public llmr::platform::Request { public: CURLRequest(const std::string &url, std::function callback, - uv_loop_t *loop) + std::shared_ptr loop) : Request(url, callback, loop) {} CURL *curl = nullptr; @@ -190,32 +190,27 @@ void curl_perform(uv_poll_t *req, int /*status*/, int events) { } int handle_socket(CURL * /*easy*/, curl_socket_t s, int action, void * /*userp*/, void *socketp) { - curl_context *context; - if (action == CURL_POLL_IN || action == CURL_POLL_OUT) { - if (socketp) { - context = (curl_context *)socketp; - } else { - context = create_curl_context(s); - } - curl_multi_assign(curl_multi, s, (void *)context); + curl_context *context = nullptr; + + if (socketp) { + context = (curl_context *)socketp; + } else if (action != CURL_POLL_REMOVE) { + context = create_curl_context(s); } - switch (action) { - case CURL_POLL_IN: - uv_poll_start(&context->poll_handle, UV_READABLE, curl_perform); - break; - case CURL_POLL_OUT: - uv_poll_start(&context->poll_handle, UV_WRITABLE, curl_perform); - break; - case CURL_POLL_REMOVE: - if (socketp) { - uv_poll_stop(&((curl_context *)socketp)->poll_handle); - destroy_curl_context((curl_context *)socketp); + if (context) { + curl_multi_assign(curl_multi, s, (void *)context); + if (action == CURL_POLL_IN || action == CURL_POLL_INOUT) { + uv_poll_start(&context->poll_handle, UV_READABLE, curl_perform); + } + if (action == CURL_POLL_OUT || action == CURL_POLL_INOUT) { + uv_poll_start(&context->poll_handle, UV_WRITABLE, curl_perform); + } + if (action == CURL_POLL_REMOVE && socketp) { + uv_poll_stop(&context->poll_handle); + destroy_curl_context(context); curl_multi_assign(curl_multi, s, NULL); } - break; - default: - abort(); } return 0; @@ -358,7 +353,7 @@ void thread_init_cb() { std::shared_ptr platform::request_http(const std::string &url, std::function callback, - uv_loop_t *loop) { + std::shared_ptr loop) { using namespace request; init_thread_once(thread_init_cb); std::shared_ptr req = std::make_shared(url, callback, loop); diff --git a/common/foundation_request.mm b/common/foundation_request.mm index ca32706ba..4d6ca9c5f 100644 --- a/common/foundation_request.mm +++ b/common/foundation_request.mm @@ -41,7 +41,7 @@ class FoundationRequest : public llmr::platform::Request { public: FoundationRequest(const std::string &url, std::function callback, - uv_loop_t *loop) + std::shared_ptr loop) : Request(url, callback, loop) { #if TARGET_OS_IPHONE active_tasks++; @@ -68,7 +68,7 @@ public: std::shared_ptr llmr::platform::request_http(const std::string &url, std::function callback, - uv_loop_t *loop) { + std::shared_ptr loop) { uv_once(&request_initialize, request_initialize_cb); std::shared_ptr req = @@ -99,7 +99,7 @@ llmr::platform::request_http(const std::string &url, } (*req_ptr)->complete(); - + delete req_ptr; }]; diff --git a/common/glfw_view.cpp b/common/glfw_view.cpp index 3cc50b591..43557ee4d 100644 --- a/common/glfw_view.cpp +++ b/common/glfw_view.cpp @@ -73,8 +73,17 @@ void GLFWView::key(GLFWwindow *window, int key, int /*scancode*/, int action, in view->map->resetPosition(); break; case GLFW_KEY_R: - if (!mods) - view->map->toggleRaster(); + if (!mods) { + std::set newAppliedClasses; + if (view->map->getAppliedClasses().count("night")) { + newAppliedClasses.insert("default"); + } else { + newAppliedClasses.insert("default"); + newAppliedClasses.insert(newAppliedClasses.end(), "night"); + } + view->map->setDefaultTransitionDuration(300); + view->map->setAppliedClasses(newAppliedClasses); + } break; case GLFW_KEY_N: if (!mods) diff --git a/include/llmr/geometry/glyph_atlas.hpp b/include/llmr/geometry/glyph_atlas.hpp index 312572f5e..0aada6a73 100644 --- a/include/llmr/geometry/glyph_atlas.hpp +++ b/include/llmr/geometry/glyph_atlas.hpp @@ -2,6 +2,7 @@ #define LLMR_GEOMETRY_GLYPH_ATLAS #include +#include #include #include @@ -11,8 +12,6 @@ namespace llmr { -class VectorTileGlyph; - class GlyphAtlas { public: @@ -30,7 +29,7 @@ public: Rect addGlyph(uint64_t tile_id, const std::string& face_name, - const VectorTileGlyph& glyph); + const SDFGlyph& glyph); void removeGlyphs(uint64_t tile_id); void bind(); diff --git a/include/llmr/geometry/sprite_atlas.hpp b/include/llmr/geometry/sprite_atlas.hpp index 220edc701..13b85e548 100644 --- a/include/llmr/geometry/sprite_atlas.hpp +++ b/include/llmr/geometry/sprite_atlas.hpp @@ -62,7 +62,7 @@ private: BinPack bin; std::map> images; std::set uninitialized; - char *data = nullptr; + uint32_t *data = nullptr; std::atomic dirty; uint32_t texture = 0; uint32_t filter = 0; diff --git a/include/llmr/map/filter_expression.hpp b/include/llmr/map/filter_expression.hpp new file mode 100644 index 000000000..50e6ce1d7 --- /dev/null +++ b/include/llmr/map/filter_expression.hpp @@ -0,0 +1,128 @@ +#ifndef LLMR_MAP_FILTER_EXPRESSION +#define LLMR_MAP_FILTER_EXPRESSION + +#include +#include + +#include +#include + +namespace llmr { + +enum class FilterOperator { + Equal, + NotEqual, + Greater, + GreaterEqual, + Less, + LessEqual +}; + +enum class ExpressionOperator { + Or, + And +}; + + +inline FilterOperator filterOperatorType(const std::string &op) { + if (op == "!=" || op == "not") { + return FilterOperator::NotEqual; + } else if (op == "==" || op == "eq") { + return FilterOperator::Equal; + } else if (op == ">" || op == "gt") { + return FilterOperator::Greater; + } else if (op == ">=" || op == "gte") { + return FilterOperator::GreaterEqual; + } else if (op == "<" || op == "lt") { + return FilterOperator::Less; + } else if (op == "<=" || op == "lte") { + return FilterOperator::LessEqual; + } else { + fprintf(stderr, "[WARNING] filter operator '%s' unrecognized\n", op.c_str()); + return FilterOperator::Equal; + } +} + +inline ExpressionOperator expressionOperatorType(const std::string &op) { + if (op == "&&" || op == "and") { + return ExpressionOperator::And; + } else if (op == "||" || op == "or") { + return ExpressionOperator::Or; + } else { + fprintf(stderr, "[WARNING] expression operator '%s' unrecognized\n", op.c_str()); + return ExpressionOperator::Or; + } +} + + +class PropertyFilter; +class PropertyExpression; + +typedef util::variant< + util::recursive_wrapper, + util::recursive_wrapper, + std::true_type +> PropertyFilterExpression; + + +class PropertyFilter { +public: + inline PropertyFilter(const std::string &field, FilterOperator op, const Value &value) : field(field), op(op), value(value) {}; + inline PropertyFilter(PropertyFilter &&filter) + : field(std::move(filter.field)), + op(filter.op), + value(std::move(filter.value)) { + } + + // Returns true if the filter passes, even if the key is missing. + inline bool isMissingFieldOkay() const { + switch (op) { + case FilterOperator::NotEqual: + return true; + default: + return false; + } + } + + inline bool compare(const Value &other) const { + switch (op) { + case FilterOperator::Equal: + return util::relaxed_equal(other, value); + case FilterOperator::NotEqual: + return !util::relaxed_equal(other, value); + case FilterOperator::Greater: + return util::relaxed_greater(other, value); + case FilterOperator::GreaterEqual: + return util::relaxed_greater_equal(other, value); + case FilterOperator::Less: + return util::relaxed_less(other, value); + case FilterOperator::LessEqual: + return util::relaxed_less_equal(other, value); + default: + return false; + } + } + +public: + std::string field; + FilterOperator op = FilterOperator::Equal; + Value value; +}; + +class PropertyExpression { +public: + inline PropertyExpression() {} + inline PropertyExpression(PropertyExpression &&expression) + : op(expression.op), + operands(std::move(expression.operands)) { + } + +public: + ExpressionOperator op = ExpressionOperator::Or; + std::vector operands; +}; + + +} + +#endif diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index ab1738f96..e20803b99 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,13 @@ public: void resize(uint16_t width, uint16_t height, float ratio = 1); void resize(uint16_t width, uint16_t height, float ratio, uint16_t fb_width, uint16_t fb_height); + // Styling + void setAppliedClasses(std::set appliedClasses); + std::set getAppliedClasses() const; + void setDefaultTransitionDuration(uint64_t duration_milliseconds = 0); + void setStyleJSON(std::string newStyleJSON); + std::string getStyleJSON() const; + // Transition void cancelTransitions(); @@ -73,8 +81,8 @@ public: void resetZoom(); void startScaling(); void stopScaling(); - double getMinZoom(); - double getMaxZoom(); + double getMinZoom() const; + double getMaxZoom() const; // Rotation void rotateBy(double sx, double sy, double ex, double ey, double duration = 0); @@ -91,17 +99,15 @@ public: void toggleDebug(); bool getDebug() const; - // TEMPORARY DEBUG API - void toggleRaster(); - public: inline const TransformState &getState() const { return state; } - inline const Style &getStyle() const { return style; } - inline GlyphAtlas &getGlyphAtlas() { return glyphAtlas; } - inline SpriteAtlas &getSpriteAtlas() { return spriteAtlas; } - inline uv_loop_t *getLoop() { return loop; } + inline std::shared_ptr getStyle() const { return style; } + inline std::shared_ptr getGlyphAtlas() { return glyphAtlas; } + inline std::shared_ptr getGlyphStore() { return glyphStore; } + inline std::shared_ptr getSpriteAtlas() { return spriteAtlas; } + inline std::shared_ptr getTexturepool() { return texturepool; } + inline std::shared_ptr getLoop() { return loop; } inline time getAnimationTime() const { return animationTime; } - inline Texturepool &getTexturepool() { return texturepool; } inline const Sources &getSources() { return sources; } private: @@ -113,7 +119,6 @@ private: // Setup void setup(); - void loadStyle(const uint8_t *const data, uint32_t bytes); void updateTiles(); void updateRenderState(); @@ -149,14 +154,18 @@ private: Transform transform; TransformState state; - Texturepool texturepool; - Style style; - GlyphAtlas glyphAtlas; - SpriteAtlas spriteAtlas; + std::shared_ptr