簡體   English   中英

在 react-google-maps 中按道具居中和縮放?

[英]Center AND zoom by prop in react-google-maps?

我正在構建一個類似於 Zillow 的地圖,其中包含頁面正文中的房地產屬性點,並在頁面標題中進行過濾。

當從外部谷歌地點過濾器中選擇谷歌地點時,我需要的是居中和縮放react-google-maps地圖。 目前我可以在地點選擇上將地圖居中,但不能放大(那是因為我需要在每次放大/縮小時重新獲取數據,所以需要控制縮放,請參見下面的代碼)。

我嘗試從這里使用fitBounds ,但我的代碼中的ref始終undefined

我有基於過濾器獲取點的 API,其參數如下:

  viewPort: {
    northEast: { lat: 57.04834755670983, lng: 24.3255340332031 },
    southWest: { lat: 56.83635114109457, lng: 23.93826596679685 }
  },
  priceMin: 0,
  priceMax: 500,
  propType: "RENT",
  numRooms: 3,
...

在標題部分還有地址過濾器輸入,它具有 Google 位置自動完成功能。 選中后,Google 會提供有關地點的信息:

"geometry" : {
... 

"viewport" : {
  "northeast" : {
    "lat" : 56.95662478029149,
    "lng" : 24.2054917802915
  },
  "southwest" : {
      "lat" : 56.9539268197085,
      "lng" : 24.2027938197085
    }
}
  ...

這是我的Map組件:

import React, { Component } from 'react';

import { compose, withProps, withState, withHandlers } from "recompose";
import {
  withGoogleMap,
  GoogleMap,
  Marker,
} from "react-google-maps";
import { MarkerClusterer } from "react-google-maps/lib/components/addons/MarkerClusterer";

const defaultMapOptions = {
  fullscreenControl: false,
  streetViewControl: false,
};

const PropertyMap = compose(
  withProps({
    loadingElement: <div>Loading...</div>,
    containerElement: <div style={{ height: "500px" }} />,
    mapElement: <div style={{ height: `100%` }} />,
  }),
  withState('zoom', 'onZoomChange', 11),
  withHandlers(() => {
    const refs = {
      map: undefined,
    }

    return {
      onMapMounted: () => ref => {
        refs.map = ref
      },
      onZoomChanged: ({ onZoomChange, onMapBoundsChange }) => () => {
        onZoomChange(refs.map.getZoom())
        onMapBoundsChange(refs.map.getBounds());

      },
      onDragEnd: ({ onMapBoundsChange }) => () => {
        onMapBoundsChange(refs.map.getBounds());
      },
      onMarkerClustererClick: () => (markerClusterer) => {
        const clickedMarkers = markerClusterer.getMarkers()
        console.log(`Current clicked markers length: ${clickedMarkers.length}`)
        console.log(clickedMarkers)
      }
    }
  }),
  withGoogleMap
)(props =>
  <GoogleMap
    defaultCenter={props.defaultCenter ? props.defaultCenter : { lat: 56.9425, lng: 24.1319 }}
    zoom={props.zoom}
    ref={props.onMapMounted}
    onZoomChanged={props.onZoomChanged}
    onDragEnd={props.onDragEnd}
    defaultOptions={defaultMapOptions}
  >
    <MarkerClusterer
      onClick={props.onMarkerClustererClick}
      averageCenter
      enableRetinaIcons
      gridSize={60}
      key={props.mapUid}
    >
      {props.features !== null && props.features.map(feature => {
        const coord = { lng: feature.geometry.coordinates[0], lat: feature.geometry.coordinates[1] };
        return <Marker key={feature.id} position={coord} />;
      })}

    </MarkerClusterer>
  </GoogleMap>
);

export default PropertyMap;

所以我想我想讓在道具中傳遞zoom參數成為可能,如下所示:

<PropertyMap
  mapUid={this.state.mapUid}
  features={this.state.features}
  key={this.state.defaultCenter ? `${this.state.defaultCenter.lat}` : '1'}
  defaultCenter={this.state.defaultCenter}
  defaultZoom={calculateZoomFromViewPort(this.state.viewPort)}
  onMapBoundsChange={this.handleMapBoundsChange}
/>

這樣我可以calculateZoomFromViewPort(this.state.viewPort) ,但是我需要以某種方式將其設置為withState zoom默認值。

所以我需要一些如何將默認縮放值傳遞給withState('zoom', 'onZoomChange', 11) ,(目前11是硬編碼的)。 但我是recompose包的新手,但它是否在react-google-maps包示例中大量使用。

如果您有其他想法,如何根據 Google place 的viewportcenter參數縮放和居中地圖,請分享!

fitbounds()是實現自動縮放的推薦方法。 記住 refs 總是在組件第一次渲染后創建。 我通過添加 fitBounds 對您的代碼進行了更改。 可能很少有語法錯誤,因為我更喜歡使用 react-google-maps,比如基於類的實用程序包裝器。 使用 redux 和組件生命周期更容易管理。 下面是最新的代碼:

import React, { Component } from 'react';

import { compose, withProps, withState, withHandlers } from "recompose";
import {
  withGoogleMap,
  GoogleMap,
  Marker,
} from "react-google-maps";
import { MarkerClusterer } from "react-google-maps/lib/components/addons/MarkerClusterer";

const defaultMapOptions = {
  fullscreenControl: false,
  streetViewControl: false,
};

const PropertyMap = compose(
  withProps({
    loadingElement: <div>Loading...</div>,
    containerElement: <div style={{ height: "500px" }} />,
    mapElement: <div style={{ height: `100%` }} />,
  }),
  withState('zoom', 'onZoomChange', 11),
  withHandlers(() => {
    const refs = {
      map: undefined,
    }

    return {

     onMarkersUpdate: ()=> () => {
     if(refs.map){
      const mapBounds = new google.maps.LatLngBounds();
      //just add markers position into mapBounds
       markers.forEach((marker)=>{
        mapBounds.extend(marker.position)
      });

       this.refs.map.fitBounds(mapBbounds);
       }
     },
      onZoomChanged: ({ onZoomChange, onMapBoundsChange }) => () => {
        onZoomChange(refs.map.getZoom())
        onMapBoundsChange(refs.map.getBounds());

      },
      onDragEnd: ({ onMapBoundsChange }) => () => {
        onMapBoundsChange(refs.map.getBounds());
      },
      onMarkerClustererClick: () => (markerClusterer) => {
        const clickedMarkers = markerClusterer.getMarkers()
        console.log(`Current clicked markers length: ${clickedMarkers.length}`)
        console.log(clickedMarkers)
      }
    }
  }),
  withGoogleMap
)(props =>
  <GoogleMap
    defaultCenter={props.defaultCenter ? props.defaultCenter : { lat: 56.9425, lng: 24.1319 }}
    zoom={props.zoom}
    ref='map'
    onZoomChanged={props.onZoomChanged}
    onDragEnd={props.onDragEnd}
    defaultOptions={defaultMapOptions}
  >
    {props.onMarkersUpdate()}
    <MarkerClusterer
      onClick={props.onMarkerClustererClick}
      averageCenter
      enableRetinaIcons
      gridSize={60}
      key={props.mapUid}
    >
      {props.features !== null && props.features.map(feature => {
        const coord = { lng: feature.geometry.coordinates[0], lat: feature.geometry.coordinates[1] };
        return <Marker key={feature.id} position={coord} />;
      })}

    </MarkerClusterer>
  </GoogleMap>
);

export default PropertyMap;

請隨時對我做出反應。 如果您為此制作一個代碼框。 修復語法錯誤會更容易。 不要錯過fitbounds() 它使我們的事情變得更容易。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM