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

如何使用Django与Leaflet判断点是否位于矩形、圆形内部

Django + Leaflet 空间范围判断功能实现方案

前端实现

基于Bootstrap的modal fade组件编写参数录入表单,示例代码如下:

<!-- 模态框触发按钮 -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#rectParamModal">
  录入矩形范围参数
</button>

<!-- Modal Fade 表单 -->
<div class="modal fade" id="rectParamModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">矩形范围参数</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <form id="rectParamForm">
          <div class="mb-3">
            <label class="form-label">西南角经度</label>
            <input type="number" step="0.000001" name="sw_lng" class="form-control" required>
          </div>
          <div class="mb-3">
            <label class="form-label">西南角纬度</label>
            <input type="number" step="0.000001" name="sw_lat" class="form-control" required>
          </div>
          <div class="mb-3">
            <label class="form-label">东北角经度</label>
            <input type="number" step="0.000001" name="ne_lng" class="form-control" required>
          </div>
          <div class="mb-3">
            <label class="form-label">东北角纬度</label>
            <input type="number" step="0.000001" name="ne_lat" class="form-control" required>
          </div>
        </form>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
        <button type="button" class="btn btn-primary" id="submitRectParam">确认提交</button>
      </div>
    </div>
  </div>
</div>

前端空间范围判断逻辑

Leaflet 内置了空间计算API,可以直接在前端完成判断,无需请求后端:

  • 矩形范围判断:使用L.LatLngBounds的contains()方法
  • 圆形范围判断:使用distanceTo()方法计算点到圆心的距离,和圆形半径比较即可,返回结果单位为米
    示例代码:
// 1. 矩形判断逻辑
document.getElementById('submitRectParam').addEventListener('click', function() {
  const formData = new FormData(document.getElementById('rectParamForm'))
  const swLng = parseFloat(formData.get('sw_lng'))
  const swLat = parseFloat(formData.get('sw_lat'))
  const neLng = parseFloat(formData.get('ne_lng'))
  const neLat = parseFloat(formData.get('ne_lat'))
  // 生成矩形范围对象
  const rectBounds = L.latLngBounds([swLat, swLng], [neLat, neLng])
  // 待判断的目标坐标点,示例为北京坐标
  const targetPoint = L.latLng(39.9042, 116.4074)
  // 输出判断结果,true为在范围内,false为不在
  console.log('是否在矩形内:', rectBounds.contains(targetPoint))
})

// 2. 圆形判断逻辑
// 示例圆形参数:圆心坐标(39.9042, 116.4074),半径1000米
const circleCenter = L.latLng(39.9042, 116.4074)
const circleRadius = 1000
const targetPoint = L.latLng(39.908, 116.41)
const distance = circleCenter.distanceTo(targetPoint)
console.log('是否在圆形内:', distance <= circleRadius)

后端实现(如需服务端校验/业务处理)

如果需要在Django端完成判断,可选择以下两种方案:

轻量实现方案(无需额外依赖)

直接手写空间判断逻辑,适合业务简单、不需要复杂空间计算的场景:

import math

# 矩形范围判断
def is_point_in_rect(target_lng, target_lat, sw_lng, sw_lat, ne_lng, ne_lat):
    # 普通场景未处理跨180度经线情况,如有全球范围需求可自行扩展
    return (sw_lng <= target_lng <= ne_lng) and (sw_lat <= target_lat <= ne_lat)

# 圆形范围判断,基于Haversine公式计算球面距离
def is_point_in_circle(target_lng, target_lat, center_lng, center_lat, radius):
    R = 6371000  # 地球半径,单位米
    phi1 = math.radians(center_lat)
    phi2 = math.radians(target_lat)
    delta_phi = math.radians(target_lat - center_lat)
    delta_lambda = math.radians(target_lng - center_lng)
    a = math.sin(delta_phi/2)**2 + math.cos(phi1)*math.cos(phi2)*math.sin(delta_lambda/2)**2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
    distance = R * c
    return distance <= radius

GeoDjango 方案(适合复杂空间业务)

如果项目已有GeoDjango环境,可直接调用内置空间API实现判断,支持更复杂的空间运算:

from django.contrib.gis.geos import Point, Polygon

# 矩形判断
def geo_is_point_in_rect(target_point, sw_lng, sw_lat, ne_lng, ne_lat):
    # target_point为GEOS的Point对象,格式为Point(lng, lat)
    rect_polygon = Polygon.from_bbox((sw_lng, sw_lat, ne_lng, ne_lat))
    return rect_polygon.contains(target_point)

表单校验

Django端可通过Form类校验前端提交的矩形参数合法性:

from django import forms

class RectParamForm(forms.Form):
    sw_lng = forms.FloatField(min_value=-180, max_value=180)
    sw_lat = forms.FloatField(min_value=-90, max_value=90)
    ne_lng = forms.FloatField(min_value=-180, max_value=180)
    ne_lat = forms.FloatField(min_value=-90, max_value=90)

    def clean(self):
        cleaned_data = super().clean()
        if cleaned_data.get('sw_lng') >= cleaned_data.get('ne_lng') or cleaned_data.get('sw_lat') >= cleaned_data.get('ne_lat'):
            raise forms.ValidationError("西南角坐标必须小于东北角坐标")
        return cleaned_data

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 12:06:04