gis-mapping
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGIS Mapping (Leaflet-First)
GIS地图开发(以Leaflet为核心)
Quick Summary
快速概览
- Leaflet-first mapping for web apps (default engine)
- Optional OpenStreetMap tiles or other providers
- Location selection (marker, polygon, rectangle) + map UI patterns
- Geofencing enforcement with client + server validation (see geofencing.md)
- Performance, clustering, and safe storage of spatial data
- 面向Web应用的以Leaflet为核心的地图开发(默认引擎)
- 可选OpenStreetMap瓦片或其他服务提供商
- 位置选择(标记点、多边形、矩形)+ 地图UI模式
- 结合客户端与服务端验证的地理围栏实施(详见geofencing.md)
- 空间数据的性能优化、聚类及安全存储
Capability Index (Leaflet-First)
功能索引(以Leaflet为核心)
Use this index to load only the section you need. Details live in
skills/gis-mapping/references/leaflet-capabilities.md.
- Basic Mapping & Visualization (core Leaflet)
- Spatial Queries (Turf.js)
- Geocoding (Nominatim or Leaflet Control Geocoder)
- Buffering & Zone Analysis (Turf.js)
- Heatmaps & Density (leaflet.heat)
- Routing & Network Analysis (OSRM / GraphHopper + leaflet-routing-machine)
- Drawing & Editing (leaflet.draw / Geoman)
- Measurement Tools (leaflet-measure or custom)
- Clustering & Aggregation (leaflet.markercluster)
- Spatial Analysis (Turf.js)
- Time-Based Analysis (custom + heat)
- Export & Printing (html2canvas/jsPDF + GeoJSON export)
使用此索引仅加载你需要的模块。详细内容请查看
skills/gis-mapping/references/leaflet-capabilities.md。
- 基础地图与可视化(核心Leaflet功能)
- 空间查询(Turf.js)
- 地理编码(Nominatim或Leaflet Control Geocoder)
- 缓冲区与区域分析(Turf.js)
- 热力图与密度分析(leaflet.heat)
- 路径规划与网络分析(OSRM / GraphHopper + leaflet-routing-machine)
- 绘图与编辑(leaflet.draw / Geoman)
- 测量工具(leaflet-measure或自定义实现)
- 聚类与聚合(leaflet.markercluster)
- 空间分析(Turf.js)
- 基于时间的分析(自定义实现+热力图)
- 导出与打印(html2canvas/jsPDF + GeoJSON导出)
When to Use
适用场景
- You need interactive maps for customers, assets, farms, or delivery zones
- Users must select or edit locations on a map
- You must enforce geo-fencing or boundary validation
- You need GIS data display with filters, legends, and clustering
- 需为客户、资产、农场或配送区域提供交互式地图
- 用户需要在地图上选择或编辑位置
- 必须实施地理围栏或边界验证
- 需要结合筛选器、图例和聚类功能展示GIS数据
Key Patterns
核心模式
- Leaflet is the default mapping engine.
- Always include attribution for the chosen tile provider.
- Capture geometry in GeoJSON and validate server-side.
- Use bounding-box checks before deeper polygon math.
- Cluster markers when data is large or dense.
- Store optional tile provider API keys in system settings (e.g., ) and load them at runtime.
osm_api_key - Default to terrain tiles (OpenTopoMap) for administrative borders.
- Leaflet为默认地图引擎
- 必须为所选瓦片服务提供商添加版权声明
- 以GeoJSON格式捕获几何数据并在服务端验证
- 在进行深度多边形计算前先使用边界框检查
- 当数据量大或密集时使用标记聚类
- 将可选瓦片服务提供商的API密钥存储在系统设置中(如)并在运行时加载
osm_api_key - 默认使用地形瓦片(OpenTopoMap)展示行政边界
Leaflet Standardization (BIRDC)
Leaflet标准化规范(BIRDC)
- Use a shared Leaflet configuration for tile URLs, attribution, and defaults.
- Prefer a shared loader or include pattern so Leaflet CSS/JS is consistent across pages.
- Use public/farmer-profile.php as the canonical Leaflet UI reference.
- 为瓦片URL、版权声明和默认配置使用共享的Leaflet配置
- 优先使用共享加载器或引入模式,确保Leaflet CSS/JS在各页面保持一致
- 以public/farmer-profile.php作为Leaflet UI的标准参考实现
Stack Choices (Frontend)
技术栈选择(前端)
- Leaflet (default): Lightweight, fastest to implement, best for most apps.
- OpenLayers (optional): Heavyweight GIS controls and projections.
- MapLibre GL JS (optional): Vector tiles, smoother at scale.
- Leaflet(默认):轻量、易于实现,适用于大多数应用
- OpenLayers(可选):提供重量级GIS控件和投影支持
- MapLibre GL JS(可选):支持矢量瓦片,大规模场景下更流畅
Data Model & Storage
数据模型与存储
- Point: +
latitude(DECIMAL(10,7))longitude - Polygon/Boundary: Store as GeoJSON (TEXT/JSON)
- Metadata: ,
location_label,addresslast_updated_at
Recommended formats:
- GeoJSON for portability across JS + backend
- WKT only if your DB tooling depends on it
- 点数据:+
latitude(DECIMAL(10,7)类型)longitude - 多边形/边界:以GeoJSON格式存储(TEXT/JSON类型)
- 元数据:、
location_label、addresslast_updated_at
推荐格式:
- 跨JS与后端的可移植性优先选择GeoJSON
- 仅当数据库工具依赖时使用WKT格式
Map Initialization (Leaflet)
地图初始化(Leaflet)
html
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>javascript
const map = L.map("map").setView([0.3476, 32.5825], 12);
const osmApiKey = window.osmApiKey || "";
const osmTileUrl = osmApiKey
? `https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?api_key=${osmApiKey}`
: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
const osm = L.tileLayer(osmTileUrl, {
attribution: "© OpenStreetMap contributors",
maxZoom: 19,
});
const terrain = L.tileLayer(
"https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
{
attribution: "© OpenTopoMap",
maxZoom: 17,
},
);
terrain.addTo(map);html
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>javascript
const map = L.map("map").setView([0.3476, 32.5825], 12);
const osmApiKey = window.osmApiKey || "";
const osmTileUrl = osmApiKey
? `https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?api_key=${osmApiKey}`
: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
const osm = L.tileLayer(osmTileUrl, {
attribution: "© OpenStreetMap contributors",
maxZoom: 19,
});
const terrain = L.tileLayer(
"https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
{
attribution: "© OpenTopoMap",
maxZoom: 17,
},
);
terrain.addTo(map);Location Selection Patterns
位置选择模式
Marker (Point)
标记点(Point)
- Single click adds/updates a marker
- Store coordinates in hidden inputs
javascript
let marker;
map.on("click", (e) => {
if (marker) map.removeLayer(marker);
marker = L.marker(e.latlng).addTo(map);
document.querySelector("#latitude").value = e.latlng.lat;
document.querySelector("#longitude").value = e.latlng.lng;
});- 单击添加/更新标记
- 将坐标存储在隐藏输入框中
javascript
let marker;
map.on("click", (e) => {
if (marker) map.removeLayer(marker);
marker = L.marker(e.latlng).addTo(map);
document.querySelector("#latitude").value = e.latlng.lat;
document.querySelector("#longitude").value = e.latlng.lng;
});Polygon / Rectangle (Area)
多边形 / 矩形(区域)
Use Leaflet Draw or Geoman. Store GeoJSON geometry.
javascript
const drawn = new L.FeatureGroup().addTo(map);
const drawControl = new L.Control.Draw({
draw: { polygon: true, rectangle: true, marker: false, circle: false },
edit: { featureGroup: drawn },
});
map.addControl(drawControl);
map.on("draw:created", (e) => {
drawn.clearLayers();
drawn.addLayer(e.layer);
document.querySelector("#boundary_geojson").value = JSON.stringify(
e.layer.toGeoJSON(),
);
});使用Leaflet Draw或Geoman工具。以GeoJSON格式存储几何数据。
javascript
const drawn = new L.FeatureGroup().addTo(map);
const drawControl = new L.Control.Draw({
draw: { polygon: true, rectangle: true, marker: false, circle: false },
edit: { featureGroup: drawn },
});
map.addControl(drawControl);
map.on("draw:created", (e) => {
drawn.clearLayers();
drawn.addLayer(e.layer);
document.querySelector("#boundary_geojson").value = JSON.stringify(
e.layer.toGeoJSON(),
);
});Geofencing (Overview)
地理围栏(概述)
Geofencing must be enforced at two levels:
- UI constraint: prevent invalid selections in the browser
- Server constraint: verify boundaries in backend validation
See geofencing.md for full patterns, point-in-polygon checks, and multi-geometry rules.
地理围栏必须在两个层面实施:
- UI约束:在浏览器中阻止无效选择
- 服务端约束:在后端验证边界
详见geofencing.md获取完整模式、点-in-多边形检查及多几何规则。
UI Patterns
UI模式
- Filters + stats in a side card, map in a large canvas
- Legend to toggle categories (customer groups, territories)
- Clustering when markers exceed ~200
- 侧边栏卡片展示筛选器和统计数据,地图占据主画布
- 图例用于切换分类(客户组、区域)
- 当标记数量超过约200个时使用聚类
Performance & UX
性能与用户体验
- Debounce search and map redraw
- Use marker clustering or server-side tiling
- Lazy load heavy layers
- Simplify large polygons for UI display
- 对搜索和地图重绘操作做防抖处理
- 使用标记聚类或服务端瓦片
- 懒加载重型图层
- 简化大型多边形以适配UI显示
Backend Validation
后端验证
Always validate coordinates server-side:
- Ensure latitude is between -90 and 90
- Ensure longitude is between -180 and 180
- Enforce geofence boundaries with the same logic as UI
- Load optional tile provider keys (for example ) from system settings when building map pages
osm_api_key
务必在服务端验证坐标:
- 确保纬度在-90到90之间
- 确保经度在-180到180之间
- 使用与UI相同的逻辑实施地理围栏边界验证
- 构建地图页面时从系统设置加载可选瓦片服务密钥(如)
osm_api_key
Privacy & Security
隐私与安全
- Location data is sensitive: protect with permissions
- Never trust client-only validation
- Avoid exposing private coordinates without authorization
- 位置数据属于敏感信息:需通过权限保护
- 绝不能仅依赖客户端验证
- 未经授权避免暴露私有坐标
Recommended Plugins
推荐插件
- Leaflet Draw or Leaflet Geoman (drawing tools)
- Leaflet MarkerCluster (performance)
- Leaflet Control Geocoder (search)
- Turf.js (geospatial analysis)
- Leaflet Draw或Leaflet Geoman(绘图工具)
- Leaflet MarkerCluster(性能优化)
- Leaflet Control Geocoder(搜索功能)
- Turf.js(地理空间分析)
References
参考资料
- geofencing.md (sub-skill)
- references/leaflet-capabilities.md
- references/leaflet-arcgis-equivalents.md (index)
- geofencing.md(子技能)
- references/leaflet-capabilities.md
- references/leaflet-arcgis-equivalents.md(索引)