Can not get radius value from Editable Circle onRadiusChanged event - reactjs

I am new to React Google Maps. I'm unable to get radius value from Circle.
https://github.com/JustFly1984/react-google-maps-api
I want to get circle redius onRadiusChanged event.
index.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import Map from './Map';
import './style.css';
const App = () => {
return (
<div>
<Map
googleMapURL="https://maps.googleapis.com/maps/api/js?key=AIzaSyDurZQBXjtSzKeieXwtFeGe-jhZu-HEGQU&libraries=drawing"
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `400px` }} />}
mapElement={<div style={{ height: `100%` }} />}
center={{ lat: -33.8665433, lng: 151.1956316 }}
zoom={15}
/>
</div>
);
};
render(<App />, document.getElementById('root'));
map.js
import React, { Component } from "react";
import {
withScriptjs,
withGoogleMap,
GoogleMap,
Marker,
Circle
} from "react-google-maps";
class MyMapComponent extends Component {
constructor(props) {
super(props);
this.state = {
radius: 50
}
}
updateRadius(e) {
console.log(e);
}
render() {
return (
<GoogleMap
defaultZoom={this.props.zoom}
defaultCenter={this.props.center}
>
<Marker google={this.props.google}
name={'Dolores park'}
draggable={true}
onDragEnd={this.onMarkerDragEnd}
position={this.props.center}
/>
<Circle
center={this.props.center}
options={{
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 1,
fillColor: "#FF0000",
fillOpacity: 0.35,
clickable: false,
draggable: false,
editable: true,
visible: true,
radius: this.state.radius, //Calculation in Meter
zIndex: 1
}}
onRadiusChanged={this.updateRadius}
/>
</GoogleMap>
);
}
}
export default withScriptjs(withGoogleMap(MyMapComponent));
Result -
undefined

onRadiusChanged (as the underlying center_changed event for a Circle class ) event does not accept any arguments. Since onRadiusChanged event handler method is not bound with its component instance in your example, the updated radius could be determined like this:
updateRadius() {
const updatedRadius = this.getRadius();
}
where this refers to native Circle object.

Related

Fontawsome as a custom marker for the react-google-maps/api component?

is there a way to use FA icon for the marker? I use this code sample:
import React, { Component } from 'react';
import { GoogleMap, LoadScript } from '#react-google-maps/api';
const containerStyle = {
width: '400px',
height: '400px'
};
const center = {
lat: -3.745,
lng: -38.523
};
class MyComponents extends Component {
render() {
return (
<LoadScript
googleMapsApiKey="YOUR_API_KEY"
>
<GoogleMap
mapContainerStyle={containerStyle}
center={center}
zoom={10}
>
<Marker
position={center}
icon={'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png'}
/>
</GoogleMap>
</LoadScript>
)
}
}
There is the icon property on the Marker component, but it works like an url, like:
<Marker position={center} icon={'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png'} />
I want to use the FA as a custom marker.
import { IconName } from "react-icons/fa";
Yes, you can use fortaswome icons for marker.
If want to use react-icons, here is how you do that:
import { FaBeer } from "react-icons/fa";
...
<Marker
position={{
lat: 18.559024,
lng: -68.388886
}}
icon={{
path: FaBeer().props.children[0].props.d,
fillColor: "#0000ff",
fillOpacity: 1,
strokeWeight: 1,
strokeColor: "#ffffff",
scale: 0.075
}}
/>
Other option is to use #fortawesome/free-solid-svg-icons.
In that case, code will look something like this:
import { faCoffee } from "#fortawesome/free-solid-svg-icons/faCoffee";
...
<Marker
position={{
lat: 18.559024,
lng: -68.388886
}}
icon={{
path: faCoffee.icon[4],
fillColor: "#0000ff",
fillOpacity: 1,
strokeWeight: 1,
strokeColor: "#ffffff",
scale: 0.075
}}
/>
Source: official documentation
Working example

How do I re-center a GoogleMap React component to a new address using react-google-maps?

I'm rendering a GoogleMap component using the "react-google-maps" library in React. I can set an initial defaultLocation that works fine when the map initially loads. In the documentation it says that the component takes a "center" prop that one can pass a lat and a lng to but I can't get it to re-render/re-center to a new location. It always shows the default location. Any idea what I am doing wrong?
Is there maybe a way how I can use state outside of the addAdressComponent class so I can dynamically set the initial defaultCenter instead of using props in the render section?
import { withGoogleMap, GoogleMap, Marker } from 'react-google-maps';
/*global google*/
const MapWithMarker = withGoogleMap((props) => (
<GoogleMap
defaultZoom={12}
defaultCenter={{ lat: 47.376888, lng: 8.541694 }}
options={{
disableDefaultUI: true,
}}
>
<Marker position={{ lat: 47.376888, lng: 8.541694 }} />
</GoogleMap>
));
class addAddressComponent extends Component {
constructor(props) {
super(props);
this.state = {
lat: 0,
lng: 0,
};
this.onSuggestSelect = this.onSuggestSelect.bind(this);
}
onSuggestSelect(suggest) {
console.log(suggest.location);
this.setState(() => {
return {
lat: 10.0,
lng: 20.022,
};
});
}
render() {
return (
<div className="wrapperClass">
<MapWithMarker
containerElement={<div style={{ height: '244px' }} />}
mapElement={<div style={{ height: '100%' }} />}
className="mapCSS"
center={(this.state.lat, this.state.lng)}
style={{
width: '348px',
height: '250px',
}}
/>
</div>
);
}
}
export default addAddressComponent;
You'll need to pass the center property to your GoogleMap component inside your MapWithMarker component. Also the center argument needs to be an object like this:
{ lat: -34.397, lng: 150.644 }
The following example lets you change the center of the map using the button:
import logo from './logo.svg';
import './App.css';
import { withScriptjs, withGoogleMap, GoogleMap, Marker } from 'react-google-maps';
import {useState} from "react";
const MyMapComponent = withScriptjs(withGoogleMap((props) =>
<GoogleMap
defaultZoom={13}
center={props.center}
defaultCenter={{ lat: -34.397, lng: 150.644 }}
>
{props.isMarkerShown && <Marker position={{ lat: -34.397, lng: 150.644 }} />}
</GoogleMap>
))
function App() {
const [position, setPosition] = useState({ lat: -34.397, lng: 150.644 });
return (
<div className="App">
<button onClick={() => setPosition({lat: 30, lng: 10})}>,
Click me
</button>
<MyMapComponent
isMarkerShown
googleMapURL="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places"
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `100%` }} />}
center={position}
mapElement={<div style={{ height: `1000px`}} />}
/>
</div>
);
}
export default App;

How to make a moving marker like Uber cars?

I create a marker like this:
import React from "react";
import config from 'config';
import { compose, withProps, withState, lifecycle } from "recompose";
import {
withScriptjs,
withGoogleMap,
GoogleMap,
Marker,
DirectionsRenderer,
Polyline,
} from "react-google-maps";
const googleApiKey = config.googleApiKey;
const HistoryView = compose(
withProps({
googleMapURL: `https://maps.googleapis.com/maps/api/js?key=${googleApiKey}&v=3.exp&libraries=geometry,drawing,places`,
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `345px` }} />,
mapElement: <div style={{ height: `100%` }} />,
}),
withState('zoom', 'onZoomChange', 11),
withScriptjs,
withGoogleMap,
lifecycle({
componentDidMount() {
const { historyCords } = this.props;
},
componentWillMount() {
this.setState({
zoomToMarkers: map => {
//console.log("Zoom to markers");
const bounds = new google.maps.LatLngBounds();
map.props.children.forEach((child) => {
if (child.type === Marker) {
bounds.extend(new google.maps.LatLng(child.props.position.lat, child.props.position.lng));
}
})
map.fitBounds(bounds);
}
})
},
})
)(props =>
<GoogleMap
//ref={props.zoomToMarkers}
defaultZoom={8}
defaultCenter={new google.maps.LatLng(props.historyCords[0].latitude, props.historyCords[0].longitude)}
center={new google.maps.LatLng(props.latitude, props.longitude)}
zoom={17}
>
{<Polyline path={props.polylineCords}
geodesic={true}
options={{
strokeColor: "#1e9494",
strokeOpacity: 0.75,
strokeWeight: 2,
icons: [
{
icon: "lineSymbol",
offset: "0",
repeat: "20px"
}
]
}}
/>}
{<Marker
options={{icon: {url: "../../public/images/red-mark.svg", scaledSize: new window.google.maps.Size(30, 62)}}}
position={{ lat: props.latitude, lng: props.longitude }}
onClick={props.onMarkerClick} />
}
</GoogleMap>
);
export { HistoryView };
Now how do I move this marker like a car on location updates?
I use states to update the position of the marker but it doesn't animate. How do I do this?
My issue is when a latlng is updated the marker jumps from one place to another but I want it to move like a car. Have you ever tracked an Uber ride on the web? something like that.
Gif for car animation

Why react-google-maps rendering one Circle component twice?

When I added react-google-maps to project, render worked twice. So I have 2 circles one under another. Also, I display the center coordinates by onDragEnd() method. This event works for only one of this circles.
Any others google maps dosen`t exist on project.
Here is some ways I was trying to fix it:
1) Use only withGoogleMap,
2) Use GoogleMapsWrapper component inside render() method of parent component,
3) Use componentDidMount();
trying everything from satckoverflow :)
and nothing helps.
import React, { Component } from 'react';
import MapForm from './mapForm';
import { GoogleMap, withGoogleMap, withScriptjs, Circle } from 'react-google-maps';
const GoogleMapsWrapper = withScriptjs(withGoogleMap(props => {
const {onMapMounted, ...otherProps} = props;
return <GoogleMap {...otherProps} ref={c => {
onMapMounted && onMapMounted(c)
}}>{props.children}</GoogleMap>
}));
class GoogleMapsContainer extends Component {
state = {
coords: {lat:0, lng: 0}
};
dragCircle = () => {
this.setState({
coords: {
lat: this._circle.getCenter().lat(),
lng: this._circle.getCenter().lng()
}
})
}
render() {
return(
<div style={{display: 'flex',flexDirection: 'row', width: '100%', marginLeft: '37px'}}>
<MapForm
filters={this.props.filters}
coords={this.state.coords}
/>
<GoogleMapsWrapper
googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${KEY}&v=3.exp&libraries=geometry,drawing,places`}
loadingElement={<div style={{height: `100%`}}/>}
containerElement={<div style={{position: 'relative',width: '100%', }} />}
mapElement={<div style={{height: `100%`}}/>}
defaultZoom={13}
defaultCenter={KYIV}
>
<Circle
ref={(circle) => {this._circle = circle}}
defaultCenter = {KYIV}
defaultDraggable={true}
defaultEditable={true}
defaultRadius={2000}
onDragEnd = {this.dragCircle}
options={{
strokeColor: `${colors.vividblue}`,
fillColor: `${colors.vividblue}`,
fillOpacity: 0.1
}}
/>
</GoogleMapsWrapper>
</div>
)
}
}
export default GoogleMapsContainer;
I need only one circle with my methods.mycircles
Ok, the problem was in React StrictMode component in project.

google maps in redux form

i'd like to use google maps for getting lat and long using redux form. I create this:
import React from 'react';
import { compose, withProps, lifecycle } from 'recompose';
import { withScriptjs, withGoogleMap, GoogleMap, Marker } from 'react-google-maps';
const MyMapComponent = compose(
withProps({
googleMapURL:
'https://maps.googleapis.com/maps/api/js?key=AIzaSyCYSleVFeEf3RR8NlBy2_PzHECzPFFdEP0&libraries=geometry,drawing,places',
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `400px` }} />,
mapElement: <div style={{ height: `100%` }} />,
}),
lifecycle({
componentWillMount() {
const refs = {};
this.setState({
position: null,
onMarkerMounted: ref => {
refs.marker = ref;
},
onPositionChanged: () => {
const position = refs.marker.getPosition();
console.log(position.toString());
},
});
},
}),
withScriptjs,
withGoogleMap
)(props => (
<GoogleMap defaultZoom={8} defaultCenter={{ lat: -34.397, lng: 150.644 }}>
{props.isMarkerShown && (
<Marker
position={{ lat: -34.397, lng: 150.644 }}
draggable={true}
ref={props.onMarkerMounted}
onPositionChanged={props.onPositionChanged}
/>
)}
</GoogleMap>
));
class MyParentComponentWrapper extends React.PureComponent {
state = {
isMarkerShown: false,
};
render() {
return (
<div>
<MyMapComponent isMarkerShown={true} />
</div>
);
}
}
export default MyParentComponentWrapper;
But it does not return any values and the does not show the lat and long in the field What should i do? it will console.log the lat and long when user drag the marker
If you want MyMapComponent to return the value to MyParentComponentWrapper just pass a callback function as a prop. Just change the parent component to:
<MyMapComponent isMarkerShown={true} onMakerPositionChanged={this.onMakerPositionChanged}/>
and the map component to:
onPositionChanged: () => {
const position = refs.marker.getPosition();
console.log(position.toString());
this.props.onMakerPositionChanged(position);
},
See working example here

Resources