You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何新增类实现多边形地块绘制?CI开发GIS绘制触发地图平移问题

地块绘制功能异常排查

异常效果截图:
点击绘制后触发地图平移的异常界面

问题根因

你贴出的是CodeIgniter框架下负责地块、几何数据读写的后端模型层代码,这部分代码只处理数据库CRUD逻辑,和你遇到的「无法触发区域绘制、点击拖拽反而平移地图」的前端交互异常完全无关。
这个异常的核心原因是地图绘制交互没有被正确激活,地图默认的拖拽平移交互始终处于最高响应优先级,点击/拖拽地图时自然只会触发平移,不会进入绘制打点状态。

排查修复步骤

  • 先排查前端依赖加载问题
    不管你用的是Leaflet、OpenLayers、Mapbox GL还是国内地图JS API,绘制功能都依赖对应的绘制插件(比如Leaflet.draw/Leaflet-Geoman、OpenLayers的Draw交互模块),漏引插件的JS/CSS文件会直接导致绘制实例初始化失败,所有绘制相关的方法调用都不会生效。按F12打开浏览器控制台,先看有没有资源加载404、JS初始化报错,先把这类基础错误清掉。
  • 确认绘制模式激活逻辑正确
    绝大多数地图SDK不会默认开启绘制,必须在点击绘制按钮后主动调用激活方法,同时拦截事件透传给平移交互:
    如果你用Leaflet + Geoman绘制插件,正确激活多边形绘制的代码参考:
    // 绑定绘制按钮点击事件
    document.querySelector('#draw-polygon-btn').addEventListener('click', () => {
      // 先关闭其他可能冲突的交互
      map.pm.disableGlobalEditMode();
      map.pm.disableGlobalDragMode();
      // 激活多边形绘制,插件会自动临时禁用地图平移
      map.pm.enableDraw('Polygon', {
        allowSelfIntersection: false,
        snappable: true
      });
    })
    
    如果你用OpenLayers,添加绘制交互时要注意阻止事件冒泡,避免透传给平移交互:
    const drawInteraction = new ol.interaction.Draw({
      source: polygonSource,
      type: 'Polygon',
      stopClick: true // 核心配置,阻止点击事件传递给下层的平移交互
    });
    map.addInteraction(drawInteraction);
    // 默认关闭绘制交互,点击按钮才激活
    drawInteraction.setActive(false);
    document.querySelector('#draw-polygon-btn').addEventListener('click', () => {
      // 临时禁用默认拖拽平移交互
      map.getInteractions().forEach(i => {
        if (i instanceof ol.interaction.DragPan) i.setActive(false);
      });
      drawInteraction.setActive(true);
    })
    // 绘制结束后记得重新启用平移交互
    drawInteraction.on('drawend', () => {
      drawInteraction.setActive(false);
      map.getInteractions().forEach(i => {
        if (i instanceof ol.interaction.DragPan) i.setActive(true);
      });
    })
    
  • 检查事件绑定冲突
    如果绘制按钮的点击事件被其他逻辑拦截、或者激活绘制的代码因为变量作用域问题拿不到map实例,会导致点击按钮后根本没执行绘制激活逻辑,地图始终停留在默认可平移状态。可以在激活绘制的代码行加个console标记,点击按钮时看控制台有没有对应输出,确认逻辑是否真的执行到了。
  • 补全后端缺失逻辑
    你当前的Sawah_model里addSawah方法调用了addSawahGeometry,但没有给出这个方法的实现,记得补上往geometries表写入geo_type、coordinates字段的逻辑,不然后端接收前端传的多边形坐标后存不到库里,权属登记的地块形状数据会丢失。

你贴出的后端模型代码如下,这部分逻辑除了缺失addSawahGeometry实现外,其余CRUD逻辑没有明显问题:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Sawah_model extends CI_Model {
  public function getAllSawah(){
    $this->db->select('f.id, f.color, f.landowner, f.crop, f.hamlet, f.planting_date, g.geo_type, g.coordinates');
    $this->db->from('field f');
    $this->db->join('geometries g', 'f.id = g.field_id');
    $q = $this->db->get();
    
    return $q->result();
  }

  public function addSawah(){
    $data = array(
      "color" => $this->input->post('color'),
      "landowner" => $this->input->post('owner'),
      "crop" => $this->input->post('crop'),
      "hamlet" => $this->input->post('hamlet'),
      "planting_date" => $this->input->post('planting_date')
    );
    $this->db->insert('field', $data);
    
    $last_id = $this->db->insert_id();
    $this->addSawahGeometry($last_id);
  }

  public function checkSawahByID($id){
    return $this->db->get_where('field', ['id' => $id])->num_rows();
  }

  public function getSawahByID($id){
    $this->db->select('f.id, f.color, f.landowner, f.crop, f.hamlet, f.planting_date, g.geo_type, g.coordinates');
    $this->db->from('field f');
    $this->db->join('geometries g', 'f.id = g.field_id');
    $this->db->where('f.id', (int)$id);
    $q = $this->db->get();
    
    return $q->row();
  }
}

内容的提问来源于stack exchange,提问作者Ellodimes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 23:00:11