I have integrate google maps into my website and i want add a marker with user location. First file is Map.js and second MapContainer.js. In MapContainer.js
in this file I have all the data for map rendering, circle, zoom, API and map dimensions
Sorry for the code format, but this is the second time I'm writing on this community
import React, { Fragment } from "react";
import {
withGoogleMap,
GoogleMap,
withScriptjs,
Marker,
Circle
} from "react-google-maps";
const Map = props => {
return (
< GoogleMap
defaultZoom={props.zoom}
defaultCenter={props.center}
>
{
props.places.map(place => {
return (
< Fragment key={place.id} >
{place.circle && <Circle
defaultCenter={{
lat: parseFloat(place.latitude),
lng: parseFloat(place.longitude)
}}
radius={place.circle.radius}
options={place.circle.options}
/>
}
</Fragment>
);
})
}
</GoogleMap >
);
}
export default withScriptjs(withGoogleMap(Map));
// position = {{ lat: 45.764288, lng: 21.209806 }}
~
import React, { Component } from "react";
import Map from "./Map";
const data = [
{
id: 1,
name: "Zona Verde",
latitude: "45.752814",
longitude: "21.229137"
},
{
id: 2,
name: "Zona Galbena",
latitude: "45.752814",
longitude: "21.229137"
},
{
id: 3,
name: "Zona Rosie",
latitude: "45.752814",
longitude: "21.229137"
},
];
data[0].circle = {
radius: 10000,
options: {
strokeColor: "green",
fillOpacity: "0.1",
fillColor: "green"
}
};
data[1].circle = {
radius: 20000,
options: {
strokeColor: "yellow",
fillColor: "yellow",
fillOpacity: "0.1"
}
};
data[2].circle = {
radius: 30000,
options: {
strokeColor: "red",
fillColor: "red",
fillOpacity: "0.1"
}
};
export default function MapContainer() {
return (
<div>
<Map
style={{ borderRadius: "25px" }}
center={{ lat: 45.764288, lng: 21.209806 }}
zoom={10}
places={data}
googleMapURL="https://maps.googleapis.com/maps/api/js?key=AIzaSyD_6NDZYcE5HDyU9onLOGrsLN2kgW0QIn4"
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `400px` }} />}
mapElement={<div style={{ height: `100%` }} />}
/>
</div>
);
}
Just put Marker component inside GoogleMap the same way like you add circles.
const Map = (props) => {
return (
<GoogleMap defaultZoom={props.zoom} defaultCenter={props.center}>
<Marker position={{ lat: 45.764288, lng: 21.209806 }} />
/* circles */
</GoogleMap>
);
};
Also you can add another prop to Map component and pass marker with other props.
<Map marker={ props.marker } style={ /* etc. */ }/>
//inside GogleMap
<Marker position={ props.marker } />
UPDATE
Use my previous answer but also add new state to MapContainer which will be passed to Map. This state will be user position taken from Geolocalization API.
const Map = (props) => {
return (
<GoogleMap defaultZoom={props.zoom} defaultCenter={props.center}>
<Marker position={{ lat: 45.764288, lng: 21.209806 }} />
/* circles */
</GoogleMap>
);
};
export default function MapContainer() {
const [ marker, setMarker ] = useState(null)
useEffect(() => {
navigator.geolocation.getCurrentPosition(
( location ) => setMarker({
let: location.coords.latitude,
lng: location.coords.longitude
})
)
}, [])
return (
<div>
<Map
marker={ marker }
style={{ borderRadius: "25px" }}
/* etc. */
/>
</div>
);
}
Then you can pass marker as prop to Map.
Related
[here is the image of polygon and I want to add multiple images of solar panel inside the polygon][1]
I want to add multiple small images of solar panel inside polygon on google maps I am using #react-google-maps/api package
import React from "react";
import {
GoogleMap,
DrawingManager,
LoadScript,
Polygon,
OverlayView,
GroundOverlay,
} from "#react-google-maps/api";
import { setRoofSurface } from "../../Features/RoofArea/roofarea.actions";
import { useDispatch, useSelector } from "react-redux";
import { CircularProgress } from "#material-ui/core";
import solar from "../../assest/images/solar.jpg";
export function AreaMap({ coords }) {
const {
OfferEditionCustomer: {
singleCustomer: { location },
},
} = useSelector((state) => state);
const dispatch = useDispatch();
const containerStyle = {
width: "100%",
height: "60%",
};
const drawingOnLoad = (drawingManager) => {
console.log(drawingManager);
};
const onPolygonComplete = (polygon) => {
var area = window.google.maps.geometry.spherical.computeArea(
polygon.getPath()
);
console.log(polygon.getPoints());
const latlng = polygon.latLngs.Rd[0].Rd.map((item) => {
return {
lat: item.lat(),
lng: item.lng(),
};
});
console.log(polygon.latLngs, "polygon");
if (latlng)
dispatch(
setRoofSurface({ name: "coords", value: JSON.stringify(latlng) })
);
dispatch(setRoofSurface({ name: "area", value: area }));
};
const center = {
lat: 40.74,
lng: -74.18,
};
const bounds = {
north: 1.773941,
south: 40.712216,
east: -74.12544,
west: -74.22655,
};
return (
<div>
<LoadScript
id="script-loader"
googleMapsApiKey=""
language={"en"}
region={"EN"}
version={"weekly"}
loadingElement={
<div
style={{
minWidth: "100%",
minHeight: "50vh",
justifyContent: "center",
alignItems: "center",
display: "flex",
}}
>
<CircularProgress />
</div>
}
libraries={["drawing,geometry"]}
>
<GoogleMap
mapContainerStyle={containerStyle}
center={location && JSON.parse(location).latlang}
zoom={20}
mapTypeId="satellite"
>
<DrawingManager
onLoad={drawingOnLoad}
onPolygonComplete={onPolygonComplete}
options={{
drawingControl: true,
drawingControlOptions: {
position: 2,
drawingModes: ["polygon"],
},
}}
/>
<Polygon
draggable={true}
editable={true}
options={{
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
}}
paths={coords && JSON.parse(coords)}
/>
{/* <OverlayView
center={location && JSON.parse(location).latlang}
mapPaneName={OverlayView.MAP_PANE}
>
<div style={{ display: "grid" }}>
{Array(20)
.fill()
.map(() => {
return (
<img
src={solar}
style={{ width: "20px", height: "20px" }}
/>
);
})}
</div>
</OverlayView> */}
</GoogleMap>
</LoadScript>
</div>
);
}
Here we do following.
1.Add a polygon
2.Get the polygon coordinates.
3.Now draw a icon with the marker in the specified coordinates
4.Then it will look like an icon inside the polygon
So here, after adds the polygon, drawn icon with the help of marker in the center place of the polygon.
var bounds = new google.maps.LatLngBounds();
var i, center;
for (i = 0; i < polygonsCoordinates.length; i++) {
bounds.extend(polygonsCoordinates[i]);
}
center = bounds.getCenter();
var image = 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png';
var beachMarker = new google.maps.Marker({
position: { lat: center.lat(), lng: center.lng() },
map: map,
icon: image
});
so like this you can add multiple markers.
hope this answer is helpful to you.
I am currently trying to populate my google map with markers by using the map function. I can't seem to get anything to populate. Are there limitations that I am not understanding or am I missing something? I tried replacing FontAwesomeIcon with something more simple but it doesn't render. If you copy paste FontAwesomeIcon multiple times within the GoogleMapReact component it seems to work but I can't seem to make it work with map. Any suggestions would be much appreciated.
render() {
const {center, zoom} = this.props;
const listingPins = this.props.testList.map((listing, index) => {
console.log(listing);
if (listing.coordinates.lat === null || listing.coordinates.lng === null){
return null
} else{
return <FontAwesomeIcon icon={faHome} size={"2x"} key={index} listing={listing} lat={listing.coordinates.lat} lng={listing.coordinates.lat} />
}
});
console.log("TEST");
console.log(listingPins);
return (
<div style={{ height: '100vh', width: '100%' }}>
<GoogleMapReact
bootstrapURLKeys={{ key: "key" }}
center={center}
zoom={zoom}
>
{listingPins}
</GoogleMapReact>
</div>
);
}
To show multiple markers on map, you have to pass an array of markers to the GoogleMapReact component as a child and map over it.
return (
<div style={{ height: '100vh', width: '100%' }}>
<GoogleMapReact>
{props.listingPins.map(pin => (
<Marker
position={{ lat: pin.latitude, lng: pin.longitude }}
key={pin.id}
/>
))}
</GoogleMapReact>
</div>
);
const createMarker = ({ map, maps }: Mapprops) => {
const markers = props.listingPins.map(data => {
return new maps.Marker({ position: data });
});
};
<GoogleMapReact
bootstrapURLKeys={{ key: "key" }}
center={center}
zoom={zoom}
onGoogleApiLoaded={createMarker}
>
</GoogleMapReact>
This would create the markers for you.
You need to make sure that the data object is in following format :
data: {
lat: number
lng: number
}
I'm facing the same problem.
I followed the answers above but they don't show any markers.
import React from 'react';
import GoogleMapReact, { Marker } from 'google-map-react';
let listingPins=[
{
id: 1,
latitude: 34.052235,
longitude: -118.243683,
shelter: 'Los Angeles'
},
{
id: 2,
latitude: 36.114647,
longitude: -115.172813,
shelter: 'Las Vegas'
},
{
id: 3,
latitude: 33.753746,
longitude: -84.386330,
shelter: 'Atlanta GA'
}
]
const defaultProps = {
center: {
lat: 36.114647,
lng: -115.172813
},
zoom: 10
};
const createMarker = ({ map, maps }: Mapprops) => {
const markers = listingPins.map(data => {
return new maps.Marker({ position: {lat: data.latitude, lng: data.longitude} });
});
};
export default function MainMap() {
return (
<GoogleMapReact
bootstrapURLKeys={{ key: "" }}
center={defaultProps.center}
zoom={defaultProps.zoom}
onGoogleApiLoaded={createMarker}
>
</GoogleMapReact>
)
}
I have played around with the geolocation of javascript. So I created a react component, which shows your current location. I want to visualize this with Google Maps. It works fine so far, but however, if the current position moves outside the start map, the map does not pan. My goal is that the marker is always centered, and the map scrolls.
This is what I have so far. The current position is being passed to the component via the props props.latitude and props.longitude.
UPDATE
Now I know why this is not working.
window.google.maps.Map(document.getElementsByClassName("google-map"))
is not working. It does not find the map this way. So it cannot update its properties.
Anybody an idea how to access the current map?
Here is the code:
import React, {useState,useRef,useCallback} from 'react';
import { compose, withProps } from "recompose"
import { withScriptjs, withGoogleMap, GoogleMap, Marker } from "react-google-maps"
function Map(props) {
const [center, setCenter] = useState({ lat: props.latitude, lng: props.longitude });
const refMap = useRef(null);
const handlePositionChanged = () => {
let position = new window.google.maps.LatLng(parseInt(props.latitude), parseInt(props.longitude));
window.google.maps.Marker(document.getElementsByClassName("google-map-marker")).setPosition(position);
window.google.maps.Map(document.getElementsByClassName("google-map")).setCenter(position);
};
return (
<GoogleMap
className="google-map"
ref={refMap}
defaultZoom={19}
mapTypeId='satellite'
defaultCenter={{ lat: props.latitude, lng: props.longitude }}
onBoundsChanged={useCallback(handlePositionChanged)}
>
<Marker className="google-map-marker" position={{ lat: props.latitude, lng: props.longitude }} position_changed={useCallback(handlePositionChanged)} />
</GoogleMap>
);
}
export default compose(
withProps({
googleMapURL: "https://maps.googleapis.com/maps/api/js?key=AIz&v=3.exp&libraries=geometry,drawing,places",
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `500px` }} />,
mapElement: <div style={{ height: `100%` }} />,
}),
withScriptjs,
withGoogleMap
)((props) => <Map latitude={props.latitude} longitude={props.longitude} />);
Instead of setting the center of the map and the marker using window.google.maps., you can use state values to change the <GoogleMap/> center parameter and the <Marker/> position parameter. So every time there's a change in the coordinates from geolocation, you need to change the state value of the Map's center and Marker's position and it the changes will then be reflected to the map. Here's a sample code snippet:
import React, { Component } from 'react';
import { withGoogleMap, GoogleMap, Marker } from 'react-google-maps';
class Map extends Component {
constructor(props) {
super(props);
this.state = {
userPosition: { lat: 40.756795, lng: -73.954298 }
};
}
onMapLoad = () => {
navigator.geolocation.getCurrentPosition(position => {
const { latitude, longitude } = position.coords;
this.setState({
userPosition: { lat: latitude, lng: longitude }
});
});
};
render() {
const GoogleMapExample = withGoogleMap(props => (
<GoogleMap
center={this.state.userPosition}
defaultZoom={13}
onLoad={this.onMapLoad()}
>
<Marker position={this.state.userPosition} />
</GoogleMap>
));
return (
<div>
<GoogleMapExample
containerElement={<div style={{ height: `500px`, width: '500px' }} />}
mapElement={<div style={{ height: `100%` }} />}
/>
</div>
);
}
}
export default Map;
I found a lot of useful information on google maps documentation but with simple use of js in html, in case of react honestly I don't understand it.
Source code:
import React, { Component } from 'react';
import {Map, InfoWindow, Marker, GoogleApiWrapper} from 'google-maps-react';
export class MainMap extends Component {
render() {
return (
<div>
<h1 className="text-center">My Maps</h1>
<Map google={this.props.google}
style={{width: '80%', margin: 'auto'}}
className={'map'}
zoom={14}>
<Marker
title={'The marker`s title will appear as a tooltip.'}
name={'SOMA'}
position={{lat: 37.778519, lng: -122.405640}} />
<Marker
name={'Dolores park'}
position={{lat: 37.759703, lng: -122.428093}} />
<Marker />
<Marker
name={'Your position'}
position={{lat: 46.475640, lng: 30.759497}}/>
</Map>
</div>
);
}
}
export default GoogleApiWrapper({
apiKey: (MY-API-KEY)
})(MainMap);
i want to add marker by clicking on map and don't know how...
help please!
The map has an onClick prop which you can give a function to handle clicks on the map. The third argument to this function includes the coordinates of the click.
You could use these coordinates to add a marker to your state that you use in the render method.
Example
class MainMap extends Component {
constructor(props) {
super(props);
this.state = {
markers: [
{
title: "The marker`s title will appear as a tooltip.",
name: "SOMA",
position: { lat: 37.778519, lng: -122.40564 }
}
]
};
this.onClick = this.onClick.bind(this);
}
onClick(t, map, coord) {
const { latLng } = coord;
const lat = latLng.lat();
const lng = latLng.lng();
this.setState(previousState => {
return {
markers: [
...previousState.markers,
{
title: "",
name: "",
position: { lat, lng }
}
]
};
});
}
render() {
return (
<div>
<h1 className="text-center">My Maps</h1>
<Map
google={this.props.google}
style={{ width: "80%", margin: "auto" }}
className={"map"}
zoom={14}
onClick={this.onClick}
>
{this.state.markers.map((marker, index) => (
<Marker
key={index}
title={marker.title}
name={marker.name}
position={marker.position}
/>
))}
</Map>
</div>
);
}
}
const App = GoogleApiWrapper({
apiKey: (MY-API-KEY)
})(MainMap);
Below is my code:
const SiteGoogleMap = compose(
withProps({
googleMapURL: `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_MAP_API_KEY}&v=3.exp&libraries=geometry,drawing,places`,
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `400px` }} />,
mapElement: <div style={{ height: `100%` }} />
}),
withScriptjs,
withGoogleMap
)((props) =>
<GoogleMap
defaultZoom={18}
defaultCenter={{ lat: 3.1314067, lng: 101.6285082 }}
>
{props.isMarkerShown && <Marker position={{ lat: -34.397, lng: 150.644
}} onClick={props.onMarkerClick} />}
<DrawingManager
defaultDrawingMode={google.maps.drawing.OverlayType.POLYGON}
defaultOptions={{
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.POLYGON
],
}
}}
/>
<Polygon path={coordinates} />
</GoogleMap>
)
I would like to get the coordinates (polygon path) from my server. Below is what I have done to get it. It is a component:
export default class Map extends Component {
state = {
isMarkerShown: false,
coordinates: []
}
componentDidMount() {
this.fetchBoundaries()
}
render () {
const { coordinates } = this.state
return (
<SiteGoogleMap
isMarkerShown={this.state.isMarkerShown}
onMarkerClick={this.handleMarkerClick}
/>
);
}
async fetchBoundaries () {
try {
const { coordinates } = this.state
const item = await service.getBoundaries('59d850878328bd177bf50b4d')
coordinates = item.boundaries
this.setState({ coordinates })
} catch (e) {
notification.show('error', 'Unable to load successfully', 'Unable to load client successfully. Please try again later.')
}
}
}
From the fetchBoundaries() function, I am able to get my coordinates. But, it just can't pass it to <Polygon path={coordinates} /> for display.
Anyone know what went wrong?