react google maps are not loading - reactjs

I have a component in my react application that uses maps but the map is not loading how can I solve this problem
import React, { useEffect, useMemo } from 'react';
import { MarkerClusterer } from '#googlemaps/markerclusterer';
const Map = () => {
const locations = useMemo(
() => [
{ lat: -31.56391, lng: 147.154312 },
{ lat: -33.718234, lng: 150.363181 },
{ lat: -33.727111, lng: 150.371124 },
],
[],
);
useEffect(() => {
const script = document.createElement('script');
script.src = `https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLE_API_KEY}`;
script.async = true;
script.defer = true;
document.body.appendChild(script);
script.onload = () => {
if (typeof window.google !== 'undefined' && window.google.maps) {
const map = new window.google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: { lat: -28.024, lng: 140.887 },
});
const infoWindow = new window.google.maps.InfoWindow({
content: '',
disableAutoPan: true,
});
// Create an array of alphabetical characters used to label the markers.
const labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// Add some markers to the map.
const markers = locations.map((position, i) => {
const label = labels[i % labels.length];
const marker = new window.google.maps.Marker({
position,
label,
});
// markers can only be keyboard focusable when they have click listeners
// open info window when marker is clicked
marker.addListener('click', () => {
infoWindow.setContent(label);
infoWindow.open(map, marker);
});
return marker;
});
// Add a marker clusterer to manage the markers.
MarkerClusterer.factory({ markers, map });
}
};
}, [locations]);
return <div id='map' />;
};
export default Map;
this is my build i want to collect markers with cluster but i fail
enter image description here
in console i see these errors
![Topluluk Tarafından Doğrulandı simgesi](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAQAAAAngNWGAAABDUlEQVR4AYXRgUZDYRjH4TegFTKgpEqiFJgoWAoMEQGBgBboChaaAKxLKAhAhQqAdAmpBIQolkCFqp2nITvNKXuA7+/Hhzey5OWjE4Nq3rzY1f9/NGHPB549492+8Ww060iCS2XdctZdI3GsECmb+HJoIX6x6EgDm+lURTH+YB7V9nAqE5WNme4YKuOiY6iMe6PaQxUUIuTbswgFVNJwA8sO3Bn6yR6bWZMSNtJwDtuWfHpQxaPx9C9zadil7jrCigbq6UXceNIVKTWUIqypm2ytJdTiNyNeXclF6GttOVfeDEc7qzjR23r3OMFqZKng1kw0mXGLrfibHTScOZWgGv9TdC6ROFeMTgwYiIxvJzMRWQbeGZUAAAAASUVORK5CYII=)
I want the markers to appear in clusters on the map, but even the map does not appear

Related

Uncaught (in promise) TypeError: mapRef.current.getBounds is not a function in reactjs while using react-google-maps/api library

i am getting error mapRef.current.getBounds is not a function and map.getBounds is not a function when i want to getBounds of map using useRef react hook
this is my code for getting data from the csv file display marker on the map and when user scroll and zoom map then load more data from csv file and display on the marker based on change latitude and longitude of the map but i am getting error
import React, { useState, useEffect, useRef } from "react";
import { GoogleMap, LoadScript, Marker } from "#react-google-maps/api";
import Papa from "papaparse";
const Map = () => {
const [markers, setMarkers] = useState([]);
const mapRef = useRef(null);
const center = {
lat: 49.87099818,
lng: -97.28513314,
};
useEffect(() => {
const fetchData = async () => {
const response = await fetch("/data/geocoords.csv");
const data = await response.text();
const parsedData = Papa.parse(data, { header: true });
const initialMarkers = parsedData.data
.filter((data) => {
const lat = parseFloat(data.latitude);
const lng = parseFloat(data.longitude);
return mapRef.current.getBounds().contains({ lat, lng });
})
.map((data) => ({
position: {
lat: parseFloat(data.latitude),
lng: parseFloat(data.longitude),
},
title: data.title,
address: data.address,
}));
setMarkers(initialMarkers);
};
fetchData();
}, []);
const handleBoundsChanged = () => {
const map = mapRef.current;
const bounds = map.getBounds();
const ne = bounds.getNorthEast();
const sw = bounds.getSouthWest();
const lat1 = ne.lat();
const lng1 = ne.lng();
const lat2 = sw.lat();
const lng2 = sw.lng();
Papa.parse("/data/geocoords.csv", {
download: true,
header: true,
complete: (results) => {
const newMarkers = results.data
.filter((data) => {
const lat = parseFloat(data.latitude);
const lng = parseFloat(data.longitude);
return (
lat >= lat2 &&
lat <= lat1 &&
lng >= lng2 &&
lng <= lng1 &&
!markers.some((marker) => marker.street === data.street)
);
})
.map((data) => ({
position: {
lat: parseFloat(data.latitude),
lng: parseFloat(data.longitude),
},
title: data.street,
}));
setMarkers([...markers, ...newMarkers]);
},
});
};
return (
<LoadScript googleMapsApiKey={"my_api_key"}>
<GoogleMap
ref={mapRef}
onBoundsChanged={handleBoundsChanged}
mapContainerStyle={{ height: "100vh", width: "100%" }}
zoom={10}
center={center}
>
{markers.map((marker, index) => (
<Marker key={index} position={marker.position} title={marker.title} />
))}
</GoogleMap>
</LoadScript>
);
};
export default Map;
this is the screen shot of my error that i'm getting in google chrome console
Please any one can solve my problem i am stuck on this from last two days thanks in advance
Try to check whether the mapRef.current. has the getBounds() method before using it in the useEffect, try this in the useEffect return statement
return mapRef.current?.getBounds()?.contains({ lat, lng });

Centralize google map issue

import React, {
useState
} from "react";
import GoogleMapReact from "google-map-react";
function GMap() {
const [latLgn, setLatLgn] = useState([{
lng: 24.7536,
lat: 59.437
},
{
lng: 24.7303,
lat: 59.4393
},
{
lng: 24.7387,
lat: 59.4497
},
]);
const [tallinn] = useState({
center: { // where i want to be centerd
lng: 24.7536,
lat: 59.437,
},
zoom: 10,
});
// Fit map to its bounds after the api is loaded
const apiIsLoaded = (map, maps, latlgn) => {
// Get bounds by our latlgn
const bounds = getMapBounds(map, maps, latlgn);
// Fit map to bounds
map.fitBounds(bounds);
// Bind the resize listener
bindResizeListener(map, maps, bounds);
};
// Re-center map when resizing the window
const bindResizeListener = (map, maps, bounds) => {
maps.event.addDomListenerOnce(map, "idle", () => {
maps.event.addDomListener(window, "resize", () => {
map.fitBounds(bounds);
});
});
};
// Return map bounds based on list of places
const getMapBounds = (map, maps, pins) => {
const bounds = new maps.LatLngBounds();
pins.forEach((pin) => {
bounds.extend(new maps.LatLng(pin[1], pin[0]));
});
return bounds;
};
return ( <
div >
<
div style = {
{
height: "100vh",
width: "100%"
}
} >
<
GoogleMapReact bootstrapURLKeys = {
{
key: AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk
}
}
defaultCenter = {
tallinn.center
}
defaultZoom = {
tallinn.zoom
}
onGoogleApiLoaded = {
({
map,
maps
}) => apiIsLoaded(map, maps, latLgn)
}
yesIWantToUseGoogleMapApiInternals >
{
latLgn.map((item, index) => ( <
div lat = {
item[1]
}
lng = {
item[0]
}
key = {
index
} >
</div>
))
} </GoogleMapReact>
</div>
</div>
);
}
export default Gmap
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
I have a problem with centralizing the map I am rendering.
although I have a state with the "lat" and "lng" as stated in the docs still, when I run the app with npm start or refreshing the page, it will centre itself somewhere in the ocean.\
PS. I will paste my "map" component only.
import React, { useState } from "react";
import GoogleMapReact from "google-map-react";
export default function GMap() {
const [latLgn, setLatLgn] = useState([{
lng: 24.7536,
lat: 59.437
},
{
lng: 24.7303,
lat: 59.4393
},
{
lng: 24.7387,
lat: 59.4497
},
]);
const [tallinn] = useState({
center: { // where i want to be centerd
lng: 24.7536,
lat: 59.437,
},
zoom: 10,
});
// Fit map to its bounds after the api is loaded
const apiIsLoaded = (map, maps, latlgn) => {
// Get bounds by our latlgn
const bounds = getMapBounds(map, maps, latlgn);
// Fit map to bounds
map.fitBounds(bounds);
// Bind the resize listener
bindResizeListener(map, maps, bounds);
};
// Re-center map when resizing the window
const bindResizeListener = (map, maps, bounds) => {
maps.event.addDomListenerOnce(map, "idle", () => {
maps.event.addDomListener(window, "resize", () => {
map.fitBounds(bounds);
});
});
};
// Return map bounds based on list of places
const getMapBounds = (map, maps, pins) => {
const bounds = new maps.LatLngBounds();
pins.forEach((pin) => {
bounds.extend(new maps.LatLng(pin[1], pin[0]));
});
return bounds;
};
return (
<div>
<div style={{ height: "100vh", width: "100%" }}>
<GoogleMapReact
bootstrapURLKeys={{key: AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk }}
defaultCenter={tallinn.center}
defaultZoom={tallinn.zoom}
onGoogleApiLoaded={({ map, maps }) => apiIsLoaded(map, maps, latLgn)}
yesIWantToUseGoogleMapApiInternals
>
{latLgn.map((item, index) => (
<div lat={item[1]} lng={item[0]} key={index}< </div>
))}
</GoogleMapReact>
</div>
</div>
);
}
ps. let me know if I should provide more information
UPDATE
I have created a sample project here.
I checked your code and I noticed a couple of things.
First, in your getMapBounds function, the bounds returned are null. This is because the values of pin[1] and pin[0] are undefined. This might be the reasoon why the map is centering in the middle of the ocean like this as this is the center of the world and coordinates are 0,0. You must use pin.lat and pin.lng instead so that it will correctly populate the value for bounds.
Second, it seems that you would like to put markers on the coordinates of your latLgn. To achieve this, you can follow the AnyReactComponent function as mentioned in the google-map-react docs instead of putting a div directly inside the latLgn.map.
Lastly, inside your latLgn.map, you must not use item[1] and item[0] as they are also both undefined instead use item.lat and item.lng.
Here's the code snippet for my working code:
import React, { useState } from "react";
import "./style.css"
import GoogleMapReact from "google-map-react";
const AnyReactComponent = ({ text }) => <div>{text}</div>;
export default function GMap() {
const [latLgn, setLatLgn] = useState([{
lng: 24.7536,
lat: 59.437
},
{
lng: 24.7303,
lat: 59.4393
},
{
lng: 24.7387,
lat: 59.4497
},
]);
const [tallinn] = useState({
center: { // where i want to be centerd
lng: 24.7536,
lat: 59.437,
},
zoom: 10,
});
// Fit map to its bounds after the api is loaded
const apiIsLoaded = (map, maps, latlgn) => {
// Get bounds by our latlgn
const bounds = getMapBounds(map, maps, latlgn);
// Fit map to bounds
map.fitBounds(bounds);
// Bind the resize listener
bindResizeListener(map, maps, bounds);
};
// Re-center map when resizing the window
const bindResizeListener = (map, maps, bounds) => {
maps.event.addDomListenerOnce(map, "idle", () => {
maps.event.addDomListener(window, "resize", () => {
map.fitBounds(bounds);
});
});
};
// Return map bounds based on list of places
const getMapBounds = (map, maps, pins) => {
const bounds = new maps.LatLngBounds();
pins.forEach((pin) => {
bounds.extend(new maps.LatLng(pin.lat, pin.lng));
console.log(pin[0])
});
return bounds;
};
return (
<div>
<div style={{ height: "100vh", width: "100%" }}>
<GoogleMapReact
bootstrapURLKeys={{key: "YOUR_API_KEY" }}
defaultCenter={tallinn.center}
defaultZoom={tallinn.zoom}
onGoogleApiLoaded={({ map, maps }) => apiIsLoaded(map, maps, latLgn)}
yesIWantToUseGoogleMapApiInternals
>
{latLgn.map((item, index) => (
<AnyReactComponent lat={item.lat} lng={item.lng} key={index} text={"(" +item.lat + "," + item.lng +")"}> </AnyReactComponent>
))}
</GoogleMapReact>
</div>
</div>
);
}
I also noticed your question in the comment section. You can use online ides like stackblitz to provide an sscce of your code and just remove the API key. You can put a note in your question that you need to put API key to see how the code works. You can refer to my working code above.

Invalid LngLat object: (NaN, NaN) in react js , "Mapbox"

The project concept is to get geolocation and showing Mapbox map using API...
import ReactDOM from "react-dom";
import React, { useRef, useEffect } from "react";
import { geolocated } from "react-geolocated";
import mapboxgl from "mapbox-gl";
import fetchFakeData from "./api/fetchFakeData";
import Popup from "./components/Popup";
import "./App.css";
mapboxgl.accessToken ="pk.eyJ1IjoiamFja3Nvbi1rYXNpIiwiYSI6ImNrbzdsaDJvNTFvc3Eycm9pdTRxYmRxZjUifQ.BzA0w0U7lP0Ka3FcKkI_1Q";
const App = (props) => {
const mapContainerRef = useRef(null);
const popUpRef = useRef(new mapboxgl.Popup({ offset: 15 }));
// initialize map when component mounts
useEffect(() => {
const map = new mapboxgl.Map({
container: mapContainerRef.current,
// See style options here: https://docs.mapbox.com/api/maps/#styles
style: "mapbox://styles/mapbox/streets-v11",
center: [props.lat, props.long],
zoom: 12.5
});
// add navigation control (zoom buttons)
map.addControl(new mapboxgl.NavigationControl(), "bottom-right");
map.on("load", () => {
// add the data source for new a feature collection with no features
map.addSource("random-points-data", {
type: "geojson",
data: {
type: "FeatureCollection",
features: []
}
});
// now add the layer, and reference the data source above by name
map.addLayer({
id: "random-points-layer",
source: "random-points-data",
type: "symbol",
layout: {
// full list of icons here: https://labs.mapbox.com/maki-icons
"icon-image": "bakery-15", // this will put little croissants on our map
"icon-padding": 0,
"icon-allow-overlap": true
}
});
});
map.on("moveend", async () => {
// get new center coordinates
const { lng, lat } = map.getCenter();
// fetch new data
const results = await fetchFakeData({ longitude: lng, latitude: lat });
// update "random-points-data" source with new data
// all layers that consume the "random-points-data" data source will be updated automatically
map.getSource("random-points-data").setData(results);
});
// change cursor to pointer when user hovers over a clickable feature
map.on("mouseenter", "random-points-layer", (e) => {
if (e.features.length) {
map.getCanvas().style.cursor = "pointer";
}
});
// reset cursor to default when user is no longer hovering over a clickable feature
map.on("mouseleave", "random-points-layer", () => {
map.getCanvas().style.cursor = "";
});
// add popup when user clicks a point
map.on("click", "random-points-layer", (e) => {
if (e.features.length) {
const feature = e.features[0];
// create popup node
const popupNode = document.createElement("div");
ReactDOM.render(<Popup feature={feature} />, popupNode);
// set popup on map
popUpRef.current
.setLngLat(feature.geometry.coordinates)
.setDOMContent(popupNode)
.addTo(map);
}
});
// clean up on unmount
return () => map.remove();
}, []); // eslint-disable-line react-hooks/exhaustive-deps
return <div className="map-container" ref={mapContainerRef} />
};
export default geolocated({
positionOptions: {
enableHighAccuracy: false
},
userDecisionTimeout: 5000
})(App);
class Gps extends React.Component {
constructor() {
super();
this.state = {
latitude: "",
longitude: ""
};
this.getMyLocation = this.getMyLocation.bind(this);
}
componentDidMount() {
this.getMyLocation();
}
getMyLocation() {
const location = window.navigator && window.navigator.geolocation;
if (location) {
location.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
},
(error) => {
this.setState({
latitude: "err-latitude",
longitude: "err-longitude"
});
}
);
}}
render() {
const { latitude, longitude } = this.state;
return (
<div>
<App lat={latitude} long={longitude} />
</div>
);
}
}
please see this link "codesandbox" : https://codesandbox.io/s/determined-river-7dt0h?file=/src/App.js
props didn't work.
see this lines:
center: [props.lat, props.long]
<App lat={latitude} long={longitude} / >
screenshot
The Problem
The Lat and Lng were initialized to an empty string, but the center property is expecting an array of numbers.
Solution
In Gps component, initialize the lat and long state values to a number as opposed to an empty string
this.state = {
latitude: 38.8951,
longitude: -77.0364
};
In my case, I was using it for web and the issue was causing because of the height of the div in which I was rendering map component. When I set the minHeight for that div, it worked fine for me.

How to Draw Polyline on mapmyindia using React?

I am just exploring Mapmyindia.
I have gone through the basic location display on the map.
I am not getting how to display polyline on map.
code for location
app.js
import "./App.css";
import SideBar from "./componants/SideBar";
import Map from "mapmyindia-react";
// import MapmyIndia, { MapMarker } from "react-mapmyindia";
function App() {
return (
<div className="App">
Hello
<Map
markers={[
{
position: [21.1588329, 72.7688111],
draggable: true,
zoom: 15,
title: "Marker title",
onClick: (e) => {
console.log("clicked ");
},
onDragend: (e) => {
console.log("dragged");
},
onMouseover: (e) => {
console.log("Mouse over");
},
},
]}
/>
{/* <Map /> */}
<SideBar></SideBar>
</div>
);
}
export default App;
Which result this
Now, Please help with drawing polyline.
I guess you're using the npm package for maps. If you go through the library's code in gitHub, you can see the owner has only added marker functionality. You can simply copy the code from there and add it manually to your project and then add the polyline functionality and then pass the data as props from your app.js file like you're doing for markers.
renderPolylines = () => {
const { polylines = [] } = this.props;
if (!this.map) {
return;
}
polylines.map(m => {
if (m?.position && Array.isArray(m.position)) {
const { position, color, weight, opacity } = m;
let points = [];
position.map(p => {
const { lat, lng } = p;
const center = new L.LatLng(lat, lng);
points.push(
new L.LatLng(center.lat, center.lng))/*array of wgs points*/
})
const polyline = new L.Polyline(points, { color, weight, opacity });
this.map.addLayer(polyline);
this.polylines.push(polyline);
}
});
};
Props for rendering polyline from app.js
polylines = {[
{
position: [
{
lat: 18.5014,
lng: 73.805,
},
{
lat: 18.5414,
lng: 73.855,
},
{
lat: 18.5514,
lng: 73.855,
},
{
lat: 18.5614,
lng: 73.855,
},
],
color: "red",
weight: 4,
opacity: 0.5,
},
]}

Functional based component marker problem

Hi i am using vanilla map js in react but in this functional based component marker is not showing but in class based component it works. But i want to use it in functional based component. Please help me. In this functional based component i am using react useEfect.
const GoogleMap = () => {
// const [googleMap, setGoogleMap] = useState();
// const [marker, setMarker] = useState();
let googleMapRef = React.createRef();
let map, marker;
// }
useEffect(() => {
const googleMapScript = document.createElement("script");
googleMapScript.src = `https://maps.googleapis.com/maps/api/js?key=AIzaSyDEkGijSUn59Urd96tftpKsizYGqkUaMFQ`;
window.document.body.appendChild(googleMapScript);
googleMapScript.addEventListener("load", () => {
map = createGoogleMap();
marker = createMarker();
});
}, [])
console.log("Marker", marker)
// componentDidMount() {
// const googleMapScript = document.createElement("script");
// googleMapScript.src = `https://maps.googleapis.com/maps/api/js?key=AIzaSyDjjx0ffXrvMyW4V8Y3Wlk-e2c2H2jAcFw`;
// window.document.body.appendChild(googleMapScript);
// googleMapScript.addEventListener("load", () => {
// this.googleMap = this.createGoogleMap();
// this.marker = this.createMarker();
// });
// }
let createGoogleMap = () => {
new window.google.maps.Map(googleMapRef.current, {
zoom: 16,
center: {
lat: 43.642567,
lng: -79.387054,
},
// disableDefaultUI: true,
});
}
let createMarker = () => {
const marker = new window.google.maps.Marker({
position: { lat: 43.642567, lng: -79.387054 },
map: map,
})
return marker
}
return (
<div
id="google-map"
ref={googleMapRef}
style={{ height: '75vh', width: "100%" }}
/>
)
}
export default GoogleMap;```

Resources