Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace InfoMarker with MapvglLayer #47

Open
wants to merge 29 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
9598914
feat: add constant
GeoLibra Jul 25, 2021
cd98523
Merge branch 'GiveHenanAHand:master' into master
GeoLibra Jul 25, 2021
31210f0
feat: add filter by category
GeoLibra Jul 25, 2021
25c710c
fix: import colorMap from common
GeoLibra Jul 25, 2021
ee91fdd
fix: modify code
GeoLibra Jul 25, 2021
cb25fe6
fix: remove common to src
GeoLibra Jul 25, 2021
a4b815e
fix: modify InfoHeader
GeoLibra Jul 25, 2021
ef61034
Merge branch 'dev' into master
GeoLibra Jul 25, 2021
ceef652
fix: replace InfoMarker with MapvglLayer
GeoLibra Jul 26, 2021
cf53d42
fix: update InfoWindow
GeoLibra Jul 26, 2021
6cef62b
fix: convert point into a GeoJSON
GeoLibra Jul 26, 2021
8b8d6a3
fix: update
GeoLibra Jul 26, 2021
93662a8
fix: fix conflict
GeoLibra Jul 27, 2021
3b80ba0
fix: fix conflict
GeoLibra Jul 27, 2021
d3e1ed4
export App
GeoLibra Jul 27, 2021
17c0d32
Merge pull request #49 from GiveHenanAHand/dev
Halcao Jul 27, 2021
297a88e
fix: resolve conflicts
GeoLibra Jul 27, 2021
73c4bf0
fix: render color with category
GeoLibra Jul 28, 2021
4c6192f
fix: add IconLayer
GeoLibra Jul 28, 2021
8d8f588
fix: valid icon
GeoLibra Jul 29, 2021
c0638e3
replace png with svg
GeoLibra Jul 29, 2021
f2da1fb
fix: update marker
GeoLibra Jul 29, 2021
7e2e8f9
Rename Marker (1).svg to Marker.svg
GeoLibra Jul 30, 2021
a0b7edc
fix: change color by focus
GeoLibra Jul 31, 2021
007050b
fix: modify center item
GeoLibra Jul 31, 2021
7908e9a
fix: replace marker
GeoLibra Jul 31, 2021
8df5707
fix: modify BaiduMap.js
GeoLibra Jul 31, 2021
d4221ec
fix: set top of the selected marker
GeoLibra Jul 31, 2021
cf24bcb
fix: modify color and click of infowindow's item
GeoLibra Aug 2, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7,186 changes: 3,593 additions & 3,593 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions public/images/marker-blue.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/marker-red.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>河南暴雨微博求助信息</title>
<script type="text/javascript" src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=mTM4lv5gl2AenfvEuC8hV6DMGyWF4mBZ"></script>
<script type="text/javascript" src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=0glwxwioYYuSFk9iaVuC25GDZb4pDL4N"></script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
27 changes: 14 additions & 13 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useEffect, useState, useMemo} from "react";
import React, { useEffect, useState, useMemo } from "react";
import { BaiduMap, InfoHeader } from "./components";
import { COLOR_MAP } from './common/constant'
import './styles/App.css';
Expand All @@ -11,16 +11,16 @@ function App() {
const [bounds, setBounds] = useState(null)
const [listDefaultText, setListDefaultText] = useState("")
// map center
const [center, setCenter] = useState({ lng: 113.802193, lat: 34.820333 })
const [center, setCenter] = useState(null)

// filter relevant states
const [ keyword, setKeyword ] = useState('')
const [ selectedCategory, setSelectedCategory ] = useState('')
const [ selectedTypes, setSelectedTypes ] = useState([])
const [keyword, setKeyword] = useState('')
const [selectedCategory, setSelectedCategory] = useState('')
const [selectedTypes, setSelectedTypes] = useState([])

// highlight relevant states
// changeList: (id -> icon) dict
const [ changeList, setChangeList ] = useState({})
const [changeList, setChangeList] = useState({})

// modal relevant states
const [ modalState, setModalState ] = useState({ modalVisible: false, item: null })
Expand All @@ -30,8 +30,8 @@ function App() {
// across different versions of json format; only for the transition phase
item.isWeibo = !item.link.startsWith('no_link')
// generate random to prevent overlap
let random1 = Math.random()-0.5
let random2 = Math.random()-0.5
let random1 = Math.random() - 0.5
let random2 = Math.random() - 0.5
if (!item.isWeibo) {
random1 = random1 / 200
random2 = random2 / 200
Expand Down Expand Up @@ -92,7 +92,7 @@ function App() {
if ('weibo' in data) return
const serverData = JSON.parse(xhr_weibo.responseText)
const items = serverData.map(createDataItem)
setData(previousData => ({...previousData, weibo: items}))
setData(previousData => ({ ...previousData, weibo: items }))
};
xhr_weibo.open("GET", "https://api-henan.tianshili.me/parse_json.json");
xhr_weibo.send()
Expand All @@ -102,7 +102,7 @@ function App() {
if ('sheet' in data) return
const serverData = JSON.parse(xhr_sheet.responseText)
const items = serverData.map(createDataItem)
setData(previousData => ({...previousData, sheet: items}))
setData(previousData => ({ ...previousData, sheet: items }))
};
xhr_sheet.open("GET", "https://api-henan.tianshili.me/manual.json");
xhr_sheet.send()
Expand All @@ -122,8 +122,8 @@ function App() {
const beginTime = Date.now() - timeRange * 60 * 60 * 1000
currentFilteredData = data[dataSource].filter(item => {
const result = (item.timestamp > beginTime) &&
item.post.indexOf(keyword) > -1 &&
item.category.indexOf(selectedCategory) > -1
item.post.indexOf(keyword) > -1 &&
item.category.indexOf(selectedCategory) > -1
// if already false
if (result === false) { return false }
// default select all
Expand Down Expand Up @@ -189,10 +189,11 @@ function App() {
// highlight item
list[item.id] = 'loc_blue'
setChangeList(list)
setCenter(item.location)
setCenter(item)
}

function handleCorrection(item) {
console.log('sssss');
setModalState({ visible: true, item: item })
}

Expand Down
3 changes: 2 additions & 1 deletion src/common/constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const COLOR_MAP = {
'求救': '#EC2215',
'帮助': '#47AE53',
'其他': '#3371BE',
'未分类': '#ac3370aa',
}

const CATEGORY_MAP = {
Expand All @@ -11,4 +12,4 @@ const CATEGORY_MAP = {
'未分类': []
}

export { COLOR_MAP, CATEGORY_MAP }
export { COLOR_MAP, CATEGORY_MAP }
149 changes: 109 additions & 40 deletions src/components/BaiduMap.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
import React, {useState, useCallback, useMemo} from "react";
import {Map, ScaleControl, ZoomControl, MapTypeControl} from 'react-bmapgl';
import { InfoMarker,InfoWindow,LocationControl } from ".";

import React, { useState, useCallback, useEffect } from "react";
import { Map, ScaleControl, ZoomControl, MapTypeControl, MapvglView, MapvglLayer } from 'react-bmapgl';
import { InfoWindow, LocationControl } from ".";
import { COLOR_MAP } from '../common/constant'

function BaiduMap(props) {
const [focus, setFocus] = useState("")
const [bounds, setBounds] = useState(null)
const [shouldAutoFocus, setShouldAutoFocus] = useState(true)

function onClickMarker(id){
setShouldAutoFocus(true)
if (focus === id) {
setFocus("")
} else {
setFocus(id)
}
}
const [listIem, setListItem] = useState(null);

const mapRef = useCallback(node => {
if (node !== null && bounds == null) {
Expand Down Expand Up @@ -47,36 +39,113 @@ function BaiduMap(props) {
props.handleBoundChanged(visibleBounds)
}

function onWindowCloseClick() {
onClickMarker(focus)
function onWindowCloseClick(e) {
e.stopPropagation()
const item = {
dataItem: {
properties: focus
}
};
onPointClick(item)
}

const infoMarkers = useMemo(() => {
return props.data.map( item => {
// color in props.changeList has a higher priority
return <InfoMarker key={item.id} item={item} icon={props.changeList[item.id] || item.icon} onClickMarker={onClickMarker}/>
})
}, [props.changeList, props.data])
const onPointClick = useCallback((e) => {
const { dataIndex, dataItem } = e;
if (dataItem) {
const { geometry, properties } = dataItem;
setShouldAutoFocus(true)
if (focus === properties.id) {
setFocus("")
} else {
setFocus(properties.id)
}
} else {
// 点击空白关闭infoWindow
setFocus("")
}
}, [focus]);

const geojson = [];
let centerPoint = null;
props.data.map((item) => {
// delete item.color
const point = {
geometry: {
type: 'Point',
coordinates: [item.location.lng, item.location.lat],
},
properties: {
...item,
icon: item.id === (focus || listIem) ? './images/marker-blue.svg' : './images/marker-red.svg',
},
}
if (item.id === (focus || listIem)) {
centerPoint = point;
} else {
geojson.push(point);
}
})
centerPoint && geojson.push(centerPoint);
let loc = { lng: 113.802193, lat: 34.820333 };

if (props.center) {
const { location } = props.center;
loc = location;
}

// 选中列表项展示infoWindow
useEffect(() => {
if (props.center) {
setListItem(props.center.id);
}
}, [props.center]);
return <Map
enableScrollWheelZoom={true}
enableDragging={true}
zoom={9}
center={props.center}
className="mapDiv"
ref={mapRef}
style={{height: "100%"}}>
<ZoomControl/>
<ScaleControl/>
<LocationControl/>
<MapTypeControl mapTypes={['normal', 'satellite']}/>
{ infoMarkers }
<InfoWindow
item={props.data.find(e => e.id === focus)}
shouldAutoCenter={shouldAutoFocus}
handleCorrection={props.handleCorrection}
onCloseClick={onWindowCloseClick}/>
</Map>
enableScrollWheelZoom={true}
enableDragging={true}
zoom={9}
center={loc}
className="mapDiv"
ref={mapRef}
style={{ height: "100%" }}>
<ZoomControl />
<ScaleControl />
<LocationControl />
<MapTypeControl mapTypes={['normal', 'satellite']} />
<InfoWindow
item={props.data.find(e => e.id === focus)}
shouldAutoCenter={shouldAutoFocus}
handleCorrection={props.handleCorrection}
onCloseClick={onWindowCloseClick} />
<MapvglView>
<MapvglLayer
type="IconLayer"
data={geojson}
options={{
// icon: (item) => {
// console.log('item', item.properties);
// if (item.properties.id === focus) {
// return './images/marker-blue.svg';
// }
// console.log('item', item);
// return './images/marker-red.svg';
// },
color: (item) => {
// console.log('item', item);
const { properties: { category } } = item
return COLOR_MAP[category]
},
size: 20,
enablePicked: true,// 是否可以拾取
selectedIndex: (item) => {
console.log('item', item);
},
selectedColor: '#5B8FF9', // 选中项颜色
autoSelect: true,// 根据鼠标位置来自动设置选中项
onClick: onPointClick,
}}
/>
</MapvglView>
</Map>
}

export default BaiduMap
export default BaiduMap
56 changes: 28 additions & 28 deletions src/components/InfoHeader.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {useCallback, useEffect, useState} from "react";
import { useCallback, useEffect, useState } from "react";
import { LEFT_FOLD } from '../icon';
import {Button, Slider, Row, Col, Input, Select, List, Radio} from 'antd';
import {SearchOutlined} from "@ant-design/icons";
import { Button, Slider, Row, Col, Input, Select, List, Radio } from 'antd';
import { SearchOutlined } from "@ant-design/icons";
import InfoItem from "./InfoItem";
import {CATEGORY_MAP} from "../common/constant";
import { CATEGORY_MAP } from "../common/constant";
import '../styles/InfoHeader.css'
const { Option } = Select

Expand All @@ -26,7 +26,7 @@ function InfoHeader(props) {
e.stopPropagation();
setIsFold(!isFold);
}, [isFold])


const handleSliderChange = (value) => {
setTimeRange(value)
Expand All @@ -48,9 +48,9 @@ function InfoHeader(props) {
<Col style={{ marginTop: 5 }}>信息来源:</Col>
<Col>
<Radio.Group defaultValue="weibo" buttonStyle="solid" onChange={handleSouceSwitched}>
<Radio.Button value="weibo">微博</Radio.Button>
<Radio.Button value="sheet">在线表格</Radio.Button>
</Radio.Group></Col>
<Radio.Button value="weibo">微博</Radio.Button>
<Radio.Button value="sheet">在线表格</Radio.Button>
</Radio.Group></Col>
</Row>
}

Expand Down Expand Up @@ -85,7 +85,7 @@ function InfoHeader(props) {
return <div className="slider-container">
<Row justify="center" align="middle">
<Col span={12}>
<Slider defaultValue={8} step={2} min={2} max={12} onAfterChange={handleSliderChange}/>
<Slider defaultValue={8} step={2} min={2} max={12} onAfterChange={handleSliderChange} />
</Col>
<Col className="label-col" span={6}>
<label>{labelText}</label>
Expand All @@ -100,25 +100,25 @@ function InfoHeader(props) {
}

return (
<div className="info-container" data-fold={isFold}>
<div className="info" data-fold={isFold}>
{souceSwitch()}
<div>{headerText()}</div>
<br />
{slider()}
</div>
<div className="info-container" data-fold={isFold}>
<div className="info" data-fold={isFold}>
{souceSwitch()}
<div>{headerText()}</div>
<br />
{slider()}
</div>
<div className="info-list-header">
<Input placeholder="搜索"
className="info-list-search"
value={props.keyword}
onChange={ e => props.notifyKeywordChange(e.target.value) }
allowClear
prefix={<SearchOutlined className="info-list-search-icon"/>}
style={{ }}
className="info-list-search"
value={props.keyword}
onChange={e => props.notifyKeywordChange(e.target.value)}
allowClear
prefix={<SearchOutlined className="info-list-search-icon" />}
style={{}}
/>
<Select defaultValue='' className="info-list-category" style={{}} onChange={handleCategoryChange}>
<Option value={''}>全选</Option>
{ categories.map(category => <Option value={category} key={category}>{category}</Option>) }
{categories.map(category => <Option value={category} key={category}>{category}</Option>)}
</Select>
<Select mode="multiple"
className="info-list-types"
Expand All @@ -130,7 +130,7 @@ function InfoHeader(props) {
disabled={types.length === 0}
onChange={value => props.notifyTypesChange(value)}>
{types.map(type => (
<Option key={type}>{type}</Option>
<Option key={type}>{type}</Option>
))}
</Select>
</div>
Expand All @@ -139,15 +139,15 @@ function InfoHeader(props) {
itemLayout="horizontal"
bordered
dataSource={displayList}
locale={ { emptyText: props.defaultText } }
locale={{ emptyText: props.defaultText }}
renderItem={item => (
<List.Item key={item.id} className={item.id === selectedId ? "selected-item" : ''} onClick={ () => { handleItemClicked(item) } }>
<InfoItem info={item} handleCorrection={props.handleCorrection}/>
</List.Item>
)}
/>
<div className="left-fold" data-fold={isFold} onClick={onLeftFold}>{LEFT_FOLD}</div>
</div>
/>
<div className="left-fold" data-fold={isFold} onClick={onLeftFold}>{LEFT_FOLD}</div>
</div>
)
}

Expand Down
Loading