Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to set bounds? #305

Closed
SVITY opened this issue Jul 18, 2016 · 19 comments
Closed

how to set bounds? #305

SVITY opened this issue Jul 18, 2016 · 19 comments

Comments

@SVITY
Copy link

SVITY commented Jul 18, 2016

I get bounds from server api. For example:
{
ne: { lat: 52.6754542, lng: 13.7611175 },
sw: { lat: 52.33962959999999, lng: 13.0891554 },
}
Google Api has fitBounds() method. Unfortunately, I don't understand how do it via this component.
Can I set bounds to map component?

Thx for help

@ryan-hamblin
Copy link

I too am still having trouble with this. I can't see it on the refs for some reason.

@ryan-hamblin
Copy link

@tomchentw I'm assuming that the open source community and yourself are no longer maintaining this library? It's been a few days since I've heard from anyone on these issues. I'm referencing the ref that is set on my google map component and I have no access to any of the methods claimed to be on the refs. Please advise. You're library is the better implementation out there so I'd hate to have to go to a different one in order to have access to some of the built in GMaps methods.

@KensoDev
Copy link

@ryanhca I've had the same issue with the map centering around markers being added.
I started working on setting the bounds and exposing this outside. Check it out here: https://github.com/kensodev/react-google-maps/tree/feature/center-map-markers

@KensoDev
Copy link

I think @tomchentw is no longer maintaining this since there's a message in the README that he's looking for other maintainers.

@evfleet
Copy link

evfleet commented Aug 8, 2016

I found myself able to access the Map instance by throwing a ref on my component and then accessing the map throwing this.refs.whateverYouCalledIt.state.map

I just kind of hacked my way around, not sure if its the best implementation but it might help.

@ryan-hamblin
Copy link

@KensoDev The link you shared takes me to a forked version of this project, I do notice you have a bunch of branches in this fork, but I'm curious as to which files you have an example for me in. I don't want to have to poke around the entire app to get what you're talking about. Thanks!

@ryan-hamblin
Copy link

@evfleet That didn't work for me? Where are you throwing "this.refs.foobar.state.map"? in the ComponentDidMount? Render? or any other lifecycle method?

@SirBryan
Copy link

SirBryan commented Aug 31, 2016

I did it in the render method.

Further up in the script, "bounds" is initialized, then extended to contain the Marker's center, and finally extended to include the Polygon's path.

This piece borrows heavily from the front page (Readme) sample, but you can see where I set the map object's bounds once the ref is instantiated (right after logging the object to the console).

return (
                <section style={{height: "100%"}}>
                <GoogleMapLoader
                containerElement={
                    <div
                    {...this.props.containerElementProps}
                    style={{
                            height: "700px",
                            width: "100%"
                        }}
                    />
                }
                googleMapElement={
                    <GoogleMap
                    ref={(map) => { console.log(map); map.fitBounds(bounds); }}
                    zoom={16}
                    center={{ lat: submission.lat), lng: submission.lon }}
                    >
                    <Marker {...markerOut} />
                    <Polygon {...polygonOut} />

                    </GoogleMap>
                }
                />
                </section>
                );

@ryan-hamblin
Copy link

ryan-hamblin commented Aug 31, 2016

This is what I have so far... and I'm getting an error because I believe I have a race condition
let bounds = new google.maps.LatLngBounds(); const {markers} = this.props; bounds.extend(markers[0]);

@SirBryan

@tomchentw
Copy link
Owner

Use the map.fitBounds public method for now.

Also, 6.0.0 is released on npm beta tag now. We also have a new demo page. Feel free to try it:
https://tomchentw.github.io/react-google-maps/

@powerslacker
Copy link

Not sure if this is useful to anyone, but in case someone is looking for the same thing, I found a way to make the map 'fit' whatever container you put it in with a little Javascript hacking.

  1. Use your constructor method on your container to set the center of the map via state
  2. Set a ref on your map in the render method
  3. Create a handleDrag() method and pass it to your component as a prop (this assumes you are using a container for your logic and a component for your presentation)
  4. Inside your presentation component use the onDrag prop to tie your container method to the user dragging the map
  5. In handleDrag() check the lat/long with this.refs.map.yourRef.map.center.lat() or this.refs.yourRef.state.map.center.lng() against your requirements for the map to fit. (Fit via lat/lng - not pixels). If the fit requirement is exceeded then use setState to change the center property to your required bounds.

I'd post more code but it's proprietary :/
Hope this helps!

@tomchentw
Copy link
Owner

Please refer to Getting Help section in the README (or #469).

@psalmdawg
Copy link

psalmdawg commented Nov 5, 2017

did anyone manage to get a working example for using fitBounds with react-google-maps?

@yougotashovel
Copy link

also looking for a way to do this, could there be an example added to the docs?

@jtruzzi
Copy link

jtruzzi commented Dec 17, 2017

I did it this way, hope it helps.

<GoogleMap ref='map'>{markers}</GoogleMap>

and in componentDidUpdate

const bounds = new window.google.maps.LatLngBounds()
this.props.hotels.map((hotel, i) => {
  bounds.extend(new window.google.maps.LatLng(
    hotel.attributes.location.lat,
    hotel.attributes.location.lng
  ));
});
this.refs.map.fitBounds(bounds)

@Wildhoney
Copy link

Wildhoney commented Dec 18, 2017

Thanks @jtruzzi – although I put it all in the render method.

const bounds = new window.google.maps.LatLngBounds();
const coordinates = this.props.locations.map(model => {
    const { latitude, longitude } = model.particulars.location.point;
    const latLng = new window.google.maps.LatLng(latitude, longitude);
    bounds.extend(latLng);
    return latLng;
});

return (
    <GoogleMap
        ref={map => map && map.fitBounds(bounds)}
        defaultZoom={8}
        defaultCenter={{ lat: -34.397, lng: 150.644 }}
        >

        {coordinates.map(({ lat, lng }) => {
            return <Marker key={hash(lat, lng)} position={{ lat: lat(), lng: lng() }} />;
        })}

    </GoogleMap>
);

@vgrem
Copy link

vgrem commented Feb 14, 2018

The example demonstrates how to center viewport for the given markers:

const MapWithAMarkers = compose(
    withProps({
        googleMapURL: "https://maps.googleapis.com/maps/api/js?key=AIzaSyC4R6AN7SmujjPUIGKdyao2Kqitzr1kiRg",
        loadingElement: <div style={{ height: `100%` }} />,
        containerElement: <div style={{ height: `400px` }} />,
        mapElement: <div style={{ height: `100%` }} />,
    }),
    lifecycle({
        componentWillMount() {

            this.setState({

                zoomToMarkers: map => {
                    //console.log("Zoom to markers");
                    const bounds = new window.google.maps.LatLngBounds();
                    map.props.children.forEach((child) => {
                        if (child.type === Marker) {
                            bounds.extend(new window.google.maps.LatLng(child.props.position.lat, child.props.position.lng));
                        }
                    })
                    map.fitBounds(bounds);
                }
            })
        },
    }),
    withScriptjs,
    withGoogleMap
)(props =>
    <GoogleMap ref={props.zoomToMarkers} defaultZoom={5} defaultCenter={{ lat: 25.0391667, lng: 121.525 }}>
        {props.markers.map(marker => (
            <Marker
                key={marker.id}
                position={{ lat: marker.lat, lng: marker.lng }}
            />
        ))}
    </GoogleMap>
    );

Demo

@stevengrimaldo
Copy link

The example demonstrates how to center viewport for the given markers:

const MapWithAMarkers = compose(
    withProps({
        googleMapURL: "https://maps.googleapis.com/maps/api/js?key=AIzaSyC4R6AN7SmujjPUIGKdyao2Kqitzr1kiRg",
        loadingElement: <div style={{ height: `100%` }} />,
        containerElement: <div style={{ height: `400px` }} />,
        mapElement: <div style={{ height: `100%` }} />,
    }),
    lifecycle({
        componentWillMount() {

            this.setState({

                zoomToMarkers: map => {
                    //console.log("Zoom to markers");
                    const bounds = new window.google.maps.LatLngBounds();
                    map.props.children.forEach((child) => {
                        if (child.type === Marker) {
                            bounds.extend(new window.google.maps.LatLng(child.props.position.lat, child.props.position.lng));
                        }
                    })
                    map.fitBounds(bounds);
                }
            })
        },
    }),
    withScriptjs,
    withGoogleMap
)(props =>
    <GoogleMap ref={props.zoomToMarkers} defaultZoom={5} defaultCenter={{ lat: 25.0391667, lng: 121.525 }}>
        {props.markers.map(marker => (
            <Marker
                key={marker.id}
                position={{ lat: marker.lat, lng: marker.lng }}
            />
        ))}
    </GoogleMap>
    );

Demo

this is only helpful if you use Recompose.

@matttk
Copy link

matttk commented Jan 4, 2019

FYI to those who didn't know: there is a onTilesLoaded property on GoogleMap, meaning with a flag, you can have a handler for when the map is first loaded. You need a flag or it will prevent you from panning, since new tiles are always loaded. I'm not sure if this is the best way to do it but it was pretty straightforward anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests