tangrams/tangram

Tangram tries to load named textures as URLs when provided the material block of a style

warpedgeoid opened this issue ยท 11 comments

TANGRAM VERSION:
0.20.1

ENVIRONMENT:

macOS Catalina w/ Safari

TO REPRODUCE THE ISSUE, FOLLOW THESE STEPS:

  • Reference a named texture in a material, e.g., as follows:
textures:
  named_texture:
    url: images/texture@3x.png
    filtering: mipmap
    density: 3
styles:
    test_style:
      base: polygons
      texcoords: true
      material:
        diffuse:
          texture: named_texture
          mapping: planar
          scale: [0.1, 0.1]

RESULT:

The browser reports failed to load url: 'http://localhost:8000/named_texture' as if it is interpreting the texture name as a filename relative to the style location. The texture is not loaded and doesn't display.

EXPECTED RESULT:

The texture should be resolved from the style and loaded, then displayed as a fill in the polygon.

Hi @warpedgeoid -- thanks for your report. You are right that this is unexpected behavior, but I haven't been able to reproduce it yet. When I try the following sample scene, I get the expected behavior with the texture loading OK. I used the file demos/images/wheel.png included in this repo renamed to demos/images/texture@3x.png to match your example (on the off chance that the @ symbol or something else was affecting behavior); change your API key as needed:

textures:
    named_texture:
        url: images/texture@3x.png
        filtering: mipmap
        density: 3

styles:
    test_style:
      base: polygons
      texcoords: true
      material:
        diffuse:
          texture: named_texture
          mapping: planar
          scale: [0.1, 0.1]

sources:
    tilezen:
        type: MVT
        url: https://tile.nextzen.org/tilezen/vector/v1/512/all/{z}/{x}/{y}.mvt
        tile_size: 512
        max_zoom: 16
        url_params:
            api_key: global.api_key

layers:
    earth:
        data: { source: tilezen }

        labels:
            draw:
                test_style:
                    order: 0
                    color: white

This gives me:

tangram-1583377282116

Do you have a comparable example I could test, perhaps with the exact image you are using? What path are you loading your scene from... there is a lot of URL normalization logic and I wonder if you're hitting an edge case there.

Just confirming that I've seen your response and that I'll try to provide an example this weekend.

I have currently the same issue. This is imho connected with using a rourter library. Type http://localhost:8000/named_texture in your browser and check if your assets are served propery and the image url is not overwritten somehow .

@siloam Iโ€™ll try to do a test and report back.

ENT8R commented

The same thing seems to happen when loading the streetcomplete-mapstyle into Tangram. A reproducible example can be viewed as a webpage at https://ent8r.github.io/streetcomplete-mapstyle/

We are trying to show oneway arrows on oneway streets by using textures. The image path also contains a @ character similar to the one that @warpedgeoid used in his example: https://raw.githubusercontent.com/ENT8R/streetcomplete-mapstyle/jawg/images/oneway_arrow@2x.png

I attached the affected code snippets and where to find them in the source code. Maybe they can help you to find the issue...

Click to view the affected code snippets

roads.yaml

layers:
  roads:
    data: { source: jawg, layer: road }
    filter: { class: [main, street, motorway_link, street_limited, service, driveway, path], not: { type: trunk } }
    draw:
      lines:
        order: 30
         join: round
         cap: round
         color: global.road_color
         width: [[5, 1px], [12, 2px], [16, 5px], [17, 8m]]

    #---- This is where the style is being applied ----#
    oneway:
      filter: { not: { oneway: 0 }, $zoom: { min: 17 } }
      draw:
        oneway-arrow:
          flat: true
          buffer: 2px
          color: global.oneway_arrow_color
          size: [[17, [6px, auto]], [20, [18px, auto]]]
          placement: spaced
          placement_spacing: [[17, 64px], [20, 256px]]
          angle: auto
          text:
            visible: false

styles:
  oneway-arrow:
    base: points
    texture: oneway-arrow

global.yaml

textures:
  oneway-arrow:
    url: https://raw.githubusercontent.com/ENT8R/streetcomplete-mapstyle/jawg/images/oneway_arrow@2x.png
    filtering: mipmap
    density: 5

Just wanted to say I'm actively looking into this at the moment, and sorry for the delay.

To finally follow up here: we traced the issue to cases where a named texture in an imported scene was being interpreted as a URL. This happens when the texture isn't defined in the imported scene where it's referenced, but is defined by an ancestor/importing scene. This has actually been intended, though undocumented, behavior, and you can see reference to it with this workaround in Mapzen's own Refill style:

https://github.com/tangrams/refill-style/blob/a4484a2c07b023738128926bb598607e6de0d1af/themes/terrain-shading.yaml#L13-L17

textures:
    # This texture is defined here so Tangram knows the scene includes a texture with this name
    # This prevents it from otherwies interpreting the texture name as a URL
    # The actual URL for the texture will be set by the included color theme.
    sdk_terrain_texture: {}

However, in discussing the issue, we agreed that this behavior should be changed as there's a reasonable expectation of this pattern working. @matteblair has already addressed this for Tangram ES in tangrams/tangram-es#2201, and the Tangram JS fix is in #770, pending merge and release.

Sorry for the long delay and thank you for the issue! We will close this issue when the fix is included in the next Tangram JS library release.

This is great, thanks!

Added some Differ test cases to cover this and related texture resolution scenarios: tangrams/differ-tests@9821619