使用react-native-maps在Android上时,当使用newLatLngBounds(LatLngBounds, int)出现错误:“地图大小不能为零...”。

15

我遇到了一个错误:

"Error using newLatLngBounds(LatLngBounds, int): Map size can't be zero. Most likely layout has not yet occured for the map view. Either wait until layout has occurred or use newLatLngBounds(LatLngBounds, int, int, int) which allows you to specify the map's dimensions".

但是我已经设置了getCurrentPosition的警报,并且从getCurrentPosition()接收到了坐标。

import React, { Component } from 'react';
import { View, Dimensions } from 'react-native';
import MapView from 'react-native-maps';


const {width, height} = Dimensions.get('window')

const SCREEN_HEIGHT = height
const SCREEN_WIDTH = width
const ASPECT_RATIO = width / height
const LATITUDE_DELTA = 0.0922
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO


class Map extends Component {
 
 constructor(props) {
  super(props)

  this.state = {
   isMapReady: false,
   initialPosition: {
    longitude: 0,
    latitude: 0,
    longitudeDelta: 0,
    latitudeDelta: 0
   },

   markerPosition: {
    longitude: 0,
    latitude: 0
   }

  }
 }

 watchID: ?number = null

 componentDidMount() {
  navigator.geolocation.getCurrentPosition((position) => {

   alert(JSON.stringify(position))

   var lat = parseFloat(position.coords.latitude)
   var long = parseFloat(position.coords.longitude)

   var initialRegion = {
    latitude: lat,
    longitude: long,
    latitudeDelta: LATITUDE_DELTA,
    longitudeDelta: LONGITUDE_DELTA
   }

   this.setState({initialPosition: initialRegion})
   this.setState({markerPosition: initialRegion})   
  },

  (error) => alert(JSON.stringify(error)))

  this.watchID = navigator.geolocation.watchPosition((position) => {
   var lat = parseFloat(position.coords.latitude)
   var long = parseFloat(position.coords.longitude)
   
   var lastRegion = {
    latitude: lat,
    longitude: long,
    longitudeDelta: LONGITUDE_DELTA,
    latitudeDelta: LATITUDE_DELTA
   }

   this.setState({initialPosition: lastRegion})
   this.setState({markerPosition: lastRegion})
  })

 }

 componentWillUnmount() {
  navigator.geolocation.clearWatch(this.watchID)
 }

 onMapLayout = () => {
    this.setState({ isMapReady: true });
  }

 render() {

  return (

   <View style={styles.containerStyle}>
    <MapView style={styles.mapStyle} initialRegion={this.state.initialPosition} onLayout={this.onMapLayout}>
     { this.state.isMapReady &&
      <MapView.Marker coordinate={this.state.markerPosition}>
      </MapView.Marker>
     }
    </MapView>
   </View>

   )

 }

}

const styles = {
 containerStyle: {
  flex:1,
  justifyContent: 'center',
  alignItems: 'center',
  backgroundColor: 'lightblue'
 },

 mapStyle: {
  left: 0,
  right: 0,
  top: 0,
  bottom: 0,
  position: 'absolute'
 }

}

export default Map;

老实说,我不知道出了什么问题......真的很感激您的帮助!谢谢!


请查看此 GitHub 问题: https://github.com/react-native-maps/react-native-maps/issues/3154#issuecomment-780740260 - Joshua Pinter
12个回答

11

这是因为地图视图尚未初始化。将调用移动到onMapLoaded覆盖事件中。

在您的内部。
  @Override
    public void onMapReady(GoogleMap googleMap)

添加:

googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
                    @Override
                    public void onMapLoaded() {
                        //Your code where the exception occurred goes here    
                    }
                }); 

5

我解决了!所以我尝试设置mapStyle的宽度和高度,但是它没有起作用,我改变了API密钥,但它仍然没有显示出来,尝试向containerStyle添加“flex:1”但仍然不起作用,直到我传递实际的高度和宽度值到包含我的地图的容器中!


4
在地图样式中,您应该提供屏幕宽度和高度或Flex:1。
mapStyle: {
       width : SCREEN_WIDTH | SomeValue ,
       height : SCREEN_HEIGHT | SomeValue 
    }

2

我曾经遇到过同样的问题,使用 flex: 1 会出错,所以我设置了固定的 width:height:。但这并不理想,我真正需要的是 flex: 1 的灵活性。最终,我使用 minHeight: 替代 height:,使它起到了作用并保留了 flex 的使用。

{
  minHeight: Dimensions.get("window").height - APPROX_HEIGHT_OF_OTHER_ELEMENTS,
  flex: 1,
}

2
我使用了"onMapReady"策略来解决这个问题。每当你渲染一个"polyline"或者"markers"时,请确保你的"MapView"已经加载完成。
原因是:一旦你的"MapView"准备就绪,就可以开始渲染标记。
const { width, height } = Dimensions.get("window");
    class Map extends Component {
    constructor(props) {
        super(props);
        this.state = {
          isMapReady: false
        };
      }
     onMapLayout = () => {
        this.setState({ isMapReady: true });
      };

    render(){
    return(
        <MapView
                  initialRegion={{
                    latitude:"your lat" ,
                    longitude:"your lng" ,
                    latitudeDelta: 0.0922,
                    longitudeDelta: 0.0421
                  }}
                  onMapReady={this.onMapLayout}
                  provider={PROVIDER_GOOGLE}
                  loadingIndicatorColor="#e21d1d"
                  ref={map => (this.map = map)}
                  style={{
                    width,
                    height,
                  }}
                  loadingEnabled={true}
                >
     {this.state.isMapReady && <MapView.Marker
            key="your key"
            identifier="marker"
            coordinate={{
              latitude: "lat",
              longitude: "lng"
            }}
            flat={true}
            anchor={anchor}
            image={image}
          />
         }
          </MapView>
         );
      }
    }

2
我进行了很多研究,寻找解决方案以及为什么会出现这个错误,但是我没有找到任何正确的答案来解释为什么会发生这种情况,也没有进行低级别的测试来理解真正发生的事情,但是通过一些测试,我意识到该组件需要一个绝对大小才能接收动画并进行操作。

因此,为了使地图的大小与视图(我的主页)的大小相对应,我创建了一个父容器用于MapView,该容器具有灵活性,填充可用大小,并通过onLayout属性为MapView提供绝对大小。

下面是一个示例,说明它是如何工作的:

const [mapViewContainerLayout, setMapViewContainerLayout] = useState<LayoutRectangle>();

<View>
   <MapContainer 
     onLayout={(e: LayoutChangeEvent) => {
        setMapViewContainerLayout(e?.nativeEvent?.layout);
     }}>
     {mapVieContainerLayout && (
         <MapView
            ...
            style={{ 
              width: mapViewContainerLayout?.width,
              height: mapViewContainerLayout?.height
            }}
            ...
         </MapView>
     )}
   </MapContainer>
</View>


0
我有一个scrollView作为父组件,但它出了问题,除非我给它高度,否则它将无法工作,但是如果删除父级scrollView,则可以使用flex:1完美地工作。

0

更改 API 密钥。这是显示功能地图的唯一原因。


0
如果您正在使用RawBottomSheet,则需要将minHeight设置为MapView样式中的原始底部表单高度。
  <MapView
        onPress={e => handleMapMarker(e.nativeEvent.coordinate)}
        showsUserLocation={true}
        showsIndoorLevelPicker={false}
        showsBuildings={false}
        ref={mapView}
        provider={PROVIDER_GOOGLE}
        customMapStyle={mapStyle}
        initialRegion={region}
        region={region}
        onMapReady={handleMap}
        loadingEnabled={true}
        loadingIndicatorColor="#e21d1d"
        // showsMyLocationButton={true}
        style={{
          flex: 1,
          minHeight: height * 0.8,
        }}>
        {isMapReady && (
          <MarkerComp
            setMarker={setMarker}
            coordinate={{...marker}}
            handleMapMarker={handleMapMarker}
          />
        )}
      </MapView>

0
在 Kotlin 中,这似乎已经起作用了:
map.setOnMapLoadedCallback {
 map.moveCamera(CameraUpdateFactory.newLatLngBounds(cameraBounds, 0))
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接