react-native-maps fitToSuppliedMarker/fitToCorodinates未显示所有标记

pgx2nnw8  于 2023-01-21  发布在  React
关注(0)|答案(7)|浏览(144)

我尝试使用简单的MapView并显示2个标记。
它们都正确显示在标测图视图上,但不能同时显示在屏幕上(默认渲染Image 1)
我必须执行手动拖动操作,然后才能在屏幕上看到两个标记。(手动拖动Map后的图像2,以便在屏幕上看到它们)
我尝试使用fitToSuppliedMarkers/fitToCoordinates,但似乎没有任何效果。

export default class FavItemMapView extends Component{

constructor(props){
    super(props)
    this.state={
        position:{
            latitude:1.286353,
            longitude:103.853067,
            latitudeDelta: 0,
            longitudeDelta: 0,
        },
        error:null
    }
    this.mapRef = null;
}

componentWillMount(){

    const favPlaceLatitude = parseFloat(this.props.navigation.state.params.latitude)
    const favPlaceLongitude = parseFloat(this.props.navigation.state.params.longitude)
    markers.push({latitude:favPlaceLatitude,longitude:favPlaceLongitude});
    navigator.geolocation.getCurrentPosition(
        (position) => {
          console.log("wokeeey" + width + height);
          console.log(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.onRegionChange(initialRegion)
        },
        (error) => this.setState({ error: error.message }),
        { enableHighAccuracy: false, timeout: 200000, maximumAge: 1000 },
      );
}

onRegionChange(region) {
    this.setState({ position:region })
}

componentDidMount(){
    //this.mapRef.fitToSuppliedMarkers(markerIDs,true);
    const favPlaceLatitude = parseFloat(this.props.navigation.state.params.latitude)
    const favPlaceLongitude = parseFloat(this.props.navigation.state.params.longitude)
    this.mapRef.fitToCoordinates([{latitude:favPlaceLatitude,longitude:favPlaceLongitude}], {
        edgePadding: {
          bottom: 200, right: 50, top: 150, left: 50,
        },
        animated: true,
    });
}

render(){

    const { navigation } = this.props;
    const favPlaceLatitude = parseFloat(navigation.state.params.latitude)
    const favPlaceLongitude = parseFloat(navigation.state.params.longitude)

    return(
        <View style={styles.container}>
            <MapView provider={MapView.PROVIDER_GOOGLE} ref={ref => {this.mapRef = ref;}} style={styles.map} region={this.state.position}>
                {this.state.position.latitude &&
                    <MapView.Marker identifier="Marker2" coordinate={{latitude:this.state.position.latitude,longitude:this.state.position.longitude}} pinColor="red"/>
                }
                {this.state.position.longitude &&
                    <MapView.Marker identifier="Marker1" coordinate={{latitude:favPlaceLatitude,longitude:favPlaceLongitude}} pinColor="green"/>
                }
            </MapView>
        </View>
    );
  }
}

const styles={
  container:{
    ...StyleSheet.absoluteFillObject,
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  map:{
    padding:100,
    ...StyleSheet.absoluteFillObject
  }
}

你能有人建议什么是错的吗?附上模拟器图像供参考。x1c 0d1xx 1c 1d 1x

2nbm6dog

2nbm6dog1#

<MapView
    provider={MapView.PROVIDER_GOOGLE}
    ref={map => {this.map = map}}
    style={{ flex: 1 }}
    initialRegion={{latitude:this.state.request.latitude,
      longitude:this.state.request.longitude,
      latitudeDelta: 0.0922,
      longitudeDelta: 0.0421,}}
    onMapReady={() => {this.map.fitToSuppliedMarkers(['mk1','mk2'],{ edgePadding: 
      {top: 50,
        right: 50,
        bottom: 50,
        left: 50}

    })}}
    >
    <Marker
    image={require('../../../assets/pin.png')}
    coordinate={{latitude:this.state.request.latitude,longitude:this.state.request.longitude}} 
    title='Punto de partida'
    identifier={'mk1'}
    >

    </Marker>

    <Marker
    image={require('../../../assets/pin_final.png')}
    coordinate={{latitude:this.state.request.latitude_destinity,longitude:this.state.request.longitude_destinity}} 
    title='Punto de destino'
    identifier={'mk2'}
>
de90aj5v

de90aj5v2#

因此,根据我使用这个库的经验-我发现最好的经验是利用MapView组件上的onMapReady属性。
https://github.com/react-native-community/react-native-maps/blob/master/docs/mapview.md#events

<MapView
  ...
  onMapReady{() => {
    this.mapRef.fitToCoordinates(...)
  }}
/>

<MapView
  ...
  onMapReady{() => {
    this.mapRef.fitToSuppliedMarkers(...)
  }}
/>

让我知道这是否有帮助,我还在学习它,但这种方法是假设您有现成的标记,您正在传递到您的Map组件渲染。

b4wnujal

b4wnujal3#

在我看来,最好的方法是在iOS中使用fitToElements,在Android中使用fitToSuppliedMarkers(或fitToCoordinates),我的代码结果如下:

import React, { useRef, useCallback } from 'react';
import { Platform } from 'react-native';
import MapView, { PROVIDER_GOOGLE, LatLng, Marker } from 'react-native-maps';

type Props = {
  origin: LatLng;
  destination: LatLng;
}

export default function ({ origin, destination }: Props) {
    const ref = useRef<MapView>(null);

    // effects
    const onMapReadyHandler = useCallback(() => {
      if (Platform.OS === 'ios') {
        ref?.current?.fitToElements(false);
      } else {
        ref?.current?.fitToCoordinates([origin, destination], {
          animated: true,
          edgePadding: {
            top: 150,
            right: 50,
            bottom: 50,
            left: 50,
          },
        });
      }
    }, [ref]);

    // UI
    return (
      <MapView
        style={{ width: '100%', height: '100%' }}
        ref={ref}
        provider={PROVIDER_GOOGLE}
        onMapReady={onMapReadyHandler}
      >
        <Marker coordinate={origin} identifier="origin" />
        <Marker coordinate={destination} identifier="destination" />
      </MapView>
    );
  }
);
des4xlb0

des4xlb04#

这就是我如何将所有标记集中在react native中:

const fitAllMarkers = () => {
map.current.fitToCoordinates(data, {
  edgePadding: {
    top: 20,
    right: 100,
    bottom: 10,
    left: 100,
  },
  animated: true,
});
};

  <MapView
    ref={map}
    provider={PROVIDER_GOOGLE}
    initialRegion={{
      latitude: data[0]?.latitude ,
      longitude: data[0]?.longitude ,
      latitudeDelta: LATITUDE_DELTA,
      longitudeDelta: LONGITUDE_DELTA,
    }}
    onMapReady={fitAllMarkers}
    onMapLoaded={fitAllMarkers}>
    {data?.map((item, ind) => {
      return (
        <Marker
          description={item.address}
          key={ind}
          identifier={`id${ind}`}
          title={item.title}
          coordinate={{
            latitude: item.latitude,
            longitude: item.longitude,
          }}>
          <Image
            source={require('../../../assets/icons/locationPin.png')}
            style={{
              width: wp(10),
              height: wp(10),
              resizeMode: 'contain',
            }}
          />
        </Marker>
      );
    })}
  </MapView>
pobjuy32

pobjuy325#

根据文档,对于方法fitToSuppliedMarkers
如果您需要在ComponentDidMount中使用此功能,请确保将其设置为超时,否则会导致性能问题。注意edgePadding仅适用于Google Maps
fitToCoordinates
如果在android的ComponentDidMount中调用会导致异常,建议在MapView onLayout事件中调用。
这也会导致这些方法无法正确工作,如问题所示。
您需要使用计时器在短时间后调用该方法,以便它工作,如下所示:

<MapView
    onMapReady={() => {
        var i = setInterval(() => { 
            this.mapRef.fitToCoordinates(...);
            clearInterval(i);
        }, 512);
    }}
    ref={(ref) => {
        this.mapRef = ref;
    }}
    ... // rest of MapView props
/>
vdzxcuhz

vdzxcuhz6#

我认为在两个平台上使用fitToSuppliedMarkers最简单的方法是使用inuseEffect Hook沿着setInterval()
在我的情况下工作得很顺利!
检查示例,

useEffect(() => {
    if (!origin || Destination == null) return;

    var i = setInterval(() => {
      console.log("i Before", i);

      mapRef?.current?.fitToSuppliedMarkers(["origin", "destination"], {
        edgePadding: {
          top: 100,
          right: 100,
          left: 100,
          bottom: 100,
          aimated: true,
        },
      });
      clearInterval(i);
      console.log("i After clear interval", i);
    }, 50);
  }, [origin, Destination]);

源代码:

import { StyleSheet, Text, View } from "react-native";
import React, {
  useCallback,
  useEffect,
  useLayoutEffect,
  useRef,
  useState,
} from "react";
import MapView, { Marker } from "react-native-maps";
import tw from "twrnc";
import { useSelector } from "react-redux";
import {
  selectDestination,
  selectOrigin,
} from "../reduxtoolkit/Slices/navSlice";
import MapViewDirections from "react-native-maps-directions";
import { GOOGLE_MAPS_APIKEY, API_URL } from "@env";

const Map = () => {
  const origin = useSelector(selectOrigin);
  const Destination = useSelector(selectDestination);

  // console.log("Origin:", origin);
  // console.log("Destination:", Destination);
  const mapRef = useRef(null);

  useEffect(() => {
    if (!origin || Destination == null) return;

    var i = setInterval(() => {
      console.log("i Before", i);

      mapRef?.current?.fitToSuppliedMarkers(["origin", "destination"], {
        edgePadding: {
          top: 100,
          right: 100,
          left: 100,
          bottom: 100,
          aimated: true,
        },
      });
      clearInterval(i);
      console.log("i After clear interval", i);
    }, 50);
  }, [origin, Destination]);

  return (
    <View style={{ flex: 1 }}>
      <MapView
        ref={mapRef}
        style={tw`flex-1`}
        initialRegion={{
          latitude: origin?.Location?.lat,
          longitude: origin?.Location?.lng,
          latitudeDelta: 0.005,
          longitudeDelta: 0.005,
        }}
        mapType="mutedStandard"
      >
        {origin && Destination && (
          <MapViewDirections
            origin={origin?.Description}
            destination={Destination?.Description}
            apikey={GOOGLE_MAPS_APIKEY}
            strokeWidth={5}
            strokeColor={"black"}
          />
        )}
        {origin?.Location && (
          <Marker
            coordinate={{
              latitude: origin?.Location?.lat,
              longitude: origin?.Location?.lng,
            }}
            title={"Origin"}
            description={origin.Description}
            identifier="origin"
          />
        )}
        {Destination?.Location && (
          <Marker
            coordinate={{
              latitude: Destination?.Location?.lat,
              longitude: Destination?.Location?.lng,
            }}
            title={"Destination"}
            description={Destination.Description}
            identifier="destination"
          />
        )}
      </MapView>
    </View>
  );
};

export default Map;

const styles = StyleSheet.create({});

谢谢!查看完整的项目代码Here

4uqofj5v

4uqofj5v7#

你能检查一下缩放级别吗?Map视图有一个缩放属性可以帮助你。你也可以使用animateToCamera

相关问题