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

p5.js结合Mappa(Leaflet)实现地图悬停弹窗与天气API展示问题

问题修复与功能实现方案

接口切换报错修复

你遇到的报错是因为两个天气接口返回结构不一致导致的:

  • 纽约点位用的/weather是单点位查询接口,返回数据顶层直接包含main、weather字段,可以直接通过json.main.temp_max读取温度
  • 佐治亚区域用的/box/city是多点位范围查询接口,返回的所有点位天气数据存放在list数组中,没有顶层main字段,直接读取json.main会返回undefined,触发属性读取报错。

修复代码示例:

// 存储温度
let temperature;
// 存储天气
let weather = "";
let points;
let json;
let longitude;
let latitude;
// 存储当前悬停的点位
let hoverPoint = null;

let myMap;
let canvas;
const mappa = new Mappa("Leaflet");
let zoom = false;
let options = {
  lat: 32.8407, //画布中心纬度
  lng: -82.6324,
  zoom: 7.4,
  style: "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png",
};

function preload() {
  let gaUrl = "https://api.openweathermap.org/data/2.5/box/city?bbox=-85.605165,30.357851,-80.839729,35.000659,10&appid=f7e1bf3a627a1b8861aa5c001a1a4f1a&units=imperial";
  json = loadJSON(gaUrl);
  data = loadJSON("/data/gaStations.json");
}

function setup() {
  canvas = createCanvas(800, 600);
  myMap = mappa.tileMap(options);
  myMap.overlay(canvas);
  fill(200, 100, 100);
  points = myMap.geoJSON(data, "Point");

  // 修复接口取值逻辑,取区域第一个点位的天气作为整体展示,也可遍历计算平均值
  if(json && json.list && json.list.length > 0){
    temperature = json.list[0].main.temp_max;
    weather = json.list[0].weather[0].description;
  }
}

function draw(){
  clear();
  hoverPoint = null;
  
  // 遍历绘制所有点位
  for(let i = 0; i < points.length; i++){
    const point = points[i];
    const pos = myMap.latLngToPixel(point.lat, point.lng);
    fill(200, 100, 100);
    noStroke();
    circle(pos.x, pos.y, 10);
    
    // 判断鼠标是否悬停在点位上
    if(dist(mouseX, mouseY, pos.x, pos.y) < 10){
      hoverPoint = {
        name: point.properties.name, // 这里替换成你gaStations.json里的点位名称字段
        pos: pos
      };
    }
  }
  
  // 绘制右上角固定天气展示
  fill(255);
  stroke(100);
  rect(width - 180, 20, 160, 60, 5);
  fill(0);
  noStroke();
  textSize(14);
  text(`区域天气: ${weather}`, width - 170, 45);
  text(`最高温度: ${temperature}°F`, width - 170, 65);
  
  // 绘制悬停悬浮框
  if(hoverPoint){
    fill(255);
    stroke(100);
    rect(hoverPoint.pos.x + 10, hoverPoint.pos.y - 40, 150, 30, 5);
    fill(0);
    noStroke();
    textSize(14);
    text(hoverPoint.name, hoverPoint.pos.x + 20, hoverPoint.pos.y - 20);
  }
}

功能说明

  • 鼠标悬停点位触发逻辑:通过latLngToPixel将点位经纬度转换为画布像素坐标,计算鼠标和点位的距离,小于10px即判定为悬停,渲染悬浮框展示点位名称
  • 天气展示:默认在右上角固定展示区域整体气象数据,也可根据点位坐标和天气接口返回的list数据匹配,在悬浮框中展示对应点位的专属气象数据
  • 接口兼容处理:添加了返回数据判空逻辑,避免接口请求异常时触发JS报错

内容的提问来源于stack exchange,提问作者Christopher Charles-Noriega

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 10:36:07