Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
basic-uniapp-v3
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-uniapp-v3
Commits
dfadc655
提交
dfadc655
authored
4月 22, 2026
作者:
吴佳伟
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: 农场地图增加农场和基地的区域渲染
上级
a9b217aa
显示空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
245 行增加
和
95 行删除
+245
-95
index.vue
src/pages/nongchang/detail/index.vue
+245
-95
没有找到文件。
src/pages/nongchang/detail/index.vue
浏览文件 @
dfadc655
...
@@ -27,7 +27,7 @@
...
@@ -27,7 +27,7 @@
})
})
const
showDialog
=
ref
(
false
)
const
showDialog
=
ref
(
false
)
onShow
(()
=>
{
onShow
(()
=>
{
getFarmbaseInfoList
()
//
getFarmbaseInfoList()
})
})
const
model
=
reactive
({
const
model
=
reactive
({
...
@@ -91,6 +91,44 @@
...
@@ -91,6 +91,44 @@
farmbaseApi
.
getFarmbaseInfoById
({
id
}).
then
((
res
)
=>
{
farmbaseApi
.
getFarmbaseInfoById
({
id
}).
then
((
res
)
=>
{
model
.
farmbaseInfo
=
res
model
.
farmbaseInfo
=
res
getDeviceTypeCount
()
getDeviceTypeCount
()
// 切换基地后,将地图视角飞到当前基地上方
let
geojson
=
res
.
geojson
if
(
typeof
geojson
===
'string'
)
{
try
{
geojson
=
JSON
.
parse
(
geojson
)
}
catch
(
e
)
{
geojson
=
null
}
}
if
(
geojson
)
{
// 直接从 geometry 坐标计算中心点和缩放范围
const
coords
=
geojson
.
features
?.[
0
]?.
geometry
?.
coordinates
?.[
0
]
if
(
coords
&&
coords
.
length
>
0
)
{
let
minLon
=
Infinity
,
minLat
=
Infinity
,
maxLon
=
-
Infinity
,
maxLat
=
-
Infinity
for
(
const
c
of
coords
)
{
if
(
c
[
0
]
<
minLon
)
minLon
=
c
[
0
]
if
(
c
[
0
]
>
maxLon
)
maxLon
=
c
[
0
]
if
(
c
[
1
]
<
minLat
)
minLat
=
c
[
1
]
if
(
c
[
1
]
>
maxLat
)
maxLat
=
c
[
1
]
}
const
center
:
[
number
,
number
]
=
[(
minLon
+
maxLon
)
/
2
,
(
minLat
+
maxLat
)
/
2
]
// 使用 flyTo 而非 fitBounds,避免 maxBounds 约束干扰
map
.
flyTo
({
center
,
zoom
:
15
,
duration
:
1000
,
})
}
}
else
if
(
res
.
longitude
&&
res
.
latitude
)
{
map
.
flyTo
({
center
:
[
Number
(
res
.
longitude
),
Number
(
res
.
latitude
)],
zoom
:
15
,
duration
:
1000
,
})
}
else
{
console
.
warn
(
'切换基地: 既没有geojson也没有经纬度'
)
}
})
})
}
}
...
@@ -108,101 +146,233 @@
...
@@ -108,101 +146,233 @@
// 查询农场数据
// 查询农场数据
const
res
=
await
NongchangAPI
.
farmsList
()
const
res
=
await
NongchangAPI
.
farmsList
()
console
.
log
(
'农场列表'
,
res
.
records
)
if
(
!
res
.
records
||
res
.
records
.
length
===
0
)
{
Message
.
toast
(
'未查询到农场信息'
)
return
}
// 获取第一个农场信息
// 获取第一个农场信息
const
item
=
res
.
records
?.[
0
]
const
item
=
res
.
records
?.[
0
]
model
.
id
=
item
.
id
model
.
id
=
item
.
id
model
.
name
=
item
.
farmName
model
.
name
=
item
.
farmName
model
.
description
=
item
.
description
model
.
description
=
item
.
description
if
(
item
.
longitude
&&
item
.
latitude
)
{
model
.
lonlat
=
`
${
item
.
longitude
}
,
${
item
.
latitude
}
`
}
else
{
// 模拟位置数据
model
.
lonlat
=
'111.024108, 29.554847'
Message
.
toast
(
'未设置农场坐标位置,已使用模拟位置数据'
)
}
// 设置页面标题
// 设置页面标题
uni
.
setNavigationBarTitle
({
uni
.
setNavigationBarTitle
({
title
:
item
.
farmName
,
title
:
item
.
farmName
,
})
})
// 设置地图中心点
map
.
flyTo
({
center
:
model
.
lonlat
.
split
(
','
).
map
(
Number
)
as
[
number
,
number
],
duration
:
0
,
})
// 渲染地块数据
// 渲染农场和基地地块数据
model
.
plots
=
[
let
farmGeojson
=
item
.
geojson
turf
.
polygon
(
// geojson 可能是字符串,需要解析
[
if
(
typeof
farmGeojson
===
'string'
)
{
[
try
{
[
111.0235
,
29.5562
],
farmGeojson
=
JSON
.
parse
(
farmGeojson
)
[
111.0255
,
29.5562
],
}
catch
(
e
)
{
[
111.0255
,
29.5558
],
console
.
error
(
'解析农场 geojson 失败:'
,
e
)
[
111.0235
,
29.5558
],
farmGeojson
=
null
[
111.0235
,
29.5562
],
}
],
}
],
if
(
farmGeojson
)
{
{
const
farmFeatures
=
farmGeojson
.
features
?
farmGeojson
.
features
:
[
farmGeojson
]
color
:
'yellow'
,
// 注入农场名称到每个 feature
name
:
'基地 A'
,
for
(
const
feature
of
farmFeatures
)
{
popup
:
`{{name}}`
,
feature
.
properties
=
feature
.
properties
||
{}
feature
.
properties
.
farmName
=
item
.
farmName
}
addDefaultGeoJSONSource
(
map
,
`
${
page
.
id
}
-farm-plot`
,
farmFeatures
)
// 添加农场填充层
map
.
addLayer
({
type
:
'fill'
,
id
:
`
${
page
.
id
}
-farm-plot-fill`
,
source
:
`
${
page
.
id
}
-farm-plot`
,
paint
:
{
'fill-color'
:
'#5db66f'
,
'fill-opacity'
:
0.2
,
'fill-outline-color'
:
'#5db66f'
,
},
},
),
})
turf
.
polygon
(
map
.
addLayer
({
[
type
:
'line'
,
[
id
:
`
${
page
.
id
}
-farm-plot-line`
,
[
111.0225
,
29.5565
],
source
:
`
${
page
.
id
}
-farm-plot`
,
[
111.0238
,
29.5568
],
layout
:
{
[
111.023
,
29.5555
],
'line-join'
:
'round'
,
[
111.022
,
29.5558
],
'line-cap'
:
'round'
,
[
111.0225
,
29.5565
],
],
],
{
color
:
'red'
,
name
:
'基地 B'
,
popup
:
`{{name}}`
,
},
},
),
paint
:
{
turf
.
polygon
(
'line-color'
:
'#5db66f'
,
[
'line-width'
:
4
,
[
[
111.0258
,
29.555
],
[
111.0262
,
29.5542
],
[
111.0252
,
29.554
],
[
111.0258
,
29.555
],
],
],
{
color
:
'blue'
,
name
:
'基地 C'
,
popup
:
`{{name}}`
,
},
},
),
})
// 添加农场名称文字标签(已禁用)
// map.addLayer({
// type: 'symbol',
// id: `${page.id}-farm-label`,
// source: `${page.id}-farm-plot`,
// layout: {
// 'text-field': ['get', 'farmName'],
// 'text-size': 16,
// 'text-anchor': 'center',
// 'text-allow-overlap': true,
// },
// paint: {
// 'text-color': '#ffffff',
// 'text-halo-color': '#5db66f',
// 'text-halo-width': 2,
// },
// })
}
else
{
console
.
warn
(
'农场没有 geojson 数据, item:'
,
JSON
.
stringify
(
item
)?.
substring
(
0
,
500
))
}
// 查询农场基地信息
const
farmbaseRes
=
await
farmbaseApi
.
list
({
farmId
:
model
.
id
})
const
farmbaseRecords
=
farmbaseRes
.
records
||
[]
model
.
farmbaseInfoList
=
farmbaseRecords
// 预定义颜色池(每个基地循环使用)
const
colorPool
=
[
{
fill
:
'#e74c3c'
,
line
:
'#e74c3c'
},
// 红
{
fill
:
'#3498db'
,
line
:
'#3498db'
},
// 蓝
{
fill
:
'#2ecc71'
,
line
:
'#2ecc71'
},
// 绿
{
fill
:
'#f1c40f'
,
line
:
'#f1c40f'
},
// 黄
{
fill
:
'#9b59b6'
,
line
:
'#9b59b6'
},
// 紫
{
fill
:
'#e67e22'
,
line
:
'#e67e22'
},
// 橙
{
fill
:
'#1abc9c'
,
line
:
'#1abc9c'
},
// 青
{
fill
:
'#e91e63'
,
line
:
'#e91e63'
},
// 粉
]
]
addDefaultGeoJSONSource
(
map
,
`
${
page
.
id
}
-plot`
,
model
.
plots
)
addDefaultSplotLayer
(
map
,
`
${
page
.
id
}
-plot`
,
{
// 为每个基地创建独立的 source 和 layer
for
(
let
i
=
0
;
i
<
farmbaseRecords
.
length
;
i
++
)
{
const
base
=
farmbaseRecords
[
i
]
let
geojson
=
base
.
geojson
// geojson 可能是字符串,需要解析
if
(
typeof
geojson
===
'string'
)
{
try
{
geojson
=
JSON
.
parse
(
geojson
)
}
catch
(
e
)
{
console
.
error
(
`解析基地
${
base
.
baseName
}
geojson 失败:`
,
e
)
continue
}
}
if
(
!
geojson
)
continue
// 为当前基地分配颜色
const
color
=
colorPool
[
i
%
colorPool
.
length
]
const
sourceId
=
`
${
page
.
id
}
-base-plot-
${
base
.
id
}
`
const
fillLayerId
=
`
${
sourceId
}
-fill`
const
lineLayerId
=
`
${
sourceId
}
-line`
const
labelLayerId
=
`
${
sourceId
}
-label`
// 处理 geojson,注入基地名称属性
const
features
=
geojson
.
features
?
geojson
.
features
:
[
geojson
]
for
(
const
feature
of
features
)
{
feature
.
properties
=
feature
.
properties
||
{}
feature
.
properties
.
baseName
=
base
.
baseName
}
// 添加 source
addDefaultGeoJSONSource
(
map
,
sourceId
,
features
)
// 添加填充层(直接创建,不使用 addDefaultSplotLayer)
map
.
addLayer
({
type
:
'fill'
,
id
:
fillLayerId
,
source
:
sourceId
,
paint
:
{
paint
:
{
'fill-opacity'
:
0.2
,
'fill-color'
:
color
.
fill
,
'fill-outline-color'
:
[
'get'
,
'color'
],
'fill-opacity'
:
0.5
,
'fill-outline-color'
:
color
.
line
,
},
},
})
})
// 添加边框层
map
.
addLayer
({
map
.
addLayer
({
type
:
'line'
,
type
:
'line'
,
id
:
`
${
page
.
id
}
-plot-line`
,
id
:
lineLayerId
,
source
:
`
${
page
.
id
}
-plot`
,
source
:
sourceId
,
layout
:
{
layout
:
{
'line-join'
:
'round'
,
'line-join'
:
'round'
,
'line-cap'
:
'round'
,
'line-cap'
:
'round'
,
},
},
paint
:
{
paint
:
{
'line-color'
:
[
'get'
,
'color'
],
'line-color'
:
color
.
line
,
'line-width'
:
2
,
'line-width'
:
3
,
},
})
// 添加基地名称文字标签
map
.
addLayer
({
type
:
'symbol'
,
id
:
labelLayerId
,
source
:
sourceId
,
layout
:
{
'text-field'
:
[
'get'
,
'baseName'
],
'text-size'
:
14
,
'text-anchor'
:
'center'
,
'text-offset'
:
[
0
,
0
],
'text-allow-overlap'
:
true
,
},
paint
:
{
'text-color'
:
'#ffffff'
,
'text-halo-color'
:
color
.
line
,
'text-halo-width'
:
2
,
},
},
})
})
}
// 将地图视角飞到第一个基地的上方
if
(
farmbaseRecords
.
length
>
0
)
{
const
firstBase
=
farmbaseRecords
[
0
]
model
.
farmbaseInfo
=
firstBase
let
firstGeojson
=
firstBase
.
geojson
if
(
typeof
firstGeojson
===
'string'
)
{
try
{
firstGeojson
=
JSON
.
parse
(
firstGeojson
)
}
catch
(
e
)
{
firstGeojson
=
null
}
}
if
(
firstGeojson
)
{
const
coords
=
firstGeojson
.
features
?.[
0
]?.
geometry
?.
coordinates
?.[
0
]
if
(
coords
&&
coords
.
length
>
0
)
{
let
minLon
=
Infinity
,
minLat
=
Infinity
,
maxLon
=
-
Infinity
,
maxLat
=
-
Infinity
for
(
const
c
of
coords
)
{
if
(
c
[
0
]
<
minLon
)
minLon
=
c
[
0
]
if
(
c
[
0
]
>
maxLon
)
maxLon
=
c
[
0
]
if
(
c
[
1
]
<
minLat
)
minLat
=
c
[
1
]
if
(
c
[
1
]
>
maxLat
)
maxLat
=
c
[
1
]
}
map
.
flyTo
({
center
:
[(
minLon
+
maxLon
)
/
2
,
(
minLat
+
maxLat
)
/
2
],
zoom
:
15
,
duration
:
0
,
})
}
}
else
if
(
firstBase
.
longitude
&&
firstBase
.
latitude
)
{
map
.
flyTo
({
center
:
[
Number
(
firstBase
.
longitude
),
Number
(
firstBase
.
latitude
)],
zoom
:
15
,
duration
:
0
,
})
}
}
getDeviceTypeCount
()
// 如果农场没有 geojson 但有坐标,则使用坐标定位
if
(
!
farmGeojson
&&
item
.
longitude
&&
item
.
latitude
)
{
model
.
lonlat
=
`
${
item
.
longitude
}
,
${
item
.
latitude
}
`
}
else
if
(
!
farmGeojson
&&
!
item
.
longitude
)
{
model
.
lonlat
=
'111.024108, 29.554847'
Message
.
toast
(
'未设置农场坐标位置,已使用模拟位置数据'
)
}
// 渲染设备数据
// 渲染设备数据
// 渲染设备数据
model
.
devices
=
[
model
.
devices
=
[
...
@@ -233,9 +403,6 @@
...
@@ -233,9 +403,6 @@
'icon-size'
:
1
,
'icon-size'
:
1
,
},
},
})
})
// 查询农场信息
getFarmbaseInfoList
()
},
},
onSourceRequestHandle
:
()
=>
{
onSourceRequestHandle
:
()
=>
{
page
.
requests
--
page
.
requests
--
...
@@ -248,28 +415,6 @@
...
@@ -248,28 +415,6 @@
},
},
})
})
/* const mapAddImage = new Image();
mapAddImage.src = '/static/images/test/mapLayer.png';
// 添加自定义图像图层
map.on('load','custom-image',()=>{
console.log("进到自定义的地图里了")
// 添加图片资源
map.addImage('custom-image', mapAddImage, { pixelRatio: 2 }); // 确保路径正确且图片可访问
// 添加图层到地图上,并指定位置和大小
map.addLayer({
id: 'custom-image-layer', // 图层的唯一ID
type: 'raster', // 或者使用 'raster' 根据需要选择类型
source: {
type: 'image', // 指定源类型为图像
url: '/static/images/test/mapLayer.png' // 同上,确保路径正确
},
layout: {
'icon-image': 'custom-image', // 使用上面添加的图片ID
'icon-anchor': 'center' // 设置锚点为图片中心,根据需要调整
}
});
}) */
// 左侧工具栏小部件
// 左侧工具栏小部件
const
[
registerToolBoxWidget
]
=
useToolBoxWidget
({
const
[
registerToolBoxWidget
]
=
useToolBoxWidget
({
show
:
true
,
show
:
true
,
...
@@ -379,7 +524,6 @@ map.on('load','custom-image',()=>{
...
@@ -379,7 +524,6 @@ map.on('load','custom-image',()=>{
}
}
// 保留原有的导航栏按钮点击回调(如果有需要的话)
// 保留原有的导航栏按钮点击回调(如果有需要的话)
onNavigationBarButtonTap
((
e
)
=>
{
onNavigationBarButtonTap
((
e
)
=>
{
console
.
log
(
e
)
if
(
e
.
index
===
0
)
{
if
(
e
.
index
===
0
)
{
Navigate
.
to
(
`/pages/jidiguanli/add?farmId=
${
model
.
id
}
`
)
Navigate
.
to
(
`/pages/jidiguanli/add?farmId=
${
model
.
id
}
`
)
}
}
...
@@ -509,6 +653,7 @@ map.on('load','custom-image',()=>{
...
@@ -509,6 +653,7 @@ map.on('load','custom-image',()=>{
</view>
</view>
</view>
</view>
<view
class=
"box-3"
>
<view
class=
"box-3"
>
<!-- 基地切换 -->
<view
class=
"box-3-tags"
>
<view
class=
"box-3-tags"
>
<view
<view
class=
"box-3-tags-item"
class=
"box-3-tags-item"
...
@@ -898,9 +1043,12 @@ map.on('load','custom-image',()=>{
...
@@ -898,9 +1043,12 @@ map.on('load','custom-image',()=>{
display
:
flex
;
display
:
flex
;
flex-direction
:
row
;
flex-direction
:
row
;
font-size
:
28
rpx
;
font-size
:
28
rpx
;
overflow-x
:
auto
;
white-space
:
nowrap
;
-webkit-overflow-scrolling
:
touch
;
.box-3-tags-item
{
.box-3-tags-item
{
width
:
31%
;
display
:
inline-block
;
height
:
100%
;
height
:
100%
;
margin-right
:
20
rpx
;
margin-right
:
20
rpx
;
text-align
:
center
;
text-align
:
center
;
...
@@ -909,6 +1057,8 @@ map.on('load','custom-image',()=>{
...
@@ -909,6 +1057,8 @@ map.on('load','custom-image',()=>{
background-color
:
rgba
(
$
color
:
#5db66f
,
$
alpha
:
0.1
);
background-color
:
rgba
(
$
color
:
#5db66f
,
$
alpha
:
0.1
);
color
:
#5db66f
;
color
:
#5db66f
;
font-weight
:
300
;
font-weight
:
300
;
padding
:
0
30
rpx
;
flex-shrink
:
0
;
}
}
.box-3-tags-item-active
{
.box-3-tags-item-active
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论