So I've fixed this my way following a few tutorials. I'm completely ignoring the react-google-maps package and I'm just using plain Javascript. Anyone who's looking for a way to add & switch between KMLayers and to add click and hover actions to it, this is how I did it and is my advice to fellow developers:
TIPS
1: Replace KML by GEOJSON
First of all, I am not using KMLayer but Datalayer now. This allows me more control and has much more documentation on Google. Therefore, you have to convert your KML to a GeoJson. I find that @Mapbox toGeoJSON does a fine job as it also keeps your custom data (which is very important if you want to have more freedom with your data!). Plus they also share their code to integrate in your application so you don't have to convert manually each time.
2: Analyze Google Api Data Layer documentation
Sounds straightforward, but still worth mentioning. As I said, Google shares a lot of information about implementing Data Layer. How to add click and mouseover events, how to style each individual shape and get that specific information, ...
Google doc on Data Layer
3: Replace loadGeoJson() by addGeoJson()
If your applications needs to switch between different Data Layers or simply has to add and remove one, you'll quickly find yourself stuck when using the loadGeoJson()
. Hence the addGeoJson()
, which will allow you to use map.data.remove()
to remove the current Data layer.
Credit: @mensi for his answer on how to remove Data Layer
FINAL CODE
import React, { Component } from 'react';
import { SearchConsumer } from '../App.js';
import Icon from '../library/icons/Icon';
var map = ''
var dataLayer = ''
export default class mapSelection extends Component {
constructor(props){
super(props)
this.onScriptLoad = this.onScriptLoad.bind(this)
}
onScriptLoad() {
// CREATE YOUR GOOGLE MAPS
map = new window.google.maps.Map(
document.getElementById('map'),
{
// ADD OPTIONS LIKE STYLE, CENTER, GESTUREHANDLING, ...
center: { lat: 50.5, lng: 4 },
zoom: 8,
gestureHandling: 'greedy',
disableDefaultUI: true,
});
}
dataHandler = (getJson) => {
// FIRST I REMOVE THE CURRENT LAYER (IF THERE IS ONE)
for (var i = 0; i < dataLayer.length; i++) {
map.data.remove(dataLayer[i])
}
// THEN I FETCH MY JSON FILE, IN HERE I'M USING A PROP BECAUSE
// I WANT TO USE THIS DATAHANDLER MULTIPLE TIMES & DYNAMICALLY
// I CAN NOW DO SOMETHING LIKE THIS:
// onClick(this.dataHandler(www.anotherlinktojsonfile.com/yourjsonfile.json))
// ON EACH BUTTON AND CHOOSE WHICH JSON FILE NEEDS TO BE FETCHED IN MY DATAHANDLER.
fetch(getJson)
.then(response => response.json())
.then(featureCollection => {
dataLayer = map.data.addGeoJson(featureCollection)
// ADD SOME NEW STYLE IF YOU WANT TO
map.data.setStyle({strokeWeight: 0.5, fillOpacity: 0 });
}
);
map.data.addListener('mouseover', (event) => {
map.data.revertStyle();
// ADD A STYLE WHEN YOU HOVER OVER A SPECIFIC POLYGON
map.data.overrideStyle(event.feature, {strokeWeight: 1, fillOpacity: 0.1 });
// IN CONSOLE LOG, YOU CAN SEE ALL THE DATA YOU CAN RETURN
console.log(event.feature)
});
map.data.addListener('mouseout', (event) => {
// REVERT THE STYLE TO HOW IT WAS WHEN YOU HOVER OUT
map.data.revertStyle();
});
}
componentDidMount() {
// LOADING THE GOOGLE MAPS ITSELF
if (!window.google) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'https://maps.google.com/maps/api/js?key=' + process.env.REACT_APP_MAPS_API_KEY;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
// Below is important.
//We cannot access google.maps until it's finished loading
s.addEventListener('load', e => {
this.onScriptLoad()
this.dataHandler('https://linktoyourjson.com/yourjsonfile.json')
})
} else {
this.onScriptLoad()
}
}
render () {
return (
<div id='mapContainer'>
<div style={{ width: '100%', height: '100%' }} id='map' />
</div>
);
}
};
EXTRA CREDITS
I also want to thank cuneyt.aliustaoglu.biz for his wel explained tutorial in using Google Maps wihout any package.
And thanks to everyone who helped me with a minor problem
QUESTIONS OR SUGGESTIONS?
If there are any questions or if I missed something, you can always ask or tell me and I'll edit this post if necessary.