React-Leaflet-将绘图列表映射到标记

React-Leaflet-mapping a list of plots to markers

我有一个 React Leaflet 地图,渲染效果很好。

我有一个状态图列表,看起来不错(如果我查看组件状态,我可以看到它们。

每个地块都有一个 GeoJSON 多边形 属性。

我有一个自定义标记组件,它根据缩放(GeoJSON 多边形或绘图多边形中心的标记)呈现不同。

我正在映射绘图列表并从每个列表实例化一个自定义标记组件。但这不会渲染任何图。

我错过了什么?

地图组件:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';
import { Map, TileLayer, LayersControl, MapControl } from 'react-leaflet';
import { GoogleLayer } from './GoogleLayer';
import { geolocated } from 'react-geolocated';
import 'leaflet-geocoder-mapzen';
import SearchBox from './searchBox';
import Control from 'react-leaflet-control';
import PlotMarker from './plotMarker';
import { centroid } from '@turf/turf';

const { BaseLayer } = LayersControl;
const key = 'MYKEY';
const hybrid = 'HYBRID';
const terrain = 'TERRAIN';
const road = 'ROADMAP';
const satellite = 'SATELLITE';

const centerLat = props => {
    if (
        props.isGeolocationAvailable &&
        props.isGeolocationEnabled &&
        props.coords
    ) {
        return props.coords.latitude;
    }
    return 32.11;
};

const centerLong = props => {
    if (
        props.isGeolocationAvailable &&
        props.isGeolocationEnabled &&
        props.coords
    ) {
        return props.coords.longitude;
    }
    return 34.963;
};

const initialMapCenter = props => {
    return [centerLat(props), centerLong(props)];
};

const initialZoomLevel = 11;

const markers = props => {
    if (props.plots) {
        return (
            <div>
                {(props.filteredPlots || props.plots).map(
                    plot =>
                        plot.feature && (
                            <PlotMarker
                                key={plot._id}
                                geoJSON={plot.feature}
                                position={centroid(plot.feature).geometry.coordinates}
                            />
                        )
                )}
            </div>
        );
    }
};
export class PlotMap extends Component {
    render() {
        this.props.plots &&
            (this.props.filteredPlots || this.props.plots).forEach(plot => {
                plot.feature &&
                    console.log(centroid(plot.feature).geometry.coordinates);
            });
        return (
            <div
                className="col-sm-8 m-auto p-0 flex-column float-right"
                style={{ height: `85vh` }}>
                <Map
                    center={initialMapCenter(this.props)}
                    zoom={initialZoomLevel}
                    zoomControl={true}
                    onZoomend={e => {
                        this.props.setZoomLevel(e.target.getZoom());
                    }}
                    onMoveEnd={e => {
                        this.props.setMapCenter(e.target.getCenter());
                    }}>
                    <LayersControl position="topright">
                        <BaseLayer name="Google Maps Roads">
                            <GoogleLayer googlekey={key} maptype={road} />
                        </BaseLayer>
                        <BaseLayer name="Google Maps Terrain">
                            <GoogleLayer googlekey={key} maptype={terrain} />
                        </BaseLayer>
                        <BaseLayer name="Google Maps Satellite">
                            <GoogleLayer googlekey={key} maptype={satellite} />
                        </BaseLayer>
                        <BaseLayer checked name="Google Maps Hybrid">
                            <GoogleLayer
                                googlekey={key}
                                maptype={hybrid}
                                libraries={['geometry', 'places']}
                            />
                        </BaseLayer>
                    </LayersControl>
                    <SearchBox postion="bottomright" />
                    {markers(this.props)}
                </Map>
            </div>
        );
    }
}

function mapStateToProps(state) {
    return {
        filteredPlots: state.plots.filteredPlots,
        plots: state.plots.plots,
        mapCenter: state.plots.mapCenter
    };
}

export default geolocated({
    positionOptions: {
        enableHighAccuracy: false
    },
    userDecisionTimeout: 5000,
    suppressLocationOnMount: false
})(connect(mapStateToProps, actions)(PlotMap));

标记组件:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';
import { Marker, GeoJSON } from 'react-leaflet';

export class PlotMarker extends Component {
    render() {
        const { key, position, geoJSON, zoomLevel } = this.props;
        if (zoomLevel > 14) {
            return <GeoJSON key={key} data={geoJSON} />;
        }
        return <Marker key={key} position={position} />;
    }
}

function mapStateToProps(state) {
    return {
        selectedPlot: state.plots.selectedPlot,
        plotBeingEdited: state.plots.plotBeingEdited,
        zoomLevel: state.plots.zoomLevel
    };
}

export default connect(mapStateToProps, actions)(PlotMarker);

问题原来是 GeoJSON 使用 long-lat,而 Leaflet 使用 lat-long(继承自 Google Maps。)所以我的标记出现在世界的另一个地方。解决这个问题非常简单——只需调用 .reverse() 作为位置传递给标记组件的坐标数组,如下所示:

<PlotMarker
      key={plot._id}
      geoJSON={plot.feature}
      position={centroid(plot.feature).geometry.coordinates}
/>