如何在react-native-map中放大/缩小?

问题描述 投票:0回答:7

我正在使用

react-native
构建地图应用程序。我使用的 API 来自此链接:https://github.com/lelandrichardson/react-native-maps

下面是我将地图带到我的应用程序上的代码。我想知道如何在该地图上给出缩放值。以及当用户单击地图上的按钮时如何更改缩放值。

我应该使用什么 Zoom API 来实现此目的?

import React, { Component, StyleSheet, View, TextInput } from "react-native";
import MapView from "react-native-maps";

class MapPage extends Component {
  constructor(props) {
    super(props);
    this.state = {
      region: {
        latitude: 4.21048,
        longitude: 101.97577,
        latitudeDelta: 10,
        longitudeDelta: 5,
      },
    };
  }

  render() {
    return (
      <View style={styles.container}>
        <TextInput style={styles.inputText}>Map</TextInput>
        <MapView
          style={styles.map}
          mapType={"standard"}
          region={this.state.region}
          zoomEnabled={true}
          scrollEnabled={true}
          showsScale={true}
        />
      </View>
    );
  }
}

module.exports = MapPage;

const styles = StyleSheet.create({
  map: {
    position: "absolute",
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
  },
  container: {
    flexDirection: "row",
    justifyContent: "space-between",
    padding: 30,
    flex: 1,
    alignItems: "center",
  },
  inputText: {
    height: 36,
    padding: 4,
    marginRight: 5,
    flex: 4,
    fontSize: 18,
    borderWidth: 1,
    borderColor: "#48BBEC",
    borderRadius: 8,
    color: "#48BBEC",
  },
});

react-native react-native-maps
7个回答
124
投票

您应该使用

animateToRegion
方法(请参阅此处

它需要一个具有

latitudeDelta
longitudeDelta
的区域对象。使用它们来设置缩放级别。

更新:

Region
对象中,
latitude
longitude
指定中心位置,
latitudeDelta
longitudeDelta
指定可视地图区域的跨度。

来自this博客文章的这张图片很好地说明了这一点(LatΔ 和 LngΔ)。


4
投票

新的 React Native Maps API 使您可以选择使用

animateCamera
参数调用
zoom
方法。

    const MapComponent= (props: any) => {
    
    const map: LegacyRef<MapView> = useRef(null);
    
    const onZoomInPress = () => {
        map?.current?.getCamera().then((cam: Camera) => {
            cam.zoom += 1;
            map?.current?.animateCamera(cam);
        });
    };
    
    return (
            <View>
                <MapView
                    ref={map}
                    provider={PROVIDER_GOOGLE}
                    region={region}>
                </MapView>
                <ButtonComponent
                    style={{position: 'absolute', bottom: 400, left: 0}}
                    onPress={onZoomInPress}>
                    Zoom In
                </MainButtonBlue>
            </View>
        );
    }

3
投票

我能够使用

Dimensions.get('window');

完成这项工作
            const window = Dimensions.get('window');
            const { width, height }  = window
            LONGITUDE_DELTA = LATITUD_DELTA + (width / height)

并默认设置

LATITUD_DELTA = 0.0922
。 然后只需使用
onRegionChangeComplete
 中的 
<MapView>

属性更新此值

2
投票
  const handleZoomIn = () => {
    map.current?.getCamera().then((cam: Camera) => {
      if (Platform.OS === 'android') {
        cam.zoom += 1;
      } else {
        cam.altitude /= 2;
      }
      map.current?.animateCamera(cam);
    });
  };

  const handleZoomOut = () => {
    map.current?.getCamera().then((cam: Camera) => {
      if (Platform.OS === 'android') {
        cam.zoom -= 1;
      } else {
        cam.altitude *= 2;
      }
      map.current?.animateCamera(cam);
    });
  };

1
投票

这就是我所做的,而且效果非常好:

function getRegion(origin, destination, zoom) {
  const oLat = Math.abs(origin.latitude);
  const oLng = Math.abs(origin.longitude);
  const dLat = Math.abs(destination.latitude);
  const dLng = Math.abs(destination.longitude);

  return {
      latitude: (origin.latitude + destination.latitude) / 2,
      longitude: (origin.longitude + destination.longitude) / 2,
      latitudeDelta: Math.abs(oLat - dLat) + zoom,
      longitudeDelta: Math.abs(oLng - dLng) + zoom,
  };                                                                                  
}

0
投票

我根据 https://github.com/tuupola/php_google_maps

中的墨卡托数学创建了以下内容

关键函数是

mercatorDegreeDeltas(latitude, longitude, width, height, zoom)
,它返回指定纬度/经度中心点、地图尺寸和缩放级别 (1-20) 的
{ latitudeDelta, longitudeDelta }

import React from 'react';
import { useWindowDimensions } from 'react-native';
import MapView from 'react-native-maps';
import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
import { useHeaderHeight } from '@react-navigation/elements';

const MERCATOR_OFFSET = Math.pow(2, 28);
const MERCATOR_RADIUS = MERCATOR_OFFSET / Math.PI;

function mercatorLatitudeToY(latitude) {
  return Math.round(
    MERCATOR_OFFSET - 
    (
      (
        MERCATOR_RADIUS *
          Math.log(
            (1 + Math.sin(latitude * (Math.PI / 180))) /
            (1 - Math.sin(latitude * (Math.PI / 180)))
          )
      ) / 2
    )
  );
}

function mercatorLongitudeToX(longitude) {
  return Math.round(
    MERCATOR_OFFSET +
      (
        (
          (MERCATOR_RADIUS * longitude) * Math.PI
        ) / 180
      )
  );
}

function mercatorXToLongitude(x) {
  return (
    (
      (x - MERCATOR_OFFSET) / MERCATOR_RADIUS
    ) * 180
  ) / Math.PI;
}

function mercatorYToLatitude(y) {
  return (
    (
      (
        Math.PI / 2
      ) -
        (2 * Math.atan(
              Math.exp(
                (
                  y - MERCATOR_OFFSET
                ) / MERCATOR_RADIUS
              )
            )
        )
    ) * 180
  ) / Math.PI;
}

function mercatorAdjustLatitudeByOffsetAndZoom(latitude, offset, zoom) {
  return mercatorYToLatitude(mercatorLatitudeToY(latitude) + (offset << (21 - zoom)));
}

function mercatorAdjustLongitudeByOffsetAndZoom(longitude, offset, zoom) {
  return mercatorXToLongitude(mercatorLongitudeToX(longitude) + (offset << (21 - zoom)));
}

function mercatorDegreeDeltas(latitude, longitude, width, height, zoom) {

  if (!zoom) {
    zoom = 20;
  }

  const deltaX = width / 2;
  const deltaY = height / 2;

  const northLatitude = mercatorAdjustLatitudeByOffsetAndZoom(latitude, deltaY * -1, zoom);
  const westLongitude = mercatorAdjustLongitudeByOffsetAndZoom(longitude, deltaX * -1, zoom);
  const southLatitude = mercatorAdjustLatitudeByOffsetAndZoom(latitude, deltaY, zoom);
  const eastLongitude = mercatorAdjustLongitudeByOffsetAndZoom(longitude, deltaY, zoom);

  const latitudeDelta = Math.abs(northLatitude - southLatitude);
  const longitudeDelta = Math.abs(eastLongitude - westLongitude);

  return { latitudeDelta, longitudeDelta };
}

// Somewhat arbitrarily, Riverside Park, Independence, KS 67301
const CENTER_UNITED_STATES = {
  latitude: 37.24435373025407,
  longitude: -95.70234410503208,
};

export default function MapViewWrapper() {
  const { width, height } = useWindowDimensions();
  const tabBarHeight = useBottomTabBarHeight();
  const headerHeight = useHeaderHeight();
  const initialRegion = React.useRef(null);
  const availableHeight = height - tabBarHeight - headerHeight;

  // Only calculate initial region once
  if (!initialRegion.current) {
    const { latitudeDelta, longitudeDelta } = mercatorDegreeDeltas(
      CENTER_UNITED_STATES.latitude,
      CENTER_UNITED_STATES.longitude,
      width,
      availableHeight,
      4,
    );
    
    initialRegion.current = {
      latitude: CENTER_UNITED_STATES.latitude,
      longitude: CENTER_UNITED_STATES.longitude,
      latitudeDelta: latitudeDelta,
      longitudeDelta: longitudeDelta,
    };
  }

  return (
    <MapView
      initialRegion={initialRegion.current}
      style={{ width: width, height: availableHeight }}
    />
  );
}

至少存在一个问题:如果将缩放从

4
更改为
3
,它不会正确居中,但较大的缩放值可以工作。我现在不需要较低的缩放值,因此我没有进一步研究数学(可能是某种溢出?)。


-1
投票
//Example of Pinch to Zoom Image in React Native
//https://aboutreact.com/react-native-pinch-to-zoom-image/

//import React in our code
import React from 'react';

//import all the components we are going to use
import { SafeAreaView, StyleSheet, View } from 'react-native';

//import ImageViewer which will help us to zoom Image
import ImageViewer from 'react-native-image-zoom-viewer';

const App = () => {
  const images = [
    {
      url:
        'https://raw.githubusercontent.com/AboutReact/sampleresource/master/sample_img.png',
    },
    {
      url:
        'https://raw.githubusercontent.com/AboutReact/sampleresource/master/old_logo.png',
    },
  ];

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <View style={styles.container}>
        <ImageViewer imageUrls={images} renderIndicator={() => null} />
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    backgroundColor: '#F5FCFF',
    flex: 1,
  },
});

export default App;
© www.soinside.com 2019 - 2024. All rights reserved.