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

disho6za  于 2022-12-27  发布在  React
关注(0)|答案(6)|浏览(164)

我正在使用react-native构建一个Map应用程序。我正在使用的API来自以下链接:https://github.com/lelandrichardson/react-native-maps.
下面是我把Map放到应用程序上的代码。我想知道如何在Map上设置缩放值。以及当用户单击Map上的按钮时,如何更改缩放值。
我应该使用什么样的缩放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",
  },
});
li9yvcax

li9yvcax1#

您应该使用animateToRegion方法(请参见此处)
它采用一个区域对象,该对象具有latitudeDeltalongitudeDelta。使用这些设置缩放级别。

    • 更新日期:**

Region对象中,latitudelongitude指定中心位置,而latitudeDeltalongitudeDelta指定可视Map区域的跨度。
这张来自this博客文章的图片很好地说明了这一点(Lat Δ和Lng Δ)。

3df52oht

3df52oht2#

新的React Native Maps API为您提供了使用zoom参数调用animateCamera方法的选项。

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>
    );
}
xurqigkl

xurqigkl3#

我可以使用Dimensions.get('window');完成此工作

const window = Dimensions.get('window');
            const { width, height }  = window
            LONGITUDE_DELTA = LATITUD_DELTA + (width / height)

并且默认设置为LATITUD_DELTA = 0.0922。然后只需使用<MapView>中的属性onRegionChangeComplete更新此值

myzjeezk

myzjeezk4#

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

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,
  };                                                                                  
}
fnvucqvd

fnvucqvd5#

我基于https://github.com/tuupola/php_google_maps中的墨卡托数学创建了以下内容
键函数为mercatorDegreeDeltas(latitude, longitude, width, height, zoom),它返回指定纬度/经度中心点、Map尺寸和缩放级别(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,它不能正确居中,但是更大的缩放值可以工作。我现在不需要更小的缩放值,所以我没有进一步研究数学(可能是某种溢出?)

yws3nbqq

yws3nbqq6#

//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;

相关问题