Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何创建一个可点击的kml地图,显示kml的元数据?_Reactjs_Google Maps_Methods_Kml_React Google Maps - Fatal编程技术网

Reactjs 如何创建一个可点击的kml地图,显示kml的元数据?

Reactjs 如何创建一个可点击的kml地图,显示kml的元数据?,reactjs,google-maps,methods,kml,react-google-maps,Reactjs,Google Maps,Methods,Kml,React Google Maps,Edit:根据,有一个名为getMetadata()的方法。我怎样才能用它归还道具? 说明: 使用React GoogleMaps软件包,我可以用自己的kml文件加载GoogleMaps。该KML文件包含多个形状,每个形状后面都有元数据。我想要的是,当用户单击其中一个形状时,他会看到该形状后面的数据,例如一个弹出窗口。 例子 假设我有一张谷歌地图,上面有一个kml文件,显示了两个国家。用户将鼠标悬停在其中一个国家,看到一个弹出窗口,显示他在哪个国家。他在第二个国家上空盘旋,得到同样的结果。当他

Edit:根据,有一个名为getMetadata()的方法。我怎样才能用它归还道具?

说明: 使用React GoogleMaps软件包,我可以用自己的kml文件加载GoogleMaps。该KML文件包含多个形状,每个形状后面都有元数据。我想要的是,当用户单击其中一个形状时,他会看到该形状后面的数据,例如一个弹出窗口。

例子 假设我有一张谷歌地图,上面有一个kml文件,显示了两个国家。用户将鼠标悬停在其中一个国家,看到一个弹出窗口,显示他在哪个国家。他在第二个国家上空盘旋,得到同样的结果。当他在全国点击kml形状时,他会收到更多信息。

这就要求我知道一些事情:

-如何在KML形状上创建悬停效果,以显示基于形状的数据
-如何在KML形状上创建显示基于形状的数据的单击事件

但是,我无法理解如何使此KML文件具有交互性。
这就是我到目前为止所拥有的:

import React, { Component } from 'react';
import { withScriptjs, withGoogleMap, GoogleMap, Marker, KmlLayer } from "react-google-maps"

const MyMapComponent = withScriptjs(withGoogleMap((props) =>
  <GoogleMap
    defaultZoom={8}
    defaultCenter={{ lat: 50.5010789, lng: 4.4764595 }}
  >
    <KmlLayer 
        url='https://example.be/kmlfile.kml'
        options={{ preserveViewport : false}}
    />
    {props.isMarkerShown && <Marker position={{ lat: 50.5010789, lng: 4.4764595 }} />}
  </GoogleMap>
))


export default class GoogleMaps extends Component {
    render(){
        return( 
            <MyMapComponent
              isMarkerShown
              googleMapURL="https://maps.googleapis.com/maps/api/js?key=MYKEY&v=3.exp&libraries=geometry,drawing,places"
              loadingElement={<div style={{ height: `100%` }} />}
              containerElement={<div style={{ height: `100%` }} />}
              mapElement={<div style={{ height: `100%` }} />}
            />
        )
    }
}
import React,{Component}来自'React';
从“react google maps”导入{withScriptjs,withGoogleMap,GoogleMap,Marker,Kmlayer}
const MyMapComponent=withScriptjs(withGoogleMap((道具)=>
{props.ismarkersown&}
))
导出默认类GoogleMaps扩展组件{
render(){
报税表(
)
}
}

因此,我通过一些教程解决了这个问题。我完全忽略了react GoogleMaps包,我只是使用纯Javascript。任何正在寻找在KMLayers之间添加和切换以及向其中添加单击和悬停操作的方法的人,我就是这样做的,这是我对其他开发人员的建议:

提示 1:用GEOJSON替换KML 首先,我现在使用的不是KMLayer,而是数据层。这让我有了更多的控制权,并且拥有了更多。因此,您必须将KML转换为GeoJson。我发现这做得很好,因为它还保留了自定义数据(如果您想更自由地使用数据,这一点非常重要!)。此外,他们还共享代码以集成到您的应用程序中,这样您就不必每次手动转换

2:分析Google Api数据层文档 听起来很简单,但仍然值得一提。正如我所说,谷歌分享了很多关于实现数据层的信息。如何添加单击和鼠标悬停事件,如何设置每个单独形状的样式并获取特定信息

3:将loadGeoJson()替换为addGeoJson() 如果您的应用程序需要在不同的数据层之间切换,或者只需添加和删除一个数据层,那么在使用
loadGeoJson()
时,您很快就会发现自己陷入困境。因此,
addGeoJson()
,这将允许您使用
map.data.remove()
删除当前数据层

信用证:@mensi感谢他对

最终代码
import React,{Component}来自'React';
从“../App.js”导入{SearchConsumer};
从“../library/icons/Icon”导入图标;
变量映射=“”
变量数据层=“”
导出默认类mapSelection扩展组件{
建造师(道具){
超级(道具)
this.onScriptLoad=this.onScriptLoad.bind(this)
}
onScriptLoad(){
//创建你的谷歌地图
map=newwindow.google.maps.map(
document.getElementById('map'),
{
//添加样式、居中、手势处理等选项。。。
中心:{lat:50.5,lng:4},
缩放:8,
手势处理:'贪婪',
disableDefaultUI:true,
});
}
dataHandler=(getJson)=>{
//首先,我删除当前层(如果有)
对于(var i=0;iresponse.json())
。然后(featureCollection=>{
dataLayer=map.data.addGeoJson(featureCollection)
//如果你想,可以添加一些新样式
map.data.setStyle({strokeWeight:0.5,fillOpacity:0});
}
);
map.data.addListener('mouseover',(事件)=>{
map.data.revertStyle();
//将光标悬停在特定多边形上时添加样式
overrideStyle(event.feature,{strokeWeight:1,fillOpacity:0.1});
//在控制台日志中,您可以看到可以返回的所有数据
console.log(event.feature)
});
map.data.addListener('mouseout',(事件)=>{
//将样式还原为悬停时的样式
map.data.revertStyle();
});
}
componentDidMount(){
//加载谷歌地图本身
如果(!window.google){
var s=document.createElement('script');
s、 类型='text/javascript';
s、 src='1〕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);
//下面是重要的。
//在google.maps加载完成之前,我们无法访问它
s、 addEventListener('load',e=>{
这个.onScriptLoad()文件
这个.dataHandler('https://linktoyourjson.com/yourjsonfile.json')
})
}否则{
这个.onScriptLoad()文件
}
}
渲染(){
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>
        );
    }
};