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

Commit

Permalink
[core] Add DDS support for icon-image
Browse files Browse the repository at this point in the history
  • Loading branch information
jfirebaugh committed Mar 31, 2017
1 parent 743d954 commit 1a9bccb
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 39 deletions.
2 changes: 1 addition & 1 deletion include/mbgl/style/conversion/make_property_setters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ auto makeLayoutPropertySetters() {
result["icon-size"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setIconSize>;
result["icon-text-fit"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<IconTextFitType>, &SymbolLayer::setIconTextFit>;
result["icon-text-fit-padding"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<std::array<float, 4>>, &SymbolLayer::setIconTextFitPadding>;
result["icon-image"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<std::string>, &SymbolLayer::setIconImage>;
result["icon-image"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<std::string>, &SymbolLayer::setIconImage>;
result["icon-rotate"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconRotate>;
result["icon-padding"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setIconPadding>;
result["icon-keep-upright"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconKeepUpright>;
Expand Down
6 changes: 3 additions & 3 deletions include/mbgl/style/layers/symbol_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ class SymbolLayer : public Layer {
PropertyValue<std::array<float, 4>> getIconTextFitPadding() const;
void setIconTextFitPadding(PropertyValue<std::array<float, 4>>);

static PropertyValue<std::string> getDefaultIconImage();
PropertyValue<std::string> getIconImage() const;
void setIconImage(PropertyValue<std::string>);
static DataDrivenPropertyValue<std::string> getDefaultIconImage();
DataDrivenPropertyValue<std::string> getIconImage() const;
void setIconImage(DataDrivenPropertyValue<std::string>);

static DataDrivenPropertyValue<float> getDefaultIconRotate();
DataDrivenPropertyValue<float> getIconRotate() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1595,11 +1595,11 @@ public static PropertyValue<String> iconImage(String value) {
/**
* Name of image in sprite to use for drawing an image background. A string with {tokens} replaced, referencing the data property to pull from.
*
* @param <Z> the zoom parameter type
* @param function a wrapper {@link CameraFunction} for String
* @param <T> the function input type
* @param function a wrapper function for String
* @return property wrapper around a String function
*/
public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> iconImage(CameraFunction<Z, String> function) {
public static <T> PropertyValue<Function<T, String>> iconImage(Function<T, String> function) {
return new LayoutPropertyValue<>("icon-image", function);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,51 @@ public void testIconImageAsCameraFunction() {
}


@Test
public void testIconImageAsIdentitySourceFunction() {
checkViewIsDisplayed(R.id.mapView);
Timber.i("icon-image");
assertNotNull(layer);

// Set
layer.setProperties(
iconImage(property("FeaturePropertyA", Stops.<String>identity()))
);

// Verify
assertNotNull(layer.getIconImage());
assertNotNull(layer.getIconImage().getFunction());
assertEquals(SourceFunction.class, layer.getIconImage().getFunction().getClass());
assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconImage().getFunction()).getProperty());
assertEquals(IdentityStops.class, layer.getIconImage().getFunction().getStops().getClass());
}

@Test
public void testIconImageAsIntervalSourceFunction() {
checkViewIsDisplayed(R.id.mapView);
Timber.i("icon-image");
assertNotNull(layer);

// Set
layer.setProperties(
iconImage(
property(
"FeaturePropertyA",
interval(
stop(1, iconImage("undefined"))
)
)
)
);

// Verify
assertNotNull(layer.getIconImage());
assertNotNull(layer.getIconImage().getFunction());
assertEquals(SourceFunction.class, layer.getIconImage().getFunction().getClass());
assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconImage().getFunction()).getProperty());
assertEquals(IntervalStops.class, layer.getIconImage().getFunction().getStops().getClass());
}

@Test
public void testIconRotateAsConstant() {
checkViewIsDisplayed(R.id.mapView);
Expand Down
14 changes: 12 additions & 2 deletions platform/darwin/src/MGLSymbolStyleLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,18 @@ MGL_EXPORT
You can set this property to an instance of:
* `MGLConstantStyleValue`
* `MGLCameraStyleFunction` with an interpolation mode of
`MGLInterpolationModeInterval`
* `MGLCameraStyleFunction` with an interpolation mode of:
* `MGLInterpolationModeExponential`
* `MGLInterpolationModeInterval`
* `MGLSourceStyleFunction` with an interpolation mode of:
* `MGLInterpolationModeExponential`
* `MGLInterpolationModeInterval`
* `MGLInterpolationModeCategorical`
* `MGLInterpolationModeIdentity`
* `MGLCompositeStyleFunction` with an interpolation mode of:
* `MGLInterpolationModeExponential`
* `MGLInterpolationModeInterval`
* `MGLInterpolationModeCategorical`
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *iconImageName;

Expand Down
6 changes: 3 additions & 3 deletions platform/darwin/src/MGLSymbolStyleLayer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ - (void)setIconIgnorePlacement:(MGLStyleValue<NSNumber *> *)iconIgnorePlacement
- (void)setIconImageName:(MGLStyleValue<NSString *> *)iconImageName {
MGLAssertStyleLayerIsValid();

auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(iconImageName);
auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toDataDrivenPropertyValue(iconImageName);
self.rawLayer->setIconImage(mbglValue);
}

Expand All @@ -249,9 +249,9 @@ - (void)setIconImageName:(MGLStyleValue<NSString *> *)iconImageName {

auto propertyValue = self.rawLayer->getIconImage();
if (propertyValue.isUndefined()) {
return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(self.rawLayer->getDefaultIconImage());
return MGLStyleValueTransformer<std::string, NSString *>().toDataDrivenStyleValue(self.rawLayer->getDefaultIconImage());
}
return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
return MGLStyleValueTransformer<std::string, NSString *>().toDataDrivenStyleValue(propertyValue);
}

- (void)setIconImage:(MGLStyleValue<NSString *> *)iconImage {
Expand Down
7 changes: 1 addition & 6 deletions platform/darwin/test/MGLSymbolStyleLayerTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ - (void)testProperties {

MGLStyleValue<NSString *> *constantStyleValue = [MGLStyleValue<NSString *> valueWithRawValue:@"Icon Image"];
layer.iconImageName = constantStyleValue;
mbgl::style::PropertyValue<std::string> propertyValue = { "Icon Image" };
mbgl::style::DataDrivenPropertyValue<std::string> propertyValue = { "Icon Image" };
XCTAssertEqual(rawLayer->getIconImage(), propertyValue,
@"Setting iconImageName to a constant value should update icon-image.");
XCTAssertEqualObjects(layer.iconImageName, constantStyleValue,
Expand All @@ -158,11 +158,6 @@ - (void)testProperties {
@"Unsetting iconImageName should return icon-image to the default value.");
XCTAssertEqualObjects(layer.iconImageName, defaultStyleValue,
@"iconImageName should return the default value after being unset.");

functionStyleValue = [MGLStyleValue<NSString *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil];
XCTAssertThrowsSpecificNamed(layer.iconImageName = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it");
functionStyleValue = [MGLStyleValue<NSString *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil];
XCTAssertThrowsSpecificNamed(layer.iconImageName = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it");
}

// icon-offset
Expand Down
33 changes: 17 additions & 16 deletions src/mbgl/layout/symbol_layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ namespace mbgl {

using namespace style;

template <class Property>
static bool has(const style::SymbolLayoutProperties::PossiblyEvaluated& layout) {
return layout.get<Property>().match(
[&] (const std::string& s) { return !s.empty(); },
[&] (const auto&) { return true; }
);
}

SymbolLayout::SymbolLayout(const BucketParameters& parameters,
const std::vector<const Layer*>& layers,
const GeometryTileLayer& sourceLayer,
Expand Down Expand Up @@ -72,15 +80,9 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,

layout.get<IconSize>() = leader.layout.evaluate<IconSize>(PropertyEvaluationParameters(zoom + 1));
layout.get<TextSize>() = leader.layout.evaluate<TextSize>(PropertyEvaluationParameters(zoom + 1));

const bool hasTextField = layout.get<TextField>().match(
[&] (const std::string& s) { return !s.empty(); },
[&] (const auto&) { return true; }
);

const bool hasText = !layout.get<TextFont>().empty() && hasTextField;

const bool hasIcon = !layout.get<IconImage>().empty();
const bool hasText = has<TextField>(layout) && !layout.get<TextFont>().empty();
const bool hasIcon = has<IconImage>(layout);

if (!hasText && !hasIcon) {
return;
Expand Down Expand Up @@ -147,7 +149,11 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
}

if (hasIcon) {
ft.icon = util::replaceTokens(layout.get<IconImage>(), getValue);
std::string icon = layout.evaluate<IconImage>(zoom, ft);
if (layout.get<IconImage>().isConstant()) {
icon = util::replaceTokens(icon, getValue);
}
ft.icon = icon;
}

if (ft.text || ft.icon) {
Expand All @@ -165,16 +171,11 @@ bool SymbolLayout::hasSymbolInstances() const {
}

bool SymbolLayout::canPrepare(GlyphAtlas& glyphAtlas) {
const bool hasTextField = layout.get<TextField>().match(
[&] (const std::string& s) { return !s.empty(); },
[&] (const auto&) { return true; }
);

if (hasTextField && !layout.get<TextFont>().empty() && !glyphAtlas.hasGlyphRanges(layout.get<TextFont>(), ranges)) {
if (has<TextField>(layout) && !layout.get<TextFont>().empty() && !glyphAtlas.hasGlyphRanges(layout.get<TextFont>(), ranges)) {
return false;
}

if (!layout.get<IconImage>().empty() && !spriteAtlas.isLoaded()) {
if (has<IconImage>(layout) && !spriteAtlas.isLoaded()) {
return false;
}

Expand Down
6 changes: 3 additions & 3 deletions src/mbgl/style/layers/symbol_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,15 @@ void SymbolLayer::setIconTextFitPadding(PropertyValue<std::array<float, 4>> valu
impl->layout.unevaluated.get<IconTextFitPadding>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-text-fit-padding");
}
PropertyValue<std::string> SymbolLayer::getDefaultIconImage() {
DataDrivenPropertyValue<std::string> SymbolLayer::getDefaultIconImage() {
return IconImage::defaultValue();
}

PropertyValue<std::string> SymbolLayer::getIconImage() const {
DataDrivenPropertyValue<std::string> SymbolLayer::getIconImage() const {
return impl->layout.unevaluated.get<IconImage>();
}

void SymbolLayer::setIconImage(PropertyValue<std::string> value) {
void SymbolLayer::setIconImage(DataDrivenPropertyValue<std::string> value) {
if (value == getIconImage())
return;
impl->layout.unevaluated.get<IconImage>() = value;
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/style/layers/symbol_layer_properties.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ struct IconTextFitPadding : LayoutProperty<std::array<float, 4>> {
static std::array<float, 4> defaultValue() { return {{ 0, 0, 0, 0 }}; }
};

struct IconImage : LayoutProperty<std::string> {
struct IconImage : DataDrivenLayoutProperty<std::string> {
static constexpr const char * key = "icon-image";
static std::string defaultValue() { return ""; }
};
Expand Down

0 comments on commit 1a9bccb

Please sign in to comment.