Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Optionally exclude CJK glyphs from offline downloads #13607

Merged
merged 5 commits into from
Dec 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions bin/offline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ int main(int argc, char *argv[]) {
args::ValueFlag<double> minZoomValue(argumentParser, "number", "Min zoom level", {"minZoom"});
args::ValueFlag<double> maxZoomValue(argumentParser, "number", "Max zoom level", {"maxZoom"});
args::ValueFlag<double> pixelRatioValue(argumentParser, "number", "Pixel ratio", {"pixelRatio"});
args::ValueFlag<bool> includeIdeographsValue(argumentParser, "boolean", "Include CJK glyphs", {"includeIdeographs"});
ChrisLoer marked this conversation as resolved.
Show resolved Hide resolved

try {
argumentParser.ParseCLI(argc, argv);
Expand All @@ -127,6 +128,7 @@ int main(int argc, char *argv[]) {
const double minZoom = minZoomValue ? args::get(minZoomValue) : 0.0;
const double maxZoom = maxZoomValue ? args::get(maxZoomValue) : 15.0;
const double pixelRatio = pixelRatioValue ? args::get(pixelRatioValue) : 1.0;
const bool includeIdeographs = includeIdeographsValue ? args::get(includeIdeographsValue) : false;
const std::string output = outputValue ? args::get(outputValue) : "offline.db";

using namespace mbgl;
Expand All @@ -136,7 +138,7 @@ int main(int argc, char *argv[]) {
try {
std::string json = readFile(geometryValue.Get());
auto geometry = parseGeometry(json);
return OfflineRegionDefinition{ OfflineGeometryRegionDefinition(style, geometry, minZoom, maxZoom, pixelRatio) };
return OfflineRegionDefinition{ OfflineGeometryRegionDefinition(style, geometry, minZoom, maxZoom, pixelRatio, includeIdeographs) };
} catch(const std::runtime_error& e) {
std::cerr << "Could not parse geojson file " << geometryValue.Get() << ": " << e.what() << std::endl;
exit(1);
Expand All @@ -148,7 +150,7 @@ int main(int argc, char *argv[]) {
const double south = southValue ? args::get(southValue) : 38.1;
const double east = eastValue ? args::get(eastValue) : -121.7;
LatLngBounds boundingBox = LatLngBounds::hull(LatLng(north, west), LatLng(south, east));
return OfflineRegionDefinition{ OfflineTilePyramidRegionDefinition(style, boundingBox, minZoom, maxZoom, pixelRatio) };
return OfflineRegionDefinition{ OfflineTilePyramidRegionDefinition(style, boundingBox, minZoom, maxZoom, pixelRatio, includeIdeographs) };
}
}();

Expand Down
6 changes: 4 additions & 2 deletions include/mbgl/storage/offline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ class TileID;
*/
class OfflineTilePyramidRegionDefinition {
public:
OfflineTilePyramidRegionDefinition(std::string, LatLngBounds, double, double, float);
OfflineTilePyramidRegionDefinition(std::string, LatLngBounds, double, double, float, bool);

/* Private */
const std::string styleURL;
const LatLngBounds bounds;
const double minZoom;
const double maxZoom;
const float pixelRatio;
const bool includeIdeographs;
};

/*
Expand All @@ -52,14 +53,15 @@ class OfflineTilePyramidRegionDefinition {
*/
class OfflineGeometryRegionDefinition {
public:
OfflineGeometryRegionDefinition(std::string styleURL, Geometry<double>, double minZoom, double maxZoom, float pixelRatio);
OfflineGeometryRegionDefinition(std::string styleURL, Geometry<double>, double minZoom, double maxZoom, float pixelRatio, bool includeIdeographs);

/* Private */
const std::string styleURL;
const Geometry<double> geometry;
const double minZoom;
const double maxZoom;
const float pixelRatio;
const bool includeIdeographs;
};

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
* tiles from minZoom up to the maximum zoom level provided by that source.
* <p>
* pixelRatio must be ≥ 0 and should typically be 1.0 or 2.0.
* <p>
* if includeIdeographs is false, offline region will not include CJK glyphs
*/
public class OfflineGeometryRegionDefinition implements OfflineRegionDefinition, Parcelable {

Expand All @@ -35,6 +37,23 @@ public class OfflineGeometryRegionDefinition implements OfflineRegionDefinition,
private double maxZoom;
@Keep
private float pixelRatio;
@Keep
private boolean includeIdeographs;

/**
* Constructor to create an OfflineGeometryRegionDefinition from parameters.
*
* @param styleURL the style
* @param geometry the geometry
* @param minZoom min zoom
* @param maxZoom max zoom
* @param pixelRatio pixel ratio of the device
*/
@Keep
public OfflineGeometryRegionDefinition(
String styleURL, Geometry geometry, double minZoom, double maxZoom, float pixelRatio) {
this(styleURL, geometry, minZoom, maxZoom, pixelRatio, true);
}

/**
* Constructor to create an OfflineGeometryRegionDefinition from parameters.
Expand All @@ -44,16 +63,19 @@ public class OfflineGeometryRegionDefinition implements OfflineRegionDefinition,
* @param minZoom min zoom
* @param maxZoom max zoom
* @param pixelRatio pixel ratio of the device
* @param includeIdeographs include glyphs for CJK languages
*/
@Keep
public OfflineGeometryRegionDefinition(
String styleURL, Geometry geometry, double minZoom, double maxZoom, float pixelRatio) {
String styleURL, Geometry geometry, double minZoom, double maxZoom, float pixelRatio,
boolean includeIdeographs) {
// Note: Also used in JNI
this.styleURL = styleURL;
this.geometry = geometry;
this.minZoom = minZoom;
this.maxZoom = maxZoom;
this.pixelRatio = pixelRatio;
this.includeIdeographs = includeIdeographs;
}

/**
Expand Down Expand Up @@ -110,6 +132,11 @@ public float getPixelRatio() {
return pixelRatio;
}

@Override
public boolean getIncludeIdeographs() {
return includeIdeographs;
}

@NonNull
@Override
public String getType() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,20 @@ public interface OfflineRegionDefinition {
float getPixelRatio();

/**
* Gest the type of the OfflineRegionDefinition for telemetry ("tileregion", "shaperegion").
* Specifies whether to include ideographic glyphs in downloaded font data.
* Ideographic glyphs make up the majority of downloaded font data, but
* it is possible to configure the renderer to use locally installed fonts
* instead of relying on fonts downloaded as part of the offline pack.
*
* Defaults to `true`
*
* @return true if offline region will include ideographic glyphs
* @see MapboxMapOptions localIdeographFontFamily
*/
boolean getIncludeIdeographs();

/**
* Gets the type of the OfflineRegionDefinition for telemetry ("tileregion", "shaperegion").
*
* @return The type of the OfflineRegionDefinition.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
* tiles from minZoom up to the maximum zoom level provided by that source.
* <p>
* pixelRatio must be &#x2265; 0 and should typically be 1.0 or 2.0.
* <p>
* if includeIdeographs is false, offline region will not include CJK glyphs
*/
public class OfflineTilePyramidRegionDefinition implements OfflineRegionDefinition, Parcelable {

Expand All @@ -31,6 +33,23 @@ public class OfflineTilePyramidRegionDefinition implements OfflineRegionDefiniti
private double maxZoom;
@Keep
private float pixelRatio;
@Keep
private boolean includeIdeographs;

/**
* Constructor to create an OfflineTilePyramidDefinition from parameters.
*
* @param styleURL the style
* @param bounds the bounds
* @param minZoom min zoom
* @param maxZoom max zoom
* @param pixelRatio pixel ratio of the device
*/
@Keep
public OfflineTilePyramidRegionDefinition(
String styleURL, LatLngBounds bounds, double minZoom, double maxZoom, float pixelRatio) {
this(styleURL, bounds, minZoom, maxZoom, pixelRatio, true);
}

/**
* Constructor to create an OfflineTilePyramidDefinition from parameters.
Expand All @@ -40,16 +59,19 @@ public class OfflineTilePyramidRegionDefinition implements OfflineRegionDefiniti
* @param minZoom min zoom
* @param maxZoom max zoom
* @param pixelRatio pixel ratio of the device
* @param includeIdeographs include glyphs for CJK languages
*/
@Keep
public OfflineTilePyramidRegionDefinition(
String styleURL, LatLngBounds bounds, double minZoom, double maxZoom, float pixelRatio) {
String styleURL, LatLngBounds bounds, double minZoom, double maxZoom, float pixelRatio,
boolean includeIdeographs) {
// Note: Also used in JNI
this.styleURL = styleURL;
this.bounds = bounds;
this.minZoom = minZoom;
this.maxZoom = maxZoom;
this.pixelRatio = pixelRatio;
this.includeIdeographs = includeIdeographs;
}

/**
Expand Down Expand Up @@ -94,6 +116,11 @@ public float getPixelRatio() {
return pixelRatio;
}

@Override
public boolean getIncludeIdeographs() {
return includeIdeographs;
}

@NonNull
@Override
public String getType() {
Expand Down
18 changes: 12 additions & 6 deletions platform/android/src/offline/offline_region_definition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ mbgl::OfflineRegionDefinition OfflineRegionDefinition::getDefinition(JNIEnv& env

jni::Local<jni::Object<OfflineRegionDefinition>> OfflineTilePyramidRegionDefinition::New(jni::JNIEnv& env, const mbgl::OfflineTilePyramidRegionDefinition& definition) {
static auto& javaClass = jni::Class<OfflineTilePyramidRegionDefinition>::Singleton(env);
static auto constructor = javaClass.GetConstructor<jni::String, jni::Object<LatLngBounds>, jni::jdouble, jni::jdouble, jni::jfloat>(env);
static auto constructor = javaClass.GetConstructor<jni::String, jni::Object<LatLngBounds>, jni::jdouble, jni::jdouble, jni::jfloat, jni::jboolean>(env);

return javaClass.New(env, constructor,
jni::Make<jni::String>(env, definition.styleURL),
LatLngBounds::New(env, definition.bounds),
definition.minZoom,
definition.maxZoom,
definition.pixelRatio);
definition.pixelRatio,
jni::jboolean(definition.includeIdeographs));
}

mbgl::OfflineTilePyramidRegionDefinition OfflineTilePyramidRegionDefinition::getDefinition(jni::JNIEnv& env, const jni::Object<OfflineTilePyramidRegionDefinition>& jDefinition) {
Expand All @@ -47,13 +48,15 @@ mbgl::OfflineTilePyramidRegionDefinition OfflineTilePyramidRegionDefinition::get
static auto minZoomF = javaClass.GetField<jni::jdouble>(env, "minZoom");
static auto maxZoomF = javaClass.GetField<jni::jdouble>(env, "maxZoom");
static auto pixelRatioF = javaClass.GetField<jni::jfloat>(env, "pixelRatio");
static auto includeIdeographsF = javaClass.GetField<jni::jboolean >(env, "includeIdeographs");

return mbgl::OfflineTilePyramidRegionDefinition(
jni::Make<std::string>(env, jDefinition.Get(env, styleURLF)),
LatLngBounds::getLatLngBounds(env, jDefinition.Get(env, boundsF)),
jDefinition.Get(env, minZoomF),
jDefinition.Get(env, maxZoomF),
jDefinition.Get(env, pixelRatioF)
jDefinition.Get(env, pixelRatioF),
jDefinition.Get(env, includeIdeographsF)
);
}

Expand All @@ -65,14 +68,15 @@ void OfflineTilePyramidRegionDefinition::registerNative(jni::JNIEnv& env) {

jni::Local<jni::Object<OfflineRegionDefinition>> OfflineGeometryRegionDefinition::New(jni::JNIEnv& env, const mbgl::OfflineGeometryRegionDefinition& definition) {
static auto& javaClass = jni::Class<OfflineGeometryRegionDefinition>::Singleton(env);
static auto constructor = javaClass.GetConstructor<jni::String, jni::Object<geojson::Geometry>, jni::jdouble, jni::jdouble, jni::jfloat>(env);
static auto constructor = javaClass.GetConstructor<jni::String, jni::Object<geojson::Geometry>, jni::jdouble, jni::jdouble, jni::jfloat, jni::jboolean>(env);

return javaClass.New(env, constructor,
jni::Make<jni::String>(env, definition.styleURL),
geojson::Geometry::New(env, definition.geometry),
definition.minZoom,
definition.maxZoom,
definition.pixelRatio);
definition.pixelRatio,
jni::jboolean(definition.includeIdeographs));
}

mbgl::OfflineGeometryRegionDefinition OfflineGeometryRegionDefinition::getDefinition(jni::JNIEnv& env, const jni::Object<OfflineGeometryRegionDefinition>& jDefinition) {
Expand All @@ -83,13 +87,15 @@ mbgl::OfflineGeometryRegionDefinition OfflineGeometryRegionDefinition::getDefini
static auto minZoomF = javaClass.GetField<jni::jdouble>(env, "minZoom");
static auto maxZoomF = javaClass.GetField<jni::jdouble>(env, "maxZoom");
static auto pixelRatioF = javaClass.GetField<jni::jfloat>(env, "pixelRatio");
static auto includeIdeographsF = javaClass.GetField<jni::jboolean>(env, "includeIdeographs");

return mbgl::OfflineGeometryRegionDefinition(
jni::Make<std::string>(env, jDefinition.Get(env, styleURLF)),
geojson::Geometry::convert(env, jDefinition.Get(env, geometryF)),
jDefinition.Get(env, minZoomF),
jDefinition.Get(env, maxZoomF),
jDefinition.Get(env, pixelRatioF)
jDefinition.Get(env, pixelRatioF),
jDefinition.Get(env, includeIdeographsF)
);
}

Expand Down
13 changes: 13 additions & 0 deletions platform/darwin/src/MGLOfflineRegion.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic, readonly) NSURL *styleURL;

/**
Specifies whether to include ideographic glyphs in downloaded font data.
Ideographic glyphs make up the majority of downloaded font data, but
it is possible to configure the renderer to use locally installed fonts
instead of relying on fonts downloaded as part of the offline pack.
See `MGLIdeographicFontFamilyName` setting. Also, for regions outside of
China, Japan, and Korea, these glyphs will rarely appear for non-CJK users.

By default, this property is set to `YES`, so that the offline pack will
include ideographic glyphs.
*/
@property (nonatomic) BOOL includesIdeographicGlyphs;

@end

NS_ASSUME_NONNULL_END
23 changes: 17 additions & 6 deletions platform/darwin/src/MGLShapeOfflineRegion.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ @implementation MGLShapeOfflineRegion {
}

@synthesize styleURL = _styleURL;
@synthesize includesIdeographicGlyphs = _includesIdeographicGlyphs;

-(NSDictionary *)offlineStartEventAttributes {
return @{
Expand Down Expand Up @@ -71,14 +72,17 @@ - (instancetype)initWithStyleURL:(NSURL *)styleURL shape:(MGLShape *)shape fromZ
_shape = shape;
_minimumZoomLevel = minimumZoomLevel;
_maximumZoomLevel = maximumZoomLevel;
_includesIdeographicGlyphs = YES;
}
return self;
}

- (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineGeometryRegionDefinition &)definition {
NSURL *styleURL = [NSURL URLWithString:@(definition.styleURL.c_str())];
MGLShape *shape = MGLShapeFromGeoJSON(definition.geometry);
return [self initWithStyleURL:styleURL shape:shape fromZoomLevel:definition.minZoom toZoomLevel:definition.maxZoom];
MGLShapeOfflineRegion* result = [self initWithStyleURL:styleURL shape:shape fromZoomLevel:definition.minZoom toZoomLevel:definition.maxZoom];
result.includesIdeographicGlyphs = definition.includeIdeographs;
return result;
}

- (const mbgl::OfflineRegionDefinition)offlineRegionDefinition {
Expand All @@ -90,7 +94,7 @@ - (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineGeometryRegi
return mbgl::OfflineGeometryRegionDefinition(_styleURL.absoluteString.UTF8String,
_shape.geometryObject,
_minimumZoomLevel, _maximumZoomLevel,
scaleFactor);
scaleFactor, _includesIdeographicGlyphs);
}

- (nullable instancetype)initWithCoder:(NSCoder *)coder {
Expand All @@ -100,7 +104,9 @@ - (nullable instancetype)initWithCoder:(NSCoder *)coder {
double minimumZoomLevel = [coder decodeDoubleForKey:@"minimumZoomLevel"];
double maximumZoomLevel = [coder decodeDoubleForKey:@"maximumZoomLevel"];

return [self initWithStyleURL:styleURL shape:shape fromZoomLevel:minimumZoomLevel toZoomLevel:maximumZoomLevel];
MGLShapeOfflineRegion* result = [self initWithStyleURL:styleURL shape:shape fromZoomLevel:minimumZoomLevel toZoomLevel:maximumZoomLevel];
result.includesIdeographicGlyphs = [coder decodeBoolForKey:@"includesIdeographicGlyphs"];
return result;
}

- (void)encodeWithCoder:(NSCoder *)coder
Expand All @@ -109,10 +115,13 @@ - (void)encodeWithCoder:(NSCoder *)coder
[coder encodeObject:_shape forKey:@"shape"];
[coder encodeDouble:_maximumZoomLevel forKey:@"maximumZoomLevel"];
[coder encodeDouble:_minimumZoomLevel forKey:@"minimumZoomLevel"];
[coder encodeBool:_includesIdeographicGlyphs forKey:@"includesIdeographicGlyphs"];
}

- (id)copyWithZone:(nullable NSZone *)zone {
return [[[self class] allocWithZone:zone] initWithStyleURL:_styleURL shape:_shape fromZoomLevel:_minimumZoomLevel toZoomLevel:_maximumZoomLevel];
MGLShapeOfflineRegion* result = [[[self class] allocWithZone:zone] initWithStyleURL:_styleURL shape:_shape fromZoomLevel:_minimumZoomLevel toZoomLevel:_maximumZoomLevel];
result.includesIdeographicGlyphs = _includesIdeographicGlyphs;
return result;
}

- (BOOL)isEqual:(id)other {
Expand All @@ -127,13 +136,15 @@ - (BOOL)isEqual:(id)other {
return (_minimumZoomLevel == otherRegion->_minimumZoomLevel
&& _maximumZoomLevel == otherRegion->_maximumZoomLevel
&& _shape.geometryObject == otherRegion->_shape.geometryObject
&& [_styleURL isEqual:otherRegion->_styleURL]);
&& [_styleURL isEqual:otherRegion->_styleURL]
&& _includesIdeographicGlyphs == otherRegion->_includesIdeographicGlyphs);
}

- (NSUInteger)hash {
return (_styleURL.hash
+ _shape.hash
+ @(_minimumZoomLevel).hash + @(_maximumZoomLevel).hash);
+ @(_minimumZoomLevel).hash + @(_maximumZoomLevel).hash
+ @(_includesIdeographicGlyphs).hash);
}

@end
Loading