nitaliano / react-native-mapbox-gl

A Mapbox GL react native module for creating custom maps
Other
2.16k stars 697 forks source link

StyleURL gives parse error but works on web #1499

Closed sfratini closed 5 years ago

sfratini commented 5 years ago

If I skip the styleURL altogether the map shows fine, but I am trying my custom styles and none of them work. They just show the land and water layers.

I made a copy of the examples in the Mapbox Studio and they work, however as soon as I change something (layer, update a style), it seems to break.

This is my style on the web (I added one layer with the 3D example on the documentation): https://gyazo.com/c61e36811f0cdb0be960b294724dea19

And this is how it looks on the app: screenshot_20190203-163534

The only thing I can see in the adb log is the following:

02-03 16:22:55.409 12817 12817 W mbgl : {x.XXXX.XXXXX}[ParseStyle]: value must be a number

I am using version 6.1.3 and I had to force okhttp to be 3.9.1.

sfratini commented 5 years ago

Actually, it happens with a copy of the basic template so something else is going on:

Mapbox with no style: screenshot_20190203-165804

Mapbox with a copy of the basic template: screenshot_20190203-165710

Also here is the log:

02-03 16:56:34.396 12817 12817 W mbgl    : {x.xxxx.xxxxx}[ParseStyle]: filter expression key must be a string
02-03 16:56:34.396 12817 12817 W mbgl    : {x.xxxx.xxxxx}[ParseStyle]: filter operator must be one of "==", "!=", ">", ">=", "<", "<=", "in", "!in", "all", "any", "none", "has", or "!has"
02-03 16:56:34.396 12817 12817 W mbgl    : {x.xxxx.xxxxx}[ParseStyle]: filter expression key must be a string
02-03 16:56:34.397 12817 12817 W mbgl    : {x.xxxx.xxxxx}[ParseStyle]: filter expression key must be a string
02-03 16:56:34.397 12817 12817 W mbgl    : {x.xxxx.xxxxx}[ParseStyle]: filter operator must be one of "==", "!=", ">", ">=", "<", "<=", "in", "!in", "all", "any", "none", "has", or "!has"
02-03 16:56:34.397 12817 12817 W mbgl    : {x.xxxx.xxxxx}[ParseStyle]: filter expression key must be a string
02-03 16:56:34.397 12817 12817 W mbgl    : {x.xxxx.xxxxx}[ParseStyle]: value must be a number
02-03 16:56:34.397 12817 12817 W mbgl    : {x.xxxx.xxxxx}[ParseStyle]: filter expression key must be a string
02-03 16:56:34.397 12817 12817 W mbgl    : {x.xxxx.xxxxx}[ParseStyle]: filter operator must be one of "==", "!=", ">", ">=", "<", "<=", "in", "!in", "all", "any", "none", "has", or "!has"
02-03 16:56:34.397 12817 12817 W mbgl    : {x.xxxx.xxxxx}[ParseStyle]: filter expression key must be a string
02-03 16:56:34.397 12817 12817 W mbgl    : {x.xxxx.xxxxx}[ParseStyle]: filter expression key must be a string
vieraleonel commented 5 years ago

Hi, I'am having the same problem with custom StyleUrl created in Mapbox Studio: web works react-native don't (both Android and iOS). Land areas are rendered transparent (or black) and water areas seem to be all right.

Basic mapbox styles (street, etc) are working correctly.

react native 55.4 mapbox 6.1.3 (installed vía npm and pods)

image

sfratini commented 5 years ago

@vieraleonel I figured it out. It is due to Mapbox Studio using new sdk features and the RN one using 5.X version. If you select on the right, the compatibility option and select the latest 5.X sdk, you should see some warnings and the things you "cant" use, and those are the ones I was seeing as warnings in my adb logcat, because those were not being parsed.

In my case, I wanted to make the 3D Building example to work, so I had to upload the tileset to mapbox studio but could not use it as a style. I had to make it work with a ShapeResource. It seems that if you have a TileJSON you should use a VectorResource and if you have a GeoJSON (like the one in the 3D Building example), you should use a ShapeResource.

I kinda wished the documentation were a bit more clean on this as I spent 3 days understanding all this and diving through the examples folder.

Here is my code:

MapboxGL.setAccessToken('XXXXXXXXXXXXXXXXXXXXXXX');

const mapStyles = MapboxGL.StyleSheet.create({
  museum: {
    fillExtrusionOpacity: 0.7,
    fillExtrusionHeight: MapboxGL.StyleSheet.identity('height'),
    fillExtrusionBase: MapboxGL.StyleSheet.identity('min_height'),
    fillExtrusionColor: MapboxGL.StyleSheet.identity('color'),  
    fillExtrusionColorTransition: { duration: 2000, delay: 0 },
  }
  });

  const shape = {} //This is NOT supposed to be empty. This is the GeoJSON object where you have the coordinates. I am just stripping it since it is very big;

class Floorplan extends React.Component {

      render(){

          return(
            <View style={{flex: 1}}>

          <MapboxGL.MapView
          showUserLocation={true}
          zoomLevel={this.props.zoomLevel}
          centerCoordinate={this.props.centerCoordinate}
          styleURL={this.props.styleUrl}
          style={{flex: 1}}
          pitch={this.props.pitch}
          heading={this.props.heading}
          scrollEnabled={this.props.scrollEnabled}
          minZoomLevel={this.props.minZoomLevel}
          logoEnabled={this.props.logoEnabled}
          attributionEnabled={this.props.attributionEnabled}
            >
            <MapboxGL.ShapeSource id="customSourceExample" shape={shape}>
            <MapboxGL.FillExtrusionLayer
              id="customSourceFill"
              style={mapStyles.museum}
            />
            </MapboxGL.ShapeSource>
            </MapboxGL.MapView>
            </View>
          );
      }

}

And here it is how it looks: screenshot_20190204-110623

Just remember the Vector accepts "mapbox://" URLs for the tilesets and the Shape DOES NOT. It requires a URL or a shape as a GeoJSON object. This is what I didnt understood at first.

nitaliano commented 5 years ago

@sfratini closing this out since it seems like you got it working. Hopefully one day there is better documentation for this