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}
/>
我有一个 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}
/>