1

I have the bounds when I move the map, but I have no clue how to get the markers contained with-in those bounds. I do not want to have to use new google.map.... I would like to keep using only React-Google-Map. If that is not possible then I will use the google instance.

I will post my code below. I am console logging out the ref to the google map and the props inside the onChange function.

Props => 

bounds:{nw: {…}, se: {…}, sw: {…}, ne: {…}}
center:{lat: 53, lng: -7.77000000000001}
marginBounds:{nw: {…}, se: {…}, sw: {…}, ne: {…}}
size:{width: 1818, height: 455}
zoom:10
__proto__:Object

Map Ref => GoogleMap {props: {…}, context: {…}, refs: {…}, updater: {…}, _getMinZoom: ƒ, …}

import React, { Component } from 'react';
import GoogleMap from 'google-map-react';

function findMarkerIndex(id, markers) {
  for (let i = markers.length; i--; ) {
    if (markers[i].id === id) {
      return i;
    }
  }
  return null;
}

export default class Map extends Component {
  constructor(props) {
    super(props);
    this.createMapOptions = this.createMapOptions.bind(this);
    this.changeMap = this.changeMap.bind(this);
    this.toggleMarker = this.toggleMarker.bind(this);

    this.state = {
      markers: []
    };
  }

  changeMap(props) {
    console.log(props);
    console.log(this.map);
  }

  toggleMarker(id) {
    const index = findMarkerIndex(id, this.state.markers);
    if (index !== null) {
      const markers = this.state.markers;
      markers[index].show = !markers[index].show;
      this.setState({ markers });
    }
  }

  closeMarker(id) {
    const index = findMarkerIndex(id, this.state.markers);
    if (index !== null) {
      const markers = this.state.markers;
      markers[index].show = false;
      this.setState({ markers });
    }
  }

  createMapOptions(maps) {
    return {
      styles: this.props.styles
    };
  }

  componentDidMount() {
    this.setState({ markers: this.props.markers });
  }

  render() {
    const Marker = this.props.markerComponent;
    const markers = (this.state.markers || []).map(marker => (
      <Marker
        key={marker.id}
        handleMarkerClick={this.toggleMarker}
        handleMarkerClose={this.closeMarker}
        {...marker}
      />
    ));
    return (
      <div
        style={{
          height: this.props.height || '800px',
          width: this.props.width || '100%'
        }}
      >
        <GoogleMap
          ref={ref => {
            this.map = ref;
          }}
          center={this.props.center || { lat: 50, lng: 25 }}
          zoom={this.props.zoom || 8}
          options={this.createMapOptions || {}}
          onChange={this.changeMap}
        >
          {markers}
        </GoogleMap>
      </div>
    );
  }
}
Taylor Austin
  • 5,407
  • 15
  • 58
  • 103

4 Answers4

5

As you control the markers that are being put into the map (this.state.markers), you can simply run .filter() over them using the bounds you have.

const { markers } = this.state;
if (markers) {
  const foundMarkers = markers.filter(marker => {
    if (
      marker.lat > se.lat &&
      sw.lat &&
      (marker.lat < ne.lat && nw.lat) &&
      (marker.lng > nw.lng && sw.lng) &&
      (marker.lng < ne.lng && se.lng)
    ) {
      return marker;
    }
  });
console.log(foundMarkers);

}
Taylor Austin
  • 5,407
  • 15
  • 58
  • 103
AKX
  • 152,115
  • 15
  • 115
  • 172
2

Not sure if this is the "best" way, but I kind of hacked this a little by just using the bounds from the onChange method.

I grabbed each of the bounds and compared them to my marker. I will post what I did and it seems to be working just fine. If it has a flaw please let me know!

changeMap(props) {
    const {
      bounds: { ne, nw, se, sw }
    } = props;
    // east for lng will be greater
    // north for lat will be greater
    const { markers } = this.state;
    if (markers) {
      markers.map(marker => {
        if (
          marker.lat > se.lat &&
          sw.lat &&
          (marker.lat < ne.lat && nw.lat) &&
          (marker.lng > nw.lng && sw.lng) &&
          (marker.lng < ne.lng && se.lng)
        ) {
          console.log(marker);
        }
      });
    }
  }
Taylor Austin
  • 5,407
  • 15
  • 58
  • 103
0

Using Es6 you can get bounds and other map options by passing variables to the changeMap function:

 changeMap = ({ center, zoom, bounds }) => {

    console.log(bounds );
  };
0

In case you have some viewport with type of LatLngBounds you can use method contains(latLng: LatLng | LatLngLiteral): boolean; to check if given LatLng point located in bounds.

Path latLng value of marker to contains(latLng), it return true if point in bounds.

const filteredMarkers = markers.filter((marker) => {
  return bounds.contains(marker.getPosition());
});
Yaroslav Trach
  • 1,833
  • 2
  • 12
  • 18