如何在 React 传单地图上显示 geodjango rest api 响应
How to display geodjango rest api response on react leaflet Map
我从 django rest 得到以下回复:
[
{
"area": 0.0,
"perimeter": 0.0,
"town_name": "Cheptais",
"town_id": 4,
"town_type": "Market Centres",
"geom": "SRID=4326;MULTIPOINT (34.4500007629395 0.800000011920929)"
},
{
"area": 0.0,
"perimeter": 0.0,
"town_name": "Dadaab",
"town_id": 3,
"town_type": "Trading Centre",
"geom": "SRID=4326;MULTIPOINT (40.3199996948242 0.070000000298023)"
},
{
"area": 0.0,
"perimeter": 0.0,
"town_name": "Eldas",
"town_id": 4,
"town_type": "Market Centres",
"geom": "SRID=4326;MULTIPOINT (39.5499992370605 2.52999997138977)"
}
]
以这种方式使用 axios 获取端点:
await axios
.get("/api/gis/areas/", headers)
.then((response) => {
this.setState({ places: response.data });
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
}
const handleEachFeature = (feature, layer) => {
layer.bindPopup('<font size="4">' + feature.properties.town_name);
}
使用react leaflet,我创建了一个地图实例如下:
<Map className="map" onEachFeature={handleEachFeature} style={{height:'100%',width:'100%'}}>
<GeoJSON data={places}/>
</Map>
但是,这不会覆盖我地图上的 api 响应。我是不是漏掉了什么?
正如我在评论中提到的,您必须将 wkt 转换为 geojson 才能使其正常工作,有几种解决方案可以实现这种转换,但最简单的方法是导入 wicket 库(只需使用 npm install wicket),你还需要用一个唯一的键来创建,这是一个来自你相同数据的工作组件(注意我没有使用 axios,因为我在本地测试数据),:
import React, { Component } from 'react'
import './styles/styles.css'
import {Map,TileLayer,GeoJSON} from 'react-leaflet'
import './leaflet/leaflet.css'
import Wkt from 'wicket'
import L from 'leaflet'
import Data from '../../Data/wkt_file.json'
import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';
// this is for maker to show up:
let DefaultIcon = L.icon({
iconUrl: icon,
shadowUrl: iconShadow
});
L.Marker.prototype.options.icon = DefaultIcon;
export default class map extends Component {
constructor(props){
super(props);
this.state={
wkt_json_holder:[],
json_ob:<></>,
json_key:1,
tile:'https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png',
}
this.setGeoJSON = this.setGeoJSON.bind(this)
this.onEach = this.onEach.bind(this)
}
async componentDidMount(){
await this.setState({wkt_json_holder:Data});
this.setGeoJSON()
}
setGeoJSON=()=>{
let json_data = this.state.wkt_json_holder.map(point=>{
let wkt_geom = point['geom'].replace('SRID=4326;','')
let wkt = new Wkt.Wkt();
wkt.read(wkt_geom)
let geojson_geom = wkt.toJson()
let coords = geojson_geom['coordinates']
let type = geojson_geom['type']
let geojson_obj={
"type": "Feature",
"geometry": {
'type':type,
'coordinates':coords
},
"properties": {
"town_name": point['town_name'], "town_id": point['town_id'], "town_type":point['town_type'], "perimeter": point['perimeter'], "area": point['area']
}
}
return geojson_obj
}
)
console.log(json_data)
let json_ob= <GeoJSON data={json_data} key={1} style={{color:'red'}} onEachFeature={this.onEach}/>
this.setState({json_ob})
}
// handling Popups
onEach(feature,layer){
console.log(feature)
let PopupContent = `
<Popup>
<p>town id:${feature.properties.town_id}</p>
<p>town name:${feature.properties.town_name}</p>
</Popup>
`
layer.bindPopup(PopupContent)
}
render() {
return (
<div style={{width:'100%',height:'100%'}}>
<Map center={[2.197035, 38.703588]} zoom={6} style={{width:'100%',height:'100%'}}>
<TileLayer url={this.state.tile}/>
{this.state.json_ob}
</Map>
</div>
)
}
}
我从 django rest 得到以下回复:
[
{
"area": 0.0,
"perimeter": 0.0,
"town_name": "Cheptais",
"town_id": 4,
"town_type": "Market Centres",
"geom": "SRID=4326;MULTIPOINT (34.4500007629395 0.800000011920929)"
},
{
"area": 0.0,
"perimeter": 0.0,
"town_name": "Dadaab",
"town_id": 3,
"town_type": "Trading Centre",
"geom": "SRID=4326;MULTIPOINT (40.3199996948242 0.070000000298023)"
},
{
"area": 0.0,
"perimeter": 0.0,
"town_name": "Eldas",
"town_id": 4,
"town_type": "Market Centres",
"geom": "SRID=4326;MULTIPOINT (39.5499992370605 2.52999997138977)"
}
]
以这种方式使用 axios 获取端点:
await axios
.get("/api/gis/areas/", headers)
.then((response) => {
this.setState({ places: response.data });
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
}
const handleEachFeature = (feature, layer) => {
layer.bindPopup('<font size="4">' + feature.properties.town_name);
}
使用react leaflet,我创建了一个地图实例如下:
<Map className="map" onEachFeature={handleEachFeature} style={{height:'100%',width:'100%'}}>
<GeoJSON data={places}/>
</Map>
但是,这不会覆盖我地图上的 api 响应。我是不是漏掉了什么?
正如我在评论中提到的,您必须将 wkt 转换为 geojson 才能使其正常工作,有几种解决方案可以实现这种转换,但最简单的方法是导入 wicket 库(只需使用 npm install wicket),你还需要用一个唯一的键来创建,这是一个来自你相同数据的工作组件(注意我没有使用 axios,因为我在本地测试数据),:
import React, { Component } from 'react'
import './styles/styles.css'
import {Map,TileLayer,GeoJSON} from 'react-leaflet'
import './leaflet/leaflet.css'
import Wkt from 'wicket'
import L from 'leaflet'
import Data from '../../Data/wkt_file.json'
import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';
// this is for maker to show up:
let DefaultIcon = L.icon({
iconUrl: icon,
shadowUrl: iconShadow
});
L.Marker.prototype.options.icon = DefaultIcon;
export default class map extends Component {
constructor(props){
super(props);
this.state={
wkt_json_holder:[],
json_ob:<></>,
json_key:1,
tile:'https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png',
}
this.setGeoJSON = this.setGeoJSON.bind(this)
this.onEach = this.onEach.bind(this)
}
async componentDidMount(){
await this.setState({wkt_json_holder:Data});
this.setGeoJSON()
}
setGeoJSON=()=>{
let json_data = this.state.wkt_json_holder.map(point=>{
let wkt_geom = point['geom'].replace('SRID=4326;','')
let wkt = new Wkt.Wkt();
wkt.read(wkt_geom)
let geojson_geom = wkt.toJson()
let coords = geojson_geom['coordinates']
let type = geojson_geom['type']
let geojson_obj={
"type": "Feature",
"geometry": {
'type':type,
'coordinates':coords
},
"properties": {
"town_name": point['town_name'], "town_id": point['town_id'], "town_type":point['town_type'], "perimeter": point['perimeter'], "area": point['area']
}
}
return geojson_obj
}
)
console.log(json_data)
let json_ob= <GeoJSON data={json_data} key={1} style={{color:'red'}} onEachFeature={this.onEach}/>
this.setState({json_ob})
}
// handling Popups
onEach(feature,layer){
console.log(feature)
let PopupContent = `
<Popup>
<p>town id:${feature.properties.town_id}</p>
<p>town name:${feature.properties.town_name}</p>
</Popup>
`
layer.bindPopup(PopupContent)
}
render() {
return (
<div style={{width:'100%',height:'100%'}}>
<Map center={[2.197035, 38.703588]} zoom={6} style={{width:'100%',height:'100%'}}>
<TileLayer url={this.state.tile}/>
{this.state.json_ob}
</Map>
</div>
)
}
}