为何我的代码无法依据JSON坐标绘制椭圆?报错'r is undefined'
问题:使用JSON绘制地图标记时出现
r is undefined错误且无椭圆绘制 我尝试用JSON文件实现基础地图绘制,目标是根据JSON里的latitude(纬度)和longitude(经度)绘制椭圆。用for循环遍历数组时,打印xgeo和ygeo出现错误提示r is undefined,而且没有椭圆被绘制。
原代码
let bkgImage; let urlMap, urlC; let mapGeoLeft, mapGeoRight, mapGeoBottom, mapGeoTop; let xgeo, ygeo; let w, h; function preload() { urlMap = "https://api.mapbox.com/styles/v1/mapbox/light-v11/static/[-123,29.7604267,-70.2553259,41]/600x400@2x?access_token=YOUR_MAPBOX_ACCESS_TOKEN"; urlC = loadJSON("cities.json") bkgImage = loadImage("US.Map.png"); } function setup() { let u1 = split(urlMap,"/"); //string let u2 = u1[8]; //taking coordinate info. let coord = split(u2,","); // taking off , coord[0] = coord[0].replace("[",""); //taking off [] coord[3] = coord[3].replace("]",""); mapGeoLeft = coord[0]; mapGeoRight = coord[2]; mapGeoTop = coord[1]; mapGeoBottom = coord[3]; createCanvas(600, 400); image(bkgImage, 0, 0, width, height); print(mapGeoRight); print(mapGeoLeft) } function draw() { for(let r = 0; r < urlC.length; r++){ let lon = urlC[r].longitude let lat = urlC[r].latitude let xgeo = map(lon, mapGeoLeft, mapGeoRight, 0, width); let ygeo = map(lat, mapGeoTop, mapGeoBottom, 0, height); fill(255,0,0); ellipse(xgeo, ygeo, 5, 5) } // print(lon); noLoop(); }
所用JSON文件(部分内容)
[ { "city": "New York", "growth_from_2000_to_2013": "4.8%", "latitude": 40.7127837, "longitude": -74.0059413, "population": "8405837", "rank": "1", "state": "New York" }, { "city": "Los Angeles", "growth_from_2000_to_2013": "4.8%", "latitude": 34.0522342, "longitude": -118.2436849, "population": "3884307", "rank": "2", "state": "California" }, { "city": "Chicago", "growth_from_2000_to_2013": "-6.1%", "latitude": 41.8781136, "longitude": -87.6297982, "population": "2718782", "rank": "3", "state": "Illinois" } ]
问题分析与修复方案
1. JSON加载验证与遍历安全
urlC.length报错的核心原因是urlC未正确加载为数组(比如文件路径错误、加载失败),导致length属性不存在,循环条件失效引发r相关错误。
- 修复:遍历前先验证
urlC是数组:if(Array.isArray(urlC)){ // 执行遍历逻辑 } else { console.log("JSON加载失败或格式错误"); }
2. 坐标类型转换错误
从urlMap提取的mapGeoLeft等变量是字符串类型,而p5.js的map()函数需要数值参数,这会导致坐标计算完全错误,椭圆无法显示。
- 修复:将提取的坐标转换为数值:
mapGeoLeft = Number(coord[0]); mapGeoRight = Number(coord[2]); mapGeoTop = Number(coord[1]); mapGeoBottom = Number(coord[3]);
3. 纬度映射方向错误
地图y轴向下,而纬度值越大越靠北(地图上方),原代码的纬度映射会导致标记位置颠倒。
- 修复:交换纬度的输入范围顺序:
let ygeo = map(lat, mapGeoBottom, mapGeoTop, 0, height);
修复后的完整代码
let bkgImage; let urlMap, urlC; let mapGeoLeft, mapGeoRight, mapGeoBottom, mapGeoTop; let xgeo, ygeo; function preload() { urlMap = "https://api.mapbox.com/styles/v1/mapbox/light-v11/static/[-123,29.7604267,-70.2553259,41]/600x400@2x?access_token=YOUR_MAPBOX_ACCESS_TOKEN"; urlC = loadJSON("cities.json"); bkgImage = loadImage("US.Map.png"); } function setup() { let u1 = split(urlMap,"/"); let u2 = u1[8]; let coord = split(u2,","); coord[0] = coord[0].replace("[",""); coord[3] = coord[3].replace("]",""); // 转换坐标为数值类型 mapGeoLeft = Number(coord[0]); mapGeoRight = Number(coord[2]); mapGeoTop = Number(coord[1]); mapGeoBottom = Number(coord[3]); createCanvas(600, 400); image(bkgImage, 0, 0, width, height); } function draw() { // 确保JSON加载为数组再遍历 if(Array.isArray(urlC)){ for(let r = 0; r < urlC.length; r++){ let lon = urlC[r].longitude; let lat = urlC[r].latitude; // 修正纬度映射方向 xgeo = map(lon, mapGeoLeft, mapGeoRight, 0, width); ygeo = map(lat, mapGeoBottom, mapGeoTop, 0, height); fill(255,0,0); ellipse(xgeo, ygeo, 5, 5); } } else { console.error("未正确加载城市JSON数组"); } noLoop(); }
内容的提问来源于stack exchange,提问作者biboo
相关产品推荐
相关产品推荐

