Files
smart-crop-ui/src/GEOMETRY_MAP_INTEGRATION_STATUS.md

11 KiB
Raw Blame History

几何计算工具 - 地图选点功能集成状态

已完成

1. 面积计算 Tab - 部分完成

  • 添加了地图/手动切换按钮
  • 添加了地图选点组件
  • 添加了条件渲染开始
  • ⚠️ 需要关闭手动输入的Card标签
  • ⚠️ 需要将计算按钮移到外面

🔧 需要继续完成的修改

修改位置

文件:/components/field/FieldSpatialQuery.tsx
对话框位置约第1436行开始


步骤1: 完成面积计算Tab的收尾

在第1550行附近找到

                </Button>
              </Card>

              {geomResult && geomResult.type === 'area' && (

将第1550行的 </Card> 改为:

              </Card>
              )}

              <Button 
                onClick={handleCalculateArea}
                className="w-full bg-green-600 hover:bg-green-700"
              >
                <Calculator className="w-4 h-4 mr-2" />
                计算面积 (ST_Area)
              </Button>

              {geomResult && geomResult.type === 'area' && (

这样就完成了面积计算Tab的地图选点功能。


步骤2: 修改周长计算Tab约第1579行

找到:

            {/* 周长计算 */}
            <TabsContent value="perimeter" className="space-y-4">
              <Card className="p-6">
                <h3 className="mb-4">多边形坐标点</h3>

替换为:

            {/* 周长计算 */}
            <TabsContent value="perimeter" className="space-y-4">
              {/* 选择方式切换 */}
              <div className="flex gap-2">
                <Button
                  variant={mapPickMode === 'polygon' ? 'default' : 'outline'}
                  onClick={() => setMapPickMode(mapPickMode === 'polygon' ? null : 'polygon')}
                  className="flex-1"
                >
                  <MousePointer2 className="w-4 h-4 mr-2" />
                  {mapPickMode === 'polygon' ? '正在使用地图选点' : '地图选点'}
                </Button>
                <Button
                  variant={mapPickMode === null ? 'default' : 'outline'}
                  onClick={() => setMapPickMode(null)}
                  className="flex-1"
                >
                  <Edit3 className="w-4 h-4 mr-2" />
                  手动输入坐标
                </Button>
              </div>

              {mapPickMode === 'polygon' ? (
                <MapPointPicker
                  points={geomPoints}
                  mode="polygon"
                  onPointsChange={setGeomPoints}
                  height="400px"
                  title="在地图上选择多边形顶点"
                />
              ) : (
                <Card className="p-6">
                  <h3 className="mb-4">多边形坐标点</h3>

然后找到周长计算的按钮部分约第1612行

                <Button 
                  onClick={handleCalculatePerimeter}
                  className="w-full mt-4 bg-blue-600 hover:bg-blue-700"
                >
                  <Ruler className="w-4 h-4 mr-2" />
                  计算周长 (ST_Perimeter)
                </Button>
              </Card>

              {geomResult && geomResult.type === 'perimeter' && (

替换为:

              </Card>
              )}

              <Button 
                onClick={handleCalculatePerimeter}
                className="w-full bg-blue-600 hover:bg-blue-700"
              >
                <Ruler className="w-4 h-4 mr-2" />
                计算周长 (ST_Perimeter)
              </Button>

              {geomResult && geomResult.type === 'perimeter' && (

步骤3: 修改中心点计算Tab约第1639行

使用与步骤2相同的模式修改中心点计算。

切换按钮和地图组件相同,计算按钮改为:

              </Card>
              )}

              <Button 
                onClick={handleCalculateCentroid}
                className="w-full bg-purple-600 hover:bg-purple-700"
              >
                <MapPin className="w-4 h-4 mr-2" />
                计算中心点 (ST_Centroid)
              </Button>

步骤4: 修改距离计算Tab约第1672行

距离计算需要为两个点分别添加地图选择。

替换整个距离计算Tab为

            {/* 距离计算 */}
            <TabsContent value="distance" className="space-y-4">
              {/* 点1选择 */}
              <Card className="p-6">
                <h3 className="mb-4">1坐标</h3>
                
                <div className="flex gap-2 mb-4">
                  <Button
                    variant={mapPickMode === 'distance-p1' ? 'default' : 'outline'}
                    onClick={() => setMapPickMode(mapPickMode === 'distance-p1' ? null : 'distance-p1')}
                    className="flex-1"
                  >
                    <MousePointer2 className="w-4 h-4 mr-2" />
                    {mapPickMode === 'distance-p1' ? '正在使用地图选点' : '地图选点'}
                  </Button>
                  <Button
                    variant={mapPickMode !== 'distance-p1' ? 'default' : 'outline'}
                    onClick={() => setMapPickMode(null)}
                    className="flex-1"
                  >
                    <Edit3 className="w-4 h-4 mr-2" />
                    手动输入坐标
                  </Button>
                </div>

                {mapPickMode === 'distance-p1' ? (
                  <MapPointPicker
                    points={[distPoint1]}
                    mode="single"
                    onPointsChange={(points) => setDistPoint1(points[0] || distPoint1)}
                    height="300px"
                    title="在地图上选择点1位置"
                  />
                ) : (
                  <div className="grid grid-cols-2 gap-3">
                    <div>
                      <label className="text-sm text-muted-foreground">纬度</label>
                      <Input
                        type="number"
                        step="0.000001"
                        value={distPoint1.lat}
                        onChange={(e) => setDistPoint1({ ...distPoint1, lat: parseFloat(e.target.value) || 0 })}
                      />
                    </div>
                    <div>
                      <label className="text-sm text-muted-foreground">经度</label>
                      <Input
                        type="number"
                        step="0.000001"
                        value={distPoint1.lng}
                        onChange={(e) => setDistPoint1({ ...distPoint1, lng: parseFloat(e.target.value) || 0 })}
                      />
                    </div>
                  </div>
                )}
              </Card>

              {/* 点2选择 */}
              <Card className="p-6">
                <h3 className="mb-4">2坐标</h3>
                
                <div className="flex gap-2 mb-4">
                  <Button
                    variant={mapPickMode === 'distance-p2' ? 'default' : 'outline'}
                    onClick={() => setMapPickMode(mapPickMode === 'distance-p2' ? null : 'distance-p2')}
                    className="flex-1"
                  >
                    <MousePointer2 className="w-4 h-4 mr-2" />
                    {mapPickMode === 'distance-p2' ? '正在使用地图选点' : '地图选点'}
                  </Button>
                  <Button
                    variant={mapPickMode !== 'distance-p2' ? 'default' : 'outline'}
                    onClick={() => setMapPickMode(null)}
                    className="flex-1"
                  >
                    <Edit3 className="w-4 h-4 mr-2" />
                    手动输入坐标
                  </Button>
                </div>

                {mapPickMode === 'distance-p2' ? (
                  <MapPointPicker
                    points={[distPoint2]}
                    mode="single"
                    onPointsChange={(points) => setDistPoint2(points[0] || distPoint2)}
                    height="300px"
                    title="在地图上选择点2位置"
                  />
                ) : (
                  <div className="grid grid-cols-2 gap-3">
                    <div>
                      <label className="text-sm text-muted-foreground">纬度</label>
                      <Input
                        type="number"
                        step="0.000001"
                        value={distPoint2.lat}
                        onChange={(e) => setDistPoint2({ ...distPoint2, lat: parseFloat(e.target.value) || 0 })}
                      />
                    </div>
                    <div>
                      <label className="text-sm text-muted-foreground">经度</label>
                      <Input
                        type="number"
                        step="0.000001"
                        value={distPoint2.lng}
                        onChange={(e) => setDistPoint2({ ...distPoint2, lng: parseFloat(e.target.value) || 0 })}
                      />
                    </div>
                  </div>
                )}
              </Card>

              <Button 
                onClick={handleCalculateDistance}
                className="w-full bg-orange-600 hover:bg-orange-700"
              >
                <MapIcon className="w-4 h-4 mr-2" />
                计算距离 (ST_Distance)
              </Button>

              {geomResult && geomResult.type === 'distance' && (
                {/* 保留原有的结果显示 */}
              )}
            </TabsContent>

步骤5: 修改包围盒计算Tab约第1758行

使用与步骤2、3相同的模式修改包围盒计算。

计算按钮改为:

              </Card>
              )}

              <Button 
                onClick={handleCalculateBBox}
                className="w-full bg-indigo-600 hover:bg-indigo-700"
              >
                <Circle className="w-4 h-4 mr-2" />
                计算包围盒 (ST_Envelope)
              </Button>

📝 修改要点总结

对于多边形计算(面积、周长、中心点、包围盒)

  1. <TabsContent> 开头添加切换按钮
  2. 添加条件渲染:{mapPickMode === 'polygon' ? <MapPointPicker /> : <Card>手动输入</Card>}
  3. 关闭手动输入的 </Card> 后添加 )}
  4. 将计算按钮移到条件渲染外面,去掉 mt-4
  5. 保留结果显示部分不变

对于距离计算

  1. 分别为点1和点2创建独立的Card
  2. 每个Card内都有切换按钮和条件渲染
  3. 使用 'distance-p1''distance-p2' 模式
  4. 使用 mode="single" 的 MapPointPicker
  5. 计算按钮和结果显示在最外面

完成后测试

  • 面积计算 - 地图选点 ✓
  • 面积计算 - 手动输入 ✓
  • 周长计算 - 地图选点
  • 中心点计算 - 地图选点
  • 距离计算 - 点1地图选择
  • 距离计算 - 点2地图选择
  • 包围盒计算 - 地图选点
  • 模式切换 - 坐标保留
  • 计算功能 - 正常工作

状态: 面积计算已完成60%需要手动完成剩余40%
预计时间: 10-15分钟
难度: 简单,重复性操作