Commit 1a9cbc05 authored by 田翔's avatar 田翔

fix: 增加地图线面

parent 16870930
{
"name": "panda-xform",
"version": "4.0.7",
"description": "4.0.7 样式调整",
"version": "4.0.8",
"description": "4.0.8 增加地图选线面",
"keywords": [
"panda-xform"
],
......
......@@ -2369,13 +2369,11 @@ const advancedWidgets = [
title: '台账名称',
type: 'string',
widget: 'AccountName',
// required: true
},
'映射字段': {
title: '映射字段',
type: 'array',
widget: 'MappedField',
// required: true,
default: [],
dependencies: ['台账名称'],
},
......
......@@ -285,8 +285,8 @@ const FormDesigner = (props, ref) => {
}
return (
<div className={styles.pandaXform} style={{ width: '100%', height: '100%', background: 'white' }}>
<div style={{ height: '100%' }}>
<div className={styles.pandaXform}>
<div style={{ width: '100%', height: '100%' }}>
<Generator
// configProvider={{ prefixCls: prefixClsPandaXform }}
canDelete={canDelete}
......
import React, { useState, useEffect, useRef } from 'react';
import { Input, Modal, Spin, Button } from 'antd';
import { CompassOutlined, SearchOutlined } from '@ant-design/icons';
import { AMapScene, AMapDrawTool, VectorLayer } from '@wisdom-map/amap';
import Drag from '../../../components/Drag'
let amapDrawTool = null; // 存储绘制工具实例
let currentMapInstance = null; // 存储地图的实例
let AMapFunction = null; // 存储地图的构造函数
let coverLayer = {}; // 存储分区的地图对象
const DrawPartition = ({ value, onChange, name, schema }) => {
const mapSettings = window.globalConfig.mapsettings;
const [loading, setLoading] = useState(false);
const [visible, setVisible] = useState(false);
const [partition, setPartition] = useState([]);
const [initPath, setInitPath] = useState([]);
const [finalPathArray, setFinalPathArray] = useState([]);
const [selectedPartition, setSelectedPartition] = useState([]);
const [drawDisabled, setDrawDisabled] = useState(false);
let _temp = [];
/* let _tempCoordinateArray = [];
let _lnglatArray = [];*/
/*
* 问题:在getAMapInfo中,react的hook函数无法生效
* */
const drawFn = (AMap, map) => {
amapDrawTool.draw({
drawMethod: 'repeat',
saveOverlayStatus: 'saveMore',
type: 'Polygon',
drawByUser: true,
drawEnd(e) {
let _arr = map.getLayerByClass('AMap.VectorLayer').getAllOverlays(); // 获取所有矢量图形,这个会包含省市区的边框
// let _arr = []
let _temp = _arr.filter(item => {
let _lng = item.getOptions().extData.lng // 来判断是自己绘制的还是生成的范围框;
if (_lng) {
return true
}
return false
});
_temp = _temp.map(item => {
let _path = item.getPath();
return _path.map(obj => [obj.lng, obj.lat])
})
setFinalPathArray(_temp);
}
})
};
const getAMapInfo = (AMap, map, callback) => {
currentMapInstance = map;
AMapFunction = AMap;
amapDrawTool = new AMapDrawTool({
map, Amap: AMap,
})
let _value = JSON.parse(value);
callback(AMap, map, _value && Array.isArray(_value) && Array.length ? _value : 'init'); // 此时确保实例已经渲染完毕,使用回调绘制区域
setListener();
};
const showMap = () => {
let _array = JSON.parse(value || '');
renderCover(AMapFunction, currentMapInstance, _array)
setVisible(true);
};
const onCancel = () => {
onChange(JSON.stringify(initPath))
setVisible(false);
setDrawDisabled(false);
};
const onOk = () => {
onChange(JSON.stringify(finalPathArray))
setInitPath(finalPathArray);
setVisible(false);
};
const drawStart = (type) => {
setDrawDisabled(true);
currentMapInstance.remove(coverLayer.markers);
drawFn(AMapFunction, currentMapInstance);
renderCover(AMapFunction, currentMapInstance, finalPathArray);
};
const setListener = () => {
let allMarkers = currentMapInstance.getLayerByClass("AMap.VectorLayer").getAllOverlays();
allMarkers.forEach(item => {
item.on('click', function (e) {
if (item.getOptions().isSelected) {
this.setOptions({
strokeColor: '#80d8ff',
isSelected: false
});
} else {
this.setOptions({
strokeColor: 'rgba(115,121,131,0.92)',
isSelected: true
});
}
})
})
}
const drawPause = () => {
// 更新
setDrawDisabled(false);
setInitPath(finalPathArray);
// 结束绘制时,将信息
amapDrawTool.pause();
// 监听鼠标点击
setListener();
};
const deletePartition = () => {
let allMarkers = currentMapInstance.getLayerByClass("AMap.VectorLayer").getAllOverlays();
let _initPath = []
allMarkers.forEach(item => {
if (item.getOptions().isSelected) {
currentMapInstance.remove([item])
} else {
_initPath.push(item.getPath());
}
});
setInitPath(_initPath)
};
const renderCover = (AMap, map, pathData) => {
if (pathData === 'init' || pathData && Array.isArray(pathData) && pathData.length) {
let _pathArray;
if (pathData !== 'init') {
_pathArray = pathData.map((item, index) => ({
type: 'Polygon',
options: {
path: [...item],
fillColor: '#632345',
strokeWeight: 3,
strokeStyle: 'solid',
strokeColor: '#998761',
bubble: false, // 需要做事件监听时,开启冒泡,在地图对象上监听事件,
selfIndex: `marker_${index}`
},
}));
}
coverLayer = new VectorLayer({
Amap: AMap,
map,
datas: pathData !== 'init' ? [..._pathArray] : [],
});
}
};
useEffect(() => {
let _temp = value && JSON.parse(value);
if (_temp) {
setPartition(_temp)
setInitPath(_temp);
}
}, []);
return (
<div style={{ overflow: 'hidden' }}>
<Input
disabled={schema.disabled}
value={value && JSON.stringify(value) || ''}
style={{ width: 0, position: 'absolute', visibility: 'hidden', }}
/>
<Button icon={<SearchOutlined />} onClick={showMap} />
<span style={{ marginLeft: 5 }}>{initPath.length ? `已绘制${initPath.length}块区域` : '未绘制区域'}</span>
{
mapSettings ?
<Drag
width={'80%'}
title="绘制区域"
visible={visible}
onCancel={onCancel}
bodyStyle={{ height: 600, overflowY: 'auto' }}
destroyOnClose={true}
footer={null}
>
{/*{loading && <Spin/>}*/}
<Button type={'primary'} disabled={drawDisabled} style={{ marginBottom: 10, marginRight: 10 }}
onClick={() => drawStart('Polygon')}>开始绘制</Button>
<Button type={'primary'} disabled={!drawDisabled} style={{ marginBottom: 10, marginRight: 10 }}
onClick={() => drawPause('Polygon')}>结束绘制</Button>
<Button type={'danger'} style={{ marginBottom: 10 }} onClick={() => deletePartition()}>删除</Button>
<div style={{ height: '90%' }}>
<AMapScene
getMapInfo={(AMap, map) => getAMapInfo(AMap, map, renderCover)}
mapsettings={mapSettings}
config={mapSettings}
loading
/>
</div>
</Drag> : null
}
</div>
)
}
export default DrawPartition;
import React from 'react'
import React, { useState, useEffect } from 'react'
import { Input, Button } from 'antd'
import { CompassOutlined } from '@ant-design/icons'
import IconPack from '../../IconPack'
import {
ArcGISSceneMap,
AutoCompleteSearch,
Drawtool as drawTool,
Graphic,
GraphicsLayer,
Point,
geomUtils,
} from '@wisdom-map/arcgismap/lib'
import Drag from '../../../components/Drag'
import { isObject, mercatorToLngLat } from '../../../../utils'
import { getLocation } from '../../../../apis/process'
const DrawPartition = (props) => {
const { value, onChange, addons } = props
const { token, client } = window.globalConfig
const { value, onChange, schema, addons } = props
const { disabled, placeholder, presetValue, addressSync } = schema
const [layersConifg, setLayersConifg] = useState(() => {
const mapConfig = window.globalConfig.mapsettings?.layers || null
return { layers: mapConfig };
});
const [visible, setVisible] = useState(false)
const [initCoordinate, setInitCoordinate] = useState([])
const [currentPointerCoordinate, setCurrentPointerCoordinate] = useState([])
const [view, setView] = useState(null)
const getView = (viewObject) => {
if (viewObject) {
setView(viewObject);
let coordGetLayer = viewObject.map.layers.find(layer => layer.id == 'coordGet');
if (coordGetLayer) {
viewObject.map.remove(coordGetLayer);
} else {
coordGetLayer = new GraphicsLayer({
id: 'coordGet',
});
}
viewObject.map.add(coordGetLayer);
if (value) {
coordGetLayer.removeAll();
const newVal = value.split(',');
const defalutGraphic = createGraphic(new Point({
x: newVal[0],
y: newVal[1],
spatialReference: {
wkid: 3857
}
}));
coordGetLayer.add(defalutGraphic);
setTimeout(() => {
viewObject.goTo({
center: geomUtils.toGeometry({ x: Number(newVal[0]), y: Number(newVal[1]) }),
scale: viewObject.scale - 1,
})
}, 2000)
}
getPoints(viewObject, coordGetLayer);
}
}
const createGraphic = (geometry) => {
return new Graphic({
geometry: geometry,
symbol: {
type: "picture-marker", // autocasts as new PictureMarkerSymbol()
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAhCAYAAAA2/OAtAAAACXBIWXMAAArrAAAK6wGCiw1aAAAGlmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNy4xLWMwMDAgNzkuZWRhMmIzZiwgMjAyMS8xMS8xNC0xMjozMDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIzLjEgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMi0xMC0xN1QwOTowODoxNSswODowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjItMTAtMTdUMDk6MTU6MzMrMDg6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjItMTAtMTdUMDk6MTU6MzMrMDg6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg1OTQyNjQzLWNlYzgtNjU0NS05YmY0LTYyZmYxYjdiYmY1OSIgeG1wTU06RG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjE3M2JmMDVmLWVmZGUtMzY0YS1hY2UxLTkwMGExYmZhZDU1NCIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjc0ZmE3MTM1LTljYTItZTM0OC04MjY1LTRjYTlhYjMzNDRmMyI+IDx4bXBNTTpIaXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNyZWF0ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6NzRmYTcxMzUtOWNhMi1lMzQ4LTgyNjUtNGNhOWFiMzM0NGYzIiBzdEV2dDp3aGVuPSIyMDIyLTEwLTE3VDA5OjA4OjE1KzA4OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgMjMuMSAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmJmNjg5ZTI3LWJkMDYtMjk0YS1hYWMyLWU2MjY3ODg2Nzg2MiIgc3RFdnQ6d2hlbj0iMjAyMi0xMC0xN1QwOToxNTozMyswODowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIzLjEgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo4NTk0MjY0My1jZWM4LTY1NDUtOWJmNC02MmZmMWI3YmJmNTkiIHN0RXZ0OndoZW49IjIwMjItMTAtMTdUMDk6MTU6MzMrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMy4xIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5EbHqSAAADjklEQVRIia2W32scVRTHP+fOZM2P3RpDmhobEpBY0qBo5kGEDYsUC+qrUNG2/4AvBaEPvvnWBxXbKqjPPghK6Zt0Nb98qYK6RUUtRce4tARiGuNOlmw2e+/xYXbT3exkk1S/cJiZM/d+7jkzZ84dYRcVMt4kcBaYBkaAAWAVKALXgY+DyP6SNFcSYCPAW8CpYc+ZtEAXiidgFaoIZYUlaxzwKXA+iOztXaGFjPc88Mmw5/qHjO6WxLaWnbBkzRrwchDZL9qghYz3InB1zHOpQ3Wgq98zHcAlJ/xpTRV4IYjs3Da0kPFGgR/GfNefkRiogAX8PeONwcU44ieDyBYbQVwaMq6/D8UpOIWagqmfb5vnx8fedIs/LcqQcf3AJQApZLzHgZ8mfJccRrOMAeegLw3l9bbbN2sG4AkfOD1olH0g70naigaAQaOsODntA8/1yH6hMUz8LpJqo1sUkBM+MOEJnaEioArOxpfWJkL9eM0JH0ije0C1jvA8sBbZ2tp2JeiQD9Ts9iL7kxhJjLTuq/rAYhXGO9ZjI/36C5J7gBbV4sOiD1zfVBk3nUJVQAyIB1hEPLS9bbAZr/SNAa5sqLQWeZI5RY2pn7vEMRsqAFekkPEM8Osh0WOpgzzYHaoqlFRuAcdNEFkHnCup4OC+zAKlOMpzQWSdAQgiew24XFbB1gcdxMox8O06p6X1pYCvHhB9JnWAtDdVqMIccLKedVuTHgVudAsD3j6ANWBTuQ1MBZFdafhb+m8Q2SJwtqJ7p1wHVoGXmoFtkTZF/I4Hr3sdqqGmUDXm/JvZk5eb3A5widO+PJxJDVQ2vvbQIGkrcUDVmGsXnn72lYrf9i26xEf3V+5E38Dmxo0j5ehVAV+JP6qGWWR1ZnT8zG/9A1tA1w7zE/c0VTWfjU8ur/T0XUyqyzvpzIWFo2MVVU3vsG5VXUuE5vP5Nedc5aPJqatbxhSbgVvGFD+cnFpwzqWbrNc5V3LOLebz+cqulROG4T9Hxx/rGVsvyeHKRs4hCPD7gw998N3g8B9N6d4Fbs3MzJTCMFSAjuUYhuFq7ang7+nlO6dQekRk7f3jU+9WxXiqWlbVn2dnZ5fCMGzp8Xtu65Hn/7jc3fv5kXL5zFJv38K65xtUi/Pz8zf3mttRFx8dmf4+4+kbk8dey+VyI/8J1lA2m03NDfR8m81mH/lfgA29N/pwbr9j77ctd/pn419SR9UArKBoRwAAAABJRU5ErkJggg==",
width: "20px",
height: "30px"
},
});
}
const getPoints = (view, coordGetLayer) => {
drawTool.activate({
view,
action: 'point',
target: 'erroSendUpWidget',// 随便写
toolTip: '左键选择位置',
drawEnd: geometry => {
setCurrentPointerCoordinate([geometry.x, geometry.y])
coordGetLayer && coordGetLayer.removeAll()
const coordGraphic = createGraphic(geometry)
coordGetLayer.add(coordGraphic)
getPoints(view, coordGetLayer)
},
rightClick: () => { getPoints(view, coordGetLayer) }
})
}
const showMap = () => {
setVisible(true)
}
const onCancel = () => {
setCurrentPointerCoordinate(initCoordinate)
setVisible(false)
}
const onOk = async () => {
if (addressSync) {
let paths = Object.keys(addons.formData)
let targetPath = null
if (Array.isArray(paths)) {
paths.forEach(v => {
let values = addons.getValue(v)
if (isObject(values)) {
for (let key in values) {
if (key === addressSync) {
targetPath = `${v}.${key}`
}
}
}
})
}
if (targetPath) {
let LngLat = mercatorToLngLat(currentPointerCoordinate[0], currentPointerCoordinate[1])
const { code, data } = await getLocation(LngLat.join(','))
if (Array.isArray(data) && data.length) {
const { pname, adname, name, address } = data[0]
addons.setValue(targetPath, `${pname}/${adname}/${name}`)
}
}
}
setVisible(false)
onChange(currentPointerCoordinate.join(','))
}
useEffect(() => {
if (value) {
let _temp = value && value.split(',') || []
setCurrentPointerCoordinate(_temp)
setInitCoordinate(_temp)
}
}, [value])
useEffect(() => {
if (addons) {
addons.setValueByPath(addons.dataPath, presetValue)
} else {
onChange(presetValue)
}
}, [presetValue])
return (
<div></div>
<div>
{
!disabled ?
<Input
disabled={disabled}
placeholder={placeholder}
value={value}
addonAfter={disabled ? null : <CompassOutlined style={{ color: 'rgba(0, 0, 0, 0.25)' }} onClick={showMap} />}
style={{ width: '100%' }}
onClick={showMap}
/>
:
<Button
icon={<CompassOutlined style={{ color: value ? '#0092fe' : 'rgba(0, 0, 0, 0.25)' }} />}
onClick={() => {
if (value) {
showMap()
}
}}
>
{value ? '查看位置' : '无位置信息'}
</Button>
}
<Drag
width={'80%'}
title="选取坐标"
visible={visible}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
bodyStyle={{ height: 600, overflowY: "auto", position: 'relative' }}
destroyOnClose={true}
{...disabled ? { footer: null } : {}}
>
<div style={{ height: '90%' }}>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
{/* {
view ? <div style={{ width: '400px', position: 'absolute', right: '0', top: '25px' }}>
<AutoCompleteSearch areaName={getCityName()} view={view} />
</div> : ''
} */}
</div>
</Drag>
</div>
)
}
......
import Coordinate from './Coordinate'
import Device from './Device'
import DrawPartition from './DrawPartition/1js'
import DrawPartition from './DrawPartition'
import SearchLocation from './SearchLocation'
const coord = {
......
......@@ -11,6 +11,8 @@ body #app {
}
.pandaXform {
width: 100%;
height: 100%;
background: white;
.fr-generator-container .left-layout {
padding: 10px 0 0 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment