maplibre / flutter-maplibre-gl

Customizable, performant and vendor-free vector and raster maps, flutter wrapper for maplibre-native and maplibre-gl-js (fork of flutter-mapbox-gl/maps)
https://pub.dev/packages/maplibre_gl
Other
226 stars 125 forks source link

[BUG] Symbols with textFields added via the AnnotationManager don't show up on the map when using a custom glpyh source #466

Open kluku opened 5 months ago

kluku commented 5 months ago

Platforms

all

Version of flutter maplibre_gl

0.20.0

Bug Description

Whenever I pass a textField parameter to the SymbolOptions, the related symbol is not visible on the map at all. When I remove textField, it appears correctly with my custom icon. This happens only when I connect to my local maptiler server (http://localhost:3650/api/maps/basic/style.json).

This server is configured in a basic way, as in the documentation. I'm using maptiler-server-map-styles-3.14.1 with the map replaced to British Isles, but that doesn't seem to matter because the map renders correctly.

If I only change a line of code: const styleUrl = 'http://localhost:3650/api/maps/basic/style.json'; to: const styleUrl = 'https://api.maptiler.com/maps/streets-v2/style.json';

then Symbols start showing up with both icons and names.

I've tried to provide fontNames parameters to symbol options and use some fonts that I can find in a subfolder of the maptiler-server-map-styles-3.14.1, like: fontNames: ['Roboto Medium'] (I also tried: 'Noto Sans Regular', 'Roboto Condensed Regular', etc.) but this didn't fix the issue.

Steps to Reproduce

As described above

Expected Results

The Symbols show up with icons and text fields

Actual Results

The Symbols are not visible when the textField parameter is provided

Code Sample

    final annotations = displayedAccounts.where((a) => a.latitude != null && a.longitude != null).map(
      (a) {
        final pos = LatLng(a.latitude ?? 0, a.longitude ?? 0);
        return SymbolOptions(
          geometry: pos,
          iconImage: 'map_marker',
          iconSize: 2,
          // textField: a.name,
          textAnchor: 'top',
          textOffset: const Offset(0, 1.2),
        );
      },
    ).toList();

    final ValueNotifier<MapLibreMapController?> mapController = useState(null);

    ...

    MapLibreMap(
        styleString: '$styleUrl?key=$apiKey',
        myLocationEnabled: true,
        initialCameraPosition: const CameraPosition(
          target: LatLng(51.5285257, -0.2667438),
          zoom: 5,
        ),
        trackCameraPosition: true,
        onMapCreated: (controller) {
          mapController.value = controller;
        },
        onStyleLoadedCallback: () async {
          final byteData = await rootBundle.load('assets/image/map_marker.png');
          final bytes = byteData.buffer.asUint8List();
          await mapController.value!.addImage('map_marker', bytes);
          final symbols = await mapController.value!.addSymbols(annotations);
         },
       ),
       ...    
josxha commented 5 months ago

It's not really possible to reproduce this behavior with the given information. All in all however I'd assume that it's a problem with your style json and not this package. You selected all as platform. Does that mean that you tested this on web, android and ios and it had all the same result?

Some ideas for debugging:

Closing this issue for now. We can reopen it if we get further information that make it possible to reproduce the problem (e.g. the information from my suggested steps).

josxha commented 5 months ago

Related discussion here: https://osmus.slack.com/archives/C05J5FMH7JN/p1718870901513139?thread_ts=1718800634.449629&cid=C05J5FMH7JN

The bug only happens on ios and web, while android works like expected. The SymbolOptions(fontNames: ) parameter doesn't get used on web (and probably iOS too) and defaults to Open Sans Regular,Arial Unicode MS Regular.

https://github.com/maplibre/flutter-maplibre-gl/blob/e84442cb2adf4acab3d59bbacb02d7c66d4c34e1/maplibre_gl/lib/src/annotation_manager.dart#L296-L308

If the map style uses a different glyph source it is not guaranteed that these fonts are available. This shows up as a 404 in the network logs of the dev tools (here for web):

image

JPFrancoia commented 1 week ago

I'm encountering the same issue on web (at least, haven't tried the other platforms yet). I'm using this style string: https://tiles.openfreemap.org/styles/positron (it's free, go ahead, it's from https://openfreemap.org/). I'm getting the same 404 on the font.

EDIT:

Someone had the same problem before: https://github.com/hyperknot/openfreemap/issues/10, in a slightly different situation though. I tried forking and I tried to set the default to Noto Sans Regular, which openfreemap is supposed to support, but I wasn't successful.

Is there a workaround?

JPFrancoia commented 1 week ago

Ok, I found a workaround. It's not pretty. I downloaded the maplibre-gl.js file, and changed this block:

                "text-font": {
                    type: "array",
                    value: "string",
                    default: ["Noto Sans Regular"],
                    requires: ["text-field"],
                    expression: { interpolated: !1, parameters: ["zoom", "feature"] },
                    "property-type": "data-driven",
                },

And I now served this modified file from my index.html file

JPFrancoia commented 1 week ago

Related discussion: https://github.com/maplibre/maplibre-gl-js/issues/4820