100.x replacement for 10.2.5 renderNativeResolution

846
7
03-21-2018 06:33 PM
MarcEtcheverry
New Contributor

I have a data source that has 96DPI 512x512 stiles for street labels.

These look very tiny on retina displays. In 10.2.5 there was a property called renderNativeResolution for tiled maps, setting it to NO managed to work around this issue.

What is the replacement for this in 100.x? Changing scaleSymbols (set to NO by default) after the layer loads does nothing.

Layer is hosted here: ext/SP_CityBM_Labels (MapServer) 

Using AGSArcGISMapImageLayer

0 Kudos
7 Replies
MarkDostal
Esri Contributor

Marc,

Sorry to hear you're having problems.  I tested this here, in the iPhone 8 simulator and on a device, and compared those images to the same data in the ArcGIS.com Map Viewer in Safari.  The results were very similar; the highway shields on the iPhone were slightly smaller that AGOL, but not by much.  An image comparing the two is below.

What device(s) and iOS versions are you seeing the difference on? How does it appear in the simulator?  Is it a slight (~10% difference) or a 2x - 3x difference?

With the 100.x releases, there is no need for the 10.2.x `renderNativeResolution` property, as the resolutions and DPIs are now all handled internally and automatically.

Mark

0 Kudos
MarcEtcheverry
New Contributor

The problem happens at high zoom levels.

Try this polygon

AGSPolygon: [[(1254577.712545, 214993.623308), (1254577.712545, 213410.613883), (1253846.642921, 213410.613883), (1253846.642921, 214993.623308)], sr: 2926], sr: 2926

Here is some sample code on how a base street layer is loaded, and then how the labels are loaded:

AGSLayer *baseLayer = [[AGSArcGISMapImageLayer alloc] initWithURL:[NSURL URLWithString:@"http:/
gisrevprxy.seattle.gov/ArcGIS/rest/services/ext/SP_CityBM_Roads/MapServer/"]];
AGSMap *map = [[AGSMap alloc] initWithBasemap:[AGSBasemap basemapWithBaseLayer:baseLayer]];
self.mapView.map = map;
AGSArcGISMapImageLayer *tiledLayerLabels = [[AGSArcGISMapImageLayer alloc] initWithURL:[NSURL
URLWithString:@"http://gisrevprxy.seattle.gov/ArcGIS/rest/services/ext/SP_CityBM_Labels/MapServer/"]];
tiledLayerLabels.name = NSLocalizedString(@"Labels", nil);
[self.mapView.map.operationalLayers addObject:tiledLayerLabels];‍‍‍‍‍‍‍‍

Then try a similar zoom level on this online site: Seattle Department of Transportation: Seattle Parking Map 

I am not really tied into using that data source for the labels, as the drawings from that ArcGIS are very low quality (no antialiasing and low resolution). If could get a higher quality (perhaps a vector) data source for labels that could be overplayed in that map, it would work well.

0 Kudos
MarkDostal
Esri Contributor

Marc,

I can see that at that zoom level the labels are pretty small.  For comparison, I ran a test app with your data on an iPhone 8 and also loaded a map with the same labels in Safari on the same iPhone 8.  The results are almost identical, so I don't think there's an issue with DPI on Retina displays.  With the 100.x releases we are basically interpreting DIPs the same way that the browser does. That’s the justification for the change from the 100.2.5 behavior.

Safari - ArcGIS.com map viewer

Test app using Runtime SDK for iOS - iPhone 8

Let us know if there's anything else we can help with.

Mark

0 Kudos
MarcEtcheverry
New Contributor

Yes, I see. But on the website that also uses ArcGIS (though perhaps an old version), they manage to have easily visible labels even at very zoomed resolutions. Is there a way to achieve this with the SDK? 

1) If you examine the requests that are made asynchronously, perhaps they are requesting something different from the ArcGIS server than the iOS SDK does? Is there any way to make the ArcGIS iOS SDK match that behavior so I get bigger labels?

Seattle Department of Transportation: Seattle Parking Map 

2) Another possible solution is using another data set for labels, like this https://developer.here.com/documentation/map-tile/topics/resource-base-lltile.html.

To achieve this I will create a map with a Web Mercator Spatial Reference, then add the Seattle WKID 2926 baseman, and then add the tile as a reference layer.

Some problems with this arise:

A) Obviously there labels are worldwide, while my map data is only for the state of Washington. Is there any way to restrict the drawing of the labels to a specific extent?

B) How exactly do I create the levelsOfDetails resolution and scale? All I know is that HERE maps provides 20 levels. I know I can pass in an array of AGSLevelOfDetail, but I am unsure on how to give the proper resolution and scale, so I am just passing in whatever OSM does right now.

C) Is it possible to get a vector based label layer from ArcGIS? AGSBasemap imageryWithLabelsVectorBasemap obviously has a AGSArcGISVectorTiledLayer reference layer

NSString *template = [NSString stringWithFormat:@"https://{subDomain}.base.maps.cit.api.here.com/maptile/2.1/labeltile/newest/normal.day.mobile/{level}/{col}/{row}/256/png?app_id=%@&app_code=%@&ppi=250&lg=eng", APIKeyHereAppID, APIKeyHereAppCode];
AGSSpatialReference *spatialReference = [AGSSpatialReference webMercator];
AGSPoint *origin = [AGSPoint pointWithX:-20037508.342789
                                      y:20037508.368847
                       spatialReference:spatialReference];

NSArray *levelsOfDetail = [[((AGSWebTiledLayer *)[[[AGSBasemap openStreetMapBasemap] baseLayers] firstObject]) tileInfo] levelsOfDetail];
AGSTileInfo *tileInfo = [AGSTileInfo tileInfoWithDPI:250
                                              format:AGSTileImageFormatPNG
                                      levelsOfDetail:levelsOfDetail
                                              origin:origin
                                    spatialReference:spatialReference
                                          tileHeight:256
                                           tileWidth:256];

AGSEnvelope *fullExtent = [AGSEnvelope envelopeWithXMin:-20037508.342789
                                                   yMin:-20037471.205137
                                                   xMax:20037285.703808
                                                   yMax:20037471.205137
                                       spatialReference:spatialReference];

AGSLayer *streetLabelsLayer = [[AGSWebTiledLayer alloc] initWithURLTemplate:template
                                                                 subDomains:@[@"1", @"2", @"3", @"4"]
                                                                   tileInfo:tileInfo
                                                                 fullExtent:fullExtent];
streetLabelsLayer.name = NSLocalizedString(@"Street Labels (HERE Maps)", nil);

AGSLayer *baseLayer = [[AGSArcGISMapImageLayer alloc] initWithURL:[NSURL URLWithString:@"https://gisrevprxy.seattle.gov/ArcGIS/rest/services/ext/SP_CityBM_Roads/MapServer/"]];
AGSLayer *linesLayer = [[AGSArcGISMapImageLayer alloc] initWithURL:[NSURL URLWithString:@"https://gisrevprxy.seattle.gov/ArcGIS/rest/services/SDOT_EXT/sdot_parking/MapServer/"]];

AGSBasemap *basemap = [AGSBasemap basemapWithBaseLayers:@[baseLayer]
                                        referenceLayers:@[linesLayer, streetLabelsLayer]];

// Possible bug: You must init your map with a spatial reference, otherwise initing it with the basemap won't display the streetLabelsLayer!
self.mapView.map = [[AGSMap alloc] initWithSpatialReference:[AGSSpatialReference webMercator]];
self.mapView.map.basemap = basemap;‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
MarkDostal
Esri Contributor

Marc,

I opened up the Seattle Parking Map on an iPhone 8 and at similar zoom levels the labels looked the same as in a test app build with the SDK and in ArcGIS.com (in Safari).  So I don't think there's any difference with how those three are displaying the labels.  I do not know of a way to increase just the label size, aside from creating a new data set with bigger labels.

If you want to use a third party service for data/labels, take a look at this Sample we provide on GitHub:  arcgis-runtime-samples-ios/arcgis-ios-sdk-samples/Layers/Web tiled layer at master · Esri/arcgis-run... 

It describes the `AGSWebTiledLayer` and "provides a simple way to integrate non-ArcGIS Services as a layer in a map."  It should answer your questions about levels-of-detail.

>> A) Obviously there labels are worldwide, while my map data is only for the state of Washington. Is there any way to restrict the drawing of the labels to a specific extent?

The map will display the entire extent of your base map; if your base map has a limited extent (say the state of Washington), that should limit the map extent to that.  Depending on the data, you might be able to perform a spatial query, only returning data in a given extent (the state of Washington).  Again, if you create a new dataset with larger labels, you would limit the labels shown that way.

>> C) Is it possible to get a vector based label layer from ArcGIS? AGSBasemap imageryWithLabelsVectorBasemap obviously has a AGSArcGISVectorTiledLayer reference layer

AGSBasemap has both "reference layers" and "base layers".  Both of those are arrays of AGSLayer objects, which has an `isVisible` property you can use to control the visibility.  I'm not aware of any layers specific to just labels that we provide.

Mark

0 Kudos
MarcEtcheverry
New Contributor

Hi Mark, thanks for the replies.

1) Is there a tool to visualize extents given a spatial reference? Like an online visualizer, or perhaps some QuickLook debug view implemented on AGSEnvelope?

2) Can you give me an example of how to limit labels to a specific extent in an ArcGIS map? The interface on ArcGIS online does not seem to work for setting an extent.

Say I create a baseman with a base layer of 

https://gisrevprxy.seattle.gov/ArcGIS/rest/services/ext/SP_CityBM_Roads/MapServer/

And then I add my own layer based on a version of http://www.arcgis.com/home/item.html?id=87fcdf91a0f14e4a9fda40a763c6f2b8  in which the style is modified to only show the labels.

I see the tiles from that base server showing the state of WA, but then I still see the labels for the entire world. I am unsure what the actual extent of my base layer is and if I can override it locally from the SDK.

(lldb) po [self.mapView.map.basemap.baseLayers valueForKey:@"fullExtent"]
<__NSSingleObjectArrayI 0x6040000139a0>(
AGSEnvelope: [(664166.810939, -527832.500274), (2636447.251560, 751797.062774)], sr: 2926
)

(lldb) po [self.mapView.map.basemap.referenceLayers valueForKey:@"fullExtent"]
<__NSArrayI 0x6080002329a0>(
AGSEnvelope: [(1244323.815281, 175753.341380), (1299107.043022, 276102.332567)], sr: 2926,
AGSEnvelope: [(-20037507.067162, -20037507.067162), (20037507.067162, 20037507.067162)], sr: 3857
)

Here is the version with my style: http://santusmarc.maps.arcgis.com/home/item.html?id=d2f77489c77b480c9b4a284bb640d966

0 Kudos
MarkDostal
Esri Contributor

> Is there a tool to visualize extents given a spatial reference?

We don't provide a specific API/method to do this, but you can accomplish this by adding an `AGSGraphicOverlay` to the mapView and then adding a new graphic (with a fill symbol) with the extent you want to visualize to the overlay.  That would display the extent in question on the map.  You could also add an attribute to the graphic describing the extent, so that when tapped on (and retrieved via an identify operation), you could display information about the extent.

> Can you give me an example of how to limit labels to a specific extent in an ArcGIS map?

I will need to research this and get back to you.

Mark

0 Kudos