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

[IOS] MGLSymbolStyleLayer text will not display if it contains letters or Numbers #122

Closed
songyuyang0918 opened this issue Dec 31, 2019 · 18 comments
Assignees

Comments

@songyuyang0918
Copy link

songyuyang0918 commented Dec 31, 2019

Platform: iOS
Mapbox SDK version: 5.5.0
Xcode version: Version 10.1 (10B61)
Devicemodels: iPad mini 3

Steps to trigger behavior:

1.I used GEOSwiftMapboxGL to convert the WKT into the pointAnno object of the MapBox through traversal.
2.The pointAnno data is then converted into an MGLPointFeature object and stored in an array.
3.Display the text label by generating MGLShapeSource and MGLSymbolStyleLayer.

屏幕快照 2019-12-20 下午5 45 57

屏幕快照 2019-12-20 下午5 34 49

Expected behavior
Display all text on the map.

Actual behavior
1.When mglshapesource.text = @ "测试" shows,
2.When mglshapesource.text = @ "测试 123" does not display
3.When mglshapesource.text = @ "测试 ABC" is not displayed

and
When text can be displayed, it is displayed at level >12, <12 is not displayed.

//1
71245379-8476fb00-234f-11ea-9112-10283a4f9844

//2,3
71245383-86d95500-234f-11ea-81f9-59a3f2d0efdf

@songyuyang0918
Copy link
Author

And I try to use the expression to manage MGLSymbolStyleLayer textOpacity, still we don't have any effect
屏幕快照 2019-12-31 上午11 40 56

@julianrex
Copy link
Contributor

@songyuyang0918 have you tried this with Android?

/cc @jmkiley

@jmkiley
Copy link
Contributor

jmkiley commented Jan 3, 2020

Hey @songyuyang0918 -

Are you still seeing this issue with 5.6.0? Also, are all of the labels missing in that layer or just some of the labels?

I was able to partially reproduce this issue with the clustering example. When I set numbersLayer.text to NSExpression(format: "mgl_join({'测试', CAST(point_count, 'NSString')})"), some features within that layer did not appear. This also applies when I set the second string to a string written in a Latin script.

I did not notice the same behavior with the equivalent Android example.

@songyuyang0918
Copy link
Author

songyuyang0918 commented Jan 6, 2020

@julianrex I'm just an IOS developer. I'm not good at Android.

@jmkiley
Thank you very much for your testing, my requirements are not on the clustering function, I just want the real label text.
I checked the operation method you used and tested it:
Layer. text = [NSExpression expressionWithFormat:@"mgl_join({' 清远街道很长的测试 ', CAST(point_count, 'NSString')} "];
I can't splicing point_count because I'm using the mglstylstylelayer.
Although the letters and Numbers are still not displayed in the test string, the words "清远街道很长的测试" are displayed comprehensively.
However, the text content of my tag is mutable and is "jiedao" in the geojson property.
I can't understand why when I use layer.text = [NSExpression expressionForKeyPath:@"jiedao"]; This expression, it's not going to show all of that, right?

1578301741621434 2020-01-06 17_15_06

And what do I do when you say "set the second string to be a Latin scripted string"?

@jmkiley
Copy link
Contributor

jmkiley commented Jan 7, 2020

Hi @songyuyang0918 -

Apologies for the confusion. The code in my comment was intended to help other people to reproduce the issue. Since you already are seeing the issue in your own code, you do not need to use the code in my comment.

Can you confirm whether you are seeing the behavior with Maps SDK v5.6.0? Are all labels within the layer missing or just some of the labels?

@jmkiley
Copy link
Contributor

jmkiley commented Jan 7, 2020

Noting that I don't see this issue if I add the following code to the Style symbol layer example in iosapp:

    MGLSymbolStyleLayer *stateLayer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:@"state-label"];
    stateLayer.text = [NSExpression expressionWithFormat:@"mgl_join:({'%@', '测试'})", [NSExpression expressionForKeyPath:@"name"]];
    stateLayer.textAllowsOverlap = [NSExpression expressionForConstantValue:@"true"];
    stateLayer.textColor = [NSExpression expressionForConstantValue:[UIColor redColor]];

@songyuyang0918 - Could you also confirm whether you see this issue when textAllowsOverlap is set to NSExpression expressionForConstantValue:@"true"] in your code?

@songyuyang0918
Copy link
Author

songyuyang0918 commented Jan 8, 2020

@jmkiley Thank you very much for your reply!

For SDK5.6.0 I use cocoapods to display timeout, I will continue to try tomorrow.

  1. I have also set textAllowsOverlap before, but that is not the effect I want. I think when the text conflicts, one of the text should be displayed, instead of two conflicting text not displayed.
  2. As for your expression, it doesn't work for me. I can't see anything.
  3. Text with letters and Numbers still cannot be displayed.

1 figure (test figure using [NSExpression expressionForKeyPath:@"jiedao"])
At level 7: no labels are displayed.
At level 9: displays a tag.
51578475627_ pic_hd
At level 12: successive labels are displayed.
61578475646_ pic_hd
At level 14:
71578475656_ pic_hd
It's like a BUG, and I don't think text conflicts should be left undisplayed.

The corresponding figure 2
layer.text = [NSExpression expressionWithFormat:@"mgl_join({'%@', '测试'})",[NSExpression expressionForKeyPath:@"jiedao"]];
Not for me, my geojson property "jiedao" is a string, and I can only display it through expressionForKeyPath, as shown in figure 1.

The third problem remains.

@jmkiley
Copy link
Contributor

jmkiley commented Jan 13, 2020

Hello @songyuyang0918 -

Could you provide a minimal test case that demonstrates the issue you are seeing? This would help us to investigate the issue.

@songyuyang0918
Copy link
Author

songyuyang0918 commented Jan 14, 2020

@jmkiley
In the process of making the demo, I found the problem.
About label display.
Use the Mapbox's default styleUrl, which displays everything.
Using my own Url, I get the problem I'm describing. Why?

屏幕快照 2020-01-14 下午5 21 59

屏幕快照 2020-01-14 下午5 22 50

Here's the example I created that requires you to add your own AccessToken:
https://pan.baidu.com/s/1j8WFWJWnzV7donCob6Eg2w

@songyuyang0918
Copy link
Author

songyuyang0918 commented Feb 14, 2020

Is there anyone else who can help me with this problem?
@jmkiley Do you have any plans to help me find this problem?

@jmkiley
Copy link
Contributor

jmkiley commented Feb 17, 2020

Hi @songyuyang0918 -

Thank you for your patience. I haven't been able to repro your issue and am unable to download your sample app. Could you share the example via Github? If you are unable to share the sample app via Github, would you be able to send it to Mapbox support with a link to this issue?

@songyuyang0918
Copy link
Author

@jmkiley Thank you very much for your patience. The pods file in my example is too large to share with github. I have sent the problem to Mapbox support.
During the process, I felt that my problem should be in the configuration file of the custom data source:
屏幕快照 2020-05-07 上午11 25 09
My full name in the question is Calm

@ZiZasaurus
Copy link
Contributor

ZiZasaurus commented May 14, 2020

@jmkiley, @1ec5, it appears that if the style json is used as the style source, if the feature being referenced for the MGLSymbolLayer text contains mixed-script, none of the labels will show. However, if the tileset is added instead as a rasterSource over a Mapbox default or custom style, regardless of if the feature contains mixed-script, the labels will show with no issue. I've attached screenshots and the sample project I used to reproduce this below.

tileset url declared in style.json:
Screen Shot 2020-05-14 at 2 58 25 PM

as a rasterSource:
Screen Shot 2020-05-14 at 3 39 12 PM

Link to sample project with access token removed: https://drive.google.com/open?id=1DlwGjT6l42DJn2HA28NQW2Lc-51koIij

Note: if running my example, make sure to comment out the raster source and layer to test the json as a style source by itself. If you're running the example to test the rasterSource, the styleURL will need to be changed from the json or simply removed.

@1ec5
Copy link
Contributor

1ec5 commented May 19, 2020

For clarity, the source.json in the project above is not a source but rather a style. If I understand the discussion above, the issue is that red labels such as “东海街道” and “环西指挥部 abc” appear if the map view is initialized with the Mapbox Streets style and OSM raster tiles are added at runtime, but not if the map view is initialized with a bundled JSON file as the style and that style contains an OSM raster tile layer baked right in.

Running the application results in this console output:

2020-05-19 09:15:58.012913-0700 MGLSymbolStyleLayer Text[10211:2395415] Task <8BF579D6-9380-4FA7-9905-E950CA5CD853>.<8> finished with error [-1002] Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSUnderlyingError=0x6000035bcdb0 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "(null)"}, NSErrorFailingURLStringKey=, NSErrorFailingURLKey=, NSLocalizedDescription=unsupported URL}

The issue is that source.json does not specify a glyphs property, so text cannot be rendered using any remotely rasterized glyphs. By default, CJK glyphs are rendered locally using system fonts, but currently it’s artificially restricted to just CJK characters: mapbox/mapbox-gl-native#7862 (comment). So if a label requires any non-CJK characters, it requires remote glyphs, but source.json doesn’t specify where to get them, so all requests for glyphs fail from then on out.

A typical glyphs value looks like:

{
  "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf"
}

But if you need to load glyph PBFs locally for some reason, it’s also possible to specify something like "foobar://glyphs/{fontstack}/{range}.pbf" and implement -[MGLMapSnapshotterTests offlineStorage:URLForResourceOfKind:withURL:] to redirect that URL to a bundled PBF file:

- (NSURL *)offlineStorage:(MGLOfflineStorage *)storage URLForResourceOfKind:(MGLResourceKind)kind withURL:(NSURL *)url {
    if (kind == MGLResourceKindGlyphs && [url.scheme isEqualToString:@"foobar"]) {
        return [[NSBundle bundleForClass:[self class]] URLForResource:@"glyphs" withExtension:@"pbf"];
    }
    return url;
}

@songyuyang0918
Copy link
Author

@1ec5 The problem has been solved successfully. Thank you for your help!

@songyuyang0918
Copy link
Author

@1ec5 Hello! Is there any way for me to load the PBF directly locally? As for the mglmapsnaptertests you mentioned, I only found the corresponding MGLMapSnapshotter class in 5.5.0. My understanding is to load the offline map.
But now I need to load the online map to achieve the MGLSymbolStyleLayer display.
My clients may not want to get remote glyphs online.
Can I get it locally using file: in a json file?
If yes, for the PBF file specification or download address?
I spent a day going to Google, but the requirements I found were obviously not in line with mine.

@1ec5
Copy link
Contributor

1ec5 commented Jun 8, 2020

#122 (comment) shows how to load the PBF file directly from a local file URL, but we don’t have any documentation on the PBF file’s format or how to create one yourself. But if you’re interested in viewing the map offline, take a look at MGLOfflineStorage and MGLOfflinePack. By adding an offline pack, you’ll end up downloading all the resources required for a given style, including any glyph PBFs that the map would normally fetch from the Mapbox Fonts API.

@1ec5
Copy link
Contributor

1ec5 commented Jun 8, 2020

If you have any questions about offline maps, please contact the Mapbox Support team. I’m closing this issue because there doesn’t seem to be a problem with the runtime styling API per se. Feel free to open separate issues about any bugs or missing features as you integrate offline maps.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants